Gooey: 為 Zig 設計的 GPU 加速 UI 框架

Gooey 是一個混合立即/保留模式(immediate/retained mode)的 UI 框架,旨在利用 Zig 程式語言構建快速、GPU 渲染的應用程式。它針對 macOS(透過 Metal)、Linux(透過 Vulkan/Wayland)以及瀏覽器(透過 WebAssembly/WebGPU)進行開發,提供一種聲明式的、基於組件的 UI 開發方法,且完全沒有外部 Zig 套件依賴。

核心架構與渲染

Gooey 利用 GPU 加速的渲染管線來確保在不同平台上的高效能。它實現了場景圖(scene graph)和批處理系統(batching system)以最小化繪圖調用(draw calls),並支援 MSAA 抗鋸齒。

特定平台的實作

  • macOS: 使用 Metal 進行渲染,並使用 CoreText 進行文字塑形(text shaping)與點陣化(rasterization)。它支援 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 透過兩個主要模組將應用程式的狀態與邏輯從其佈局原語(layout primitives)中分離出來:Cx (Context) 與 ui

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(): 用於需要框架存取的作業,例如退出應用程式或管理實體(entities)。
  • 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 functions,例如 easeOutBackeaseInOutCubic)以及如 animateOn 等用於數值變更的觸發器。
  • 自定義著色器: 開發者可以加入自定義的 Metal (MSL) 或 WebGPU (WGSL) 著色器來進行後處理特效。
  • 主題化: 內建支援淺色與深色模式(基於 Catppuccin),並配備語義化顏色系統以便於自定義。

社群洞察與評論

雖然該專案因擴展了 Zig 生態系並提供了 Electron-based apps 的替代方案而受到讚賞,但部分社群成員對其開發流程與效能提出了疑慮:

"我懷疑這就是我們現在得到的東西:低品質的程式碼,快速表達出來的... 低品質、由 LLM 生成的垃圾,如果你想要安全、穩定、高效能且足以用於生產環境的軟體,你真的不應該使用它。"

其他評論則集中在需要更完善的文件的說明,以及對於像表單或終端機等簡單介面使用 GPU 加速框架可能產生的潛在功耗問題。

Sources