唠叨之书

始依

在学了rust那会儿,我有很多想做的东西,可我总是个思想上的巨人,行动上的矮子。有一天,我心血来潮的开始了解rust的gui框架,以为我后续的开发做准备。

那会我感觉看起来好像没什么可用性很高的框架啊,我也试过其中一款框架,可是因为api的原因,竟然连个界面切换的功能都无法实现。

可那会儿却没什么令我满意的框架,原因也很简单,每个框架都有自己的问题,抛开生态不说,我认为现有的框架最大的问题是“设计"。

其中,我翻到了miniquad的源码,受其鼓舞,最终,我决定自己开发一款rustgui框架。

思考与设计与理念与成果

开发这个框架,我是慢慢来的,从最初开始还不太熟练,总是被编译器卡住到现在成了我最熟练的语言。

flor 进入验证阶段的大版本,到现在是第五个,这个版本,与我最初的想法有很大的出入,像极了rust的创始人看到了现在的rust的样子,和自己想的完全不一样,但与之不同的是我很满意现在的设计。

当前的设计,融合了传统的控件式开发和现代的web开发的各种设计元素。其表现,完全符合我心目中的既要,又要,还要的rust gui框架。

最开始的设计目标

  • 高性能
  • 低编译后体积
  • 高api一致性
  • 多窗口支持
  • 不强制绑定上下文

我认为现有的rustgui框架的问题:

  • 不支持多窗口
  • 强制对上下文进行绑定
  • 数据跨范围访问
  • 控件/组件扩展

其中,最大的问题就是,强制绑定上下文,所以我的每一版设计都在向着这个方向努力。只不过之前的版本更倾向与寻找一种类c#那种窗口类的思想靠拢。

但是随着一次又一次的设计验证失败,有一天,我看到了floem框架,深受其启发,以其声明式布局、信号系统、对控件的管理思想进行了借鉴,开始进入了第五版(目前版本)设计。第五版设计进入后,很自然而然的实现了我要的api一致性,而且可扩展性表现非常良好,就一步一步的走到了现在。

目前设计的成果与表现:

  • 高性能
  • 低编译后体积
  • 高api一致性
  • 自写平台支持
  • 不强制绑定上下文
  • 支持跨线程交互的,响应式信号系统[1]
  • 句柄暴露,支持作为native使用
  • 多窗口支持,可在任意线程、任意位置创建窗口
  • 基于即时模式保留模式[2],天然支持高性能动画。各窗口可独立设置刷新模式。
  • 声明式UI DSL
  • 原子类样式解析支持[3]
  • 终端应用体验偏简单,复杂度由框架/控件作者吸收。
  • 支持异步任务调度和 UI 更新,无需手动切换 UI 线程

[1]: 信号支持跨线程,实现了Copy特征,可以随处移动,随处赋值,不用像c# 那样因为等待ui线程而出现性能问题。
[2]: 保留模式是基于即时模式实现的,对于需要高刷新的控件,保留模式依然具备即时模式的性能。
[3]: 构建时提供原子类名原子类名会被框架的布局系统和对应的控件按照顺序分别解析,高效可控构建应用布局。

如果你也认可这些设计理念,那你一定会喜欢这个框架的。

这些设计特点的集于一身,还带来了一些别样的隐性好处,比如:

  • 天然支持协作
  • 无论是传统开发过来的还是现在web开发过来的程序员都可以在其中找到自己熟悉的思想。
  • 支持异步任务调度和UI更新,无需手动切换线程

设计理念/思想指导总纲

  • API 的使用体验优先,先思考 API 设计成什么样最好用,再思考,如何实现。使用体验,上手难度,维护成本,是框架的核心诉求。
  • 布局 DSL 中使用宏是 gui 的恶梦,限制大且不说,IDE 提示支持也不一定好,像个黑盒一样,写错后,报错信息也不一定清楚。 极大的提高了框架的上手难度和维护容易度,所以在本框架中,非必要不使用宏,宏不是不用,而是优先级很低。
  • 性能和编译体积是原初需求,所以功能能力支持,会尽可能的拆为特性,以保证框架的最小化能力。

关于未来

Q: 以后还会有下一个迭代版本,或者其他思路的gui框架吗?

A: 在我看来,所有的解决方案都是为了回答某个问题出现的,这个框架的最想要解决的问题是,脱离上下文的强制绑定。所以,会不会有,取决于会不会有新的没有答案的问题出现。

其他框架大多是为了某个具体用途、某种范式、某类应用而生,而这个框架的出现,是因为没有任何一个框架不是为了一个专一的事情而出现的。

所以,这个框架的愿景是: 让 Flor 成为 Rust 生态中大家默认会想到、愿意尝试的 GUI 选项之一。当开发者需要原生桌面应用时,希望它能自然进入候选,就像C++QtC#WPF 那样。

正如是这个框架名字的寓意:

繁花继开,各放异彩。