第弐拾話
Asuka と MyGo
プラットフォーム純正のウィジェットか、フレームワークが描く UI か。それぞれが動く環境(MyGo のスマートフォン対応は近日公開予定)と、どちらを使うべきか
MyGo を使うと、Go でデスクトップアプリを作れます。スマートフォンへの対応も近日予定です。Asuka も MyGo も Go だけで完結し、どちらも cgo を使わずにデスクトップの API を呼び出します。両者が違うのは、アプリが動く場所と、何より UI を何が表示するかです。MyGo は UI を自前で描画するか、Web ページを表示します。Asuka は各プラットフォーム純正のウィジェットを表示します。
UI を表示するもの
MyGo のウィンドウが表示するのは、次の二つのどちらかです。
- MyGo が自前で描画する UI。GPU(Mac では Metal、Windows では Direct3D 11、ほかに OpenGL)で、MyGo のテーマに沿った見た目に描画します。テキストはシステムのテキストエンジンが担当し、描画した内容からアクセシビリティツリーを組み立てます。
- Web ページ。システムの Web ビュー(WKWebView、WebView2、WebKitGTK)で表示し、MyGo が生成する TypeScript クライアントを通じてアプリの Go のコードを呼び出します。
Asuka のアプリは、各プラットフォーム純正のウィジェットを表示します。たとえば ui.Button は、iOS では UIButton、Android では MaterialButton、Mac では NSButton、Windows では Windows 11 風に描画された Win32 の BUTTON、Linux では GtkButton、ブラウザーでは <button> になります。一覧はコンポーネントにあります。Asuka は、すべてのプラットフォームに共通の Go 製レイアウトエンジンでウィジェットを配置し、プロパティを設定します。描画するのはプラットフォームです。そのため、ウィジェットはプラットフォーム自身のものとして動作します。テキスト入力と自動修正、入力メソッド、スクリーンリーダー、メニュー、スクロール、フォーカスも、すべてプラットフォームのものです。
この違いから、次のような差が生まれます。
- 見た目。 スタイルを何も設定しない Asuka のアプリは、各プラットフォームのアプリと同じ見た目になり、プラットフォームが変わればそれに追従します(新しい iOS でボタンのデザインが変わったり、新しい libadwaita でスイッチのデザインが変わったりした場合です)。MyGo のウィンドウは MyGo のテーマどおりの見た目で、どのシステムでも同じように描画されます。
- テキスト、入力、アクセシビリティ。 Asuka ではプラットフォームのものを使い、処理もプラットフォームが行います。MyGo では MyGo 独自のもので、自前で描画した内容の上に作られています。
- ウィジェットでは表せないもの。 MyGo は、ほかの部分と同じ方法で何でも描画します。Asuka には、対応するウィジェットがないものを描くためのパッケージがあり、プラットフォームの描画機能を使って描きます。
asuka/sdk/chart、asuka/sdk/svg、それにシェーダー用のui.Shaderです。 - 画面なしでの画像出力。 MyGo にはソフトウェアレンダラーがあります。ウィンドウもディスプレイも GPU も使わずに、CPU でメモリ上に描画するので、テストやサーバーがどんなマシンでもビューを画像にレンダリングできます(
ui.NewTester、ui.Render)。Asuka のウィジェットはプラットフォームが描画するため、画像にするにはプラットフォームが動いている必要があります。デスクトップならウィンドウ(ASUKA_SNAPSHOT。Linux のサーバーでは Xvfb)、あるいはシミュレーター、エミュレーター、ブラウザーです。それがない環境では、uitestが画面をテキストで記述します。各ビューの種類、フレーム、表示している内容です(テスト)。
動作する環境
| MyGo | Asuka | |
|---|---|---|
| スマートフォン | 近日対応予定 | iOS と Android |
| デスクトップ | Mac、Windows、Linux | Mac、Windows、Linux |
| ブラウザー | 自前で描画する UI(WebGL 2 を使った canvas 上) | ページの DOM(WebAssembly から操作。Web) |
ビューの更新
MyGo のビューはアプリの状態から組み立てる関数で、フレームのたびに状態から作り直されます。Asuka のコンポーネントは一度だけ実行されます。コンポーネントはビューを作ってシグナルと結びつけ、シグナルが変わると、そのシグナルを読んでいるビューだけが、フレームごとに一つのバッチで更新されます(基本概念)。
使い分け
Asuka が向いているのは、次のような場合です。
- 今すぐスマートフォン向けにアプリを作りたい、あるいは一つのコードベースからスマートフォン、デスクトップ、Web 向けに作りたい。
- 各プラットフォームのアプリと同じ見た目と操作感にしたい。コントロール、テキスト入力、アクセシビリティ、ナビゲーションまで含めて。
MyGo が向いているのは、次のような場合です。
- デスクトップ向けのアプリで、UI を Web フロントエンドで作る。既存の Web のコード、HTML と CSS、リッチなドキュメント、ブラウザーにしかない機能を使いたい。
- 各プラットフォームの見た目ではなく、どのデスクトップでも同じように描画される独自の見た目にしたい。エディター、インスペクター、ゲームなどです。
- ビューをヘッドレスで画像にレンダリングしたい。ピクセルを比較するスナップショットテストや、サーバーでの画像生成などです。