「プログラミング」タグアーカイブ

Irrlicht日本語対応カスタムGUIテスト4

IrrIM Test 2007.11.21a Ver.

前回までの続き。Irrlicht.dllと多言語用改造コードを分離するプロジェクトです。

Windows版のみですが、ソースがまとまったので公開します。Irrlichtのライセンスに従い自由にご使用下さい。

IrrIM Test 2007.11.21a

また、フィードバック もお待ちしております。1.4betaとIrrIM、どちらの不具合か分からない場合でも、気にせずお気軽に報告下さい。

Irrlicht日本語対応カスタムGUIテスト2

前回に続き、Irrlicht.dllに手を加えず各国語対応するテスト第二弾。今回はマルチバイト文字の入力にチャレンジ。1.4βで試作。

Official Irrlicht with Custom GUI 2

Irrlichtのキーイベントでは、幾ら頑張っても完全にマルチバイト文字を取得することは出来ません(Linuxの場合は不明)。そこで、Irrlicht外部でWM_IME_CHARを横取りしてしまおうと計画。テストソースを書き上げて実行。

動 か な い

コンパイルエラーという訳ではありません。そもそも、WM_IME_CHARイベントを取得できないんです。IrrlichtMLでは内部でWM_IME_CHARを検出し、その情報を元にマルチバイト文字を取得しています。それが、外部に移しただけで機能しなくなるとは…。

とりあえず、回避作の目処は立ちましたので、近いうちに前回の分もセットで新しい実装をお披露目できるかと思います。

Irrlicht1.4はconst修飾子で関数厳格化されている

Irrlicht1.4から関数の修飾子が厳格化されます。例えば、get系の値取得関数は、メンバ変数の値を変更しないように、インターフェースクラスの段階からconst修飾子に縛られているのです。もちろん、不都合があるならメンバ関数をconst修飾子無しでオーバーライドしてしまえば、従来と変わりなく既存ソースを流用できます。

そこで、Irrlichtを使用している人も、その他の人も、ここでC++のconst修飾子についておさらいしましょう。

const char* foo(const char* str) const;

最初のconstから順番に説明していきます。

  1. 戻り値の値はfoo関数外部で変更されない
  2. 引数strの値はfoo関数内部で変更されない
  3. メンバ変数の値はfoo関数によって変更されない

プログラマが明示的に宣言することで、関数の挙動がある程度分かるようになります。そのため、後々の保守作業において効果を発揮します。うっかりメンバ変数の値を変更してしまい、謎の不具合に悩まされる事も少なくなるでしょう。

しかし、const修飾子は問題がない訳ではありません。特に上記例の3番目のconst宣言は厄介です。関数内でメンバ変数に手を加えるような実装がなされていると、コンパイルが通りません。関数設計を見直そうにも時間がない。バグ混入も恐ろしい。お手上げです。

そこで、mutable修飾子の出番です。これを用いてメンバ変数を宣言すると、特別にconst関数内でも値の変更が認められます。このアンチconstとも言うべき修飾子の存在は、本来期待される制限を歪めてしまう為、何だか本末転倒な感じではあります。最終手段として使うにとどめるのがいいでしょうね。

話は戻りますが、Irrlicht1.4βでもmutable修飾子が使われているところがありました。多少やりすぎなところもあり、IReferenceCounted::grub()にまでconst宣言がされてました。果たして、そこまで必要なのか疑問に思ってます。

Irrlichtの日本語対応カスタムGUIテスト

Irrlicht.dllに手を加えず、各国語対応するテスト第一弾。1.4βで試しています。

Official Irrlicht with Custom GUI

IGUIFileOpenDialogの派生クラスを作る事により日本語表示が可能。コードはIrrlichtMLからコピペしただけです。ただし、これだけでは表示するGUIオブジェクトの管理が面倒になるかと思います。なので、GUIElementFactoryに登録してしまったほうがいいでしょう。

ちなみに、このテストはirrTTを使わなくても、日本語ビットマップフォントを作成して読み込ませれば成功するはず。

参考文献:Custom GUI Development(Irrlicht Forum)

Irrlicht.dllのソースを書き換えずとも、IGUIElementを継承して新しいGUIを作成できる。既に登録されているGUIを複合的に組み合わせる事も可能。詳しくは各GUIエレメントのソースか、GUIエディタのプロジェクトを参照のこと。もし、GUIエディタで自分が作成した新GUIを編集したいのなら以下のようにするといい。

  1. IGUIElementのserialize/deserializeAttributes/getTypeをオーバーライドすること。そうすれば、編集、読み込み、書き込みが可能になる。
  2. 子エレメントはsetSubElement(true)を呼び出し、親の管理化であることを宣言する。
  3. 名称からGUIオブジェクトを生成できるように、カスタムエレメントを新規IGUIElementFactoryに登録する。