• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright Louis Dionne 2013-2017
2 // Distributed under the Boost Software License, Version 1.0.
3 
4 #include <boost/hana/assert.hpp>
5 #include <boost/hana/at_key.hpp>
6 #include <boost/hana/contains.hpp>
7 #include <boost/hana/map.hpp>
8 #include <boost/hana/pair.hpp>
9 #include <boost/hana/string.hpp>
10 
11 #include <functional>
12 #include <string>
13 #include <vector>
14 namespace hana = boost::hana;
15 
16 
17 template <typename ...Events>
18 struct event_system {
19     using Callback = std::function<void()>;
20     hana::map<hana::pair<Events, std::vector<Callback>>...> map_;
21 
22     template <typename Event, typename F>
onevent_system23     void on(Event e, F handler) {
24         auto is_known_event = hana::contains(map_, e);
25         static_assert(is_known_event,
26             "trying to add a handler to an unknown event");
27 
28         map_[e].push_back(handler);
29     }
30 
31     template <typename Event>
triggerevent_system32     void trigger(Event e) const {
33         auto is_known_event = hana::contains(map_, e);
34         static_assert(is_known_event,
35             "trying to trigger an unknown event");
36 
37         for (auto& handler : this->map_[e])
38             handler();
39     }
40 };
41 
42 template <typename ...Events>
make_event_system(Events...events)43 event_system<Events...> make_event_system(Events ...events) {
44     return {};
45 }
46 
47 
main()48 int main() {
49     auto events = make_event_system(
50         BOOST_HANA_STRING("foo"),
51         BOOST_HANA_STRING("bar"),
52         BOOST_HANA_STRING("baz")
53     );
54 
55     std::vector<std::string> triggered_events;
56     events.on(BOOST_HANA_STRING("foo"), [&] {
57         triggered_events.push_back("foo:1");
58     });
59     events.on(BOOST_HANA_STRING("foo"), [&] {
60         triggered_events.push_back("foo:2");
61     });
62     events.on(BOOST_HANA_STRING("bar"), [&] {
63         triggered_events.push_back("bar:1");
64     });
65     events.on(BOOST_HANA_STRING("baz"), [&] {
66         triggered_events.push_back("baz:1");
67     });
68 
69     events.trigger(BOOST_HANA_STRING("foo"));
70     events.trigger(BOOST_HANA_STRING("bar"));
71     events.trigger(BOOST_HANA_STRING("baz"));
72 
73     BOOST_HANA_RUNTIME_CHECK(triggered_events == std::vector<std::string>{
74         "foo:1", "foo:2", "bar:1", "baz:1"
75     });
76 }
77