Commit 7c53a4a7 authored by Johannes Braun's avatar Johannes Braun
Browse files

Implemented new messages

parent 83d27b80
#include <util/messages.h>
#include <iostream>
#include <string>
#include <cassert>
class MyObserver : public msg::Observer
template<>
struct prop
{
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()
{
// 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 << "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 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->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.
}
// 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;
......
......@@ -7,6 +7,8 @@
#include <imgui/imgui_glfw.h>
#include <core/message_tags.h>
#include <core/state.h>
namespace glare::component
{
size_t PlayerController::s_current_id = 0;
......@@ -17,7 +19,7 @@ namespace glare::component
core::Context::current().callbacks().addKeyActionCallback("player_controller" + std::to_string(m_id), std::bind(&PlayerController::onKeyAction, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
core::Context::current().callbacks().addMouseButtonCallback("player_controller" + std::to_string(m_id), std::bind(&PlayerController::onMouseButtonAction, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
registerForMessage(tags::camera);
core::Context::current().messages()->addObserver(this, tags::camera);
}
PlayerController::~PlayerController()
......@@ -25,7 +27,7 @@ namespace glare::component
try {
core::Context::current().callbacks().removeKeyActionCallback("player_controller" + std::to_string(m_id));
core::Context::current().callbacks().removeMouseButtonCallback("player_controller" + std::to_string(m_id));
unregisterForMessage(tags::camera);
core::Context::current().messages()->removeObserver(this, tags::camera);
}
catch (...)
{
......@@ -37,9 +39,9 @@ namespace glare::component
return core::Context::current().camera()->owner() == owner();
}
void PlayerController::handle(messaging::message_t &message)
void PlayerController::onNotify(msg::id_type id, msg::message_type message)
{
switch (message.name)
switch (id)
{
case tags::camera:
{
......
#ifndef __PLAYERCONTROLLER_H
#define __PLAYERCONTROLLER_H
#include <util/messaging.h>
#include <core/graph/component.h>
#include <core/control.h>
#include <util/messages.h>
namespace glare::component
{
class PlayerController : public core::SceneComponent, public messaging::Receiver
class PlayerController : public core::SceneComponent, public msg::Observer
{
public:
PlayerController();
~PlayerController();
void handle(messaging::message_t &message) override;
void onNotify(msg::id_type id, msg::message_type message) override;
void onKeyAction(controls::Key key, controls::ButtonAction action, controls::KeyMods mods);
void onMouseButtonAction(controls::MouseButton button, controls::ButtonAction action, controls::KeyMods mods);
......
#include "scene_node.h"
#include <core/message_tags.h>
#include <core/state.h>
#include <imgui/imgui_glfw.h>
namespace glare::core
......@@ -19,13 +19,13 @@ namespace glare::core
void SceneNode::onAttached(std::shared_ptr<SceneNode> node)
{
node->start();
messaging::Handler::getInstance().submit(tags::nodes, 1);
Context::current().messages().id(tags::nodes).push();
}
void SceneNode::onDetached(std::shared_ptr<SceneNode> node)
{
node->end();
messaging::Handler::getInstance().submit(tags::nodes, 1);
Context::current().messages().id(tags::nodes).push();
}
void SceneNode::onDestroy()
......@@ -83,7 +83,7 @@ namespace glare::core
if (m_cached_transform != transform)
{
m_cached_transform = transform;
messaging::Handler::getInstance().submit(tags::graph_transform, transform);
Context::current().messages().id(tags::graph_transform).push(std::make_any<math::Transform>(transform));
notifyTransform();
}
}
......
#ifndef INCLUDE_MESSAGE_TAGS_H
#define INCLUDE_MESSAGE_TAGS_H
#include <util/messaging.h>
#include <util/messages.h>
namespace tags
{
constexpr uint32_t graph_transform = messaging::tag("GRTR");
constexpr uint32_t mesh_transform = messaging::tag("M TR");
constexpr uint32_t nodes = messaging::tag("NODE");
constexpr uint32_t camera = messaging::tag("CAMR");
constexpr uint32_t light = messaging::tag("LGHT");
constexpr uint32_t scene = messaging::tag("SCEN");
constexpr uint32_t material = messaging::tag("MATR");
constexpr msg::id_type graph_transform = msg::make_id("GRTR");
constexpr msg::id_type mesh_transform = msg::make_id("M TR");
constexpr msg::id_type nodes = msg::make_id("NODE");
constexpr msg::id_type camera = msg::make_id("CAMR");
constexpr msg::id_type light = msg::make_id("LGHT");
constexpr msg::id_type scene = msg::make_id("SCEN");
constexpr msg::id_type material = msg::make_id("MATR");
}
#endif // !INCLUDE_MESSAGE_TAGS_H
......@@ -30,14 +30,14 @@ namespace glare::core
{
ImGui::PushID(owner()->name().c_str());
if (ImGui::DragFloat("Focus Distance", &m_focus_distance, 0.05f, 0.05f, 10000.f))
messaging::Handler::getInstance().submit(tags::camera, 1);
Context::current().messages().id(tags::camera).push();
if (ImGui::DragFloat("DOF Size", &m_dof_size, 0.05f, 0.05f, 10000.f))
messaging::Handler::getInstance().submit(tags::camera, 1);
Context::current().messages().id(tags::camera).push();
if (ImGui::Button("Make Default"))
{
core::Context::current().switchCamera(std::static_pointer_cast<Camera>(shared_from_this()));
messaging::Handler::getInstance().submit(tags::camera, 1);
Context::current().messages().id(tags::camera).push();
}
ImGui::PopID();
}
......@@ -87,7 +87,7 @@ namespace glare::core
void Camera::onTransform()
{
messaging::Handler::getInstance().submit(tags::camera, 1);
Context::current().messages().id(tags::camera).push();
}
void Camera::setProjection(Projection projection)
......
#include "light.h"
#include <imgui/imgui_glfw.h>
#include <util/messaging.h>
#include <imgui/imgui_glfw.h>
#include <util/messages.h>
#include <core/message_tags.h>
#include <core/numeric/geometry.h>
#include "core/state.h"
......@@ -20,7 +20,7 @@ namespace glare::core
{
// Light has been removed
if (core::Context::hasCurrentContext() && !core::Context::current().window().isClosing())
messaging::Handler::getInstance().submit(tags::light, LightUpdate{ m_id, nullptr });
Context::current().messages().id(tags::light).push(std::make_any<LightUpdate>(m_id, nullptr));
}
void LightComponent::setParameters(const LightParameters& data)
......@@ -108,7 +108,7 @@ namespace glare::core
void LightComponent::onTransform()
{
// Light just has changed
messaging::Handler::getInstance().submit(tags::light, LightUpdate{ m_id, this });
Context::current().messages().id(tags::light).push(std::make_any<LightUpdate>(m_id, this));
}
void LightComponent::onDebugGui()
......@@ -189,7 +189,7 @@ namespace glare::core
if (changed)
{
Log_Info << m_color.r << ", " << m_color.g << ", " << m_color.b;
messaging::Handler::getInstance().submit(tags::light, LightUpdate{ m_id, this });
Context::current().messages().id(tags::light).push(std::make_any<LightUpdate>(m_id, this));
}
}
......@@ -206,7 +206,7 @@ namespace glare::core
m_id = current_id++;
// Light has been added
messaging::Handler::getInstance().submit(tags::light, LightUpdate{ m_id, this });
Context::current().messages().id(tags::light).push(std::make_any<LightUpdate>(m_id, this));
}
core::Context::current().lights().submit(buildLightShadow());
......
......@@ -190,6 +190,8 @@ namespace glare::core
struct LightUpdate
{
LightUpdate(uint64_t id, LightComponent* ptr) : light_id(id), ptr(ptr) {}
uint64_t light_id;
LightComponent* ptr;
};
......
#include "material.h"
#include <imgui/imgui_glfw.h>
#include <util/messaging.h>
#include <util/messages.h>
#include <core/state.h>
#include <core/message_tags.h>
......@@ -58,8 +58,8 @@ namespace glare::core
ImGui::Spacing();
changed |= ImGui::DragFloat("IOR", &index_of_refraction, 0.001f, 0.1f, 10.f);
if (changed)
messaging::Handler::getInstance().submit(tags::material, 1);
if (changed)
Context::current().messages().id(tags::material).push();
ImGui::EndPopup();
}
ImGui::PopID();
......
......@@ -63,7 +63,7 @@ namespace glare::core
m_drawable->destroy();
SceneComponent::onDestroy();
messaging::Handler::getInstance().submit(tags::nodes, 1);
Context::current().messages().id(tags::nodes).push();
}
void BatchRenderer::onStart()
......
......@@ -63,10 +63,6 @@ namespace glare::core
m_texture_renderer->shader().bindSubroutine(gl::ShaderType::eFragment, "u_light_sample[3]", "sampleAmbient");
}
void GBuffer::handle(messaging::message_t &message)
{
}
void GBuffer::record(std::function<void()> render_function) const
{
......
......@@ -10,13 +10,11 @@
#include <core/res/texture2d_multisample.h>
#include <core/objects/light.h>
#include <util/messaging.h>
#include "texture_renderer.h"
namespace glare::core
{
class GBuffer : public messaging::Receiver
class GBuffer
{
public:
GBuffer(unsigned int width, unsigned int height, unsigned samples);
......@@ -29,8 +27,6 @@ namespace glare::core
void activate() const;
void deactivate() const;
void handle(messaging::message_t &message) override;
void draw() const;
void setSkybox(std::shared_ptr<Skybox> skybox);
......
......@@ -5,7 +5,8 @@
#include <core/objects/material.h>
#include "batch_drawable.h"
#include <util/messaging.h>
#include <util/messages.h>
#include <core/state.h>
#include <core/message_tags.h>
namespace glare::core
......@@ -36,7 +37,7 @@ namespace glare::core
void onTransform() override
{
messaging::Handler::getInstance().submit(tags::mesh_transform, 1);
Context::current().messages().id(tags::mesh_transform).push();
}
};
}
......
......@@ -192,13 +192,18 @@ namespace glare::core
return m_batch_light_renderer;
}
msg::SharedHandler& Context::messages()
{
return m_messages;
}
void Context::destroy()
{
m_shall_be_destroyed = true;
if (m_current_context == this)
m_current_context = nullptr;
m_contexts.erase(id());
messaging::Handler::getInstance().lock();
m_messages->lock();
m_window.close();
//m_graph_root->clearChildren();
//messaging::Handler::getInstance().unlock();
......@@ -229,7 +234,7 @@ namespace glare::core
if (m_main_camera) {
// If camera is adaptive, the width and height will be updated, otherwise, it should stay the same size
m_main_camera->update();
messaging::Handler::getInstance().submit(messaging::make_message(tags::camera, 1));
m_messages.id(tags::camera).push();
}
m_gbuffer.updateSize(width, height);
......
......@@ -16,6 +16,7 @@
#include "rendering/batch_render_list.h"
#include <util/files.h>
#include <util/messages.h>
namespace glare::core
{
......@@ -108,6 +109,7 @@ namespace glare::core
BatchLightRenderer& lights();
AnimationManager& animations();
Window& window();
msg::SharedHandler& messages();
std::shared_ptr<SceneNode> graph() const;
std::shared_ptr<Skybox> skybox() const;
std::shared_ptr<Camera> camera() const;
......@@ -143,6 +145,7 @@ namespace glare::core
BatchRenderList m_batch_render_list;
BatchLightRenderer m_batch_light_renderer;
Window m_window;
msg::SharedHandler m_messages;
};
template<typename... Args>
......
......@@ -21,17 +21,14 @@ namespace glare::raytrace
// And register tags and evaluators for receiving and process scene changes
registerForMessage(tags::camera);
core::Context::current().messages()->addObserver(this, tags::camera, tags::light, tags::mesh_transform, tags::nodes, tags::material);
m_evaluators.emplace(tags::camera, TagEvaluator(DirtyFlags::eCamera));
registerForMessage(tags::light);
m_evaluators.emplace(tags::light, TagEvaluator(DirtyFlags::eLight));
// Only update on mesh transform changes if the collector is currently active.
registerForMessage(tags::mesh_transform);
m_evaluators.emplace(tags::mesh_transform, TagEvaluator(DirtyFlags::eMeshTransform, [&](const messaging::message_t &message) { return m_is_active; }));
registerForMessage(tags::nodes);
m_evaluators.emplace(tags::nodes, TagEvaluator(DirtyFlags::eAll, [&](const messaging::message_t &message) { return m_is_active; }));
registerForMessage(tags::material);
m_evaluators.emplace(tags::material, TagEvaluator(DirtyFlags::eMaterial));
// Only update on mesh transform changes if the collector is currently active.
m_evaluators.emplace(tags::mesh_transform, TagEvaluator(DirtyFlags::eMeshTransform, [&](const msg::message_type &message) { return m_is_active; }));
m_evaluators.emplace(tags::nodes, TagEvaluator(DirtyFlags::eAll, [&](const msg::message_type &message) { return m_is_active; }));
if (scene_root)
collect(scene_root);
......@@ -41,11 +38,7 @@ namespace glare::raytrace
{
if (core::Context::hasCurrentContext() && !core::Context::current().window().isClosing())
{
unregisterForMessage(tags::camera);
unregisterForMessage(tags::mesh_transform);
unregisterForMessage(tags::light);
unregisterForMessage(tags::material);
unregisterForMessage(tags::nodes);
core::Context::current().messages()->removeObserver(this, tags::camera, tags::light, tags::mesh_transform, tags::nodes, tags::material);
}
}
......@@ -54,10 +47,10 @@ namespace glare::raytrace
m_dirty_flags |= flags;
}
void SceneCollector::handle(messaging::message_t &message)
void SceneCollector::onNotify(msg::id_type id, msg::message_type message)
{
// tag -> setdirty and submit change, all on condition that...
m_evaluators.at(message.name).evaluate(*this, message);
m_evaluators.at(id).evaluate(*this, message);
if (m_scene_root)
collect();
......@@ -116,12 +109,12 @@ namespace glare::raytrace
m_is_active = active;
}
void SceneCollector::TagEvaluator::evaluate(SceneCollector& collector, const messaging::message_t& message) const
void SceneCollector::TagEvaluator::evaluate(SceneCollector& collector, const msg::message_type& message) const
{
if (!run_if || (run_if && run_if(message)))
{
collector.setDirty(flags);
messaging::Handler::getInstance().submit(send_tag, 0);
core::Context::current().messages().id(send_tag).push();
}
}
}
......@@ -8,7 +8,7 @@
#include <core/objects/camera.h>
#include <core/numeric/flags.h>
#include <core/message_tags.h>
#include <util/messaging.h>
#include <util/messages.h>
#include "global_collector_unit.h"
#include "local_bvh.h"
......@@ -26,7 +26,7 @@ namespace glare::raytrace
eAll = ~0
};
class SceneCollector : public messaging::Receiver
class SceneCollector : public msg::Observer
{
public:
......@@ -35,7 +35,7 @@ namespace glare::raytrace
~SceneCollector();
void setDirty(DirtyFlags flags);
void handle(messaging::message_t &message) override;
void onNotify(msg::id_type id, msg::message_type message) override;
void collect(std::shared_ptr<core::SceneNode> scene_root = nullptr);
......@@ -65,10 +65,10 @@ namespace glare::raytrace
struct SceneCollector::TagEvaluator
{
private:
static bool default_predicate(const messaging::message_t &message) { return true; }
static bool default_predicate(const msg::message_type &message) { return true; }
public:
using run_predicate = std::function<bool(const messaging::message_t &message)>;
using run_predicate = std::function<bool(const msg::message_type &message)>;
TagEvaluator(DirtyFlags flags, uint32_t send_tag, run_predicate run_if = &default_predicate)
: flags(flags), run_if(run_if), send_tag(send_tag) {}
......@@ -76,7 +76,7 @@ namespace glare::raytrace
TagEvaluator(DirtyFlags flags, run_predicate run_if = &default_predicate)
: TagEvaluator(flags, tags::scene, run_if) {}
void evaluate(SceneCollector& collector, const messaging::message_t& message) const;
void evaluate(SceneCollector& collector, const msg::message_type& message) const;
DirtyFlags flags;
run_predicate run_if;
......
......@@ -53,7 +53,7 @@ namespace glare::raytrace
m_generator_type = ray_generator;
m_trace_buffer = std::make_unique<core::Buffer>();
registerForMessage(tags::scene);
core::Context::current().messages()->addObserver(this, tags::scene);
if (collector)
initialize(collector);
......@@ -62,7 +62,7 @@ namespace glare::raytrace
Pathtracer::~Pathtracer()
{
if (core::Context::hasCurrentContext() && !core::Context::current().window().isClosing())
unregisterForMessage(tags::scene);
core::Context::current().messages()->removeObserver(this, tags::scene);
}
void Pathtracer::loadSettings(const fs::path &xml_file)
......@@ -236,9 +236,9 @@ namespace glare::raytrace
reset();
}
void Pathtracer::handle(messaging::message_t& message)
void Pathtracer::onNotify(msg::id_type id, msg::message_type message)
{
switch (message.name)
switch (id)
{
case tags::scene:
reset();
......
......@@ -8,7 +8,7 @@
#include <core/base/program.h>
#include <core/graph/scene_node.h>
#include <core/objects/skybox.h>
#include <util/messaging.h>
#include <util/messages.h>
#include <raytrace/data/global_collector.h>
#include "raygenerator.h"
......@@ -25,7 +25,7 @@ namespace glare::raytrace
eEmission = 3
};
class Pathtracer : public messaging::Receiver
class Pathtracer : public msg::Observer
{
public:
Pathtracer();
......@@ -47,7 +47,7 @@ namespace glare::raytrace
void initialize(std::shared_ptr<SceneCollector> collector);
void reload(std::shared_ptr<core::SceneNode> graph_root);
void handle(messaging::message_t &message) override;
void onNotify(msg::id_type id, msg::message_type message) override;
void reset();
......
#include "messages.h"
namespace msg
{
Observer::Observer()
: m_on_notify(std::bind(&Observer::onNotify, this, std::placeholders::_1, std::placeholders::_2))
{}
Observer::Observer(std::function<void(id_type, message_type)> on_notify)
: m_on_notify(std::move(on_notify))
{}
Observer::~Observer()
{
if (!m_links.empty())
for (auto&& link : m_links)
for (auto&& id : link.second)
link.first->removeObserverNoID(this, id);
}
void Observer::removeID(id_type id, std::shared_ptr<Handler> handler)
{
auto&& link =