Gooey: 为 Zig 设计的 GPU 加速 UI 框架

Gooey 是一个混合即时/保留模式的 UI 框架,旨在利用 Zig 编程语言构建快速、GPU 渲染的应用。它针对 macOS (通过 Metal)、Linux (通过 Vulkan/Wayland) 和浏览器 (通过 WebAssembly/WebGPU),提供了一种声明式的、基于组件的 UI 开发方法,且没有任何外部 Zig 包依赖。

核心架构与渲染

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

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: 一个支持列缩放、排序和选择的二维虚拟化表格。

表单验证与无障碍功能

Gooey 包含一个全面的验证系统 (gooey.validation),支持必填字段、电子邮件格式和密码强度。它通过 ValidatedTextInput 集成,既能提供视觉错误信息,且能为屏幕阅读器 (VoiceOver, Orca, ARIA) 提供无障碍信息。

动画与特效

  • 动画系统: 内置支持缓动函数 (例如 easeOutBackeaseInOutCubic) 和用于值变化的触发器如 animateOn
  • 自定义着色器: 开发者可以加入自己的 Metal (MSL) 或 WebGPU (WGSL) 着色器,用于后处理特效。
  • 主题化: 内置支持浅色和深色模式 (基于 Catppuccin),并带有语义化颜色系统,便于自定义。

社区见解与批评

虽然该项目因扩展了 Zig 生态系统并为基于 Electron 的应用提供了替代方案而受到称赞,但一些社区成员对开发过程和性能提出了担忧:

"我怀疑这是否就是我们现在所得到的:低质量的代码,快速表达... 低质量、LLM 生成的垃圾,如果你想要安全、稳定、高性能、生产就绪的软件,你真的不应该使用它。"

其他批评集中在对更全面文档的需求,以及对于表单或终端等简单界面,使用 GPU 加速框架可能带来的潜在功耗问题。

Sources