I have been playing around with the new C++11 standard lately and decided to create a basic event-handling system. The code below provides a small example of my current implementation.
#include <functional>
#include <vector>
#include <iostream>
template <typename Event>
class EventBroadcaster
{
public:
typedef std::function<void(const Event&)> Connection;
void connect(Connection&& connection)
{
connections.push_back(std::move(connection));
}
void signal(const Event& event)
{
for (const auto& connection : connections)
{
connection(event);
}
}
private:
std::vector<Connection> connections;
};
struct MouseMotion
{
int x = 0;
int y = 0;
};
class Input : public EventBroadcaster<MouseMotion>
{
public:
void process()
{
MouseMotion mouseMotion;
mouseMotion.x = 10;
mouseMotion.y = 20;
signal(mouseMotion);
}
};
int main()
{
int x = 0;
int y = 0;
Input input;
input.connect([&](const MouseMotion& e){
x += e.x;
y += e.y;
});
input.process();
std::cout << x << "," << y << std::endl; // Output: 10,20
return 0;
}
The above solution does work quite nicely if the Input
class would only broadcast a single event. There might however be the case that the Input
class would want to be able to send KeyPress
events besides just MouseMotion
events.
I thought about using multiple inheritance. Making Input
inherit both EventBroadcaster<MouseMotion>
and EventBroadcaster<KeyPress>
. This results in compiler errors warning of ambiguous functions. The solution provided in the following answer Multiple Inheritance Template Class does work for the protected signal
function, but not for the public connect
function called outside the Input
class.
Besides multiple inheritance I wondered if variadic-templates could help my with my problem. I have looked at (partial) template specialization and unpacking variadic-templates. But have been unable to come with an (elegant) solution.
What would be the best way to support multiple event types?