A simplified version of of QT’s Signals/Slots, one that does not require macros may be of use here. I recently created a simple signal only class based on Robert Penner’s AS3 Signals. It was an opportunity for me to use modern C++ features. It supports both method and lambda callbacks and uses variadic templates for simplified syntax. The code is very compact in less than 200 lines. Although I suspect it would grow a bit to properly cope with multi-threaded use.
For example, say the entity class provided some rudimentry signals
Signal<float> signalUpdate; // update() called
Signal<> signalEnteredScene; // onEnter
Signal<> signalExitedScene; // onExist
From the component you could then do :
entity.signalUpdate.add([](float dt) { /* get updates */});
or if you want to use member functions :
entity.signalUpdate.add(std::bind(&ThisClass::callbackFunction,this,std::placeholders::_1));
entity.signalUpdate.add(SIGNAL_CB_METHOD1(ThisClass:callbackFunction));
With the callback function looking like :
void ThisClass::callbackFunction(float dt);
SIGNAL_CB_METHOD1 is just an example of a macro that would hide the std::bind nastiness in the line above
The entity’s update() function would then just simply do a :
signalUpdate.dispatch(deltaTime);
Components could use the same system to interact with each other. Say we wanted to play a sound when two physics bodies collided :
The PhysicsComponent
could define
Signal<Body,Body> signalBodiesCollided;
and dispatch at the end of the collision code
signalBodiesCollided.dispatch(bodyA,bodyB);
In the SoundComponent
's initialization :
entity.getComponent<PhysicsComponent>().signalBodiesCollided.add(SIGNAL_CB_METHOD1(SoundComponent::onBodiesCollieded))
void SoundComponent::onBodiesCollieded(Body a, Body b); // play a sound in here
It really is just a simple observer pattern. I am definitely no expert in ECS or Event systems but I’ve used this signaling method in a few projects and have been happy with the results, so just tossing my ideas out there.
Rick