#include "event.hpp" #include "dynamic-array.hpp" #include struct BaseEventBucket { char name[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; }; template struct EventBucket : public BaseEventBucket { using BaseEventBucket::name; DynArray callbacks{8}; }; using EventArr = DynArray>; using TickArr = DynArray>; EventArr eventBuckets{0, nullptr}; TickArr tickBuckets{0, nullptr}; template void EventBucketFind(const char *name, BaseEventBucket*& bkt) { assert(strlen(name) <= 16); char safeName[16]; memset(safeName, '\0', 16); memcpy(safeName, name, strlen(name)); BaseEventBucket *baseBkt = nullptr; DynArrayBase *arr = nullptr; if constexpr(std::is_same::value) { arr = &eventBuckets; } if constexpr(std::is_same::value) { arr = &tickBuckets; } assert(arr != nullptr); for (long i = 0; i < arr->elementCount; ++i) { if constexpr(std::is_same::value) { EventArr &tArr = *reinterpret_cast(arr); baseBkt = &tArr[i]; } if constexpr(std::is_same::value) { TickArr &tArr = *reinterpret_cast(arr); baseBkt = &tArr[i]; } assert(baseBkt != nullptr); if (strncmp(safeName, baseBkt->name, 16) == 0) { bkt = baseBkt; return; } } if constexpr(std::is_same::value) { EventArr &tArr = *reinterpret_cast(arr); bkt = &tArr.Push(); } if constexpr(std::is_same::value) { TickArr &tArr = *reinterpret_cast(arr); bkt = &tArr.Push(); } assert(bkt != nullptr); memcpy(bkt->name, safeName, 16); } template<> void Event_RegisterCallback(const char *name, EventHandler handler) { assert(handler != nullptr); BaseEventBucket *bkt = nullptr; EventBucketFind(name, bkt); EventBucket *tBkt = reinterpret_cast *>(bkt); tBkt->callbacks.Push(handler); } template<> void Event_UnregisterCallback(const char *name, EventHandler handler) { assert(handler != nullptr); BaseEventBucket *bkt = nullptr; EventBucketFind(name, bkt); EventBucket *tBkt = reinterpret_cast *>(bkt); for (int64_t i = 0; i < tBkt->callbacks.Count(); ++i) { if (tBkt->callbacks[i] == handler) { tBkt->callbacks.Remove(i); break; } } } template<> void Event_Dispatch(const char *name) { BaseEventBucket *bkt = nullptr; EventBucketFind(name, bkt); EventBucket *tBkt = reinterpret_cast *>(bkt); for (int64_t i = 0; i < tBkt->callbacks.Count(); ++i) { tBkt->callbacks[i](); } } template<> void Event_RegisterCallback(const char *name, TickEvent handler) { assert(handler != nullptr); BaseEventBucket *bkt = nullptr; EventBucketFind(name, bkt); EventBucket *tBkt = reinterpret_cast *>(bkt); tBkt->callbacks.Push(handler); } template<> void Event_UnregisterCallback(const char *name, TickEvent handler) { assert(handler != nullptr); BaseEventBucket *bkt = nullptr; EventBucketFind(name, bkt); EventBucket *tBkt = reinterpret_cast *>(bkt); for (int64_t i = 0; i < tBkt->callbacks.Count(); ++i) { if (tBkt->callbacks[i] == handler) { tBkt->callbacks.Remove(i); break; } } } template<> void Event_Dispatch(const char *name, double d) { BaseEventBucket *bkt = nullptr; EventBucketFind(name, bkt); EventBucket *tBkt = reinterpret_cast *>(bkt); for (int64_t i = 0; i < tBkt->callbacks.Count(); ++i) { tBkt->callbacks[i](d); } } void Event_Teardown() { tickBuckets.~DynArray(); eventBuckets.~DynArray(); }