Gooey: ZigのためのGPU加速UIフレームワーク

Gooeyは、Zigプログラミング言語を使用して、高速でGPUレンダリングされたアプリケーションを構築するために設計された、ハイブリッドな即時/保持モードUIフレームワークです。macOS (via Metal)、Linux (via Vulkan/Wayland)、およびブラウザ (via WebAssembly/WebGPU) をターゲットとしており、外部のZigパッケージへの依存なしに、宣言的なコンポーネントベースのUI開発アプローチを提供します。

コアアーキテクチャとレンダリング

Gooeyは、異なるプラットフォーム間で高いパフォーマンスを確保するために、GPU加速レンダリングパイプラインを利用します。シーングラフとバッチングシステムを実装してドローコールを最小限に抑え、MSAAアンチエイリアシングをサポートしています。

プラットフォーム固有の実装

  • macOS: レンダリングにMetalを使用し、テキストのシェイピングとラスタライズにCoreTextを使用します。macOS 26.0以降のネイティブな「Liquid Glass」透明ウィンドウ効果をサポートしています。
  • Linux: レンダリングにVulkanを使用し、ウィンドウ管理にWayland (特にXDG shell) を使用します。テキストレンダリングは、ラスタライズ用のFreeType、シェイピング用のHarfBuzz、および検出用のFontconfigからなるネイティブスタックによって処理されます。
  • WebAssembly: WebGPUをターゲットとし、HTML5 Canvasをテキストレンダリングに使用します。なお、Zig 0.16.0時点では、std.Io.Threadedに関するアップストリームの問題により、WASMビルドは一時的に延期されています。

API設計: CxとUIの分離

Gooeyは、Cx (Context) と ui という2つの主要なモジュールを通じて、アプリケーションの状態とロジックをレイアウトのプリミティブから分離します。

Cx モジュール

Cxは、状態へのアクセス、イベントハンドラ、アニメーション、およびフォーカス管理を含む、アプリケーションの「頭脳」を管理します。主要なメソッドには cx.state(), cx.update(), および cx.render() が含まれます。

ui モジュール

uiは、宣言的なレイアウトプリミティブを提供します。要素の配置にはflexboxスタイルのシステムを使用します。主要なプリミティブは以下の通りです:

  • ui.box(): flexboxレイアウトを持つコンテナ。
  • ui.hstack() / ui.vstack(): 水平および垂直スタック。
  • ui.text(): 折り返しとフォーマットをサポートするテキストレンダリング。
  • ui.when(): ブール値の状態に基づく条件付きレンダリング。

状態管理とイベントハンドリング

Gooeyは「Pure State Pattern」を採用しており、アプリケーションの状態をUIロジックから分離して保持するため、UIを実行することなく状態を完全にテストすることが可能です。

ハンドラタイプ

状態を変化させる、またはフレームワークと対話するために、Gooeyはいくつかのハンドラタイプを提供しています:

  • cx.update(): 純粋な状態の変更用。
  • cx.updateWith(): 引数を必要とする変更用 (8バイトに制限、例えば u64 やポインタ)。
  • cx.command(): アプリの終了やエンティティの管理など、フレームワークへのアクセスを必要とする操作用。
  • cx.defer(): 現在のイベントハンドラが完了した後にコードを実行するために使用されます。これは、モーダルダイアログやファイルピッカーを開く際のデッドロックを回避するために非常に重要です。

std.Io によるバックグラウンド作業

高負荷な操作 (I/O, ネットワークリクエスト) は、Zig 0.16の std.Io を使用してUIスレッド以外で処理されます。バックグラウンドタスクは、境界付きのロックフリーな std.Io.Queue(T) に結果をプッシュし、レンダーループが毎フレームそれを取り出します。これにより、UIスレッドがブロックされることがなく、状態への同時アクセスがロックなしで行われないことが保証されます。

高度なUI機能

仮想化リストとテーブル

大規模なデータセットに対して、Gooeyは高性能な仮想化コンポーネントを提供します:

  • UniformList: アイテムの高さが一定のリストを効率的にレンダリングします。
  • VirtualList: レンダリングされた高さをキャッシュすることで、可変アイテムの高さをサポートします。
  • DataTable: 列のサイズ変更、ソート、および選択をサポートする2D仮想化テーブル。

フォームバリデーションとアクセシビリティ

Gooeyは、必須フィールド、メール形式、およびパスワード強度をサポートする包括的なバリデーションシステム (gooey.validation) を含んでいます。ValidatedTextInput と統合することで、視覚的なエラーメッセージと、スクリーンリーダー (VoiceOver, Orca, ARIA) 用のアクセシブルなメッセージの両方を提供します。

アニメーションとエフェクト

  • アニメーションシステム: Easing関数 (例: easeOutBack, easeInOutCubic) と、値の変化に対する animateOn のようなトリガーを内蔵サポートしています。
  • カスタムシェーダー: 開発者は、ポストプロセッシング効果のために独自の Metal (MSL) または WebGPU (WGSL) シェーダーを組み込むことができます。
  • テーマ設定: Catppuccinに基づいたライトモードとダークモードの組み込みサポート (セマンティックカラーシステムによる簡単なカスタマイズが可能) を備えています。

コミュニティの洞察と批判

このプロジェクトは、Zigエコシステムを拡張し、Electronベースのアプリへの代替案を提供しているとして称賛されていますが、一部のコミュニティメンバーからは、その開発プロセスやパフォーマンスに関する懸念が示されています:

"I wonder if this is just what we get now: low quality code, expressed rapidly... low quality, LLM generated crap that you really shouldn't use if you want secure, stable performant, production-ready software."

その他の批判は、より包括的なドキュメントの必要性や、フォームやターミナルなどの単純なインターフェースのためのGPU加速フレームワークの潜在的な電力消費量に焦点を当てています。

Sources