From 6804436b4eb2dd4a7f6f8985c22cc3adb2aae6f6 Mon Sep 17 00:00:00 2001 From: Georg Hagen Date: Fri, 28 Feb 2025 16:47:22 +0100 Subject: [PATCH] Add EventHandle to manage smartptr based events more conveniently --- openVulkanoCpp/Base/Event.hpp | 51 +++++++++++++++++++ .../Scene/Prefabs/ArBackgroundDrawable.cpp | 19 +++---- .../Scene/Prefabs/ArBackgroundDrawable.hpp | 5 +- 3 files changed, 60 insertions(+), 15 deletions(-) diff --git a/openVulkanoCpp/Base/Event.hpp b/openVulkanoCpp/Base/Event.hpp index a547e88..0e1c1fa 100644 --- a/openVulkanoCpp/Base/Event.hpp +++ b/openVulkanoCpp/Base/Event.hpp @@ -484,4 +484,55 @@ namespace OpenVulkano { return std::pair, Method>(instance, method); } + + class EventHandle + { + std::weak_ptr m_owner; + IEventHandler* m_handler; + + public: + EventHandle() : m_handler(nullptr) {} + + EventHandle(const std::weak_ptr& owner, IEventHandler* handler) + : m_owner(owner), m_handler(handler) + {} + + EventHandle(const EventHandle& other) = delete; + + EventHandle(EventHandle&& other) noexcept : m_owner(other.m_owner), m_handler(other.m_handler) + { + other.m_owner.reset(); + other.m_handler = nullptr; + } + + template + EventHandle (const std::shared_ptr& owner, Event EVENT_OWNER_T::* event, HANDLER_T&& handler) + : m_owner(owner), m_handler((owner.get()->*event).operator+=(handler)) + {} + + ~EventHandle() { if (m_handler) Close(); } + + void Close() + { + if (!m_handler) return; + if (auto acquired = m_owner.lock()) + { + m_handler->SetInvalid(); + } + m_handler = nullptr; + m_owner.reset(); + } + + EventHandle& operator =(const EventHandle& other) = delete; + + EventHandle& operator =(EventHandle&& other) noexcept + { + Close(); + m_owner.swap(other.m_owner); + std::swap(m_handler, other.m_handler); + return *this; + } + + operator bool() const noexcept { return m_handler; } + }; } diff --git a/openVulkanoCpp/Scene/Prefabs/ArBackgroundDrawable.cpp b/openVulkanoCpp/Scene/Prefabs/ArBackgroundDrawable.cpp index 32c75e8..5af5e6d 100644 --- a/openVulkanoCpp/Scene/Prefabs/ArBackgroundDrawable.cpp +++ b/openVulkanoCpp/Scene/Prefabs/ArBackgroundDrawable.cpp @@ -18,7 +18,6 @@ namespace OpenVulkano::Scene ArBackgroundDrawable::ArBackgroundDrawable(const Ptr& arSession) : Drawable(DrawEncoder::GetDrawEncoder(), DrawPhase::BACKGROUND) - , m_arSession(arSession) { m_shader.topology = Topology::TRIANGLE_STRIP; m_shader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/background"); @@ -29,27 +28,21 @@ namespace OpenVulkano::Scene SetShader(&m_shader); m_intrinsicsBuffer.Init(sizeof(Math::CameraIntrinsicWithResolution), &FALLBACK_INTRINSICS); m_intrinsicsBuffer.updateFrequency = UpdateFrequency::Always; - if (m_arSession) - m_arSession->OnNewFrame += EventHandler(this, &ArBackgroundDrawable::OnNewArFrame); + Init(arSession); } void ArBackgroundDrawable::Init(const Ptr& arSession) { - if (m_arSession) - { - if (m_arSession == arSession) return; - Close(); - } + if (m_eventHandle) Close(); if (!arSession) return; - m_arSession = arSession; - m_arSession->OnNewFrame += EventHandler(this, &ArBackgroundDrawable::OnNewArFrame); + m_eventHandle = { arSession, &AR::ArSession::OnNewFrame, EventHandler(this, &ArBackgroundDrawable::OnNewArFrame) }; } void ArBackgroundDrawable::Close() { - if (m_arSession) m_arSession->OnNewFrame -= EventHandler(this, &ArBackgroundDrawable::OnNewArFrame); - m_arSession = nullptr; - m_nextFrame = nullptr; + m_eventHandle.Close(); + m_lastFrame = m_nextFrame = nullptr; + m_texture = nullptr; Drawable::Close(); } diff --git a/openVulkanoCpp/Scene/Prefabs/ArBackgroundDrawable.hpp b/openVulkanoCpp/Scene/Prefabs/ArBackgroundDrawable.hpp index 960d256..9aaf973 100644 --- a/openVulkanoCpp/Scene/Prefabs/ArBackgroundDrawable.hpp +++ b/openVulkanoCpp/Scene/Prefabs/ArBackgroundDrawable.hpp @@ -6,6 +6,7 @@ #pragma once +#include "Base/Event.hpp" #include "Base/Wrapper.hpp" #include "Scene/Drawable.hpp" #include "Scene/Shader/Shader.hpp" @@ -26,7 +27,7 @@ namespace OpenVulkano { Shader m_shader; UniformBuffer m_intrinsicsBuffer; - Ptr m_arSession; + EventHandle m_eventHandle; Ptr m_nextFrame, m_currentFrame, m_lastFrame; const Texture* m_texture = nullptr; @@ -35,7 +36,7 @@ namespace OpenVulkano public: ArBackgroundDrawable(const Ptr& arSession = nullptr); - ~ArBackgroundDrawable() override { if (m_arSession) ArBackgroundDrawable::Close(); } + ~ArBackgroundDrawable() override { ArBackgroundDrawable::Close(); } void Init(const Ptr& arSession);