Add EventHandle to manage smartptr based events more conveniently
This commit is contained in:
@@ -484,4 +484,55 @@ namespace OpenVulkano
|
||||
{
|
||||
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; }
|
||||
};
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ namespace OpenVulkano::Scene
|
||||
|
||||
ArBackgroundDrawable::ArBackgroundDrawable(const Ptr<AR::ArSession>& arSession)
|
||||
: Drawable(DrawEncoder::GetDrawEncoder<ArBackgroundDrawable>(), 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<AR::ArSession>& 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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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<AR::ArSession> m_arSession;
|
||||
EventHandle m_eventHandle;
|
||||
Ptr<AR::ArFrame> m_nextFrame, m_currentFrame, m_lastFrame;
|
||||
const Texture* m_texture = nullptr;
|
||||
|
||||
@@ -35,7 +36,7 @@ namespace OpenVulkano
|
||||
public:
|
||||
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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user