Как стать автором
Обновить

Комментарии 15

ни разу не "размыли логику" или не "спрятали зависимости"

А какие аргументы то приведены? Выглядит так что если цепочка вызов увеличится, как это происходит в многослойном ООП, то сложно отследить кто вообще что вызвал и в каком порядке, и как это прервать.

А какие аргументы приведены в обратном направлении? Event Bus не лучше и не хуже любого другого подхода.

А те же K-Syndicate, например, во главе с целым архитектором из Plarium'а, не думая его откидывают из-за несуществующей проблемы.
https://www.youtube.com/shorts/WTF1IS4NTBM

не бы стал полагаться на инфу из Ютуб шортса )

EB не подходит в этом качестве, он позволяет различным компонентам приложения обмениваться сообщениями, чтото вроде email. Удобен, универсален, но есть ряд недостатков, которые делают его не подходящим активых систем (без существенных доработок в виде приоритезации, фильтров, актуализации)

Непредсказуемое время обработки: ЕВ основан на паттерне "подписка" на события, и время выполнения обработчика ивента может плавать от компонента к компоненту, без доработки в виде подсистемы тасок ваш персонаж будет иметь заметрный лаг инпута. В контексте игры непредсказуемую точность реакции.

Небольшая производительность: EB имеет существенные накладные расходы при обработке событий, фильтрации и маршрутизации сообщений, что опять же плохо сказывается на управлении персонажем игре.

Слабая связанность систем: контроллер плеера в 99% требует непосредственного отслеживания состояния, т.е. позиции, скорости, анимаций и тд. Придется в EB протаскивать логику плеера. Оно вам надо?

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

Чтото сложнее передвижения кубика по уровню с таким подохдм сделать не получится

Подожди следующие части)

Но зачем натягивать сову на глобус, а затем мужественно преодолевать последствия? Ну просто это уже не один раз пройдено :) Ждем-с!

А если игра не realtime? В принципе, привязка изменения глобального состояния игры к очереди (или очередям) событий выглядит довольно логично. Для какого-нибудь пошагового кравлера или стратегии выглядит ок. Понятно, что для реалтайма большие накладные расходы и относительная непредсказуемость времени реакции будут неприемлемы (скорее всего).

И при этом ни разу не "размыли логику" или не "спрятали зависимости"

Почему не размыли и не спрятали, если сделали и то и другое по факту? Какой код тогда имеет размытые зависимости, если с этим кодом всё в порядке?

И второй момент, раз EventBus настолько классный, что через него предлагается дробить игровую логику на некие шаги, то появляется вопрос, а насколько это легко дебажить, искать ошибки при отсутствующих подписчиках например, и в целом производить навигацию по коду?

А как бы мы ее не размыли, если бы делали без шины событий? Но при этом бы делали нормально)
Сделали бы еще IMoveController, который бы пробросили в IMoveService, который бы через ICharacterRepository получал игрока и вызывал бы у него этот Move()
Итого +4 класса ради того же результата, где сильнее размыта логика?)
И тогда назови мне паттерн, который не размывает логику за счет увеличения количества промежуточных классов) Стратегия, фабрика, медиатор, декоратор, адаптер, мост, посетитель?

Дело не только в количестве сущностей. Вопрос практический - современные IDE подсвечивают стек вызовов методов между классами при дебаге, и сканируют использования методов для навигации по коду. В случае с EB я не видел примеров удобной навигации, большую кодовую базу поддерживать будет тяжело. Единственный пример использования аналога EB я могу представить только когда количество методов у класса на столько большое, что только у него в API накладные расходы на EB меньше, чем на написание большого кол-ва сигнатур методов руками.

Если у меня в игре много "потребителей" инпута, то я бы сделал интерфейс IInputListener и сервис InputListenerProvider, всё. Зачем мне делать 4 доп. класса не знаю.
Получилось бы очень похоже, есть контроллер и логика, и есть третья сущность, про которую контроллер и логика знают, и которая обеспечивает между ними связь.
Только в данном случае эта третья сущность не EventBus, а маленький провайдер, отдающий интерфейс, и я могу по имплементациям данного интерфейса сразу оказаться в методе обработчике, а не искать по usageам где у меня используется мой MoveMessage и где на него идёт подписка.
Вышло длиннее? Не думаю. Потому что в примере из статьи не разобран главный кейс для которого нам в принципе нужна абстракция, а именно ситуация когда потребителей инпута может быть много. В таком случае при смене обработчика нам надо одним классом отписаться, затем другим классом подписаться, вместо простого вызова InputListenerProvider.ReplaceListener(this) в классе, который хочет слушать инпут.
Ну да, теперь какой-то слой логики знает про InputListenerProvider, но от того, что этот же слой будет знать про MoveMessage фактическая зависимость от инпута никуда не уйдёт, просто станет неявной.

Касательно паттернов. Из "промежуточных классов" я увидел только "адаптер", и может какой-нибудь "мост", но у этих паттернов есть своё применение.
Причём все эти паттерны работают по прямому вызову методов, то есть моя логика знает и зависит от "стратегии" или от той же "фабрики", поэтому размывания фактически нет.
Размыть зависимости может неправильное использование паттерна "наблюдатель", из которого EventBus по факту и появился, а всё остальное может размыть логику только если очень постараться, например если писать +4 класса на какую-то простую логику.
Я же не против умеренного декаплинга, абстракций, переиспользования логики, умеренного соблюдения SRP, или тех же ивентов, да я даже не против самого EventBus, но имхо использовать его как в статье я бы не стал и считаю ошибочным.

В том же видео вообще пример с множеством подписчиков и айдишниками, что неоптимальный и крайне странный подход, но я так понимаю это будет в следующей статье, поэтому ладно уж. Про скорость передачи сообщений через EventBus, сравнение строк и мусор при отписках я тоже говорить не буду, это меньшая из проблем.

Такую логику очень удобно тестить из-за слабой связанности компонентов.

Спасибо! Можете дополнить статью комментариями что такое ITickable и ActorComponent?

Спасибо, поправил
ActorComponent пока что лишний - залез из будущих реализаций.

Ну у вас же GC в более-менее серьезной игре просто зафризит все из-за постоянного создания объектов для шины на тиках. Не учите вредному или хотя бы сразу такие минусы рассказывайте.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории