ECS架构的思考

2023-05-16

最近在整理Demo代码,遇到一个设计问题,这个问题是transform组件到底放到哪里比较合适?我们都知道逻辑,物理,渲染模块都会用到transform组件。比如渲染模块会将transform数据转换到instance buffer中。通常渲染模块做为底层模块会提供一个接口供上层的逻辑模块调用,也就是说将transform放到了逻辑模块中。但是对于渲染模块来说提供这个接口会影到渲染模块的设计。比如将instance buffer放到ResourceNode中(FrameGraph架构),而ResourceNode是放到PassNode中的,这样就需要提供一系列的接口才能将transform数据设置到instance buffer中(GameObject->PassNode->ReourceNode)。我举得这个例子只是冰山一角,很多底层提供的接口都需要各种中转。因为我们的设计思路是自顶向下调用。这种设计是合理的因为我们希望底层库的设计者不被上层代码限制。但是这种设计并不优雅,为什么passnode要提供一个设置transform的接口呢?思考到这里我停留了很久,最终我发现ecs架构在处理这个问题上相当优雅。ecs将逻辑,物理, 渲染模块处理成平级的系统,它们彼此独立只关心自己system所需的数据,接口非常优雅。为此,我希望将ecs架构做为demo的核心架构。网上对ecs架构的讨论也很火热,褒贬不一,说一下我的观点吧。

上面这段话思维混乱,主要是我当时对渲染层的逻辑还不太熟悉。现在看来,对于Transform数据来说,逻辑层包含全部的数据,而渲染层包含需要渲染的数据,Transform数据从逻辑层到渲染层需要一个筛选处理。传统的架构因为数据和逻辑没有分离,需要将数据从一个系统塞进另一个系统中,它们是上下级的关系,而ecs系统将逻辑和数据分离,这样不同系统其实是平级的,它们共同处理相同的数据,只是处理上有先后顺序,从这个角度来说ecs架构很优雅而传统架构感觉很臃肿。

ecs是值得被尝试的架构,说一句不负责任的话就是存在即合理,ecs在最近被推出,一定是传统的游戏框架出了问题,因此许多人才会不遗余力的推出一种新的架构。其实ecs架构的思想并不新颖,只是在游戏这个行业可能用的比较少。此时的C程序员可能会看着我们C++程序员笑而不语了:)

任何程序设计都离不开数据结构与函数,狭义的讲,程序设计就是使用函数来处理数据。最初的编程语言是机器码,这种语言对机器特别友好,但是人阅读起来太麻烦了。因此汇编语言诞生了,汇编语言核心就是将字母组成的指令映射成数字组成的机器码。第一款汇编语言的编译器应该是用机器码写的,有了这个编译器我们就可以使用汇编语言来写汇编语言的编译器了。汇编语言从可读性上提高了编程的效率,但是汇编语言还是太接近机器语言了,它还是太关注硬件细节了。因此前辈们创造了最伟大的语言c语言。c语言不仅更接近人类的思维,而且他还能保证运行效率,因为一款优秀的编译器生成的汇编代码往往比我们手写的更高效。C语言很单纯,它符合编程的核心思想使用函数处理数据,因此c语言编程也被称为过程式编程。c语言已经很完美了,它可以胜任任何复杂的系统,比如操作系统。有人说c语言开发效率低,这点我不敢苟同,软件开发耗时更多的是在设计迭代上跟语言关系不大。人类总是贪婪的,懒惰也是一种贪婪的表现。为了能让编程语言更加符合人类的思维,OOP诞生了。我是一名C++程序员,OOP编程对我影响最大,如今看到ecs架构真的是感慨万千。以前引以为傲的OOP编程三大核心思想封装,继承,多态,如今正在被一步一步的推翻。

上面这段话我想表达的是ecs这种优雅的架构很适合c语言的过程式编程。

封装

