アーキテクチャーをいろいろ考えてまとまってきたものを書いていきます。
概要
- プロジェクト概要
- プロジェクトの流れ
- C++ 版について
- その他版について
- ウィンドウ周り挙動
- まとめ
1. プロジェクト概要
なーんかCrossPlatformを考えたら、なんで今までOpenGLをやらなかったんだろか…DirectXしか触ったことないことをちょっと悔やむ感じ。やるしかないかー
— 遥佐保 (@hr_sao) 2015, 1月 20
OpenGL はめんどいからなー。やるなら OpenGL 城で動く xaml レイヤー作りたいけど。
— モノトーン@UP2715Kほしいいいいい (@mntone) 2015, 1月 20
@mntone しましょう!
— 遥佐保 (@hr_sao) 2015, 1月 20
!?
やる気はなかった。というか何度も考えてたし作ろうと思ってて実は下調べしてた事実もある。けど、最近 RoboBinding という存在知って、「ああ、なら UI は個々のプラットフォームで書けばいいか」なんて思ったりしてた。
基本的にやることは WinRT xaml の cross platforms 化。つまり iOS や OS X、Android、Linux、Windows Desktop での利用を目指す。WinRT xaml とほぼ 1:1 に機能的にプロジェクションを目指す。使える言語としては C++, Obj-C (meta-data binding support), C#, Java (reflection binding support), Swift (未定)。スクリプト言語サポートも将来的にあり得るかも。
Swift が未定なのは、リフレクション使えるらしいですが、LLVM でどうコンパイルされるのか、また iOS 上でどう動くのかで状況が変わってくるので詳しい人調査してください。
とりあえず手元でメインに使ってる環境が Windows なので、Windows Desktop 向けに Java と C#, C++ を使いたいと思いたい、ですが… C++ の meta-data binding はスケジュール的にもっとあと。
2. プロジェクトの流れ
- [Phase I] プロトタイプの作成。アーキテクチャー設計
- [Phase II] 本格版作成開始。自動でいろいろなものを作るものを設計。簡易 xaml を実現 (Binding できる機構をもつが、実際のエンジンは作らない)。
- [Phase III] リフレクション Binding 作成。各言語レイヤーに Binding Engine を載せる (Java, C#)。
- [Phase IV] 正式な xaml 再現および派生コントロールを大量に書く。
- [Phase V] Android, iOS に移植 (Swift で meta-data binding を使うならここで作成; LLVM/clang を使った自動生成)。
- [Phase VI] OS X, Linux に移植。
Phase I を 3 月末、Phase III を今年の夏までに完了したい。
Swift はよく知らない。リフレクション使えるみたいだけど、使えるならそっち積極的に使いたいし、使えないなら使えないで何らかの逃げ道がいる。
3. C++ 版について
ある程度下調べして見当がついた。実際には共有ライブラリー (dll, so) を直接叩く感じになると思うけど、実際のところわかりません。
Binding するには C++/CX のようなメタデータを自動生成する必要がありますが、辛いので、LLVM/clang に頼る形で投げます (むしろ最新実装を使えるメリットにもなります)。Java による制約がかなり強く、unsigned は ABI 互換のためにまず排除される予定です。つまり uint8, int32, int64, single, double ぐらいしか使えないかなぁ、と。座標演算は内部で single で扱う予定で、ここをできるだけ高速化したいなぁという思いがあります。
具体的な話は何もできてないですが、C++ 版と書いてるのはまあそれなりに理由がありまして、C++ つかって各言語プロジェクションをしたいからです。POD な構造は C でも使えますが C はサポート論外になるかなぁ。
4. その他版について
一応、C++ クラスを継承できるようにしたいなぁ、って思ったりしてます。C# で C++ のクラスを継承できたりするのもあるみたいなので不可能じゃないと思ってますが修羅場なんじゃないかな、って思ったり。Proxy クラス挟めばいけるのか未知数ですね…
ただまあ、Obj-C/Swift はこのあたりは比較的楽だと思います。同じ LLVM 空間にいるので。問題は VM 使った CLR とか JVM のほうで、こちらをどうやって実現できるか、ってのはまだ未定です。コードビハインド生成は 1 つのコアプログラムに MEF (Managed Extensibility Framework) あたりで拡張すればすぐできると思うし、とりあえず自動がツール周りは C# か F# で書く予定です。
MEF、Mono でも動くのですかね
MEF を使う理由としてあげられるのは、たとえば JVM 言語だけど、せっかく Java で書かれた Xxaml あるのだから、Scala から使いたい! って思った人が自動でコードビハインド生成するプログラムとしてちょっと付け加えればいい、みたいな、そんな構想を目指してます。
ほかにも問題があって、Java なのですが、partial がないのでどのようにするか、ってことですかね。Scala なら trait 使って class で extend すればいいと思うのですが、これができない。「xaml オブジェクトを生成する」=「オブジェクトを生成する」というのが 1:1 に絡みついているのが xaml の特徴なのですが、partial がない C++ や Java では苦労しそうだなぁ… って。C++ なら define してください、でいいと思ってるのですが、Java はまだ考えてない…
とりあえず問題点として
があげられます。このあたり慎重に設計しないと将来が絶望かな、って思います。
あと逆パターンについてもよく考えないとダメ。たとえば Java で作られたカスタムコントロールを正しく実行できるか、などです。基本的にオーバーロードができれば C++ から Measure 読んだら内部で MeasureOverride が呼ばれてこのときオーバーロードされてるから Java 側が呼ばれる、みたいなのがいいわけです。このようなシームレス連携が肝です。
5. ウィンドウ周りの挙動
電話やタブレットと違いデスクトップ OS ではウィンドウを意識することになります。いわゆるマルチウィンドウですが、Android なら 5 から、可能といったところでしょうか。これを明確にサポートするならそういう風に xaml を買えるべきなのか、あるいはコードベースで実装するのか、ってのが気になります。
たとえば、WinRT xaml ですがマルチウィンドウによる Navigation 遷移を採用していて、Page をシームレスに移動することを実現しています。私的にはこの方法はモバイル Platforms では優れていると考えます。しかし Desktop Platforms には最適だとは思えません。メモリーがたくさんあるので、別のウィンドウとして表示するのが最適だと思われます。
したがって、WinRT xaml とは違う何らかの要素をここにぶち込みたいと考えています。WinRT xaml は Frame ですが、これをきちんと Window として扱おうかなぁ…、ってね。まだ未定。
new Window().Navigate( typeof( XXPage ) );
とかやっぱりいいのかなぁ。でも Android とかで気楽にできればそれはそれでマルチウィンドウアプリがやりやすいかもしれません。わかりません。
問題があって、Android では Activity 次元で管理してますが、manifest に NativeActivity とウィンドウを関連付ける制約が起こってもおかしくないかもしれませんね。いや、まあ同じものを流用するのもアリなのかなぁ。どちらにせよ、Intent ハンドリングとかの問題を絡めてこのあたり検討する必要がありそうです。
6. まとめ
疑問に思っていること、考えていることをありのままに書きました。ある程度考えていたことなので、昨日の今日で結構いろいろなことを疑問に思ってあるのはそういうことですが。やっぱりいくつかの技術課題をクリアしないといけない。失敗したら、使いにくいものになってしまう、ってのが思ってることだなぁ。
とりあえずお力ください。あと 3 日で C# や Java における技術基礎をまとめたいです。そのとき改めていろいろ書こうかな、って。
ものとーんさんがやる気や…!!
— 遥佐保 (@hr_sao) 2015, 1月 20
以上