如何减少实体-组件-系统中的 Duck-typing 现象?
例子
这是一个coliru 演示。
我的 ECS 中有 2 个系统:-
System_Projectile
:管理所有弹丸和子弹方面。
System_Physic
:管理物理组件。
有 2 个组件类型 : Com_Projectile
, Physics
.
有时,我发现在某个组件中缓存指向另一个实体的指针是件好事:-
class Com_Projectile : public Component{
public:
Entity* physic;
Entity* physicSecondary; //just to show that it is possible to have >1 physic
};
如果我想改变 的位置Com_Projectile
,我会打电话给manage(Com_Projectile::physic)
。
class System_Projectile{
public: static void manage(Entity* projectile){
Com_Projectile* comP = getComponent<Com_Projectile>(projectile);
//suffer duck-typing at "comP->physic"
System_Physic::setVelocity(comP->physic,Vec3(1,0,0));
}
};
问题
基于上述代码段的真实程序可以正常工作。
但是,在编码时,Com_Projectile::physic
遭受鸭式打字。
physic
我没有得到关于' 类型的C++ 语义线索。
(变量名和注释除外)因此,我必须意识到这一点。
Coder 对类型的误解只会在运行时被检测到。
但在实践中,这种错误很少发生。我必须回忆起
System_Physic::
可以做我想做的事情的系统名称(),
然后回忆起函数的名称(System_Physic::setVelocity()
在这种情况下)。- 总之,我的大脑有很多间接性。
在我过去,当我使用大量(深度)继承时,它会容易得多,就像这样:-
physic->setVelocity(Vec3(1,0,0));
我真的很怀念列出所有与物理相关的功能的可爱内容助手。
问题
如何减少 ECS 系统某些部分的鸭式打字?
更具体地说,再次启用可爱内容辅助的设计模式是什么?
我目前的解决方法
让Com_Projectile
缓存Physic* physic
而不是Entity*
:-
class Com_Projectile{
public: Physics* physic; //edited from "Entity* physic"
};
坏处:-
- 它将促进不需要的(?)耦合。
- 我必须在
Physics
里面转发声明Com_Projectile.h
。 - 我将不得不将复杂的功能(例如
setVelocity()
)从系统(例如Sys_Physic::
)移动到组件(例如Physics::
)中。 - 总的来说,我打破了实体-组件-系统的宗教信仰
->我可能会在某些方面受到惩罚(?)。