diff --git a/atlas/core/application.hpp b/atlas/core/application.hpp index 1284b8ba..840ef1d7 100644 --- a/atlas/core/application.hpp +++ b/atlas/core/application.hpp @@ -123,13 +123,18 @@ namespace atlas { */ static uint32_t image_size(); + protected: + [[nodiscard]] ref renderer_instance() const { + return m_renderer; + } + private: void set_current_api(api api); private: float m_delta_time = 0.f; ref m_window; - scope m_renderer = nullptr; + ref m_renderer = nullptr; glm::mat4 m_proj_view; uint32_t m_current_frame_index = -1; vk::imgui_context m_ui_context; diff --git a/atlas/core/common.hpp b/atlas/core/common.hpp index eee99ad2..32407a51 100644 --- a/atlas/core/common.hpp +++ b/atlas/core/common.hpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include diff --git a/atlas/core/event/types.hpp b/atlas/core/event/types.hpp index dc8447c2..a1167e1b 100644 --- a/atlas/core/event/types.hpp +++ b/atlas/core/event/types.hpp @@ -17,4 +17,15 @@ namespace atlas::event { uint64_t entity1; uint64_t entity2; }; + + /** + * @brief event to trigger when to transition specific scenes + * + * @param from_scene is the current scene that is being transitioned from + * @param to_scene is the new scene that is going to be transitioned to + */ + struct scene_transition { + const void* from_scene; + const void* to_scene; + }; }; \ No newline at end of file diff --git a/atlas/core/utilities/state.hpp b/atlas/core/utilities/state.hpp index e2ab32f5..6183f6db 100644 --- a/atlas/core/utilities/state.hpp +++ b/atlas/core/utilities/state.hpp @@ -28,15 +28,33 @@ namespace atlas { void invoke_ui_update(); void invoke_start(); - void poll_update(const std::function& p_callback); + // TODO: Look into a different way of doing this + void poll_update(void* p_address, + const std::function& p_callback); - void poll_defer_update(const std::function& p_callback); + void poll_defer_update(void* p_address, + const std::function& p_callback); - void poll_physics_update(const std::function& p_callback); + void poll_physics_update(void* p_address, + const std::function& p_callback); - void poll_ui_update(const std::function& p_callback); + void poll_ui_update(void* p_address, + const std::function& p_callback); - void poll_start(const std::function& p_callback); + void poll_start(void* p_address, + const std::function& p_callback); + + // TEMP: This is a temporary solution, should look into doing this + // differently + void remove_update(void* p_address); + + void remove_defer_update(void* p_address); + + void remove_physics_update(void* p_address); + + void remove_ui_update(void* p_address); + + void remove_start(void* p_address); }; @@ -70,8 +88,9 @@ namespace atlas { static_assert(std::is_member_pointer_v, "Cannot register a function that is not a member " "function of a class object"); - detail::poll_start( - [p_instance, p_callable]() { (p_instance->*p_callable)(); }); + detail::poll_start(p_instance, [p_instance, p_callable]() { + (p_instance->*p_callable)(); + }); } /** @@ -101,8 +120,9 @@ namespace atlas { static_assert(std::is_member_pointer_v, "Cannot register a function that is not a member " "function of a class object"); - detail::poll_update( - [p_instance, p_callable]() { (p_instance->*p_callable)(); }); + detail::poll_update(p_instance, [p_instance, p_callable]() { + (p_instance->*p_callable)(); + }); } /** @@ -130,8 +150,9 @@ namespace atlas { static_assert(std::is_member_pointer_v, "Cannot register a function that is not a member " "function of a class object"); - detail::poll_physics_update( - [p_instance, p_callable]() { (p_instance->*p_callable)(); }); + detail::poll_physics_update(p_instance, [p_instance, p_callable]() { + (p_instance->*p_callable)(); + }); } /** @@ -161,8 +182,9 @@ namespace atlas { static_assert(std::is_member_pointer_v, "Cannot register a function that is not a member " "function of a class object"); - detail::poll_defer_update( - [p_instance, p_callable]() { (p_instance->*p_callable)(); }); + detail::poll_defer_update(p_instance, [p_instance, p_callable]() { + (p_instance->*p_callable)(); + }); } /** @@ -194,8 +216,9 @@ namespace atlas { static_assert(std::is_member_pointer_v, "Cannot register a function that is not a member " "function of a class object"); - detail::poll_ui_update( - [p_instance, p_callable]() { (p_instance->*p_callable)(); }); + detail::poll_ui_update(p_instance, [p_instance, p_callable]() { + (p_instance->*p_callable)(); + }); } }; \ No newline at end of file diff --git a/atlas/drivers/renderer_context.hpp b/atlas/drivers/renderer_context.hpp index 49ce24de..56e75374 100644 --- a/atlas/drivers/renderer_context.hpp +++ b/atlas/drivers/renderer_context.hpp @@ -2,6 +2,7 @@ #include #include #include +#include namespace atlas { /** @@ -65,6 +66,10 @@ namespace atlas { return background_color(p_color); } + void current_scene_context(ref p_scene) { + return current_scene(std::move(p_scene)); + } + private: virtual void preload_assets(const VkRenderPass& p_renderpass) = 0; @@ -76,6 +81,8 @@ namespace atlas { virtual void post_frame() = 0; virtual void background_color(const std::array& p_color) = 0; + + virtual void current_scene(ref) = 0; }; ref initialize_renderer( diff --git a/atlas/drivers/vulkan-cpp/vk_renderer.hpp b/atlas/drivers/vulkan-cpp/vk_renderer.hpp index c40aeda1..cb59f8a9 100644 --- a/atlas/drivers/vulkan-cpp/vk_renderer.hpp +++ b/atlas/drivers/vulkan-cpp/vk_renderer.hpp @@ -59,6 +59,8 @@ namespace atlas::vk { void post_frame() override; + void current_scene(ref) override; + private: VkDevice m_device = nullptr; vk_physical_driver m_physical; @@ -88,5 +90,7 @@ namespace atlas::vk { glm::mat4 m_model = { 1.f }; ::vk::texture m_white_texture; + + ref m_current_scene; }; }; diff --git a/atlas/renderer/renderer.hpp b/atlas/renderer/renderer.hpp index 2c7f6745..aef247d5 100644 --- a/atlas/renderer/renderer.hpp +++ b/atlas/renderer/renderer.hpp @@ -22,6 +22,9 @@ namespace atlas { const std::string& p_tag = "Renderer"); void preload(const VkRenderPass& p_renderpass); + + void current_scene(ref); + /** * @brief Indicates to the renderer is at the start of the next frame to * prepare workloads before next frame is processeed diff --git a/editor/application.cpp b/editor/application.cpp index 6c9ccc3e..1c23ddac 100644 --- a/editor/application.cpp +++ b/editor/application.cpp @@ -19,8 +19,8 @@ class editor_application : public atlas::application { // TODO -- this is going to be changed with the use of the level // streamer API - m_world = - atlas::create_strong_ref(m_allocator, "Editor World"); + m_world = atlas::create_strong_ref( + m_allocator, "Editor World", renderer_instance()); } private: diff --git a/editor/editor_world.cpp b/editor/editor_world.cpp index b0b070ef..f25e936c 100644 --- a/editor/editor_world.cpp +++ b/editor/editor_world.cpp @@ -3,20 +3,18 @@ #include #include "level_scene.hpp" -editor_world::editor_world() { - console_log_fatal("Instantiate Default editor_world!"); -} - -editor_world::editor_world(const std::string& p_tag) { +editor_world::editor_world( + const std::string& p_tag, + /*NOLINT*/ atlas::ref p_renderer_instance) + : m_renderer(/*NOLINT*/ p_renderer_instance) { m_main_world = atlas::system_registry::create_world(p_tag); - console_log_trace("m_main_world->get_tag() = {}", m_main_world->name()); - m_bus.create_listener(); m_bus.create_listener(); m_bus.create_listener(); atlas::ref first_scene = atlas::create_ref("LevelScene", m_bus); + m_renderer->current_scene(first_scene); m_main_world->add_scene(first_scene); } \ No newline at end of file diff --git a/editor/editor_world.hpp b/editor/editor_world.hpp index 4426dbc7..50a06310 100644 --- a/editor/editor_world.hpp +++ b/editor/editor_world.hpp @@ -1,14 +1,17 @@ #pragma once +#include #include #include +#include class editor_world { public: - editor_world(); - editor_world(const std::string& p_tag); + editor_world(const std::string& p_tag, + atlas::ref p_renderer_instance); private: atlas::ref m_main_world; atlas::event::event_bus m_bus; + atlas::ref m_renderer; }; \ No newline at end of file diff --git a/editor/level_scene.cpp b/editor/level_scene.cpp index dacac959..edd96f46 100644 --- a/editor/level_scene.cpp +++ b/editor/level_scene.cpp @@ -1,5 +1,6 @@ #include "level_scene.hpp" #include +#include #include #include #include diff --git a/src/atlas/core/application.cpp b/src/atlas/core/application.cpp index a5161eac..c1304963 100644 --- a/src/atlas/core/application.cpp +++ b/src/atlas/core/application.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -20,7 +21,7 @@ namespace atlas { }; m_window = create_window(settings); - m_renderer = create_scope( + m_renderer = create_ref( settings, m_window->current_swapchain().image_size(), "Renderer"); m_renderer->set_background_color({ p_settings.background_color.x, diff --git a/src/atlas/core/utilities/state.cpp b/src/atlas/core/utilities/state.cpp index 31683e3a..24f45316 100644 --- a/src/atlas/core/utilities/state.cpp +++ b/src/atlas/core/utilities/state.cpp @@ -1,60 +1,96 @@ #include -#include +#include namespace atlas { namespace detail { - inline std::deque> s_update{}; - inline std::deque> s_defer_update{}; - inline std::deque> s_ui_update{}; - inline std::deque> s_physica_update{}; - inline std::deque> s_start{}; + // inline std::deque> s_update{}; + // inline std::deque> s_defer_update{}; + // inline std::deque> s_ui_update{}; + // inline std::deque> s_physica_update{}; + // inline std::deque> s_start{}; - void poll_update(const std::function& p_callback) { - s_update.emplace_back(p_callback); + // TODO: This should be done in a better way + // Potential replace this approach with using std::hive from C++26 + inline std::unordered_map> s_update{}; + inline std::unordered_map> + s_defer_update{}; + inline std::unordered_map> s_ui_update{}; + inline std::unordered_map> + s_physica_update{}; + inline std::unordered_map> s_start{}; + + void poll_update(void* p_address, + const std::function& p_callable) { + // s_update.emplace_back(p_callback); + s_update.emplace(p_address, p_callable); + } + + void poll_defer_update(void* p_address, + const std::function& p_callback) { + s_defer_update.emplace(p_address, p_callback); + } + + void poll_physics_update(void* p_address, + const std::function& p_callback) { + s_physica_update.emplace(p_address, p_callback); + } + + void poll_ui_update(void* p_address, + const std::function& p_callback) { + s_ui_update.emplace(p_address, p_callback); + } + + void poll_start(void* p_address, + const std::function& p_callback) { + s_start.emplace(p_address, p_callback); + } + + void remove_update(void* p_address) { + s_update.erase(p_address); } - void poll_defer_update(const std::function& p_callback) { - s_defer_update.emplace_back(p_callback); + void remove_defer_update(void* p_address) { + s_defer_update.erase(p_address); } - void poll_physics_update(const std::function& p_callback) { - s_physica_update.emplace_back(p_callback); + void remove_physics_update(void* p_address) { + s_physica_update.erase(p_address); } - void poll_ui_update(const std::function& p_callback) { - s_ui_update.emplace_back(p_callback); + void remove_ui_update(void* p_address) { + s_ui_update.erase(p_address); } - void poll_start(const std::function& p_callback) { - s_start.emplace_back(p_callback); + void remove_start(void* p_address) { + s_start.erase(p_address); } void invoke_on_update() { - for (auto& on_update : s_update) { + for (auto& [address, on_update] : s_update) { on_update(); } } void invoke_defer_update() { - for (auto& on_update : s_defer_update) { + for (auto& [address, on_update] : s_defer_update) { on_update(); } } void invoke_physics_update() { - for (auto& on_update : s_physica_update) { + for (auto& [address, on_update] : s_physica_update) { on_update(); } } void invoke_ui_update() { - for (auto& on_update : s_ui_update) { + for (auto& [address, on_update] : s_ui_update) { on_update(); } } void invoke_start() { - for (auto& on_update : s_start) { + for (auto& [address, on_update] : s_start) { on_update(); } } diff --git a/src/atlas/drivers/vulkan-cpp/vk_renderer.cpp b/src/atlas/drivers/vulkan-cpp/vk_renderer.cpp index 09a3b1b1..bc79f807 100644 --- a/src/atlas/drivers/vulkan-cpp/vk_renderer.cpp +++ b/src/atlas/drivers/vulkan-cpp/vk_renderer.cpp @@ -200,6 +200,10 @@ namespace atlas::vk { }); } + void vk_renderer::current_scene(ref p_scene) { + m_current_scene = p_scene; + } + void vk_renderer::background_color(const std::array& p_color) { m_color = { { p_color.at(0), p_color.at(1), p_color.at(2), p_color.at(3) } @@ -209,11 +213,12 @@ namespace atlas::vk { void vk_renderer::preload_assets(const VkRenderPass& p_renderpass) { m_final_renderpass = p_renderpass; // set 1 -- material uniforms - ref current_world = system_registry::get_world("Editor World"); - ref current_scene = current_world->get_scene("LevelScene"); + // ref current_world = system_registry::get_world("Editor + // World"); ref current_scene = + // current_world->get_scene("LevelScene"); flecs::query<> caching = - current_scene->query_builder().build(); + m_current_scene->query_builder().build(); caching.each([this](flecs::entity p_entity) { const mesh_source* target = p_entity.get(); diff --git a/src/atlas/renderer/renderer.cpp b/src/atlas/renderer/renderer.cpp index 26cdff7c..95b81109 100644 --- a/src/atlas/renderer/renderer.cpp +++ b/src/atlas/renderer/renderer.cpp @@ -30,4 +30,8 @@ namespace atlas { void renderer::set_background_color(const std::array& p_color) { m_render_context->set_background_color(p_color); } + + void renderer::current_scene(ref p_scene) { + m_render_context->current_scene_context(std::move(p_scene)); + } };