diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2023-11-29 21:03:15 -0500 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2023-11-29 21:03:15 -0500 |
| commit | e111f78d519363a3d76237ff0a62dcbd5e53e3d6 (patch) | |
| tree | ccb3860f1bc30cd21fc52f9e4ac3ba86a63ddcd3 /src | |
| parent | 8142cbb3d1a926d5c8cb5c59a0ea259948c59ad1 (diff) | |
major events refactor to add second event callback type
Diffstat (limited to 'src')
| -rw-r--r-- | src/event.cpp | 135 | ||||
| -rw-r--r-- | src/event.hpp | 19 | ||||
| -rw-r--r-- | src/window.cpp | 2 |
3 files changed, 120 insertions, 36 deletions
diff --git a/src/event.cpp b/src/event.cpp index 89756d4..fdea2f4 100644 --- a/src/event.cpp +++ b/src/event.cpp @@ -1,62 +1,133 @@ #include "event.hpp" +#include <type_traits> -struct EventBucket { +struct BaseEventBucket { char name[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - DynArray<EventHandler> callbacks{8}; }; -DynArray<EventBucket> eventBuckets{0, nullptr}; -void EventBucketFind(const char *name, char *safeName, EventBucket*& bkt) { +template<typename Fn> +struct EventBucket : public BaseEventBucket { + using BaseEventBucket::name; + DynArray<Fn> callbacks{8}; +}; +using EventArr = DynArray<EventBucket<EventHandler>>; +using TickArr = DynArray<EventBucket<TickEvent>>; +EventArr eventBuckets{0, nullptr}; +TickArr tickBuckets{0, nullptr}; + +template<typename Fn> +void EventBucketFind(const char *name, BaseEventBucket*& bkt) { assert(strlen(name) <= 16); + char safeName[16]; memset(safeName, '\0', 16); memcpy(safeName, name, strlen(name)); - for (long i = 0; i < eventBuckets.Count(); ++i) { - EventBucket *tmpBkt = eventBuckets.GetPtr() + (sizeof(EventBucket) * i); - if (strncmp(safeName, tmpBkt->name, 16) == 0) { - bkt = tmpBkt; - break; + + BaseEventBucket *baseBkt = nullptr; + DynArrayBase *arr = nullptr; + + if constexpr(std::is_same<Fn, EventHandler>::value) { + arr = &eventBuckets; + } + if constexpr(std::is_same<Fn, TickEvent>::value) { + arr = &tickBuckets; + } + assert(arr != nullptr); + for (long i = 0; i < arr->elementCount; ++i) { + if constexpr(std::is_same<Fn, EventHandler>::value) { + EventArr &tArr = *reinterpret_cast<EventArr *>(arr); + baseBkt = &tArr[i]; + } + if constexpr(std::is_same<Fn, TickEvent>::value) { + TickArr &tArr = *reinterpret_cast<TickArr *>(arr); + baseBkt = &tArr[i]; + } + assert(baseBkt != nullptr); + if (strncmp(safeName, baseBkt->name, 16) == 0) { + bkt = baseBkt; + return; } } + if constexpr(std::is_same<Fn, EventHandler>::value) { + EventArr &tArr = *reinterpret_cast<EventArr *>(arr); + bkt = &tArr.Push(); + } + if constexpr(std::is_same<Fn, TickEvent>::value) { + TickArr &tArr = *reinterpret_cast<TickArr *>(arr); + bkt = &tArr.Push(); + } + assert(bkt != nullptr); + memcpy(bkt->name, safeName, 16); } -void Event_RegisterCallback(const char *name, EventHandler handler) { +template<> +void Event_RegisterCallback<EventHandler>(const char *name, EventHandler handler) { assert(handler != nullptr); - char safeName[16]; - EventBucket *bkt = nullptr; - EventBucketFind(name, safeName, bkt); - if (bkt == nullptr) { - bkt = &eventBuckets.Push(); - memcpy(bkt->name, safeName, 16); + BaseEventBucket *bkt = nullptr; + EventBucketFind<EventHandler>(name, bkt); + EventBucket<EventHandler> *tBkt = reinterpret_cast<EventBucket<EventHandler> *>(bkt); + tBkt->callbacks.Push(handler); +} + +template<> +void Event_UnregisterCallback<EventHandler>(const char *name, EventHandler handler) { + assert(handler != nullptr); + BaseEventBucket *bkt = nullptr; + EventBucketFind<EventHandler>(name, bkt); + EventBucket<EventHandler> *tBkt = reinterpret_cast<EventBucket<EventHandler> *>(bkt); + for (uint64_t i = 0; i < tBkt->callbacks.Count(); ++i) { + if (tBkt->callbacks[i] == handler) { + tBkt->callbacks.Remove(i); + break; + } } - bkt->callbacks.Push(handler); } -void Event_UnregisterCallback(const char *name, EventHandler handler) { +template<> +void Event_Dispatch<EventHandler>(const char *name) { + BaseEventBucket *bkt = nullptr; + EventBucketFind<EventHandler>(name, bkt); + EventBucket<EventHandler> *tBkt = reinterpret_cast<EventBucket<EventHandler> *>(bkt); + for (long i = 0; i < tBkt->callbacks.Count(); ++i) { + tBkt->callbacks[i](); + } +} + +template<> +void Event_RegisterCallback<TickEvent>(const char *name, TickEvent handler) { assert(handler != nullptr); - char safeName[16]; - EventBucket *bkt = nullptr; - EventBucketFind(name, safeName, bkt); - if (bkt == nullptr) return; - for (uint64_t i = 0; i < bkt->callbacks.Count(); ++i) { - if (bkt->callbacks[i] == handler) { - bkt->callbacks.Remove(i); + BaseEventBucket *bkt = nullptr; + EventBucketFind<TickEvent>(name, bkt); + EventBucket<TickEvent> *tBkt = reinterpret_cast<EventBucket<TickEvent> *>(bkt); + tBkt->callbacks.Push(handler); +} + +template<> +void Event_UnregisterCallback<TickEvent>(const char *name, TickEvent handler) { + assert(handler != nullptr); + BaseEventBucket *bkt = nullptr; + EventBucketFind<TickEvent>(name, bkt); + EventBucket<TickEvent> *tBkt = reinterpret_cast<EventBucket<TickEvent> *>(bkt); + for (uint64_t i = 0; i < tBkt->callbacks.Count(); ++i) { + if (tBkt->callbacks[i] == handler) { + tBkt->callbacks.Remove(i); break; } } } -void Event_Dispatch(const char *name) { - char safeName[16]; - EventBucket *bkt = nullptr; - EventBucketFind(name, safeName, bkt); - if (bkt == nullptr) return; - for (long i = 0; i < bkt->callbacks.Count(); ++i) { - bkt->callbacks[i](); +template<> +void Event_Dispatch<TickEvent, double>(const char *name, double d) { + BaseEventBucket *bkt = nullptr; + EventBucketFind<TickEvent>(name, bkt); + EventBucket<TickEvent> *tBkt = reinterpret_cast<EventBucket<TickEvent> *>(bkt); + for (long i = 0; i < tBkt->callbacks.Count(); ++i) { + tBkt->callbacks[i](d); } } void Event_Teardown() { + tickBuckets.~DynArray(); eventBuckets.~DynArray(); } diff --git a/src/event.hpp b/src/event.hpp index defa588..7eb48c2 100644 --- a/src/event.hpp +++ b/src/event.hpp @@ -9,10 +9,23 @@ #include <cstring> typedef void (*EventHandler)(); +typedef void (*TickEvent)(double); + +template<typename Fn> +void Event_RegisterCallback(const char *name, Fn handler); +template<typename Fn> +void Event_UnregisterCallback(const char *name, Fn handler); +template<typename Fn, typename... Arguments> +void Event_Dispatch(const char *name, Arguments... args); + +template<> void Event_RegisterCallback<EventHandler>(const char *name, EventHandler handler); +template<> void Event_UnregisterCallback<EventHandler>(const char *name, EventHandler handler); +template<> void Event_Dispatch<EventHandler>(const char *name); + +template<> void Event_RegisterCallback<TickEvent>(const char *name, TickEvent handler); +template<> void Event_UnregisterCallback<TickEvent>(const char *name, TickEvent handler); +template<> void Event_Dispatch<TickEvent, double>(const char *name, double d); -void Event_RegisterCallback(const char *name, EventHandler handler); -void Event_UnregisterCallback(const char *name, EventHandler handler); -void Event_Dispatch(const char *name); void Event_Teardown(); #endif /* PKE_EVENT_HPP */ diff --git a/src/window.cpp b/src/window.cpp index 0827da5..2b75cdd 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -2432,7 +2432,7 @@ void RecordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) { ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); - Event_Dispatch("RenderImGui"); + Event_Dispatch<EventHandler>("RenderImGui"); ImGui::Render(); auto drawData = ImGui::GetDrawData(); |
