log
どうして今まで気がつかなかったのかが謎だけど、GraphにanchorTableを持たせるんじゃなくて、アンカーを扱う物理演算PL_Anchorに持たせればJSONで物理演算を出力するのが面倒という問題は解決されるじゃないかと今朝5時に気がついた。
変更した。
JythonでJavaのクラスMapに対して isinstance(obj, Map)なんてのできるんだなぁ。 typeするとPyJavaInstanceとか表示されるけど、getClassすればJavaのクラスが得られるし。
IGRINObjectというインターフェイスを作ってみた。 XML-RPC経由で操作できるオブジェクトたちが持つべきメソッドを インターフェイスの形で明確化。
あー。 クラスでgetNameという名前のメソッドを宣言すると、 ClassクラスのgetNameとややこしくなりそう。 うーん。nameはそもそもクラスの名前と紛らわしいからと言ってクラスの名前の側をclassnameと書いているんだけど、nameもidに変えてしまったほうがいいのかもなぁ。nameでは一意であることがあまりアピールされていないし。
何も頂点のない状態でJSON形式で保存してpprintで整形するとこんな感じ。
{'Edge': {},
'Law': {'Anchor': {'classname': 'org.nishiohirokazu.layout.PL_Anchor',
'params': {'target': {}, 'id': 'Anchor'}},
'Repulsion': {'classname': 'org.nishiohirokazu.layout.PL_Repulsion',
'params': {'id': 'Repulsion',
'repulsionK': 0.02,
'repulsionRadius': 3.0}},
'SpringEdge': {'classname': 'org.nishiohirokazu.layout.PL_SpringEdge',
'params': {'defaultNormalLength': 1.0,
'defaultSpringStrength': 0.1,
'id': 'SpringEdge'}}},
'Vertex': {},
'version': 'alpha0.20'}
ぎゃー。 JythonのPyFloatクラスやPyIntegerクラスはPyObjectを直接継承している!PyNumberとかないの?!
File "plugins\grinedit-app\menu-saveAsJSON\init.py", line 52, in func java.lang.ClassFormatError: Invalid method Code length 75346 in class file org/python/pycode/_pyx13100頂点のグラフをJSONで出したものをJythonでevalしたら「そんな長いものはevalできない」と怒られてしまった。 JSONをPythonとして扱うのは無理みたいだ。 「Pythonとして読める」というメリットが使えないのであればJSONにこだわる理由はあまりない。単に永続化したいだけならpickleで、人間に見やすくしたいならYAMLで、XMLにしたいならXMLで。
Edgeの頂点をセットするメソッドで、引数として与えられた「頂点のid」を解決して自分のフィールドに頂点を置いている。 その為、単純に永続化されたファイルから復元したときにEdgeの作成が頂点の作成より先に来るとエラーになる。解決法はいくつかある。
- ローダに手を加えて頂点を先に作成するようにする
- 一番早いけど、やな感じ。
- 実際にレンダリングなどで頂点オブジェクトを使うときまで評価を遅延させる
- nullチェックの分遅い。あと、微妙。
- 頂点への参照を直接持つのをやめて、頂点のidで持つ。
- これが一番美しい。現状では作成した後で頂点のつながっている頂点を変えることはできない(消して新しく作るしかない)けど、これなら普通のsetterで頂点のidを変更するだけでつながる先が変わる。
- ただし描画や整形のたびに全ての辺が2回ずつHashtableで名前解決をする。
多少不満が残るけども、1番目の選択肢で。
ふぅ。できた。 日曜日ももう終わりかぁ…。
JYaml - Yaml library for the Java language。ListとMapが扱えて、書いてないけどStringも当然扱えるだろうから、CommonGatewayを通せばほとんどコーディングなしでシリアライズできるかもなぁ。でもまぁ、それは今すぐじゃなくていいや。