封装就是抽象,是对复杂功能的拆解,其实就是在做一件事情,化繁为简。因此无论你使用什么语言都会进行封装,只是封装的手法不一样,比如c语言封装可能体现在一个.c文件中,而C++则是一个class类。因此封装并不是oop独有的,oop只是将表现手法变的简单了,oop将操作和数据放到了一起。就是这么一个简单的手法,让编程更加符合人类的思维了(偷懒。。。),因此开发效率大大提高。说到这里必须要提一下c语言的结构体,结构体是对数据的封装。考虑内存布局结构体数组可以分为soa和aos两种。在c语言中这两种布局都会被经常使用。但是到了C++基本上就变成aos这种了,原因就是因为class对数据和操作的封装。而ecs则倾向于soa,因为它的内存布局对缓存命中更加友好。这里其实可以看出机器语言和人类思维是相悖的,越接近人类的思维,越会抛弃对机器语言的友好。ECS架构其实是对OOP语言封装的一次打击,也就是我们所谓的数据与逻辑分离。要怪只能怪内存不争气,读写速度怎么发展的这么慢。操作与数据分离,会让系统更加的解耦,这也是我最开始考虑ecs架构的初衷。

上面这段话基本没什么毛病,c++的封装的确很容易让我们写出aos结构的代码,但是ecs架构虽然将数据和逻辑分离,但是还有很多system内部的数据需要封装在class中,从这个角度说封装并不是c++的错,而是我们过渡使用了封装的设计思想。

继承

继承是oop里面最大的败笔,当然继承设计的初衷是好的,就是复用能力,比如人只要继承眼睛,嘴巴就可以获得视觉和味觉。其实继承的层次结构,更多的是体现在设计上和语言关系不大。但是多重继承给人的感觉就是没有安全感,阅读起来太麻烦,而且会出现菱形结构。与继承相比组件模式更符合人的思维。因此EC架构其实是对oop架构继承的一次打击。继承的设计思想没有错,只是语言的表现手法不如组合更符合人的逻辑思维。ECS是EC的进阶版,它也是摒弃了继承(多重继承)而使用组件来完成复用。

因为继承可以被组件很好的替代,所以多重继承在编程上确实很鸡肋,单继承还是很有用的,可以用来做单例,多态。

多态
多态是对接口的复用,比如speak接口可以说中文也可以说英语,这种接口的复用要依靠封装和继承。C语言也可以实现多态,但是要在结构体里面存储函数指针,咳咳这不就是c++的封装了么。多态很美好给oop长脸了。ecs框架里面system只能靠if else了吧。

其实ecs架构很像过程式编程,ecs架构用c语言写更合适。

多态很重要,ecs中的System组件就需要使用多态来调用System,但是其他地方目前我还没有用到多态。

ecs架构的优点

1.内存布局更加高效

2.模块解耦性更好

3.对多线程编程友好

4.system很适合做白盒测试

缺点

1.反人类思维开发效率低

2.多人合作,开发效率可能呈指数倍递增

最后想说的是风水轮流转,谁说c++比c高级了,是英雄还是狗熊,取决于所处的时代。

目前在使用了ecs系统之后感觉它的缺点不明显,并不反人类,开发效率也不低,但这不代表结论,因为我做的功能还太少。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ECS架构的思考 的相关文章

