0 Коммуникация в Svelto.ECS
Grigory laboja lapu pirms 6 gadiem

Одна из проблем, решение которой никогда не было стандартизировано ни одной реализацией ECS, - это связь между системами. Это еще одно место, где я много думал, и Svelto.ECS решает его двумя новыми способами. Третий способ - использование стандартного паттерна Наблюдатель / Наблюдаемый, приемлемого в очень конкретных и специфических случаях.

DispatchOnSet / DispatchOnChange

Ранее мы увидели, как позволить Движкам обмениваться данными через Компоненты сущностей с помощью опроса данных (Data polling). DispatchOnSet и DispatchOnChange являются единственными ссылками (не значимыми типами), которые могут быть возвращены свойствами Компонентов сущностей, но тип универсального параметра T должен быть значимым типом. Названия функций звучат как диспетчер событий, но вместо этого их следует рассматривать как методы проталкивания (Push) данных, как противоположные опросам данных, что немного похоже на привязку данных. Вот и все, иногда опрос данных неудобен, мы не хотим опрашивать переменную каждый кадр, когда знаем, что данные редко меняются. DispatchOnSet и DispatchOnChange не могут запускаться без изменения данных, это позволяет рассматривать их как механизм привязки данных вместо обычного события. Также нет функции запуска для вызова, вместо этого значение данных, удерживаемых этими классами, должно быть установлено или изменено. В коде Survival нет больших примеров, но вы можете увидеть, как работает булево поле targetHit из IGunHitTargetComponent. Разница между DispatchOnSet и DispatchOnChange заключается в том, что последний запускает событие только тогда, когда данные фактически изменяются, а первое всегда.

Секвенсер

Идеальные Движки полностью инкапсулированы, и вы можете написать логику этого движка в виде последовательности инструкций с использованием Svelto.Tasks и перичеслителями (IEnumerators). Однако это не всегда возможно, так как в некоторых случаях Движки должны отправлять события другим Движкам. Обычно это выполняется через данные Сущности, особенно с использованием DispatchOnSet и DispatchOnChange, однако, как и в случае Сущностей, “поврежденных” в примере, на нем действует серия независимых и несвязанных Движков. В других случаях вы хотите, чтобы последовательность была строгой в порядке вызова движков, как в примере, где я хочу, чтобы смерть всегда происходила для последнего. В этом случае последовательность не только очень проста в использовании, но и очень удобна! Рефакторинг последовательностей очень прост. Поэтому используйте IEnumerator Svelto Tasks для «вертикальных» движков и последовательности для «горизонтальной» логики между движками.

Наблюдатель / Наблюдаемый

Я оставил возможность использовать этот паттерн специально для случаев, когда устаревший код или код не использующий Svelto.ECS должен взаимодействовать с движками Svelto.ECS. Для остальных случаев его следует использовать с особой осторожностью, так как существует вероятность злоупотребления паттерном, так как он знаком большинству кодеров, новичков в Svelto.ECS, и Секвенсоры, как правило, являются, лучшим выбором.