« 環境依存部分 | メイン | KAG3 のコンパイル時間とバイトコード »

2011年12月13日

吉里吉里Java:: プラグイン

    

ソースコードを加えてコンパイルしてしまえば、プラグイン機構はなくてもいいと言えばいいんだけど、あった方が良いことも確か。PC なら、jar ファイルからクラスを読み込んで動的にロード出来るので、その辺りのハンドリングを決めておけば実現することは難しくない。
リフレクションによって、Java のクラスを TJS2 のクラスに登録してしまえるので、クラスの追加は楽に行える。

問題は、Android 。
以前、LGPL の ライブラリを使った時は、動的読み込みにするために Android のサービスによる RPC を使った。
計測はしていないが、RPC なのでオーバーヘッドが気になる。
で、以前少し TJS2 を Delvik バイトコードにして動かすことについて調べていた時に、ClassLoader に Delvik バイトコード食わせてクラスをロード出来るのを思い出し、検索してみたら普通に dex ファイルからクラスを読めるようだ。
以下参考。

Custom Class Loading in Dalvik(翻訳)
アプリケーションパッケージ(.apk)中のクラスを列挙する
アプリケーションパッケージ(.apk)中のクラスを列挙してロードする

これが出来るのなら Android でもプラグインを作ることが出来るな。
吉里吉里Javaとは関係ないけど、サービスを使っていたものはこっちに切り替えようかなと思った。

リフレクションによる呼び出しのオーバーヘッドは、TJS2 の関数呼び出しから見た場合、それほど大きくない。
TJS2 の関数呼び出しとループ処理(TJS2から複数回呼び出しのためのループ)を合わせて計測した場合、リフレクションにしたことによるオーバーヘッドは10%強程度。
周辺部にある程度呼び出しコストがあるためか、リフレクションのオーバーヘッドは意外と少ない。
集中的に呼び出した場合でこれくらいなので、実使用で組み込み関数呼び出しばかりするような状況でなければ、それほど気にすることはないようだ。
ただ、TJS2 の組み込みクラスはリフレクションではなく、メソッドごとにクラスが作られるスタイルで実装したが(オリジナルのC++のTJSと同じような形)。
リフレクションと比べた場合のデメリットは、クラスが増大するためかバイナリサイズは大きくなることと、ちょっと記述が面倒なこと。
オリジナルはマクロで軽減しているが、Java はマクロがないのでちまちま書く必要がある。
無名インナークラスがあるおかげで、C++ で書くのに比べたらかなりマシだけど。
リフレクションなら、簡略化しようとしたら登録関数一発で Java のクラスを TJS2 のクラスに出来るけど。

初期リリースにはプラグイン機能を入れないつもりでいるけど、入れられることがわかったので良かった。



投稿者 Takenori : 2011年12月13日 18:47




comments powered by Disqus
Total : Today : Yesterday : なかのひと