Created
August 22, 2017 17:49
-
-
Save thai-ng/aa033a633e5425b3a5c51328bc16fc5e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <vector> | |
#include <iostream> | |
#include <memory> | |
#include <algorithm> | |
#include <type_traits> | |
using namespace std; | |
class EventHandler | |
{ | |
public: | |
template <typename Instance, | |
typename Function, | |
typename = enable_if_t<is_member_function_pointer_v<Function>>> | |
EventHandler(Instance i, Function f) : self_(new model<Instance, Function>(i, f)) {} | |
void operator() () | |
{ | |
(*self_)(); | |
} | |
bool operator== (const EventHandler& other) const | |
{ | |
return (*self_) == (*(other.self_)); | |
} | |
private: | |
struct concept_t | |
{ | |
virtual ~concept_t() = default; | |
virtual void operator() () = 0; | |
virtual bool operator== (const concept_t& other) const = 0; | |
}; | |
template <typename I, typename F> | |
struct model : concept_t | |
{ | |
model(I x, F f) : instance_(move(x)), function_(move(f)) {} | |
void operator() () override | |
{ | |
(instance_->*function_)(); | |
} | |
bool operator== (const concept_t& other) const override | |
{ | |
if (typeid(*this) == typeid(other)) | |
{ | |
auto o = static_cast<const model&>(other); | |
return instance_ == o.instance_ && function_ == o.function_; | |
} | |
return false; | |
} | |
I instance_; | |
F function_; | |
}; | |
unique_ptr<concept_t> self_; | |
}; | |
class Event | |
{ | |
public: | |
void addEventHandler(EventHandler handler) | |
{ | |
if (find(begin(handlers), end(handlers), handler) == end(handlers)) | |
{ | |
handlers.emplace_back(move(handler)); | |
} | |
else | |
{ | |
cout << "Handler already exist\n"; | |
} | |
} | |
void fire() | |
{ | |
for (auto& handler : handlers) | |
{ | |
handler(); | |
} | |
} | |
private: | |
vector<EventHandler> handlers; | |
}; | |
class Actor | |
{ | |
int id; | |
public: | |
Actor(int i) : id(i) {} | |
void DoTheThing() | |
{ | |
cout << "Actor "<< id << " doing the thing\n"; | |
} | |
void DoAnotherThing() | |
{ | |
cout << "Actor " << id << " doing another thing!\n"; | |
} | |
}; | |
void doTheThing() | |
{ | |
cout << "Free do the thing\n"; | |
} | |
int main() | |
{ | |
auto actor1 = make_unique<Actor>(1); | |
auto actor2 = make_unique<Actor>(2); | |
Event myEvent; | |
myEvent.addEventHandler(EventHandler(actor1.get(), &Actor::DoTheThing)); | |
myEvent.addEventHandler(EventHandler(actor2.get(), &Actor::DoTheThing)); | |
myEvent.addEventHandler(EventHandler(actor1.get(), &Actor::DoTheThing)); | |
// myEvent.addEventHandler(EventHandler(actor1.get(), &doTheThing)); // Error: Not a member function | |
myEvent.fire(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment