ファイルロードの仕組み

ファイルのパース

ファイルのロードは、FIFileSprFIFileXのようなFIFileの派生クラスのLoadImp()メソッドが行います。 ファイルパースの実装は、boost::spiritを用いて実装されています。Init()メソッドでパーサの文法を定義しています。

ディスクリプタの生成

パーサはFILoadContextをコンテキストとして用いながらパースを進めます。 fieldItsにロード中のデータの型情報をセットしていきます。 ノード名やメンバ名からディスクリプタやメンバの型を知る必要がありますが、ビルド時にSWIGで生成しているディスクリプタの型情報を??Sdk::RegisterSdk()が登録したものを用いています。 新しいノードが出てくる度にFILoadContext::datasにディスクリプタを用意し、データをロードするとそこに値をセットしていきます。 他のノードへの参照は、この時点ではノード名の文字列で記録しておきます。

参照のリンク

ファイルをすべてロードし終わると、LoadImp()から抜けて、FIFile::Load(FILoadContext*)に戻ってきます。 他のノード(他のディスクリプタ)への参照をノード名の文字列を頼りにポインタでつないでいきます。

オブジェクトの生成

オブジェクト生成は、FILoadContext::CreateScene()が、 ディスクリプタツリーを根本からたどりながら順に行います。 ディスクリプタからオブジェクトを生成するのは、そのオブジェクトの先祖オブジェクトです。先祖オブジェクトが生成できない場合はSDKの生成を試みます。 SDK以外が一番根本にあるファイルをロードするためには、予め先祖オブジェクトを用意しておく必要があります。 FIFile::Load(ObjectIfs& objs, const char* fn)objs引数はその役割をします。

生成されたオブジェクトは、親のAddChildObject()ですぐに子として追加されます。

参照のリンク

ディスクリプタ間の参照はポインタになっていますが、シーングラフは繋がっていません。ディスクリプタの参照に従って、ディスクリプタから生成されたオブジェクト間に参照を追加します。リンクは、AddChildObject()関数を呼び出すことで行われます。親子と参照の区別はつかなくなります。あるノードの下に子ノードを書いても、別のところに書いたノードへの参照を書いても同じシーグラフになるわけです。