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