Skip to content

Commit

Permalink
bugfix: correctly handle closing the game window
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Pollind <[email protected]>
  • Loading branch information
pollend committed Apr 2, 2023
1 parent bd6fdff commit bb0d8c4
Show file tree
Hide file tree
Showing 18 changed files with 543 additions and 525 deletions.
46 changes: 9 additions & 37 deletions HPL2/core/include/engine/Event.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,9 @@ namespace hpl

template <typename... Params>
class EventHandler;

enum class ConnectionType: uint8_t {
Direct, // handler will be connected directly to the event
QueueConnection, // handler will be queued to be connected to the event need to call Process() to process the queue
};

template <typename... Params>
class QueuedEventLoopHandler;

template <typename... Params>
class Event final
Expand All @@ -54,8 +52,8 @@ namespace hpl
public:

using Callback = std::function<void(Params...)>;
using Handler = EventHandler<Params...>;

using Handler = EventHandler<Params...>;
using QueuedEventHandler = QueuedEventLoopHandler<Params...>;

Event() = default;
Event(Event&& rhs);
Expand Down Expand Up @@ -115,7 +113,7 @@ namespace hpl
// (except for on assignment since that will also add the handle to the event; i.e. there is no way to unbind the callback after being added to an event)
EventHandler() = default;
explicit EventHandler(std::nullptr_t);
explicit EventHandler(Callback callback, ConnectionType connection = ConnectionType::Direct);
explicit EventHandler(Callback callback);
EventHandler(const EventHandler& rhs);
EventHandler(EventHandler&& rhs);

Expand Down Expand Up @@ -147,25 +145,17 @@ namespace hpl
const Event<Params...>* m_event = nullptr; //< The connected event
int32_t m_index = 0; //< Index into the add or handler vectors (negative means pending add)
Callback m_callback; //< The lambda to invoke during events
ConnectionType m_connectionType = ConnectionType::Direct; //< The connection type
std::queue<std::tuple<typename std::remove_reference<Params>::type...>> m_queuedEvents; //< The queued events
std::mutex m_mutex; //< Mutex used to guard m_queuedEvents
};



template <typename... Params>
EventHandler<Params...>::EventHandler(Callback callback, ConnectionType connection)
: m_callback(std::move(callback)),
m_connectionType(connection)
EventHandler<Params...>::EventHandler(Callback callback)
: m_callback(std::move(callback))
{
}


template <typename... Params>
EventHandler<Params...>::EventHandler(const EventHandler& rhs)
: m_callback(rhs.m_callback)
, m_connectionType(rhs.m_connectionType)
, m_event(rhs.m_event)
{
// Copy the callback and event, then perform a Connect to the event
Expand All @@ -180,12 +170,10 @@ namespace hpl
}
}


template <typename... Params>
EventHandler<Params...>::EventHandler(EventHandler&& rhs)
: m_event(rhs.m_event)
, m_index(rhs.m_index)
, m_connectionType(rhs.m_connectionType)
, m_callback(std::move(rhs.m_callback))
{
// Moves all of the data of the r-value handle, fixup the event to point to them, and revert the r-value handle to it's original construction state
Expand All @@ -202,7 +190,6 @@ namespace hpl
Disconnect();
}


template <typename... Params>
EventHandler<Params...>& EventHandler<Params...>::operator=(const EventHandler& rhs)
{
Expand All @@ -211,9 +198,7 @@ namespace hpl
{
Disconnect();
m_callback = rhs.m_callback;
m_connectionType = rhs.m_connectionType;
m_event = rhs.m_event;
m_connectionType = rhs.m_connectionType;
// Copy the callback and event, then perform a Connect to the event
if (m_callback && m_event)
{
Expand All @@ -239,7 +224,6 @@ namespace hpl
// Moves all of the data of the r-value handle, fixup the event to point to them, and revert the r-value handle to it's original construction state
m_event = rhs.m_event;
m_index = rhs.m_index;
m_connectionType = rhs.m_connectionType;
m_callback = std::move(rhs.m_callback);

rhs.m_event = nullptr;
Expand Down Expand Up @@ -292,13 +276,6 @@ namespace hpl
{
return;
}

std::lock_guard<std::mutex> lock(m_mutex);
while(!m_queuedEvents.empty()) {
auto& data = m_queuedEvents.front();
std::apply(m_callback, data);
m_queuedEvents.pop();
}
}

template <typename... Params>
Expand Down Expand Up @@ -449,12 +426,7 @@ namespace hpl
{
if (handler)
{
if(handler->m_connectionType == ConnectionType::Direct) {
handler->m_callback(params...);
} else {
std::lock_guard<std::mutex> lock(handler->m_mutex);
handler->m_queuedEvents.push(std::tuple<Params...>(params...));
}
handler->m_callback(params...);
}
}

Expand Down
Empty file.
67 changes: 67 additions & 0 deletions HPL2/core/include/engine/QueuedEventLoopHandler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@

#pragma once

#include "engine/Event.h"
#include "engine/Interface.h"
#include "engine/UpdateEventLoop.h"

namespace hpl {

/**
* Events are queued and processed on the event loop.
*/
template<typename... Params>
class QueuedEventLoopHandler
{
public:
using TargetEvent = hpl::Event<Params...>;

struct Options {
public:
/**
* called before processing queued events
*/
std::function<void()> onBegin = [](){};
/**
* called after all queued events have been processed
*/
std::function<void()> onEnd = [](){};
/**
* a filter function that returns true if the event should be queued
*/
std::function<bool(Params...)> filter = [](Params...){ return true; };
};
inline QueuedEventLoopHandler(BroadcastEvent event, TargetEvent& targetEvent, TargetEvent::Callback callback, const Options options = Options {}):
m_dispatchHandler([&, options, callback](float value) {
std::lock_guard<std::mutex> lock(m_mutex);
options.onBegin();
while(!m_queuedEvents.empty()) {
auto& data = m_queuedEvents.front();
std::apply(callback, data);
m_queuedEvents.pop();
}
options.onEnd();
}),
m_handler([&, options](Params... params) {
std::lock_guard<std::mutex> lock(m_mutex);
if(options.filter(params...)) {
m_queuedEvents.emplace(std::tuple<Params...>(params...));
}
})
{
Interface<IUpdateEventLoop>::Get()->Subscribe(event, m_dispatchHandler);
m_handler.Connect(targetEvent);
}

QueuedEventLoopHandler(const QueuedEventLoopHandler&) = delete;
QueuedEventLoopHandler(QueuedEventLoopHandler&&) = delete;
QueuedEventLoopHandler& operator=(const QueuedEventLoopHandler&) = delete;
QueuedEventLoopHandler& operator=(QueuedEventLoopHandler&&) = delete;
private:
hpl::IUpdateEventLoop::UpdateEvent::Handler m_dispatchHandler;
hpl::Event<Params...>::Handler m_handler;
std::queue<std::tuple<typename std::remove_reference<Params>::type...>> m_queuedEvents;
std::mutex m_mutex;
};

} // namespace hpl
3 changes: 1 addition & 2 deletions HPL2/core/include/graphics/Enum.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,7 @@ namespace hpl
Anisotropic
};

enum class BlendFunc: uint32_t {
};
enum class BlendFunc: uint32_t {};
BlendFunc CreateFromMaterialBlendMode(eMaterialBlendMode mode);
BlendFunc CreateBlendFunction(BlendOperator type, BlendOperand src, BlendOperand dst);
BlendOperand GetBlendOperandSrc(BlendFunc func);
Expand Down
Loading

0 comments on commit bb0d8c4

Please sign in to comment.