Boilerplate-free syntax for full life cycle of events - entities with single component.
No need to define filters, pools, and worlds in every place you want to use events, everything is inside one EventsBus object.
Special support for singleton events - no more silly situations, when you have to run foreach loop over filter, even if you sure, that there can be only one entity.
publicclass TestCreatingEventsSystem :IEcsRunSystem{publicvoid Run(IEcsSystemssystems){varshared= systems.GetShared<SharedData>();varevents= shared.EventsBus;// create new singleton event, if such event already exists, method returns body of existing one
events.NewEventSingleton<PlayerReloadGunEvent>()=new PlayerReloadGunEvent {NextMag= ...,IsFastReload= ...};
events.NewEventSingleton<PlayerMoveEvent>().Direction = ...;
events.NewEventSingleton<PlayerJumpEvent>();// create new usual/non-singleton/replicant event:
events.NewEvent<CreateVFX>()=new CreateVFX {AssetPath= ..., Parent = ..., Position = ..., Orientation = ...};
events.NewEvent<PlayActionMusic>().Type = ...
events.NewEvent<TestEvent>();}}
Check events on existence:
publicclassTestCheckingEventsSystem:IEcsRunSystem{publicvoidRun(IEcsSystemssystems){varshared= systems.GetShared<SharedData>();varevents= shared.EventsBus;// check existence of singleton eventif(events.HasEventSingleton<PlayerJumpEvent>()){
character.StartJumping()}// check existence of group of events
if (!events.HasEvents<PlayActionMusic>()){
audio.PlayDefaultMusic();}}}
Use or modify event bodies:
publicclassTestUsingModifyingEventsSystem:IEcsRunSystem{publicvoidRun(IEcsSystemssystems){varshared= systems.GetShared<SharedData>();varevents= shared.EventsBus;// check existence of singleton event and get event body to use (method returns by value - C# limitation)if(events.HasEventSingleton<PlayerMoveEvent>(outvar moveEventBody)){
character.Move(moveEventBody.Direction);}// get singleton event body by ref to modify its fieldsif(events.HasEventSingleton<PlayerMoveEvent>()){refvarmoveEventBody=ref events.GetEventBodySingleton<PlayerMoveEvent>();
moveEventBody.Direction =-moveEventBody.Direction;}// get filter and pool of according event typeforeach(var entity in events.GetEventBodies<CreateVFX>(outvar creationEventsPool)){refvareventBody=ref creationEventsPool.Get(entity);vareffectAsset= GetAsset(eventBody.AssetPath);vareffect= Object.Instantiate(effectAsset.Visual, eventBody.Position, eventBody.Orientation, eventBody.Parent);
...}}}
Destroy events
publicclassTestEventsDestructionSystem:IEcsRunSystem{publicvoidRun(IEcsSystemssystems){varshared= systems.GetShared<SharedData>();varevents= shared.EventsBus;// destroy singleton event, does nothing if event didn't exist in the first place
events.DestroyEventSingleton<PlayerJumpEvent>();// destroy events you don't likeforeach(var entity in events.GetEventBodies<CreateVFX>(outvar vfxCreationEventsPool)){refvareventBody=ref vfxCreationEventsPool.Get(entity);if(eventsBody.Position.y <0){
vfxCreationEventsPool.Del(entity);}}// destroy all events of this type
events.DestroyEvents<TestEvent>();}}
Destroy events of some types automatically:
privatevoidStart(){world=new EcsWorld();sharedData=new SharedData
{EventsBus=new EventsBus(),
...};systems=new EcsSystems(world, sharedData);
systems
// gameplay events
...// automatically remove all events of these types.Add(sharedData.EventsBus.GetDestroyEventsSystem().IncSingleton<PlayerReloadGunEvent>().IncSingleton<PlayerMoveEvent>().IncSingleton<PlayerJumpEvent>().IncReplicant<CreateVFX>().IncReplicant<PlayActionMusic>().IncReplicant<TestEvent>()).Init();}
Initialization:
Event component (aka event body) should implement one (and only one) event type:
/// <summary>/// Simultaneously there can be only one instance of this event type/// </summary>publicinterfaceIEventSingleton{}/// <summary>/// Simultaneously there can be multiple instances of this event type/// </summary>publicinterfaceIEventReplicant{}
privatevoidStart(){world=new EcsWorld();sharedData=new SharedData
{// EventsBus object will create its own internal EcsWorld to manage eventsEventsBus=new EventsBus(),
...};// you can get EventsBus' internal events world, but it's modification is not safe
#if UNITY_EDITOR
UnityIntegration.EcsWorldObserver.Create(sharedData.EventsBus.GetEventsWorld());
#endif
// now you can use events in every system you likesystems=new EcsSystems(world, sharedData);
...}// do not forget to destroy EventsBus and other worldsprivatevoidOnDestroy(){
systems.Destroy();
world.Destroy();
sharedData.EventsBus.Destroy();}
About
Boilerplate-free syntax for full life cycle of events - entities with single component. Special support for singleton events.