Как уменьшить явление типизации утки в сущности-компонент-системе?
Вот колиру демо.
В моей 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
тип.Таким образом, я должен быть сознательный об этом.
Недопонимание кодера о типе будет обнаружено только во время выполнения.
На практике такая ошибка встречается очень редко.
Я должен вспомнить название системы (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::
). Как уменьшить число уток в какой-то определенной части системы ECS?
В частности, что такое шаблон дизайна, чтобы снова включить симпатичный контент-ассистент?
Одной из идей было бы рассматривать ваши реализации компонентов как канал, по которому вы взаимодействуете с системами. В любом случае это их намерение быть управляемым данными способом влияния на поведение.
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 ) );
Задача физической системы состоит в том, чтобы измерять скорость на физическом компоненте и применять ее вместе с любыми другими атрибутами данных для моделирования внутренней физики.
Другими словами, обрабатывайте входное состояние системы как комбинацию значений текущего компонента и любого другого изменяемого состояния, которое испускает предыдущая система.
Помимо того, что вы избежали упомянутой вами утки, вы также получите код, за которым легче следовать, и он течет легче. Это также открывает двери для того, чтобы их можно было легко изменять с помощью скриптовых систем и других внешних факторов влияния, манипулируя геттерами / сеттерами на ваших компонентах.
Других решений пока нет …