Lightweight events and requests for Morpeh
🔖 Request is a queued command that can consumed in the same frame in which it was sent. A request can be sent from multiple systems, but only one system must handle it.
Important
If you publish requests but do not consume them this may lead to a memory leak because all requests are stored until they are consumed.
// get request
var damageRequest = World.GetRequest<DamageRequest>();
// send request
damageRequest.Publish(new DamageRequest { ... });
// handle request
foreach (var request in damageRequest.Consume()) { ... }
🔖 Event is a one-frame action that is processed on the next frame after it is sent. An event can be processed in many systems. Good practice is to send events only from one system.
Important
Events live only for one frame so it is necessary to process events every frame otherwise some events may be lost.
// get event
var damageEvent = World.GetEvent<DamageEvent>();
// send event
damageEvent.NextFrame(new DamageEvent { ... });
// handle event
foreach (var evt in damagedEvent.publishedChanges) { ... }
// subscribe to event
var subscription = damagedEvent.Subscribe(changes => { ... });
// do not forget to unsubscribe from event
subscription.Dispose();
Assume that the game has a damage mechanics. So we create DamageRequest
and DamageEvent
. Damage request can be sent from AttackSystem
, ExplosionSystem
and so on.
Then DamageSystem
handles that request and send damage event. Damage event can be handled in PlaySoundOnDamageSystem
, ExplodeOnDeathSystem
and others.
Click to show demo code
using System;
using Scellecs.Morpeh;
using Scellecs.Morpeh.Systems;
public struct DamageRequest : IRequestData {
public EntityId targetEntityId;
}
public struct DamagedEvent : IEventData {
public EntityId targetEntityId;
}
public class DamageSystem : UpdateSystem {
private Request<DamageRequest> damageRequest;
private Event<DamagedEvent> damagedEvent;
public override void OnAwake() {
damageRequest = World.GetRequest<DamageRequest>();
damagedEvent = World.GetEvent<DamagedEvent>();
}
public override void OnUpdate(float deltaTime) {
foreach (var request in damageRequest.Consume()) {
ApplyDamage(request.targetEntityId);
damagedEvent.NextFrame(new DamagedEvent {
targetEntityId = request.targetEntityId,
});
}
}
private void ApplyDamage(EntityId target) { }
}
public class PlaySoundOnDamageSystem : UpdateSystem {
private Event<DamagedEvent> damagedEvent;
public override void OnAwake() {
damagedEvent = World.GetEvent<DamagedEvent>();
}
public override void OnUpdate(float deltaTime) {
foreach (var evt in damagedEvent.publishedChanges) {
PlaySound(evt.targetEntityId);
}
}
private void PlaySound(EntityId target) { }
}
Library distributed as git package (How to install package from git URL)
Git URL: https://github.com/codewriter-packages/Morpeh.Events.git
Morpeh.Events is MIT licensed.