C++ 减少实体构件系统中的Duck类型缺陷

C++ 减少实体构件系统中的Duck类型缺陷,c++,design-patterns,c++14,duck-typing,entity-system,C++,Design Patterns,C++14,Duck Typing,Entity System,如何减少实体构件系统中的Duck类型化现象 例子 这里有一个 我的ECS中有两个系统:- 系统\u射弹:管理所有射弹和射弹方面。 系统\u Physic:管理Physic的组件 有两种组件类型:Com\u射弹,物理 有时,我发现在某些组件中缓存指向另一个实体的指针是很好的:- class Com_Projectile : public Component{ public: Entity* physic; Entity* physicSecondary; //just to

如何减少实体构件系统中的Duck类型化现象

例子 这里有一个

我的ECS中有两个系统:-

系统\u射弹
:管理所有射弹和射弹方面。
系统\u Physic
:管理Physic的组件

有两种组件类型:
Com\u射弹
物理

有时,我发现在某些组件中缓存指向另一个实体的指针是很好的:-

class Com_Projectile : public Component{
    public:
    Entity* physic;
    Entity* physicSecondary; //just to show that it is possible to have >1 physic
};
如果我想更改
Com\u抛射体的位置
,我将调用
manage(Com\u抛射体::physic)

我真的很怀念那些列出所有与物理有关的函数的可爱内容

问题: 如何在ECS系统的某些部分减少duck类型?
更具体地说,什么是设计模式来再次启用可爱的内容辅助

我目前的解决办法 让
Com\u
缓存
Physic*Physic
而不是
实体*
:-

class Com_Projectile{
    public: Physics* physic; //edited from "Entity* physic"
};
缺点:-

  • 它将促进不必要的(?)耦合
  • 我必须在
    Com_.h
    内转发声明
    Physics
  • 我必须将复杂函数(例如
    setVelocity()
    )从系统(例如
    Sys\u Physic::
    )移动到组件(例如
    物理:
  • 总的来说,我正在破坏实体组件系统
    ->我可能会在某些方面受到惩罚(?)
如何在ECS系统的某些部分减少duck类型?
更具体地说,什么是设计模式来再次启用可爱的内容辅助

一个想法是将组件实现视为与系统交互的管道。无论如何,这就是他们的意图,以数据驱动的方式影响行为

class Physics : public Component<Physics> {
public:
  Vector3 GetVelocity() const;
  void SetVelocity(const Vector3& velocity);
private:
  Vector3 velocity_;
}
课堂物理:公共组件{
公众:
向量3 GetVelocity()常量;
空隙设置速度(常数矢量3和速度);
私人:
矢量3速度;
}
现在,为了设置速度,只需调用:

Physics* physics = getComponent<Physics>( projectile->physic );
if ( physics ) 
  physics->SetVelocity( Vector3( 1, 0, 0 ) );
Physics*Physics=getComponent(射弹->物理);
if(物理)
物理->设定速度(矢量3(1,0,0));
然后,物理系统的任务是获取物理组件上的速度,并将其与任何其他数据属性一起应用于内部物理模拟

换句话说,将系统的输入状态视为当前组件值和先前系统发出的任何其他可变状态的组合


除了避免您提到的duck类型之外,您还可以得到更容易理解和更容易流动的代码。它还为脚本系统和其他外部影响者打开了变异之门,所有这些都是通过操纵组件上的getter/setter实现的。

我花了一年多的时间才相信并接受这是一个正确的解决方案。感谢它工作得很好。
class Physics : public Component<Physics> {
public:
  Vector3 GetVelocity() const;
  void SetVelocity(const Vector3& velocity);
private:
  Vector3 velocity_;
}
Physics* physics = getComponent<Physics>( projectile->physic );
if ( physics ) 
  physics->SetVelocity( Vector3( 1, 0, 0 ) );