I am currently trying my hand at developing a small game engine, and I am using EnTT for the ECS and event system. Because all of the EnTT stuff is just implementation stuff, I don't want to have any of it exposed, so I am developing wrappers for all of the stuff I am going to use.
I am currently trying to wrap the event dispatcher in my own class. Here's how the EnTT event dispatcher is used (from their wiki):
struct an_event { int value; };
struct another_event {};
struct listener {
void receive(const an_event &) { /* ... */ }
void method(const another_event &) { /* ... */ }
};
// ...
listener listener;
dispatcher.sink<an_event>().connect<&listener::receive>(listener);
dispatcher.sink<another_event>().connect<&listener::method>(listener);
Seems pretty simple, so I tried to do this to wrap just that line up:
template<typename E, typename L>
void EventManager::subscribe(L listener) {
dispatcher.sink<E>().connect<&L::receive>(listener);
}
And that didn't work, I got this error:
error: invalid operands of types ‘<unresolved overloaded function type>’ and ‘void (handler::*)(const TestEvent1&)’ to binary ‘operator<’
However, I didn't give it much thought, because I wanted to be able to have more than one handler per class anyway, so then I tried to find a way to also pass the handler function itself as a template argument:
template<typename E, typename L, void(L::*callback)(const E&)>
void EventManager::subscribe(L listener) {
dispatcher.sink<E>().connect<callback>(listener);
}
And I got the same result. After this, I tried numerous ways of doing this, and none of them were able to even compile. I even tried wrapping just the connect
function by itself, and that didn't work either in any way.
Is this approach even possible? How can I achieve this?