Skip to content

Instantly share code, notes, and snippets.

@masfj
Created February 5, 2018 15:05
Show Gist options
  • Save masfj/513b65def51510b884b11117b3d4f32d to your computer and use it in GitHub Desktop.
Save masfj/513b65def51510b884b11117b3d4f32d to your computer and use it in GitHub Desktop.
#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