Jun 21, 2007

XUL/Migemo [Forked Edition] 0.6.xでAPIまわりがゴタゴタしてる件

うあああやっちまった。既にAPI使ってくれてる人がいたにもかかわらずAPIを予告なしに変更するというを…… 一応、本家XUL/Migemoと互換のAPI(xulMigemoCoreオブジェクト)も備えていて、そちらは動作を変えないようにしているので、XPCOMを叩かずにそっちを使ってもらっていれば今回の変更の影響は受けなかったと思うんだけど、そんなことを言っても後の祭りというやつで。

なぜこうもグダグダになってしまっているかというと、どうすれば国際化を楽にできるか、サービス同士の絡みを最小限に抑えられるか、という点で自分の中で考えが固まっていなかったからだ。

当初はpIXMigemo型のインターフェースを実装した物を「エンジン」として、それをまるごと取り換える方法を考えていた。しかしこれは後から考えてみると、実装の負担がとても大きい。サービス同士の依存関係をツリーっぽく表すと、最初の設計は以下のようになる。

  • pIXMigemoFind
    • pIXMigemo(エンジン、国際化の対象)
      • pIXMigemoTextTransform(エンジンの一部、国際化の対象)
      • pIXMigemoDictionary(エンジンの一部、国際化の対象)
      • pIXMigemoCache
      • pIXMigemoDicManager
        • pIXMigemoDictionary
        • pIXMigemoCache

最初の国際化(0.6.x〜0.6.2)ではこの設計のまま国際化していた。しかしこの設計だと、pIXMigemoはキャッシュの扱いもマネージャの管理も一手に引き受けなくてはならない。

そこで、0.6.3からは言語ごとの処理に関わる部分だけを抜き出して、次のように変更した。

  • pIXMigemoFind
    • pIXMigemo
      • pIXMigemoEngine(エンジン、国際化の対象)
        • pIXMigemoTextTransform(エンジンの一部、国際化の対象)
        • pIXMigemoDictionary(エンジンの一部、国際化の対象)
      • pIXMigemoCache
      • pIXMigemoDicManager
        • pIXMigemoDictionary
        • pIXMigemoCache

これで、エンジン部は入力文字列から正規表現を生成する処理だけに専念することができる。

ただ、キャッシュを制御するpIXMigemoCacheが国際化の対象となるエンジンの下ではなくその一つ上位のサービス(pIXMigemo)にぶら下がっているということで、複数言語のエンジンを同時に動かそうと思ったら、「対応するpIXMigemoEngineを持った、各言語用のpIXMigemo」を複数持てるようにしないといけない。ところが、getService()でpIXMigemoのサービスを取得するとそれを実現できないし、逆に、createInstance()を使うとpIXMigemoに連なってpIXMigemoCacheまでその都度新しいインスタンスが作成されてしまい、ウィンドウが違うと同じ日本語のMigemo検索でもキャッシュが別々になってしまう、という風な事が起こる(二つ以上のpIXMigemoCacheが同じキャッシュファイルに同時に書き込みしようとしてトラブルになる、という事態も考えられる)。

「対応するpIXMigemoEngineを持った、各言語用のpIXMigemo」のサービスのインスタンスを各言語ごとに一つだけ生成できるようにするために苦肉の策で0.6.3で導入したのが、pIXMigemoFactoryサービスだ。このサービスは内部に「言語に対応したpIXMigemoのインスタンス」のリストを保持していて、既にインスタンスを生成済みの言語のサービスについて生成要求があった時には既存インスタンスをそのまま返却し、なければ新規にインスタンスを生成する、という挙動を行う。

いちばん理想的なのは、Components.classes['@piro.sakura.ne.jp/xmigemo/core;1?lang=ja'].getService(Components.interfaces.nsIXMigemo)でいつでも一つだけの「その言語に対応したpIXMigemoEngineを持ったpIXMigemoのインスタンス」を返せるようにすることなんだけど……残念ながらそのやり方がわからないし、そもそも、できるのかどうかも分からない。

という所で詰まっているのが現状という次第です。

エントリを編集します。

wikieditish message: Ready to edit this entry.











拡張機能