Commit 83d27b80 authored by Johannes Braun's avatar Johannes Braun
Browse files

New messages are working very well, but not used yet.

parent a9cb6e9d
......@@ -3,28 +3,51 @@
#include <string>
#include <cassert>
msg::SharedHandler messages;
class MyObserver : public msg::Observer
{
public:
void onNotify(msg::id_type id, msg::message_type msg) override
{
assert(msg.type() == typeid(std::string));
std::cout << "MyObserver received: id=" << id << ", Payload=\"" << std::any_cast<std::string>(msg) << "\"" << '\n';
}
};
int main()
{
msg::Observer observer = [](msg::id_type id, msg::message_type msg)
// A general message handler.
msg::SharedHandler messages;
// Two kinds of observers, one in class form and one with a lambda notifier.
MyObserver my_observer;
msg::Observer lambda_observer([](msg::id_type id, msg::message_type msg)
{
assert(msg.type() == typeid(std::string));
std::cout << "Rec Msg id="<< id << ", Payload:\"" << std::any_cast<std::string>(msg) << "\"" << '\n';
};
std::cout << "Lambda observer received: id=" << id << ", Payload=\"" << std::any_cast<std::string>(msg) << "\"" << '\n';
});
// Register both for some arbitrary IDs
messages->addObserver(&my_observer, 0, 2, 244);
messages->addObserver(&lambda_observer, 0, 5, 2);
// Scope testing for releasing the observer's registration on destruction.
{
auto observer2 = std::make_unique<msg::Observer>([](msg::id_type id, msg::message_type msg) {
//Do notheringle
auto scope_observer = std::make_unique<msg::Observer>([](msg::id_type id, msg::message_type msg) {
assert(msg.type() == typeid(std::string));
std::cout << "Scope observer received: id=" << id << ", Payload=\"" << std::any_cast<std::string>(msg) << "\"" << '\n';
});
messages.handler->addObserver(observer2.get(), 0, 5, 2);
messages->addObserver(scope_observer.get(), 0, 5, 2);
// publish a message to see it working.
messages.id(0).push(std::make_any<std::string>("This will be received by all receivers including the scoped observer."));
// On leaving the scope, scope_observer will be destroyed and removed from the handler registration list.
}
messages.handler->addObserver(&observer, 0, 3, 5, 2, 1);
messages.handler->push(3, std::make_any<std::string>("Test One"));
messages.handler->push(5, std::make_any<std::string>("Aiuhdfioaudj"));
messages.handler->push(2, std::make_any<std::string>("OPdiauh"));
messages.handler->push(244, std::make_any<std::string>("Naopdij"));
// Some more messages for the remaining Observers
messages.id(5).push(std::make_any<std::string>("This will only be received by lambda_observer."));
messages.id(2).push(std::make_any<std::string>("This will be received by both my_observer and lambda_observer."));
messages.id(244).push(std::make_any<std::string>("This will only be received by my_observer."));
system("pause");
return 0;
......
......@@ -26,9 +26,9 @@ namespace msg
friend class Handler;
public:
Observer() : m_on_notify(std::bind(&Observer::onNotify, this, std::placeholders::_1, std::placeholders::_2)) {}
Observer(std::function<void(id_type, message_type)> on_notify) : m_on_notify(std::move(on_notify)) {}
explicit Observer(std::function<void(id_type, message_type)> on_notify) : m_on_notify(std::move(on_notify)) {}
~Observer();
virtual ~Observer();
virtual void onNotify(id_type id, message_type message) {}
private:
......@@ -63,8 +63,6 @@ namespace msg
std::unique_lock<std::mutex>(m_queue_mutex);
m_messages[id].push(std::move(message));
tryWork();
//addObserverRec(nullptr, 1, 3, 4, 5, 2);
}
template<typename... Args>
......@@ -106,10 +104,12 @@ namespace msg
m_observers.erase(id);
}
void removeObserverRecNonRMID(Observer* observer, id_type id)
void removeObserverNoID(Observer* observer, id_type id)
{
std::unique_lock<std::mutex>(m_observers_mutex);
auto&& obs = m_observers[id];
if (obs.empty())
return;
obs.erase(std::remove(obs.begin(), obs.end(), observer));
if (obs.empty())
m_observers.erase(id);
......@@ -128,7 +128,7 @@ namespace msg
auto&& observers = m_observers[id];
for (auto&& observer : observers)
observer->m_on_notify(id, std::move(message));
observer->m_on_notify(id, message);
}
void tryWork()
......@@ -170,19 +170,52 @@ namespace msg
};
// Helper struct for wrapping a const and initialized handler pointer as the handler needs to exist as a shared_ptr to work properly.
struct SharedHandler
{
struct MessagePort
{
friend struct SharedHandler;
private:
void operator=(const MessagePort& other) = delete;
MessagePort(id_type id, Handler* handler) : id(id), handler(handler) {}
id_type id = 0;
Handler* handler = nullptr;
public:
void push(message_type data) const
{
handler->push(id, data);
}
};
Handler& operator*() const
{
return *handler;
}
Handler* operator->() const
{
return handler.get();
}
MessagePort id(id_type i) const
{
return MessagePort{ i, handler.get() };
}
private:
const std::shared_ptr<Handler> handler = std::make_shared<Handler>();
};
Observer::~Observer()
inline Observer::~Observer()
{
if (!m_links.empty())
for (auto&& link : m_links)
{
for (auto&& id : link.second)
link.first->removeObserver(this, id);
}
link.first->removeObserverNoID(this, id);
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment