转自云风的BLOG: https://blog.codingnow.com/2017/12/lua_ieaae_ecs_oue.html

前段时间,我写了一篇 浅谈《守望先锋》中的 ECS 构架 。最近想试试在 Lua 中实现一个简单的 ECS 框架,又仔细琢磨了一下。

我思考后的结论是:ECS 并不是一个新概念,它的提出其实是和语言相关的。ECS 概念的诞生起于游戏行业,相关框架基本都是基于 C++ 来开发的。它其实是对 C++ 对象模型的一个反思。ECS 针对组件组合对象,而反对 C++ 固有的基于继承的对象模型。对象模型才是 ECS 的设计核心理念。而离开 C++ 的对象模型,ECS 并不是什么新鲜的东西。

我的这个观点也不新鲜,在 ECS 的 Wikipedia 页上也有类似的说法:

In the original talk at GDC Scott Bilas compares C++ object system and his new Custom component system. This is consistent with a traditional use of this term in general Systems engineering with Common Lisp Object System and Type system as examples. Therefore, the ideas of “Systems” as a first-class element is a personal opinion essay. Overall, ECS is a mixed personal reflection of orthogonal well-established ideas in general Computer science and Programming language theory. For example, components can be seen as a mixin idiom in various programming languages. Alternatively, components are just a small case under the general Delegation (object-oriented programming) approach and Meta-object protocol. I.e. any complete component object system can be expressed with templates and empathy model within The Orlando Treaty vision of Object-oriented programming,

抛开理论不谈,如果要在 Lua 中实践,我们到底可以做点什么呢?

我认为需要有这几个方面:

首先应该对 Lua 加强类型系统。Lua 的动态性天然支持把不同的组件聚合在一起,我们把不同的 Component 放在一张表里组合成 Entity 就足够了。但如果 Component 分的很细的话,用很多的表组合成一个 Entity 对象的额外开销不小。不像 C++ ,结构体聚合的额外开销几乎为零。我们完全可以把不同 Component 的数据直接平坦放在一个 table 中,只要键值不冲突即可。但是我们需要额外的类型信息方便运行时从 Entity 中萃取出 Component 来。另外,如果是 C / Lua 混合设计的话,某些 Component 还应该可以是 userdata 。

从节省空间及方便遍历的角度讲,我们甚至可以把同类的 C Component 聚合在一大块内存中,然后在 Entity 的 table 中只保留一个 lightuserdata 即可。ECS 的 System 最重要的操作就是遍历处理同类 Component ,这样天然就可以分为 C System 和 Lua System 。数据的内聚性很高,可以直接区分开 C data 和 Lua Data 。

然后、就是方便的遍历。ECS 的 System 需要做的就是筛选出它关心的 Entity ,针对其中的 Component 做操作。如果需要筛选结果大大少于全体 Entity 数量,遍历逐个判断就会效率很低。好在在 Lua 中,我们可以非常容易地做出 cache ,只需要遍历筛选一次,在监控新的 Component 的诞生就可以方便的维护遍历用的集合了。

我写了一个初步的版本。打算等到实际使用起来再慢慢完善。

它可以实现成一个纯 Lua 版,但我特地尝试把里面的两个函数编写了 C 的等价版,看起来可以提高不少性能。

这里的 API 中, Entity 全部使用唯一数字 id 标识,而不主张直接引用 entity 的 table 。这也是一般 ECS 框架的通用做法。数字 id 可以提高健壮性,还可以避免对已经销毁的 Entity 错误的引用。如果需要 C / Lua 混合编程的话,在 C 中引用 id 也方便的多。

类型系统是这样设计的:

每个 Component 有一个 16bit 的唯一类型 id ,每个 Entity 是由若干 Component 组合而成,我将它们的类型 id 升序排列成一个字符串,作为整个 Entity 的动态类型。然后 Lua 中实现了一个 cache ,可以从这个类型字符串转换成易用的类型对象。类型对象用来对 Entity 做筛选,从里面分离出 Component 。这个类型字符串的拼接我实现的是一个 C 版本,虽然 Lua 也能实现的出来,但是效率会低很多。

大部分 Component 我主张直接平坦的放在 Entity 对象表中,但若需要用 C 结构来承载,或单独用一个子表,也提供了 Component 类型注册方法,可以在 new component 时定义一个专门的构造函数(以及 delete 时的析构函数)。

这里还提供了遍历包含特定 Component 的 Entity 集合 的迭代器。它由一个弱表实现的 cache 来管理。在第一次遍历时,会创建一个集合,收集 Entity 全体集合中符合要求的部分,把筛选出来的 id 记录下来。一旦遍历集合创建好,它还会跟踪新的 Component 的创建,自动加进来。

这里的迭代器,我同时实现了 Lua 版本和 C 版本。C 版本的性能会高一些,我认为这个 C 版本在遍历相关集合时,性能表现不会差于用 C/C++ 实现的原生容器。

