作者:Bingo
链接:https://www.zhihu.com/question/24462113/answer/83371803
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
用C++写UI库最本质的思想就是不用C++「写」UI。
不管是开放C++底层库到XML+Json+Lua的实现,或是单一使用XML完成布局管理,或是现前流行的使用Electron(http://electron.atom.io/)也就是HTML+CSS+JS完成UI实现的,本质上都不希望使用C++来完成繁复的工作。
所以C++主要是用来完成支持上层脚本运行的底层框架搭建的,也会根据是否是跨平台而有很大的区别,是否要在C++中完成回调也不同(避免回调最好的办法莫过于ImGui),严格来讲大致分为这样一些。
1. 基本的渲染底层:OpenGL/DirectX支持? 平台支持? GPU支持? 外部库,推荐skia(Docs)或者nanovg(memononen/nanovg: Antialiased 2D vector drawing library on top of OpenGL for UI and visualizations.)),
2. 脚本解析框架:XML/HTML?推荐Gumbo(google/gumbo-parser · GitHub),也支持XML解析,相较TinyXML用户体验会好不少; Json/CSS? Lua/JS? 都是自己考虑设计造轮子要考虑到的点。
3. 内存管理: 是否要在UI库中自行划定内存池、小内存分配器的概念?推荐可以看「提高C++性能的编程技术」(http://www.amazon.cn/%E6%8F%90%E9%AB%98C-%E6%80%A7%E8%83%BD%E7%9A%84%E7%BC%96%E7%A8%8B%E6%8A%80%E6%9C%AF-%E5%B8%83%E5%B0%94%E5%8D%A1/dp/B004S76ZV4)里面对于内存分配讲解的由浅入深,拉屎美文必备。
4. 事件管理: 是否使用事件这样一个不太「稳定」的点来完成信息传递这一步是有争议的,但对于个人的造轮子项目会是一个非常直观的选择。选用全局的事件队列+局部事件队列都是不错的选择。基本上谈到事件都会引申到callback。不管你的回调是在脚本中实现的,或是在C++中完成,都需要对回调进行一系列的管理操作
6. 布局管理: 这一部分事实上会是一个比较锦上添花的作用,一般已经是完成了大部分基础平台的搭建,那么可以考虑各类Layout实现,推荐查阅Android的五大不同Layout(http://developer.android.com/guide/topics/ui/declaring-layout.html,借鉴意义比较大)
7. 动画管理: 同样的也是一个比较后期的模块,作为客户端动画的佼佼者,iOS上的Core Animation会是一个很不错的借鉴对象(About Core Animation),可以观察网上各类博文的使用来仿造其具体动画实现。Tweener的实现网上蛮多的,随便拉一个就是了(Google的就不错https://code.google.com/archive/p/cpptweener/)。
8. 单元测试: 其实这一部分应该是最先就建构的部分,单凡上规模上W的代码量光靠一句「应该对吧」已经无法印证代码的正确性,所以每个模块做好「充分」的单元测试非常的有必要,尤其是自行实现的数学库等。推荐gTest(http://code.google.com/p/googletest/)
======================================================================
一点小事:说前端是世界上开发界面最好的一项搭配之一我想这不会有任何异议,但在游戏这样高FPS要求下HTML+CSS+JS的组合未免有些吃力。因此两者较好的结合我认为会是HTML+CSS完成逻辑与样式布局分离的思想,C++完成与游戏引擎逻辑的结合,本质上而言会增加初始化脚本解析的耗费但这在具体应用中是可以接受的。
因此先前造了几次轮子,自己写的TattyUI(https://github.com/BentleyBlanks/TattyUI)使用HTML+CSS+C++完成界面开发(雏形),欢迎Star+怒喷(目前只支持Windows+OSX,未测试Linux)。
<img src="//pic.ikafan.com/imgp/L3Byb3h5L2h0dHBzL3BpYzEuemhpbWcuY29tLzUwLzdhMzFmNGI2NWIwYThiNjViMDk1ZjdkYTJmMjZjNWY0X2hkLnBuZw==.jpg" data-rawwidth="1303" data-rawheight="826" class="origin_image zh-lightbox-thumb" width="1303" data-original="https://pic1.zhimg.com/7a31f4b65b0a8b65b095f7da2f26c5f4_r.png">
https://www.zhihu.com/question/24462113