Commit a9cb6e9d authored by Johannes Braun's avatar Johannes Braun
Browse files

New msg

parent 2d49af97
#include <core/state.h>
#include <core/res/res.h>
#include <core/objects/skybox.h>
#include <components/PlayerController.h>
#include <core/rendering/mesh_drawable.h>
#include <core/rendering/batch_renderer.h>
#include <core/rendering/batch_render_list.h>
#include <core/objects/camera.h>
#include "util/files.h"
using namespace glare;
int main(int argc, char* argv[])
{
auto context_id = core::Context::createAsCurrent(files::asset("/preferences/default.xml"));
// Load a scene and attach it to the constant root
core::Context::current().graph()->attach(core::global_resources::scenes.get(files::asset("meshes/scenery/cbox.dae"), 1.0f));
// Create a skybox
core::Context::current().skybox()->reset(core::Skybox::collectFilesFrom(files::asset("textures/ryfjallet/")));
// Add a PlayerController to move around
core::Context::current().camera()->owner()->makeComponent<component::PlayerController>();
// Render the scene with the pathtracer
core::Context::current().loop([]() { core::Context::current().draw(core::Context::DrawMode::eGBuffer); });
}
\ No newline at end of file
#include <util/messages.h>
#include <iostream>
#include <string>
#include <cassert>
msg::SharedHandler messages;
int main()
{
msg::Observer 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';
};
{
auto observer2 = std::make_unique<msg::Observer>([](msg::id_type id, msg::message_type msg) {
//Do notheringle
});
messages.handler->addObserver(observer2.get(), 0, 5, 2);
}
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"));
system("pause");
return 0;
}
\ No newline at end of file
#ifndef INCLUDE_MESSAGES_H
#define INCLUDE_MESSAGES_H
#include <any>
#include <atomic>
#include <mutex>
#include <queue>
#include <map>
#include <set>
#include <vector>
namespace msg
{
using message_type = std::any;
using id_type = uint32_t;
constexpr id_type make_id(char name[4])
{
return (name[0] << 24) | (name[1] << 16) | (name[2] << 8) | (name[3]);
}
class Handler;
class Observer
{
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)) {}
~Observer();
virtual void onNotify(id_type id, message_type message) {}
private:
void removeID(id_type id, std::shared_ptr<Handler> handler)
{
auto&& link = m_links[handler];
link.erase(id);
if (link.empty())
{
m_links.erase(handler);
}
}
void addID(id_type id, std::shared_ptr<Handler> handler)
{
m_links[handler].insert(id);
}
std::map<std::shared_ptr<Handler>, std::set<id_type>> m_links;
std::function<void(id_type, message_type)> m_on_notify;
};
class Handler : public std::enable_shared_from_this<Handler>
{
friend class Observer;
public:
void push(id_type id, message_type message)
{
if (m_message_lock) return;
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>
void removeObserver(Observer* observer, Args... ids)
{
removeObserverRec(observer, ids...);
}
template<typename... Args>
void addObserver(Observer* observer, Args... ids)
{
addObserverRec(observer, ids...);
}
private:
void addObserverRec(Observer* observer, id_type id)
{
std::unique_lock<std::mutex>(m_observers_mutex);
m_observers[id].push_back(observer);
observer->addID(id, shared_from_this());
}
template<typename... Args>
void addObserverRec(Observer* observer, id_type id, Args... ids)
{
addObserverRec(observer, id);
addObserverRec(observer, ids...);
}
void removeObserverRec(Observer* observer, id_type id)
{
std::unique_lock<std::mutex>(m_observers_mutex);
auto&& obs = m_observers[id];
observer->removeID(id, shared_from_this());
if (obs.empty())
return;
obs.erase(std::remove(obs.begin(), obs.end(), observer));
if (obs.empty())
m_observers.erase(id);
}
void removeObserverRecNonRMID(Observer* observer, id_type id)
{
std::unique_lock<std::mutex>(m_observers_mutex);
auto&& obs = m_observers[id];
obs.erase(std::remove(obs.begin(), obs.end(), observer));
if (obs.empty())
m_observers.erase(id);
}
template<typename... Args>
void removeObserverRec(Observer* observer, id_type id, Args... ids)
{
addObserverRec(observer, id);
addObserverRec(observer, ids...);
}
void notifyObservers(id_type id, message_type message)
{
std::unique_lock<std::mutex>(m_observers_mutex);
auto&& observers = m_observers[id];
for (auto&& observer : observers)
observer->m_on_notify(id, std::move(message));
}
void tryWork()
{
if (m_work_lock) return;
m_work_lock = true;
while (!m_message_lock)
{
std::unique_lock<std::mutex>(m_queue_mutex);
if (m_messages.begin() != m_messages.end())
{
auto&& item = *(m_messages.begin());
if (item.second.empty())
{
m_messages.erase(m_messages.begin());
}
else
{
notifyObservers(item.first, item.second.front());
item.second.pop();
}
}
else
{
break;
}
}
m_work_lock = false;
}
std::atomic_bool m_message_lock{ false };
std::atomic_bool m_work_lock{ false };
std::mutex m_queue_mutex;
std::map<id_type, std::queue<message_type>> m_messages;
std::mutex m_observers_mutex;
std::map<id_type, std::vector<Observer*>> m_observers;
};
struct SharedHandler
{
const std::shared_ptr<Handler> handler = std::make_shared<Handler>();
};
Observer::~Observer()
{
if (!m_links.empty())
for (auto&& link : m_links)
{
for (auto&& id : link.second)
link.first->removeObserver(this, id);
}
}
}
#endif // !INCLUDE_MESSAGES_H
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