TextReadStream および TextWriteStream は暫定実装です。
この部分に関してはファイルから TJS スクリプトを実行する為の仮実装です。
オリジナルの吉里吉里2と同様に TextReadStream / TextWriteStream は、吉里吉里側に移動(実装)される予定です。
TJS2 側には、TextReadStream / TextWriteStream のインターフェイスと、ファクトリクラスのインターフェイスが置かれ、ファクトリクラスを登録することでそこから TextReadStream / TextWriteStream が返される実装となる予定です。
指摘のあったアーカイブ以外に、吉里吉里2では xp3アーカイブからの読み込みが必要であるのと、パッチのためのファイル検索順等の実装が必要となります。
xp3アーカイブは多重(jar/apk内)にアーカイブ化されている可能性もあるので、その辺りも考慮する必要があります。
その部分については、吉里吉里側での実装となるので、まだ実装自体行われていません。
なお、Androidのリソース ( drawable / sound / raw ) フォルダについては、
によって、リソースのID が得られるので、その ID を使うことで、文字列からリソースを開くことが出来ますね。
インターフェイスと、ファクトリクラスのインターフェイスが置かれ、ファクトリクラスを登録することでそこから TextReadStream / TextWriteStream が返される実装となる予定です。
そこは推察していたのですが、これでは場所ごとにSPIまたはそれに類する実装(コンクリートクラスとファクトリクラスのセット)が必要となり、 これらのクラスは場所ごとに(詳細に関しては他にも固有なものがあるかもしれませんが)主にコンストラクタの内容が多少違うだけのいわゆる"怠け者クラス"を 事前にわかる場所(少なくともjar,assets,raw等があるresフォルダ,XP3)、それに加えて事前にはわからない独自のアーカイブの数*2(コンクリートとファクトリ)ほどクラス数が必要になってしまいます。
このこと自体怠け者クラスを大量に生み出す設計になるばかりか、個々の実装を必要とする継承による方法およびファクトリ方式ではJAXPのように煩雑になりがちです。
Javaによくあるファクトリの乱用とデザインパターンの強要は使い勝手が悪く制限される部分もありますので今後の開発のことも踏まえ避けるべきだと私は考えます。
少し外れますが問題点がもう一つ、Androidの場合TextReadStreamに限らずいちいちファクトリを使っていてはメモリを余分に消費する事とキャッシュされてない部分の短いサイクルのnewとGCを頻発させバッテリも喰らいCPUパワーを消費し端末にやさしくありません。
PCとHotSpotVMとは違いAndroidのスペックとVMは(invokevirtualの呼び出しが実行速度に影響を与えるくらいには)貧弱ですのでこちらに合わせた実装のほうが良いように思われます。
たぶん考えているものに相違があるのだと思いますが、なぜ場所ごとにクラスが必要になるのでしょうか?
ファクトリクラスがパスから InputStream を生成し、それを TextReadStream に渡して返す作りにすれば良いだけではないでしょうか?
( この場合ファクトリクラスと呼ぶのは不適切かもしれませんが )
もう一つの問題点として書かれていることですが、それは KAG3 が Android でまともに動作しないくらいに致命的な問題でしょうか?
後、現状ファクトリを使っているところはありましたか?
たぶん考えているものに相違があるのだと思いますが、~~
ファクトリクラスがパスから InputStream を生成し、それを TextReadStream に渡して返す作りにすれば良いだけではないでしょうか?
一つ確認ですが、このファクトリクラスというのはAbstract FactoryパターンではなくFactory Methodパターンを持つひとつのManagerクラスという意味ですか?
インターフェイスと、ファクトリクラスのインターフェイスが置かれ、ファクトリクラスを登録することでそこから TextReadStream / TextWriteStream が返される実装となる予定です。
とあったのでAbstract Factoryパターンという前提で話していたのですが。
Factory Methodパターンを持つひとつのManagerクラスという意味です。
説明はオリジナルのTJS2の実装を踏襲すると書いたつもりでしたが、誤解を生む表現だったかもしれませんね。
Factory Methodパターンを持つひとつのManagerクラスという意味です。
了解しました。ではFactory Methodパターンということでお話しします。
AbstractFactoryではないのなら問題点は
ということだけです。
Factory MethodならばConcreteTextReadStreemごとのAbstractFactoryは不要です。
しかし、コンストラクタに文字列を渡してしまうと文字列から実際のリソースを取得する処理が、リソースの場所ごとに TextReadStreemに存在してしまうため場所の数だけConcreteTextReadStreemが必要になってしまいます。
リソースの種類を表す引数を追加してもいいですがこれでは決め打ちとなり多様性が損なわれます。
そこでInputStreemを渡すコンストラクタを持ちリソースの取得をTextReadStreemの外から出すことで、 リソース取得の責任をTextReadStreemから解放しファイルパス文字列に依存せずTextReadStreemをインスタンス化させます。
InputStreemを得る手段は何でもよく、パスからファイルだろうがURLから開いたストリームだろうが気にする必要はなくなります。
また、InputStreemを利用することはJavaの慣例と整合性があるのでopenRawResource(int)・getAssets().open(String)・getResourceAsStream(String)の他も、 とくにグルーコードなどもなく既存のAPIからTextReadStreemをインスタンス化できます。
ストリームの生成を文字列に依存せずよく知られた・既にある方法を利用することで柔軟性をもたせ煩雑なコードを減らすことが目的です。
指摘を読むと何点か違和感を覚えるのですが、吉里吉里2がどのようにファイルを扱っているのか理解していますか?
理解していないようなのでクローズ
現状ではリソースをファイルパス文字列の形で知りえない場合にリソースを取得できません。
特定のAPIを経由してならリソースを取得できるがプログラマが自由にアクセスできない場合もこれに含みます。
とくにAndroidで動作させる妨げになっています。
Androidではjavaではリソースは
またはアーカイブなどから独自にInputStreemを取得します。
よってTextReadStreamのコンストラクタに文字列を渡し、内部でnew FileInputStream(String)としてしまうと 上記のいずれかの方法でファイルを扱えなくなってしまいます。
これはコンストラクタTextReadStream(String, String)の他にTextReadStream(InputStreem, String)を持つべきです。
さらにこれに関連して、スクリプト上ではファイルパス文字列を用いてリソースにアクセスしているため tjsからjavaへファイルを要求した場合、文字列からInputStreemを取得する補助クラスが必要になると思われます。 少なくとも上記のjarとassetsから適切に取得できる必要があります。
rawフォルダの場合openRawResource(int)を呼ぶ以外に 透過的な方法がないのでファイルを置くのは決め打ちできるstartup.tjsのみに限定したほうがいいかもしれません。