All ECS architectures run into the problem of event processing eventually. Event processing does not fit neatly into the ECS philosophy, but few moderately complex games can really do without it. So any solution will necessarily feel not entirely ECS-kosher at first.
Approaches I have seen are:
- Attach events as transient components to the entities they belong to, and remove said components after the event was processed. The feasibility of this solution greatly depends on how costly it is in your architecture to add and remove components. If your architecture does not allow duplicate components on entities, then there is also the drawback that each event can only happen once per update to each entity.
- Add the possibility for systems to have event queues. When an event happens, you put it into the event queue of the system which handles the event. The system then processes its event queue in its update.
- If you are using event queues anyway, you can also do them properly. With one global EventManager system which receives all events. Systems can subscribe to events they are interested in and then the EventManager will put those events into their event queues.
But in any case, you should still follow the ECS philosophy that data belongs into components and code into systems. So what actually happens as part of an event should be handled by a system. Components should not contain variables which map to functions or lambda expressions.