Event Dispatcher para Unity
Señales tipadas despachadas a través de un servicio, con soporte para autoregistro y sin singletons estáticos.
Para qué sirve este sistema
El bajo acoplamiento en Unity suele empezar con eventos de C#. Luego aparecen UnityEvents en el Inspector. Después surge un bus de mensajes a medida porque nadie quiere cablear UnityEvents uno a uno entre escenas. Cada proyecto acaba con su propia variante de la misma idea, y el código resultante sigue filtrando referencias entre sistemas que no deberían conocerse.
El Event Dispatcher de Serenity es la forma estándar de despachar señales dentro de la foundation. Es basado en servicio, las señales son tipadas y las acciones pueden autoregistrarse mediante un atributo. Todos los demás sistemas de la foundation lo usan, así que las señales no son un añadido posterior, son la manera en que los sistemas hablan entre sí.
El problema en Unity
Los eventos de Unity vienen en demasiados sabores y ninguno es del todo adecuado para comunicación entre sistemas. Los eventos de C# son simples pero fáciles de filtrar. Los UnityEvents son visibles en el Inspector pero se resisten al refactor. Los buses de eventos estáticos son cómodos pero pelean con los tests unitarios. Ninguno anima a usar payloads tipados y todos tienden a crecer orgánicamente hasta que el grafo de dependencias entre sistemas es imposible de dibujar.
Encima, el registro es la parte que todo el mundo olvida. Las suscripciones son fáciles de añadir y fáciles de filtrar. Cuando un sistema necesita escuchar una señal, encontrar el momento adecuado para registrarse y el momento adecuado para desregistrarse suele ser lo bastante tedioso como para que la gente se lo salte.
Cómo lo aborda Serenity
Serenity expone la capa de eventos a través de IEventDispatcherService, con IEventDispatcherAction para los manejadores y EventDispatcherSignal como contrato de señal tipada. El autoregistro está soportado mediante AutoRegisterEventActionAttribute, así que las acciones se pueden descubrir y registrar desde el instalador en vez de hacerlo a mano.
La implementación Unity es UnityEventDispatcherService, registrada vía UnityEventDispatcherInstaller. El dispatcher es un servicio, no un singleton estático. Los tests pueden reemplazarlo. Los demás sistemas lo resuelven a través de la interfaz y nunca tocan un global.
El diagnóstico es de primer nivel. La capa de Infraestructura incluye UnityFileLogService y UnityFileLogSettings, registrados mediante UnityFileLogInstaller, así que el flujo de señales se puede volcar a un fichero de log durante el desarrollo. Cuando algo va mal puedes ver las señales reales que se dispararon y el orden en que se manejaron.
Cómo encaja en Serenity
Event Dispatcher vive en el namespace Serenity.EventDispatcher. Entidades de Dominio como EventDispatcherSignal y EventDispatcherSignalDelegate describen el contrato. La capa de Aplicación expone las interfaces de servicio y acción. La capa de Infraestructura aporta UnityEventDispatcherService junto con el servicio de log a fichero usado para diagnósticos mediante UnityFileLogService y UnityFileLogSettings.
Todos los demás sistemas de la foundation usan el dispatcher para comunicarse. Los menús emiten OnMenuSubmitOptionSignal. Los modales emiten OnShowModalSignal, OnCloseModalSignal y OnModalSubmitOptionSignal. Game Mode emite StartGameSignal, EnterMenuSignal y GameModeChangedSignal. Los reproductores de audio y música emiten PlayAudioClipSignal y PlayMusicTrackSignal. Game Settings emite OnGameSettingsOnValueUpdatedSignal. El dispatcher es el tejido conectivo que mantiene desacoplados a estos sistemas.
Flujo de trabajo práctico
- Define tu tipo de señal como una clase que extiende EventDispatcherSignal.
- Define una acción que implemente IEventDispatcherAction para esa señal.
- Decora la acción con AutoRegisterEventActionAttribute si quieres que el instalador la descubra.
- Lanza la señal a través de IEventDispatcherService desde el código que quiera notificar.
- Suscríbete con acciones o delegados registrados desde el código que quiera reaccionar.
- Reemplaza el servicio en tests si necesitas afirmar que se lanzó una señal.
Qué incluye
- Dispatcher basado en servicio IEventDispatcherService sin singletons estáticos
- Contrato de señal tipada a través de EventDispatcherSignal y EventDispatcherSignalDelegate
- Interfaz de acción IEventDispatcherAction para manejadores reactivos
- Soporte de autoregistro vía AutoRegisterEventActionAttribute
- Implementación Unity UnityEventDispatcherService con registro a través de instalador
- Diagnóstico mediante UnityFileLogService y UnityFileLogSettings
- Usado como capa conectiva entre todos los demás sistemas de Serenity
- Testeable de forma aislada porque el servicio se resuelve a través de una interfaz
Cuándo usarlo
- Proyectos que quieren que los sistemas de gameplay se comuniquen sin referenciarse entre sí.
- Equipos que prefieren señales tipadas frente a UnityEvents o eventos crudos de C# para la comunicación entre sistemas.
- Bases de código que se mueven de buses de eventos estáticos hacia un servicio resoluble.
- Juegos que necesitan diagnóstico o replay del flujo de eventos durante el desarrollo.
Sistemas relacionados
Usa Serenity cuando quieras una capa de eventos tipada que el resto de la foundation ya habla, pero que te sigue dejando definir tus propias señales y acciones para tu juego.
English
Español
Català