以上是对 Entity 和 Component 的支持。System 相关的方法,我还没有想好可以做点什么。等用到了再完善。

Lua下的ECS框架相关推荐

  1. Unity下的ECS框架 Entitas简介

    最近随着守望先锋制作组在gdc上发布的一个关于ecs的talk,ecs这个架构算是得到了一定的曝光度. 在这之前,github上就一直有一个C#的ecs框架名为Entitas,截止现在已经有1300+ ...

  2. ECS框架的初步探究

    欢迎参与讨论,转载请注明出处. 本文转载自:https://musoucrow.github.io/2018/03/19/ecs_first/ 前言 在阅读这篇文章之前,你需要了解一下何为ECS框架. ...

  3. ios开发愤怒的小鸟的Lua语言:Wax框架详解(一)

    核心提示:我们都知道Objective-C和Cocoa语言可以开发iOS应用,但是一年前,苹果决定在iOS系统上使用Lua语言.Wax框架的想法很简单:凡是Objective-C能做的,Lua也能做! ...

  4. CV:Win10下深度学习框架安装之Tensorflow/tensorflow_gpu+Cuda+Cudnn(最清楚/最快捷)之详细攻略(图文教程)

    CV:Win10下深度学习框架安装之Tensorflow/tensorflow_gpu+Cuda+Cudnn(最清楚/最快捷)之详细攻略(图文教程) 导读 本人在Win10下安装深度学习框架Tenso ...

  5. python网站设计理念_简单介绍下python Django框架的历史,设计理念及优势_Django讲解2...

    简单介绍下python Django框架的历史,设计理念及优势 Django是一个高层次的 Python Web 框架,它是一个鼓励快速开发和干净,实用的框架设计.Django可以更容易地快速构建更好 ...

  6. Net Core下多种ORM框架特性及性能对比

    在.NET Framework下有许多ORM框架,最著名的无外乎是Entity Framework,它拥有悠久的历史以及便捷的语法,在占有率上一路领先.但随着Dapper的出现,它的地位受到了威胁,本 ...

  7. eclipse spring mysql,eclipse环境下的springboot框架+mybatis访问MySQL报错空指针

    "/")public classTestController { @RequestMapping("/login")publicString login() { ...

  8. dept在Java里面_EmpDeptManager 在JavaEE环境下搭建三大框架体系实现员工的增删改查系统 Develop 261万源代码下载- www.pudn.com...

    文件名称: EmpDeptManager下载  收藏√  [ 5  4  3  2  1 ] 开发工具: Java 文件大小: 39 KB 上传时间: 2016-07-08 下载次数: 0 提 供 者 ...

  9. 云开发系列课程 | FaaS场景下的SSR框架

    本篇内容主要介绍FaaS场景下的SSR框架,也就是在FaaS场景下怎么开发服务端渲染页面.服务端渲染是指前后端同构的服务端渲染,即React SSR.在介绍SSR框架之前,首先简单介绍一下Server ...

最新文章

  1. 升级jquery-easyui1.4.5后treegrid无法显示
  2. 用了Python,老板再也不用担心我写不了CUDA了!
  3. 打印并输出 log/日志到文件(C++)
  4. MATLAB设置当前工作目录
  5. LeetCode 1114. 按序打印
  6. 学习python:模块的建立与发布
  7. you need python_Life is short, you need Python!
  8. 最详细全国区号汇总(json格式)
  9. 【写博客常用】Word文档中怎么插入分隔线
  10. ubuntu多显示器单触摸屏校准
  11. HTTP中的status code什么意思
  12. js实现上下左右移动小方块
  13. boost库之geometry
  14. 远山启:用数学照亮人性与自由
  15. HTML基本页面模板
  16. 表示条件:10 x 100或x 0的c语言表达式是,西安培华学院c语言期未考试A.doc
  17. Win10电脑无法复制粘贴怎么办【系统天地】
  18. python机器学习之决策树(decision tree)
  19. Windows 注册表操作 reg 命令详解
  20. mySQL没有 with as

热门文章

  1. 转:罗永浩多年前的求职信,人家牛逼是种习惯
  2. Re-脱壳技术 脱壳实战(3): 脱壳及修复IAT
  3. matlab gui做输入,用户在matlab GUI中的输入
  4. IO流使用available()的大坑
  5. TCP连接握手为什么3次?断开为什么是4次?TCP的优化-SCTP协议
  6. 【Unity开发小技巧】FMS有限状态机详解
  7. matlab循环调用变量,关于循环变量的调用问题
  8. Excel 神操作,利用公式对比两个不同的表,替换内容(保姆级教程)
  9. 10.12 快手游戏 客户端 一面40min
  10. 【AGC】SDK未经用户同意获取AndroidID问题