我和Irisia的故事

这里只是叙事文,没有什么资料在这里,可以跳过。

Irisia GUI的诞生

撰写这篇文档时是2023年4月份,我是一名大二本科生,8年前开始自学编程,2021年接触Rust。由于我很早开始接触电子游戏Minecraft(我的世界),因此受到其影响,走上编程道路。在一开始,我通过编写JSON文件使游戏中的生物做出各种动作开始,慢慢接触了JS,接着进入Web的领域,利用手边的各种框架(有Vue开发经验)和JS库开发与Minecraft相关工具,包括皮肤制作器ShadowSkin和联机工具MCMU,这些都可以在我的GitHub个人主页找到。经过几年和Web端开发,我逐渐理解了GUI的设计理念和网络编程的方式。这些经验为我开发Irisia GUI打下了设计方向的基础。

时间来到2021年的春天,经朋友介绍认识了Rust这门语言。当我开始试着了解它时,就和它的编程理念一拍即合,于是开始了Rust的学习生涯。由于我是从Web端“转行”到Rust,因此花费了半个多月才具备设计Rust程序的能力。之后经过长达一年的磨合,我通过Rust异步编程开发了MCMU的Rust版本——MCMU2,后来迭代出改进版的MCMU2-alpha版本。借助Rust的力量,MCMU的性能和功能都逐渐增加,但是也面临着一个重要的问题——没有图形界面。

起初我并没有打算自己做GUI,而是放眼crates.io去寻找合适的GUI框架,但却收获寥寥。我尝试了一些比较热门的GUI框架,例如Iced,Druid,imgui甚至tauri,但都不能令我满意。在经过长时间考察后,我决定亲手设计一个GUI框架,这就是Irisia GUI。

准备工作

在开始着手设计Irisia GUI前,刚开始我必须选择一个图形库。因为当时Rust生态中的图形库功能参差不齐,本身也尚未成熟,甚至连阴影盒子的功能都没有得到良好的支持,所以我没有局限在纯Rust开发的图形库中。我开始寻找FFI方案,很快发现Skia具有良好的跨平台性、强大的功能以及方便易用的Rust绑定。我设计了一些简单的测试程序,在由winit启动的窗口上,测试Skia在Windows平台和Android平台的绘制正常后,定下来使用Skia作为图形库后端。

紧接着我需要解决窗口启动器的问题。虽然我认可winit的跨平台性,但是它仍缺失一些关键功能,例如在Android端弹出虚拟键盘和启用剪贴板功能。于是我在winit的repo中提了相关issue,得到了基于jni弹出虚拟键盘和利用copypasta库获得剪贴板功能的解决方案。前者运行良好,但是后者却缺少移动端支持。于是我模仿基于jni弹出虚拟键盘的方案,很快实现了对安卓剪贴板操控方式的支持方案,并提交了Pull Request。项目管理者十分相中这个实现方式,但由于仓库代码的格式化和rustfmt默认格式不同,最终没有成功Merge到主分支,后续我也没有再关注。但可以确定的是,这两个方案运行良好,解决了刚需问题。

在我试着兼容winit的同时,并没有放弃尝试别的窗口启动器。我尝试了sdl2的方案,发现它的功能和winit近似。在测试跨平台性时,Windows端不需要过多干预即可运行,而Android端就没有那么幸运了。为了能在Android端编译运行,我学习了如何使用Gradle,利用插件对Rust工程打包,但是过程比较繁琐,这也是后来没有选择sdl2的原因。最终,sdl2带动skia在Windows端和Android端成功运行。但是,又因为rust绑定的sdl2的文档比较缺乏,维护不足,因此最终放弃了该方案。