#include "event.hpp" #include "pk.h" #include #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; pk_arr_t callbacks; }; using EventArr = pk_arr_t>; using TickArr = pk_arr_t>; EventArr eventBuckets; TickArr tickBuckets; 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; pk_arr *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->next; ++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); pk_arr_append_t(&tArr, {}); bkt = &tArr[tArr.next-1]; } if constexpr(std::is_same::value) { TickArr &tArr = *reinterpret_cast(arr); pk_arr_append_t(&tArr, {}); bkt = &tArr[tArr.next-1]; } 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); pk_arr_append_t(&tBkt->callbacks, 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 (uint32_t i = 0; i < tBkt->callbacks.next; ++i) { if (tBkt->callbacks[i] == handler) { pk_arr_remove_at(&tBkt->callbacks, 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.next; ++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); pk_arr_append_t(&tBkt->callbacks, 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 (uint32_t i = 0; i < tBkt->callbacks.next; ++i) { if (tBkt->callbacks[i] == handler) { pk_arr_remove_at(&tBkt->callbacks, i); break; } } } template<> void Event_Dispatch(const char *name, double d) { BaseEventBucket *bkt = nullptr; EventBucketFind(name, bkt); EventBucket *tBkt = reinterpret_cast *>(bkt); for (uint32_t i = 0; i < tBkt->callbacks.next; ++i) { tBkt->callbacks[i](d); } } void Event_Teardown() { pk_arr_reset(&tickBuckets); pk_arr_reset(&eventBuckets); }