ECS 编程在Pelagia中的实现
前言
ECS是源于"Expression Problem"问题的技术解决方案。其主要特点是以对象属性为切片进行数据管理的方式。这种方式在开发中易于对数据和方法进行扩展。
Pelagia是首个全方位解决无锁编程问题的工具。是对多线程和文件存储系统的高度整合。用户可以像普通单线程开发一样编写软件。Pelagia会根据函数间依赖关系自动将用户编写的函数分配到不同的线程。你可以在这里找它https://github.com/surparallel/pelagia
Pelagia是从并行编程的角度反推出数据管理方式。ECS编程是从语言对数据使用的角度产生的技术框架。为什么这两个角度最后都推导出"Expression Problem"问题。我想这就是殊途同归吧。
游戏框架ECS
在GDC2017来自暴雪的Tim Ford介绍了<守望先锋> 游戏框架ECS(https://github.com/sschmid/Entitas-CSharp)。他与经典的Actor模式区别非常大。他将数据和方法进行剥离。数据存储在Entity中,方法存储在System中。虽然还存在广义上的对象,这个对象内标记了多个所使用的Entiry和System。这种分离使得数据的聚合度非常的高。可以将分散在多个对象中的单一属性聚合在一起。
例如,我们有两个类,分别为教师和学生。
class teacher {
string name,
}
class student {
string name,
int grades,
}
在学生的类中存在特殊的属性grades。如果我想遍历所有学生的grades就需要建立一个学生的索引。如果为每个有特殊属性的类都建立索引显然非常的麻烦。
使用ECS技术就会将对象的属性数据都放在一起之并自动为每个属性建立索引。
在pelagia中使用的面向属性
这与我在pelagia中使用的面向属性的技术本质是一样的。
是一种面向属性的数据切片方式。
我们常用的数据切割方式有几种。
函数式编程(function):对数据任意切割,没有范围的界定。
面向对象(object):以行的方式对数据进行切割。
ECS或pelagia编程(attribute):在面向对象的基础上再以列的方式进行分割或则只用列的方式。
所不同的是pelagia为了实现lock-free编程。pelagia将所有数据放入数据库内。
将数据与编程语言彻底解耦。并预留了更多的操作方法。
ECS也不是新出现的技术,他源自Expression Problem。
"Expression Problem"是Wadler在1998年提出的。
被认为是一种逆对象化的方法。
我理解他所表达的是在当前对象化的基础上,增加了一个新的纬度组织数据。
新增的纬度不是消灭对象化,而是更加丰富了对象化。
在pelagia中新添加了simple.json和simple.lua来演示如何进行ECS编程。
你可以在src目录下找到他们。
simple示例描述了一个图书管理系统。
在这个系统中只有教授可以借阅馆藏级别的图书。
simple.json 主要描述了方法使用属性的组织结构。
"acc_insert":{
"orderType":"lua",
"file":"simple.lua",
"fun":"acc_insert",
"weight":1,
"acc_title":{
"weight":1,
"nosave":0,
"noshare":0
}
},
这段描述了“acc_insert”方法来源的lua文件和函数。
以及需要写入“acc_title”属性。
pelagia对写入属性非常敏感,对读取属性没有要求。
我们可以通过下面的指令运行他们。
>iwj simple.json
>rcj init_test
>rcj borrow_test
在simple.lua 中 init_test 初始化了要使用的数据。
borrow_test则模拟了借阅的过程。
通过pajo指令可以看到order在线程中分配的情况。
通过ppa指令可以看到order可以最多分配到3个线程中。