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);
|
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)
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user