随机推荐

  • UICollectionView 常用

    minimumLineSpacing minimumInteritemSpacing https zhangferry com 2021 07 19 iOSWeeklyLearning 19
  • solidity This declaration shadows an existing declaration

    中文解释 解决 xff1a 变量重复定义 xff0c 变量名和函数名不能相同 和之前写的各种代码不一样 xff0c 没看明白这个警告 后来仔细看了一下代码 xff0c 发现有函数名和其他函数里的变量名一致 xff0c 导致的警告 修改后警告
  • openzeppelin erc20各种接口

    ERC 20 这套接口 合约和应用程序都与 ERC20 代币标准相关 有一些核心合约实现了 EIP 中指定的功能和定义 xff1a IERC20 包含所有ERC20应该实现的接口IERC20Metadata 对ERC20接口的扩展 xff0
  • Next.js Polygon, Solidity,The Graph,IPFS,Hardhat web3博客系统

    参考 源文档The Complete Guide to Full Stack Web3 Development DEV Community 源码 xff0c 源文章里的github项目无法直接运行 xff0c 经过修改后可mac中可用Git
  • node.js 开发笔记

    依赖 package json里 dependencies xff08 运行时依赖 xff09 devDependencies xff08 常用 xff0c 开发时依赖 xff0c 运行不依赖 xff09 peerDependencies
  • React Native 混合ios android开发 及常用框架

    英文文档 xff1a Setting up the development environment React Native 中文文档 xff1a 集成到现有原生应用 React Native 中文网 ios 在集成过程中 xff0c 需要
  • React native RN 开发实例

    多入口加载方式 React Native 混合开发多入口加载方式 知乎 initialProperties 官方文档 xff1a React Navigation moduleName 案例 xff1a GitHub hcn1519 Rea
  • vscode 正则表达式查找替换

    参考 可以用在 VS Code 中的正则表达式小技巧 掘金 正则匹配中文数字 小豆芽菜的博客 CSDN博客 案例 想在 七百零四章 前加入 第 条件 搜索条件 注意底下章后面有空格 xff0c 这个是根据我的原文来定制的 xff0c 原文里
  • swift xcode 宏定义ifdef debug

    DEBUG 代码中 if DEBUG print 34 file as NSString lastPathComponent function 34 endif
  • Swift UIView SnapKit updateConstraints 如何做动画(animate animation)和 cornerRadius

    动画 UIView animate withDuration 0 3 let newWidth 61 self progressBgView width 2 progressValue self progressView snp updat
  • Linux网络命令

    目录 一 网络配置命令 1 1 ifconfig命令 查看网络接口信息 二 hostname 查看主机名称 2 1 查看主机名 2 2 修改主机名称 2 3 永久修改主机名 xff0c 修改后重启生效 三 route 查看路由表条目 四 n
  • Xcode 14.3 Archive AFNetworking.framework failed: No such file or directory

    参考 Xcode 14 3 Archive 失败 掘金 项目搜索 source 61 34 readlink 34 source 34 34 替换为 xff1a source 61 34 readlink f 34 source 34 34
  • xcode Swift Log CocoaLumberjack

    参考 iOS CocoaLumberJack日志库集成 简书 logging How to capture Device Logs in iOS during Runtime into a file in Documents Directo
  • UITabbar 颜色 color

    if available iOS 15 let tabBarAppearance 61 UITabBarAppearance tabBarAppearance backgroundColor 61 white tabBarAppearanc
  • Pyinstaller 打包 Tkinter 程序时引入图标解决方法

    Pyinstaller 打包 Tkinter 程序时引入图标解决方法 描述 在windows下开发python的gui程序时 多数使用pyinstaller py2exe等打包工具 在因为tkinter框架时 代码中使用iconbitmap
  • mysql基本操作

    修改字段属性 xff1a 修改字段属性 ALTER TABLE tb name MODIFY 字段名称 字段类型 完整性约束条件 将email字段 VARCHAR 50 修改成VARCHAR 200 注意 xff0c 修改时如果不带完整性约
  • <context:component-scan/>标签爆红

    lt xml version 61 34 1 0 34 encoding 61 34 UTF 8 34 gt lt beans xmlns 61 34 http www springframework org schema beans 34
  • iOS exit函数深入浅出

    1 exit函数 C C 43 43 函数exit用来终止当前程序 xff0c 函数定义如下 xff1a void exit int status 官方说明如下 xff1a Terminates the process normally p
  • 前端妹子如何在 sqlserver 2008 中如何用自定义函数 解析json数据

    导航 前言 xff1a 开始干活 xff1a 0 预告1 首先先建立一个 通用的json解析自定义函数 xff08 这个代码是网络上找到的成熟代码 xff09 2 重点讲解一下 函数 parseJSON 的用法3 学会了函数 parseJS
  • ECS架构的思考

    最近在整理Demo代码 xff0c 遇到一个设计问题 xff0c 这个问题是transform组件到底放到哪里比较合适 xff1f 我们都知道逻辑 xff0c 物理 xff0c 渲染模块都会用到transform组件 比如渲染模块会将tra