У меня есть все виды систем очистки (проверки) и проверки работоспособности (задачи), которые всегда должны обновляться при создании нового типа триггера.
...
В эксони хранятся в разных хранилищах, и у меня нет хорошего решения для обеспечения какого-либо взаимного исключения из них.
Лично мне нравится, когда система сущностей уведомляет системы компонентов, когда список компонентов сущности изменяетсяпо любой конкретной причине.Преимущество заключается в том, что это позволяет системам затем создавать и поддерживать внутреннюю структуру данных, которая наилучшим образом соответствует их потребностям, чтобы отслеживать любое состояние компонента, необходимое для быстрой и эффективной обработки на этапе обновления игрового цикла.
При этом я бы создал TriggerSanityCheckSystem
, который поддерживает некоторую структуру данных, которая отслеживает, есть ли у сущности существующее отношение триггера или нет.Если это произойдет, эта система либо выдаст исключение, либо каким-либо образом запретит добавление нового компонента триггера в объект.Если система обнаружит, что у объекта нет существующего триггера, она зарегистрирует, что добавляется новый, возможно, его тип, и продолжит работу.
Этот TriggerSanityCheckSystem
будет запущен раньше любого другогосистема триггеров, чтобы гарантировать требуемое требование взаимной исключительности, прежде чем разрешить компонентную логику для триггеров.
ОБНОВЛЕНИЕ
Здесь может быть лучший подход, я просто не уверен, еслиэто будет соответствовать вашему дизайну.В своем первоначальном вопросе вы упомянули следующее:
В традиционном упе это было бы тривиально: сохранить один указатель на сущность для базового типа, получить и реализовать новый риггер и все.
Что если бы вместо этого вы могли это сделать?Первая проблема здесь в том, что у вас есть несколько реализаций этих триггеров, но для каждой сущности должна быть разрешена только одна из этих реализаций.Что, если вместо этого взаимная исключительность обусловлена самой реализацией самого компонента.
struct TriggerDelegatingComponent
{
BaseTrigger *delegate_;
}
Цель в том, чтобы у вас была единственная система, которая управляет этим типом компонента, и она ограничивает сущности, имеющие только один экземпляр компонента.и компонент ограничивает логику одной реализацией триггера, сводя на нет всю потребность в этих проверках работоспособности .
В этом подходе вы смешиваете лучшее из обоих миров, ECS и OOP.