Comments 6
Без возможности приоритизации и фильтрации событий на этом велосипеде можно очень быстро приехать в Race Condition Hell. Советую обратить внимание на библиотеку UniRx, вполне подходит под описанные вами задачи.
0
Мммм, объект подписывается на тот тип событий который ему нужен, при необходимости отсекает при обработке — интересно конкретно ему это событие или нет. И я там написал что лучше использовать для группы объектов отдельный ивент. Вполне себе фильтрация.
Насчёт приоритетов и Race Condition Hell, всем надо пользоваться с умом ) можно любую технологию загнать в угол. Если нам нужно обновить пул данных по изменению или определенным условиям — тут нет Race Condition, в Unity это происходит в рамках обработки 1го кадра. Если за один кадр вдруг здоровье персонажа меняется насколько раз и таким образом мы получим кривые данные и в не то время- это уже проблема архитектуры/логики.
ЗЫ Насчёт UniRx я в курсе )
Насчёт приоритетов и Race Condition Hell, всем надо пользоваться с умом ) можно любую технологию загнать в угол. Если нам нужно обновить пул данных по изменению или определенным условиям — тут нет Race Condition, в Unity это происходит в рамках обработки 1го кадра. Если за один кадр вдруг здоровье персонажа меняется насколько раз и таким образом мы получим кривые данные и в не то время- это уже проблема архитектуры/логики.
ЗЫ Насчёт UniRx я в курсе )
0
Не критикуя статью, покритикую подход.
Я считаю что глобальные аггрегаторы событий нарушают принципы SOLID.
За 6 лет работы с Unity я не видел ни одного проекта, в котором глобальные аггрегаторы событий оправдывали бы себя. В основном все заканчивается спагетти кодом с кучей неявных зависимостей.
Про re-usability кода можно вообще забыть — любой процесс переноса модуля в другой проект заканчивается жестким рефакторингом с поиском по всему проекту, где и что на что подписано.
Этим, кстати, на мой взгляд страдают JS фреймворки и дизайны вроде React / Redux. Все отлично работает, когда у вас TODO приложение с двумя событиями. А когда у вас команда на 50 человек, тысячи классов и событий, все это становится очень трудно поддерживать.
0
В целом согласен, просто приведу ряд аргументов за конкретное решение:
1) ивенты тут это конкретные классы или структуры, всегда можно посмотреть кто на них подписан и что передаётся внутри. То есть это не какой то DoSomething().Invoke;
Вызов в моем решении это — Invoke(new DoSomething {data});
И всегда можно глянуть кто что делает с классом DoSomething;
2) Самое правильное использование агрегаторов — пробрасывание инфы до интерфейса и/или некая реактивность логики. В бизнес приложениях всё понятно — MVC, MVVM и тд, и там есть уже конкретные реализации. В играх же часто надо чтобы когда что то случилось, случилось что то еще, без дополнительныъ связей. Реальный пример из жизни — при наведении на игровой элемент, должны появиться тултипы(конкретные, с конкретной инфой) и подсветиться элементы интерфейса связанные с тем что под курсором. Это можно пробросить за 1-2 ивента(можно за один, но лучше логически разделить на подсветку определенной группы и вызов определенного тултипа с опред. инфой) и несколько строчек кода. Другие решения приведут к большему количеству кода/контролирующих сущностей.
1) ивенты тут это конкретные классы или структуры, всегда можно посмотреть кто на них подписан и что передаётся внутри. То есть это не какой то DoSomething().Invoke;
Вызов в моем решении это — Invoke(new DoSomething {data});
И всегда можно глянуть кто что делает с классом DoSomething;
2) Самое правильное использование агрегаторов — пробрасывание инфы до интерфейса и/или некая реактивность логики. В бизнес приложениях всё понятно — MVC, MVVM и тд, и там есть уже конкретные реализации. В играх же часто надо чтобы когда что то случилось, случилось что то еще, без дополнительныъ связей. Реальный пример из жизни — при наведении на игровой элемент, должны появиться тултипы(конкретные, с конкретной инфой) и подсветиться элементы интерфейса связанные с тем что под курсором. Это можно пробросить за 1-2 ивента(можно за один, но лучше логически разделить на подсветку определенной группы и вызов определенного тултипа с опред. инфой) и несколько строчек кода. Другие решения приведут к большему количеству кода/контролирующих сущностей.
0
Это борьба с плохой архитектурой, а не удобство работы. Правильная архитектура это та, которая реализует самое простое из возможных решений.
В вашем примере — при наведении на ящик, подстветкой его и показыванием тултипа. Логика подсказывает, что событие всего одно, и две реакции на него.
В вашем решении же тот, кто кидает эвент должен знать что-то о подписчиках, которым может понадобиться этот эвент и конструировать два события для двух листенеров, потому что каждому из них нужны разные данные. Но эмиттер вообще не должно волновать, кто будет слушать этот эвент.
В вашем примере — при наведении на ящик, подстветкой его и показыванием тултипа. Логика подсказывает, что событие всего одно, и две реакции на него.
В вашем решении же тот, кто кидает эвент должен знать что-то о подписчиках, которым может понадобиться этот эвент и конструировать два события для двух листенеров, потому что каждому из них нужны разные данные. Но эмиттер вообще не должно волновать, кто будет слушать этот эвент.
0
Почему вы решили что тот кто кидает ивент должен что то знать о подписчиках?
Тут будет два ивента — потому что будут кейсы когда нужно подсвечивать интерфейсы, но не показывать тултип и наоборот. В обоих случаях будет компонент который отслеживает поведение курсора, и будет вызывать ивенты, например ShowToolTip. Ему абсолютно не важно кто подписчик. Подписчиком в архитектуре может быть фабрика тултипов, может быть вьюменеджер и тд. А в этом ивенте можно передать достаточно контекста, чтобы понять — нужен ли тултип с картинкой, или текстом, или анимированный и тд. В этом отличие от остальных агрегаторов, в которых сложно передавать контекст.
Рассмотрим реализацию без ивента — хорошая альтернатива это прослойка с контроллером тултипов и DI.
PS почему я считаю альтернативу с DI более слабой — у нас как раз появляется связанность и дополнительные сущности/интерфейсы/фабрики и тд.
Тут будет два ивента — потому что будут кейсы когда нужно подсвечивать интерфейсы, но не показывать тултип и наоборот. В обоих случаях будет компонент который отслеживает поведение курсора, и будет вызывать ивенты, например ShowToolTip. Ему абсолютно не важно кто подписчик. Подписчиком в архитектуре может быть фабрика тултипов, может быть вьюменеджер и тд. А в этом ивенте можно передать достаточно контекста, чтобы понять — нужен ли тултип с картинкой, или текстом, или анимированный и тд. В этом отличие от остальных агрегаторов, в которых сложно передавать контекст.
Рассмотрим реализацию без ивента — хорошая альтернатива это прослойка с контроллером тултипов и DI.
PS почему я считаю альтернативу с DI более слабой — у нас как раз появляется связанность и дополнительные сущности/интерфейсы/фабрики и тд.
-2
Sign up to leave a comment.
Агрегатор событий для Unity3d (Event Aggregator)