モノトーンの伝説日記

Apex Legends, Splatoon, Programming, and so on...

Xxaml (Cross xaml) についての話 (6) ~ プロトタイプ公開した話。

 昨日の夜、プロトタイプを公開しました。

概要

  1. プロトタイプの解説 (設計)
  2. まとめ

1. プロトタイプの解説 (設計)

 まだ描画周りの実装がちゃんとできてないです。

 描画周りは描画 Queue に一度描画命令を貯めて、描画自体のフェーズは独立したものとして書こうと考えています。

1.1. オブジェクト

 すべてのオブジェクトは COM のような自己参照カウントオブジェクトです。ただしクロスプラットフォームのため、特別な xobject と xobject_sptr が用意されます。

 xobject は COM でいう IUnknow や IInspectable に当たると思ってもらって構いません。どちらかというと IInspectable 思考が強いと思われます (型情報を持っています)。

1.2. 例外

 言語プロジェクションで容易に扱うため、C++ 例外は使用しません。代わりに xresult (COM でいう HResult) を利用します。

 C++ も言語 Binding が用意される予定で、C++ から使うための C++ Proxy は作成される予定です。この場合、C++ 例外を使います。

 仕組みとしては、各言語レイヤーで xresult を処理して例外に置き換えます。これにより各言語で正しく例外が扱うことができ、比較的コードも簡素になります。

1.3. 今後

 とりあえず OpenGL 描画レイヤーと Win32 命令処理を正しく実装する必要があります。

 そこができれば xaml コンパイラー (xxbf: Cross Xaml Binary Format; Code Behind) の作成が必要です。これはまだ全く手を付けていないです。

 そして何といっても xaml 要素の参照方法です。XML スキーマの仕組みを使って参照されるわけですが、このあたりをどう実装するかです。

[C++ Xaml Tree Builder]
    -> [xml schema] -> [IXamlMetadataProvider]

 こんな感じでしょうか。まず xaml の builder が xml schema を見て各 UI ライブラリーの IXamlMetadataProvider にアクセスします (んー、ロード時にこの ptr を追加するのが一番ベストっぽい)。それから情報を得る、といった感じです。

 Binding 周りは以下の通り

[C++ Property System]
    -> [native metadata system]/[JVM/CLR reflection system]

 native の場合はコンパイラーからすべて情報を生成します。メタデータが生成するかどうかをメタデータコンパイラーが識別する必要があるので、C++ では // [bindable] みたいなのが妥当でしょうか。リフレクションも同じです。

 これらは共通のインターフェースを通して実装することができます。JVMCLR も 1 つの metadata という形で C++ に認識することにより、Java, C# 混在の状態が可能となります。

 問題は、C++ が認識できる型である必要ということですが、これは各言語が差異を吸収すれば可能になります。

  1. C++ で Binding のデータを参照
  2. XamlTypeInfoProvider [各アプリに 1 つ] に問い合わせます。
  3. IXamlType からクラス (列挙) の情報を得ます。
  4. IXamlMember から型の情報を得ます (getter/setter はこれを介してアクセスされます)。

 ここで注目すべき点は IXamlType/IXamlMember ですが、これは各言語で実装することができます。

 たとえば C# で書かれた UI ライブラリーを利用したいとき、XamlTypeInfoProvider から C# の IXamlType へと自動でリダイレクトするようにすれば問題ないわけです。

 難しいことは GC なオブジェクトをきっちり管理することです。UI オブジェクトにしろ何に白各ライブラリー側での吸収になりそうな気がします。たとえば、Binding オブジェクトにしろ、1 つのオブジェクトに対して、1 つのダミーオブジェクトを発行する必要があります。これはユニークで、ダミーオブジェクトは各仮想マシンで正しく言語オブジェクトに還元される必要があります。

 Binding をそのままリフレクションで参照するわけじゃないので、型情報さえあればダミーオブジェクトの型から各情報にアクセスすることができます。これはきわめて簡単でそして native と GC をうまく動かすことが可能になります。

 以上で基本的な技術課題のほとんどが解決されています。唯一の問題として、C#Java の UI ライブラリーをどのように起動させるか、です。このプロセスがまだ確立されていなくて、実際ここがうまくいかないと UI ライブラリーはアプリと同一のバイナリーに含む以外の選択肢がなくなってしまいます。

 ただ、それではうまみがないので、何らかの方法を研究する必要があるかも…

 Java の UI ライブラリーと Java のアプリなら XamlTypeInfoProvider で 1 つの仮想マシンでうまく動かせますが、Java から C# のオブジェクトを参照したりはとりあえず難しいってことで。今後の課題かな…

2. まとめ

 メモリーリーク問題や、xaml コントロールの開発お待ちしております! xaml が得意な人は xaml の演算部分を実装していただけると助かります! レイアウトエンジン結構作るの大変です!

 プロトタイプといっても大半のコードがそのまま本番にも使えると思います。

 クロスプラットフォームで様々な言語で xaml を使ってアプリを作れる時代を作りましょう!

 GitHub: https://github.com/mntone/XXaml