Add EventHandle to manage smartptr based events more conveniently

This commit is contained in:
Georg Hagen
2025-02-28 16:47:22 +01:00
parent 3317fcac23
commit 6804436b4e
3 changed files with 60 additions and 15 deletions

View File

@@ -484,4 +484,55 @@ namespace OpenVulkano
{ {
return std::pair<std::weak_ptr<Instance>, Method>(instance, method); return std::pair<std::weak_ptr<Instance>, Method>(instance, method);
} }
class EventHandle
{
std::weak_ptr<void> m_owner;
IEventHandler* m_handler;
public:
EventHandle() : m_handler(nullptr) {}
EventHandle(const std::weak_ptr<void>& 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<class EVENT_OWNER_T, typename... EVENT_ARGS, typename HANDLER_T>
EventHandle (const std::shared_ptr<EVENT_OWNER_T>& owner, Event<EVENT_ARGS...> 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; }
};
} }

View File

@@ -18,7 +18,6 @@ namespace OpenVulkano::Scene
ArBackgroundDrawable::ArBackgroundDrawable(const Ptr<AR::ArSession>& arSession) ArBackgroundDrawable::ArBackgroundDrawable(const Ptr<AR::ArSession>& arSession)
: Drawable(DrawEncoder::GetDrawEncoder<ArBackgroundDrawable>(), DrawPhase::BACKGROUND) : Drawable(DrawEncoder::GetDrawEncoder<ArBackgroundDrawable>(), DrawPhase::BACKGROUND)
, m_arSession(arSession)
{ {
m_shader.topology = Topology::TRIANGLE_STRIP; m_shader.topology = Topology::TRIANGLE_STRIP;
m_shader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/background"); m_shader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/background");
@@ -29,27 +28,21 @@ namespace OpenVulkano::Scene
SetShader(&m_shader); SetShader(&m_shader);
m_intrinsicsBuffer.Init(sizeof(Math::CameraIntrinsicWithResolution), &FALLBACK_INTRINSICS); m_intrinsicsBuffer.Init(sizeof(Math::CameraIntrinsicWithResolution), &FALLBACK_INTRINSICS);
m_intrinsicsBuffer.updateFrequency = UpdateFrequency::Always; m_intrinsicsBuffer.updateFrequency = UpdateFrequency::Always;
if (m_arSession) Init(arSession);
m_arSession->OnNewFrame += EventHandler(this, &ArBackgroundDrawable::OnNewArFrame);
} }
void ArBackgroundDrawable::Init(const Ptr<AR::ArSession>& arSession) void ArBackgroundDrawable::Init(const Ptr<AR::ArSession>& arSession)
{ {
if (m_arSession) if (m_eventHandle) Close();
{
if (m_arSession == arSession) return;
Close();
}
if (!arSession) return; if (!arSession) return;
m_arSession = arSession; m_eventHandle = { arSession, &AR::ArSession::OnNewFrame, EventHandler(this, &ArBackgroundDrawable::OnNewArFrame) };
m_arSession->OnNewFrame += EventHandler(this, &ArBackgroundDrawable::OnNewArFrame);
} }
void ArBackgroundDrawable::Close() void ArBackgroundDrawable::Close()
{ {
if (m_arSession) m_arSession->OnNewFrame -= EventHandler(this, &ArBackgroundDrawable::OnNewArFrame); m_eventHandle.Close();
m_arSession = nullptr; m_lastFrame = m_nextFrame = nullptr;
m_nextFrame = nullptr; m_texture = nullptr;
Drawable::Close(); Drawable::Close();
} }

View File

@@ -6,6 +6,7 @@
#pragma once #pragma once
#include "Base/Event.hpp"
#include "Base/Wrapper.hpp" #include "Base/Wrapper.hpp"
#include "Scene/Drawable.hpp" #include "Scene/Drawable.hpp"
#include "Scene/Shader/Shader.hpp" #include "Scene/Shader/Shader.hpp"
@@ -26,7 +27,7 @@ namespace OpenVulkano
{ {
Shader m_shader; Shader m_shader;
UniformBuffer m_intrinsicsBuffer; UniformBuffer m_intrinsicsBuffer;
Ptr<AR::ArSession> m_arSession; EventHandle m_eventHandle;
Ptr<AR::ArFrame> m_nextFrame, m_currentFrame, m_lastFrame; Ptr<AR::ArFrame> m_nextFrame, m_currentFrame, m_lastFrame;
const Texture* m_texture = nullptr; const Texture* m_texture = nullptr;
@@ -35,7 +36,7 @@ namespace OpenVulkano
public: public:
ArBackgroundDrawable(const Ptr<AR::ArSession>& arSession = nullptr); ArBackgroundDrawable(const Ptr<AR::ArSession>& arSession = nullptr);
~ArBackgroundDrawable() override { if (m_arSession) ArBackgroundDrawable::Close(); } ~ArBackgroundDrawable() override { ArBackgroundDrawable::Close(); }
void Init(const Ptr<AR::ArSession>& arSession); void Init(const Ptr<AR::ArSession>& arSession);