--- /dev/null
+#include <msp/game/eventbus.h>
+#include <msp/game/eventobserver.h>
+#include <msp/game/eventsource.h>
+#include <msp/test/test.h>
+
+using namespace std;
+using namespace Msp;
+
+class EventBusTests: public Test::RegisteredTest<EventBusTests>
+{
+public:
+ EventBusTests();
+
+ static const char *get_name() { return "Event bus"; }
+
+private:
+ void broadcast_events();
+ void targeted_events();
+ void observe_single();
+ void observer_lifetime();
+};
+
+struct E1 { int value; };
+struct E2 { int value; };
+
+EventBusTests::EventBusTests()
+{
+ add(&EventBusTests::broadcast_events, "Broadcast events");
+ add(&EventBusTests::targeted_events, "Targeted events");
+ add(&EventBusTests::observe_single, "Observe single source");
+ add(&EventBusTests::observer_lifetime, "Observer lifetime");
+}
+
+void EventBusTests::broadcast_events()
+{
+ Game::EventBus bus;
+ Game::EventSource<E1> src1(bus);
+ Game::EventSource<E2> src2(bus);
+ Game::EventObserver obs1(bus);
+ Game::EventObserver obs2(bus);
+ int value11 = 0;
+ int value12 = 0;
+ int value21 = 0;
+ int value22 = 0;
+ obs1.observe<E1>([&value11](const E1 &e){ value11 = e.value; });
+ obs1.observe<E2>([&value12](const E2 &e){ value12 = e.value; });
+ obs2.observe<E1>([&value21](const E1 &e){ value21 = e.value; });
+ obs2.observe<E2>([&value22](const E2 &e){ value22 = e.value; });
+ src1.emit<E1>(42);
+ src2.emit<E2>(7777);
+ EXPECT_EQUAL(value11, 42);
+ EXPECT_EQUAL(value21, 42);
+ EXPECT_EQUAL(value12, 7777);
+ EXPECT_EQUAL(value22, 7777);
+}
+
+void EventBusTests::targeted_events()
+{
+ Game::EventBus bus;
+ Game::EventSource<E1> src(bus);
+ Game::EventObserver obs1(bus);
+ Game::EventObserver obs2(bus);
+ int value1 = 0;
+ int value2 = 0;
+ obs1.observe<E1>([&value1](const E1 &e){ value1 = e.value; });
+ obs2.observe<E1>([&value2](const E1 &e){ value2 = e.value; });
+ src.emit_to<E1>(obs1, 42);
+ EXPECT_EQUAL(value1, 42);
+ EXPECT_EQUAL(value2, 0);
+}
+
+void EventBusTests::observe_single()
+{
+ Game::EventBus bus;
+ Game::EventSource<E1> src1(bus);
+ Game::EventSource<E1> src2(bus);
+ Game::EventObserver obs(bus);
+ int value1 = 0;
+ int value2 = 0;
+ obs.observe<E1>(src1, [&value1](const E1 &e){ value1 = e.value; });
+ src1.emit<E1>(42);
+ src2.emit<E1>(7777);
+ EXPECT_EQUAL(value1, 42);
+ EXPECT_EQUAL(value2, 0);
+}
+
+void EventBusTests::observer_lifetime()
+{
+ Game::EventBus bus;
+ Game::EventSource<E1> src(bus);
+ int value = 0;
+ {
+ Game::EventObserver obs(bus);
+ obs.observe<E1>([&value](const E1 &e){ value = e.value; });
+ src.emit<E1>(42);
+ EXPECT_EQUAL(value, 42);
+ }
+ src.emit<E1>(7777);
+ EXPECT_EQUAL(value, 42);
+}