Created
February 5, 2018 15:05
-
-
Save masfj/513b65def51510b884b11117b3d4f32d to your computer and use it in GitHub Desktop.
This file contains 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 <string> | |
#include <functional> | |
#include <vector> | |
#include <queue> | |
#include <algorithm> | |
#include <memory> | |
#include <iostream> | |
namespace | |
{ | |
class message | |
{ | |
public: | |
message(const std::string& event) | |
: event_(event) | |
{ | |
} | |
constexpr const std::string& | |
event(void) const noexcept | |
{ | |
return this->event_; | |
} | |
private: | |
std::string event_; | |
}; | |
class message_bus | |
{ | |
public: | |
using message_fn_t = std::function<void (const message&)>; | |
public: | |
message_bus(void) | |
: receivers_(), | |
messages_() | |
{ | |
} | |
~message_bus(void) | |
{ | |
} | |
void | |
add_receiver(message_fn_t receiver) | |
{ | |
this->receivers_.push_back(receiver); | |
} | |
void | |
send(const message& msg) | |
{ | |
this->messages_.push(msg); | |
} | |
void | |
notify(void) | |
{ | |
while (this->messages_.empty() == false) | |
{ | |
auto msg = this->messages_.front(); | |
std::for_each(std::begin(this->receivers_), | |
std::end(this->receivers_), | |
[&msg](message_fn_t fn) | |
{ | |
fn(msg); | |
}); | |
this->messages_.pop(); | |
} | |
} | |
private: | |
std::vector<message_fn_t> receivers_; | |
std::queue<message> messages_; | |
}; | |
class bus_node | |
{ | |
public: | |
bus_node(std::shared_ptr<message_bus> bus) | |
: bus_(bus) | |
{ | |
this->bus_->add_receiver(this->notify_function()); | |
} | |
virtual void update(void) = 0; | |
protected: | |
virtual void | |
on_notify(const message&) | |
{ | |
} | |
message_bus::message_fn_t | |
notify_function(void) | |
{ | |
auto fn = [this](const message& msg) | |
{ | |
this->on_notify(msg); | |
}; | |
return fn; | |
} | |
void | |
send(const message& msg) | |
{ | |
this->bus_->send(msg); | |
} | |
private: | |
std::shared_ptr<message_bus> bus_; | |
}; // class bus_node | |
///// | |
class component_a: public bus_node | |
{ | |
public: | |
component_a(std::shared_ptr<message_bus> bus) | |
: bus_node(bus) | |
{ | |
} | |
virtual void | |
update(void) override | |
{ | |
// message msg("Hi! I'm component A."); | |
// this->send(msg); | |
} | |
protected: | |
virtual void | |
on_notify(const message& msg) override | |
{ | |
std::cout << "The component A received: " | |
<< msg.event() | |
<< std::endl; | |
} | |
}; // class component_a | |
class component_b: public bus_node | |
{ | |
public: | |
component_b(std::shared_ptr<message_bus> bus) | |
: bus_node(bus) | |
{ | |
} | |
virtual void | |
update(void) override | |
{ | |
message msg("Hello! I'm component B."); | |
this->send(msg); | |
} | |
protected: | |
virtual void | |
on_notify(const message& msg) override | |
{ | |
std::cout << "The component B received: " | |
<< msg.event() | |
<< std::endl; | |
} | |
}; // class component_b | |
} // namespace | |
int | |
main(int argc, char* argv[]) | |
{ | |
static_cast<void>(argc); | |
static_cast<void>(argv); | |
auto bus = std::make_shared<message_bus>(); | |
component_a ca(bus); | |
component_b cb(bus); | |
for (auto i = 0; i < 5; ++i) | |
{ | |
ca.update(); | |
cb.update(); | |
bus->notify(); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment