diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2024-11-14 14:46:23 -0500 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2024-11-14 14:46:23 -0500 |
| commit | b2548ba4ce295fcd94a50123fb543fac2ef2bc33 (patch) | |
| tree | 444a32abb4a094c4fa2f7bc9a95aa86963ad4110 /src | |
| parent | b1d926361b9d613ad712ad161f9a8b7ccab4551d (diff) | |
add pk.h and major pkmem refactor
Completely replaces the memory module with pkmem
pkmem is a newer implementation of the same
bucket memory structure.
Also includes replacing pkstr.h with pk.h's pkstr
Diffstat (limited to 'src')
38 files changed, 1541 insertions, 1010 deletions
diff --git a/src/array.hpp b/src/array.hpp index 7db2252..8878ce4 100644 --- a/src/array.hpp +++ b/src/array.hpp @@ -1,9 +1,7 @@ #ifndef PKE_ARRAY_HPP #define PKE_ARRAY_HPP -#include "macros.hpp" -#include "memory-type-defs.hpp" -#include "memory.hpp" +#include "vendor/pk.h" #include <cstdint> #include <cstring> @@ -34,7 +32,7 @@ inline void PkeArray_SoftReset(PkeArray_Base *arrIn) { } template<typename D> -inline void PkeArray_Add(PkeArray_Base *arrIn, const D &val, MemBucket *bkt = nullptr) { +inline void PkeArray_Add(PkeArray_Base *arrIn, const D &val, struct pk_membucket *bkt = nullptr) { auto *arr = static_cast<PkeArray<D> *>(arrIn); if (arr->reserved == arr->next) { long originalCount = arr->reserved; @@ -46,11 +44,11 @@ inline void PkeArray_Add(PkeArray_Base *arrIn, const D &val, MemBucket *bkt = nu arr->reserved *= 2.5; diff = arr->reserved - originalCount; } - auto *newData = Pke_New<D>(arr->reserved, bkt); + auto *newData = pk_new<D>(arr->reserved, bkt); memset(newData + (sizeof(D) * originalCount), 0xFF, sizeof(D) * diff); if (arr->data != nullptr && arr->data != CAFE_BABE(D)) { memcpy(newData, arr->data, sizeof(D) * originalCount); - Pke_Delete<D>(arr->data, originalCount, bkt); + pk_delete<D>(arr->data, originalCount, bkt); } arr->data = newData; } diff --git a/src/asset-manager.cpp b/src/asset-manager.cpp index 6ff4600..2784b1e 100644 --- a/src/asset-manager.cpp +++ b/src/asset-manager.cpp @@ -9,7 +9,7 @@ #include <fstream> #include <future> -const PkeHandleItemIndex_T maxAssetItemsPerBucket = 64; +const pk_handle_item_index_T maxAssetItemsPerBucket = 64; BucketContainer<Asset, AssetHandle> Asset_BucketContainer{}; @@ -38,7 +38,7 @@ void AM_Load_Task(Asset &asset) { return; } asset.size = std::filesystem::file_size(asset.basePath); - asset.ptr = Pke_New(asset.size, 64); + asset.ptr = pk_new_base(asset.size, 64); file.seekg(0, std::ios::beg); file.read(static_cast<char *>(asset.ptr), asset.size); file.close(); @@ -77,7 +77,7 @@ AssetHandle AM_Register(AssetKey key, AssetType type, const void *data, int64_t strncpy(asset.key, key, AssetKeyLength); asset.basePath = nullptr; asset.size = size; - asset.ptr = Pke_New(size, alignment); + asset.ptr = pk_new_base(size, alignment); memcpy(asset.ptr, data, size); asset.state = PKE_ASSET_LOADING_STATE_LOADED; asset.type = type; @@ -95,13 +95,13 @@ AssetHandle AM_Register(AssetKey key, AssetType type, const char *path) { asset.handle = assetHandle; strncpy(asset.key, key, AssetKeyLength); int64_t pathLen = strlen(path); - auto *copiedPath = Pke_New<char>(pathLen + 1); + auto *copiedPath = pk_new<char>(pathLen + 1); copiedPath[pathLen] = '\0'; strncpy(copiedPath, path, pathLen); asset.basePath = copiedPath; asset.state = PKE_ASSET_LOADING_STATE_LOADING; asset.type = type; - std::packaged_task<void()> *task = Pke_New<std::packaged_task<void()>>(); + std::packaged_task<void()> *task = pk_new<std::packaged_task<void()>>(); new (task) std::packaged_task<void()>( [&asset] { AM_Load_Task(asset); }); @@ -126,13 +126,13 @@ AssetHandle AM_Register(const char *path, AssetType type) { new (&asset) Asset{}; asset.handle = assetHandle; strncpy(asset.key, assetKey, AssetKeyLength); - auto *copiedPath = Pke_New<char>(pathLen + 1); + auto *copiedPath = pk_new<char>(pathLen + 1); copiedPath[pathLen] = '\0'; strncpy(copiedPath, path, pathLen); asset.basePath = copiedPath; asset.state = PKE_ASSET_LOADING_STATE_LOADING; asset.type = type; - std::packaged_task<void()> *task = Pke_New<std::packaged_task<void()>>(); + std::packaged_task<void()> *task = pk_new<std::packaged_task<void()>>(); new (task) std::packaged_task<void()>( [&asset] { AM_Load_Task(asset); }); @@ -149,7 +149,7 @@ void AM_Release(AssetHandle assetHandle) { } const Asset *AM_Get(AssetHandle assetHandle) { - auto validationResult = ValidateHandle(assetHandle, Asset_BucketContainer.pkeHandle, maxAssetItemsPerBucket); + auto validationResult = pk_handle_validate(assetHandle, Asset_BucketContainer.pkeHandle, maxAssetItemsPerBucket); assert(validationResult == 0); auto &asset = Asset_BucketContainer.buckets[assetHandle.bucketIndex][assetHandle.itemIndex]; if (asset.state == PKE_ASSET_LOADING_STATE_LOADED) { @@ -161,7 +161,7 @@ const Asset *AM_Get(AssetHandle assetHandle) { return nullptr; } asset.state = PKE_ASSET_LOADING_STATE_LOADING; - std::packaged_task<void()> *task = Pke_New<std::packaged_task<void()>>(); + std::packaged_task<void()> *task = pk_new<std::packaged_task<void()>>(); new (task) std::packaged_task<void()>( [&asset] { AM_Load_Task(asset); }); @@ -174,7 +174,7 @@ const Asset *AM_Get(AssetHandle assetHandle) { } else { char buf[256]; buf[255] = '\0'; - snprintf(buf, 255, "[AM_Get] Attempting to retrieve asset: '%.16s' which had a state of '%hhu', but did not have a valid future and thus cannot wait for completion", asset.key, asset.state); + snprintf(buf, 255, "[AM_Get] Attempting to retrieve asset: '%.16s' which had a state of '%hhu', but did not have a valid future and thus cannot wait for completion", asset.key, static_cast<AssetLoadingState_T>(asset.state)); throw buf; } } @@ -226,7 +226,7 @@ void AM_DebugPrint() { printf("\tptr %p\n", asset.ptr); printf("\tfuture: %i\n", asset.future.valid()); printf("\treferenceCount: %i\n", asset.referenceCount); - printf("\tAssetLoadingState: %hhu\n", asset.state); + printf("\tAssetLoadingState: %hhu\n", static_cast<AssetLoadingState_T>(asset.state)); } } } @@ -238,7 +238,7 @@ void AM_GC() { if (asset.referenceCount > 0) continue; if (asset.ptr != nullptr && asset.ptr != CAFE_BABE(void)) { - Pke_Delete(asset.ptr, asset.size); + pk_delete_base(asset.ptr, asset.size); } asset.size = 0; asset.ptr = CAFE_BABE(void); diff --git a/src/asset-manager.hpp b/src/asset-manager.hpp index 6204614..4d96c59 100644 --- a/src/asset-manager.hpp +++ b/src/asset-manager.hpp @@ -1,18 +1,17 @@ #ifndef PKE_ASSET_MANAGER_HPP #define PKE_ASSET_MANAGER_HPP -#include "macros.hpp" -#include "memory.hpp" +#include "vendor/pk.h" #include <cstdint> #include <future> -struct AssetHandle : public PkeHandle { }; +struct AssetHandle : public pk_handle { }; -constexpr AssetHandle AssetHandle_MAX = AssetHandle{}; +constexpr AssetHandle AssetHandle_MAX = AssetHandle{ pk_handle_MAX_constexpr }; -TypeSafeInt_Const_Expr(AssetLoadingState, uint8_t, 0xFF); -TypeSafeInt_Const_Expr(AssetType, uint8_t, 0xFF); +TypeSafeInt_constexpr(AssetLoadingState, uint8_t, 0xFF); +TypeSafeInt_constexpr(AssetType, uint8_t, 0xFF); const int64_t AssetKeyLength = 16; using AssetKey = char[AssetKeyLength]; diff --git a/src/bucketed-array.hpp b/src/bucketed-array.hpp index b40251c..0f8b395 100644 --- a/src/bucketed-array.hpp +++ b/src/bucketed-array.hpp @@ -2,31 +2,33 @@ #define PKE_BUCKETED_ARRAY_HPP #include <cstddef> +#include <cassert> -#include "memory.hpp" +#include "vendor/pk.h" -constexpr PkeHandleBucketIndex_T BucketContainerDefaultBucketCount = 16; -constexpr PkeHandleItemIndex_T BucketContainerDefaultItemCount = 256; +constexpr pk_handle_bucket_index_T BucketContainerDefaultBucketCount = 16; +constexpr pk_handle_item_index_T BucketContainerDefaultItemCount = 256; -template<typename T, typename CT = PkeHandle, PkeHandleBucketIndex_T BKT_CNT = BucketContainerDefaultBucketCount> +template<typename T, typename CT = struct pk_handle, pk_handle_item_index_T BKT_CNT = BucketContainerDefaultBucketCount> struct BucketContainer { CT limits; CT pkeHandle; T* buckets[BKT_CNT]; }; -template<typename T, typename CT, PkeHandleBucketIndex_T BKT_CNT> +template<typename T, typename CT, pk_handle_item_index_T BKT_CNT> void Buckets_Init(BucketContainer<T, CT, BKT_CNT> &bktContainer, size_t maxItemCount = BucketContainerDefaultItemCount) { bktContainer.limits.bucketIndex = BKT_CNT; bktContainer.limits.itemIndex = maxItemCount; - bktContainer.pkeHandle.hash = 0; - for (PkeHandleBucketIndex_T i = 0; i < BKT_CNT; ++i) { + bktContainer.pkeHandle.bucketIndex = 0; + bktContainer.pkeHandle.itemIndex = 0; + for (pk_handle_item_index_T i = 0; i < BKT_CNT; ++i) { bktContainer.buckets[i] = nullptr; } - bktContainer.buckets[0] = Pke_New<T>(maxItemCount); + bktContainer.buckets[0] = pk_new<T>(maxItemCount); } -template<typename T, typename CT, PkeHandleBucketIndex_T BKT_CNT> +template<typename T, typename CT, pk_handle_item_index_T BKT_CNT> inline CT Buckets_NewHandle(BucketContainer<T, CT, BKT_CNT> &bktContainer) { CT returnValue = bktContainer.pkeHandle; bktContainer.pkeHandle.itemIndex += 1; @@ -36,15 +38,15 @@ inline CT Buckets_NewHandle(BucketContainer<T, CT, BKT_CNT> &bktContainer) { assert(bktContainer.pkeHandle.bucketIndex < bktContainer.limits.bucketIndex); } if (bktContainer.pkeHandle.itemIndex == 0) { - bktContainer.buckets[bktContainer.pkeHandle.bucketIndex] = Pke_New<T>(bktContainer.limits.itemIndex); + bktContainer.buckets[bktContainer.pkeHandle.bucketIndex] = pk_new<T>(bktContainer.limits.itemIndex); } return returnValue; } -template<typename T, typename CT, PkeHandleBucketIndex_T BKT_CNT> +template<typename T, typename CT, pk_handle_item_index_T BKT_CNT> static inline constexpr void Buckets_Destroy(BucketContainer<T, CT, BKT_CNT> &bktContainer) { - for (PkeHandleBucketIndex_T i = 0; i <= bktContainer.pkeHandle.bucketIndex; ++i) { - Pke_Delete<T>(bktContainer.buckets[i], bktContainer.limits.itemIndex); + for (pk_handle_item_index_T i = 0; i <= bktContainer.pkeHandle.bucketIndex; ++i) { + pk_delete<T>(bktContainer.buckets[i], bktContainer.limits.itemIndex); bktContainer.buckets[i] = CAFE_BABE(T); } } diff --git a/src/camera.cpp b/src/camera.cpp index 3982642..75aa40f 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -5,7 +5,6 @@ #include "camera.hpp" #include "ecs.hpp" #include "math-helpers.hpp" -#include "memory.hpp" #include "physics.hpp" PkeCamera NullCamera { @@ -21,7 +20,7 @@ PkeCamera NullCamera { }; PkeCamera *ActiveCamera = &NullCamera; -const PkeHandleItemIndex_T MAX_CAMERAS_PER_BUCKET = 32; +const pk_handle_item_index_T MAX_CAMERAS_PER_BUCKET = 32; BucketContainer<PkeCamera, CameraHandle> Camera_BucketContainer{}; btSphereShape CameraShape{1.f}; @@ -34,10 +33,10 @@ PkeCamera &PkeCamera_Register_Inner(PkeCamera &cam, const InstPos &instPos) { btVector3 localInertia(0, 0, 0); CameraShape.calculateLocalInertia(instPos.mass, localInertia); - cam.phys.inst->bt.motionState = Pke_New<btDefaultMotionState>(MemBkt_Bullet); + cam.phys.inst->bt.motionState = pk_new<btDefaultMotionState>(MemBkt_Bullet); new (cam.phys.inst->bt.motionState) btDefaultMotionState(instPos.posRot); - cam.phys.inst->bt.rigidBody = Pke_New<btRigidBody>(MemBkt_Bullet); + cam.phys.inst->bt.rigidBody = pk_new<btRigidBody>(MemBkt_Bullet); new (cam.phys.inst->bt.rigidBody) btRigidBody(instPos.mass, cam.phys.inst->bt.motionState, &CameraShape, localInertia); cam.phys.inst->bt.rigidBody->setLinearVelocity(btVector3(0,0,0)); @@ -72,10 +71,10 @@ PkeCamera *PkeCamera_Get(CameraHandle cameraHandle) { PkeCamera *PkeCamera_Get(EntityHandle handle) { assert(handle != EntityHandle_MAX); - for (PkeHandleBucketIndex_T b = 0; b <= Camera_BucketContainer.pkeHandle.bucketIndex; ++b) { + for (pk_handle_bucket_index_T b = 0; b <= Camera_BucketContainer.pkeHandle.bucketIndex; ++b) { auto &bkt = Camera_BucketContainer.buckets[b]; long itemCount = Camera_BucketContainer.pkeHandle.bucketIndex == b ? Camera_BucketContainer.pkeHandle.itemIndex : Camera_BucketContainer.limits.itemIndex; - for (PkeHandleItemIndex_T i = 0; i < itemCount; ++i) { + for (pk_handle_item_index_T i = 0; i < itemCount; ++i) { auto &cam = bkt[i]; if (cam.handle == handle) return &Camera_BucketContainer.buckets[cam.camHandle.bucketIndex][cam.camHandle.itemIndex]; @@ -107,7 +106,7 @@ void PkeCamera_AttachToInstance(CameraHandle cameraHandle, CompInstance *inst) { cam.phys.inst->bt.rigidBody->activate(); assert(cam.phys.constraint == nullptr || cam.phys.constraint == CAFE_BABE(btTypedConstraint)); - cam.phys.constraint = Pke_New<btTypedConstraint>(MemBkt_Bullet); + cam.phys.constraint = pk_new<btTypedConstraint>(MemBkt_Bullet); new (cam.phys.constraint) btPoint2PointConstraint(*cam.phys.inst->bt.rigidBody, *inst->bt.rigidBody, btVector3(0.f, -1.f, -1.f), cameraOffset); BtDynamicsWorld->addConstraint(cam.phys.constraint); @@ -119,7 +118,7 @@ void PkeCamera_DetachFromInstance(CameraHandle cameraHandle, CompInstance *inst) assert(cameraHandle != CameraHandle_MAX); auto &cam = Camera_BucketContainer.buckets[cameraHandle.bucketIndex][cameraHandle.itemIndex]; BtDynamicsWorld->removeConstraint(cam.phys.constraint); - Pke_Delete<btTypedConstraint>(cam.phys.constraint, MemBkt_Bullet); + pk_delete<btTypedConstraint>(cam.phys.constraint, MemBkt_Bullet); cam.phys.constraint = CAFE_BABE(btTypedConstraint); cam.stale = PKE_CAMERA_STALE_POSROT; } @@ -127,10 +126,10 @@ void PkeCamera_DetachFromInstance(CameraHandle cameraHandle, CompInstance *inst) void PkeCamera_SetPrimary(CameraHandle cameraHandle) { assert(cameraHandle != CameraHandle_MAX); auto &primaryCam = Camera_BucketContainer.buckets[cameraHandle.bucketIndex][cameraHandle.itemIndex]; - for (PkeHandleBucketIndex_T b = 0; b <= Camera_BucketContainer.pkeHandle.bucketIndex; ++b) { + for (pk_handle_bucket_index_T b = 0; b <= Camera_BucketContainer.pkeHandle.bucketIndex; ++b) { auto &bkt = Camera_BucketContainer.buckets[b]; long itemCount = Camera_BucketContainer.pkeHandle.bucketIndex == b ? Camera_BucketContainer.pkeHandle.itemIndex : Camera_BucketContainer.limits.itemIndex; - for (PkeHandleItemIndex_T i = 0; i < itemCount; ++i) { + for (pk_handle_item_index_T i = 0; i < itemCount; ++i) { auto *cam = &bkt[i]; if (cam->parentHandle != primaryCam.parentHandle) { continue; @@ -148,7 +147,7 @@ void PkeCamera_Destroy(CameraHandle cameraHandle) { if (cam.phys.constraint != nullptr && cam.phys.constraint != CAFE_BABE(btTypedConstraint)) { // reminder: this is not currently handled by ECS BtDynamicsWorld->removeConstraint(cam.phys.constraint); - Pke_Delete<btTypedConstraint>(cam.phys.constraint, MemBkt_Bullet); + pk_delete<btTypedConstraint>(cam.phys.constraint, MemBkt_Bullet); } ECS_MarkForRemoval(camPtr); @@ -176,7 +175,7 @@ PkeCamera *PkeCamera_GetCameras(int64_t bucketIndex, int64_t &count) { void PkeCamera_Init() { Buckets_Init(Camera_BucketContainer, MAX_CAMERAS_PER_BUCKET); - NullCamera.phys.inst = Pke_New<CompInstance>(); + NullCamera.phys.inst = pk_new<CompInstance>(); InstPos instPos{ .scale = btVector3(1.f, 1.f, 1.f), .mass = 1.f, @@ -187,11 +186,11 @@ void PkeCamera_Init() { void PkeCamera_Teardown() { Buckets_Destroy(Camera_BucketContainer); BtDynamicsWorld->removeRigidBody(NullCamera.phys.inst->bt.rigidBody); - Pke_Delete<btDefaultMotionState>(NullCamera.phys.inst->bt.motionState, MemBkt_Bullet); - Pke_Delete<btRigidBody>(NullCamera.phys.inst->bt.rigidBody, MemBkt_Bullet); + pk_delete<btDefaultMotionState>(NullCamera.phys.inst->bt.motionState, MemBkt_Bullet); + pk_delete<btRigidBody>(NullCamera.phys.inst->bt.rigidBody, MemBkt_Bullet); NullCamera.phys.inst->bt.motionState = CAFE_BABE(btDefaultMotionState); NullCamera.phys.inst->bt.rigidBody = CAFE_BABE(btRigidBody); - Pke_Delete<CompInstance>(NullCamera.phys.inst); + pk_delete<CompInstance>(NullCamera.phys.inst); NullCamera.phys.inst = CAFE_BABE(CompInstance); } @@ -206,10 +205,10 @@ void PkeCamera_Tick(double delta) { * could be that removing pos and rot from the camera would make this unnecessary? * See the camera serializer for more. */ - for (PkeHandleBucketIndex_T b = 0; b <= Camera_BucketContainer.pkeHandle.bucketIndex; ++b) { + for (pk_handle_bucket_index_T b = 0; b <= Camera_BucketContainer.pkeHandle.bucketIndex; ++b) { auto &bkt = Camera_BucketContainer.buckets[b]; long itemCount = Camera_BucketContainer.pkeHandle.bucketIndex == b ? Camera_BucketContainer.pkeHandle.itemIndex : Camera_BucketContainer.limits.itemIndex; - for (PkeHandleItemIndex_T i = 0; i < itemCount; ++i) { + for (pk_handle_item_index_T i = 0; i < itemCount; ++i) { auto &cam = bkt[i]; if (cam.handle == EntityHandle_MAX) { continue; diff --git a/src/camera.hpp b/src/camera.hpp index f4714c1..156aa5c 100644 --- a/src/camera.hpp +++ b/src/camera.hpp @@ -1,20 +1,19 @@ #ifndef PKE_CAMERA_HPP #define PKE_CAMERA_HPP +#include "vendor/pk.h" #include "components.hpp" -#include "macros.hpp" #include "vendor/glm_include.hpp" -#include "memory-type-defs.hpp" #include <cstdint> -TypeSafeInt_Const_Expr(PkeCameraType, uint8_t, 0xFF); -TypeSafeInt_Const_Expr(PkeCameraView, uint8_t, 0xFF); -TypeSafeInt_Const_Expr(PkeCameraStaleFlags, uint8_t, 0xFF); +TypeSafeInt_constexpr(PkeCameraType, uint8_t, 0xFF); +TypeSafeInt_constexpr(PkeCameraView, uint8_t, 0xFF); +TypeSafeInt_constexpr(PkeCameraStaleFlags, uint8_t, 0xFF); -struct CameraHandle : public PkeHandle {}; +struct CameraHandle : public pk_handle {}; -constexpr CameraHandle CameraHandle_MAX = CameraHandle{}; +constexpr CameraHandle CameraHandle_MAX = CameraHandle{ pk_handle_MAX_constexpr }; constexpr PkeCameraType PKE_CAMERA_TYPE_PERSPECTIVE = PkeCameraType{1 << 0}; constexpr PkeCameraType PKE_CAMERA_TYPE_ORTHOGONAL = PkeCameraType{1 << 1}; diff --git a/src/components.hpp b/src/components.hpp index 7d298ec..025d5f0 100644 --- a/src/components.hpp +++ b/src/components.hpp @@ -2,7 +2,7 @@ #define PKE_COMPONENTS_HPP #include "dynamic-array.hpp" -#include "macros.hpp" +#include "vendor/pk.h" #include "physics.hpp" #include "plugin-types.hpp" @@ -13,13 +13,13 @@ const uint64_t ECS_UNSET_VAL = 0xFFFFFFFFFFFFFFFF; const uint32_t ECS_UNSET_VAL_32 = 0xFFFFFFFF; -struct EntityHandle : public PkeHandle { }; -struct GrBindsHandle : public PkeHandle { }; -struct InstanceHandle : public PkeHandle { }; +struct EntityHandle : public pk_handle { }; +struct GrBindsHandle : public pk_handle { }; +struct InstanceHandle : public pk_handle { }; -constexpr EntityHandle EntityHandle_MAX = EntityHandle{}; -constexpr GrBindsHandle GrBindsHandle_MAX = GrBindsHandle{}; -constexpr InstanceHandle InstanceHandle_MAX = InstanceHandle{}; +constexpr EntityHandle EntityHandle_MAX = EntityHandle{ pk_handle_MAX_constexpr }; +constexpr GrBindsHandle GrBindsHandle_MAX = GrBindsHandle{ pk_handle_MAX_constexpr }; +constexpr InstanceHandle InstanceHandle_MAX = InstanceHandle{ pk_handle_MAX_constexpr }; struct Entity_Base { EntityHandle handle = EntityHandle_MAX; diff --git a/src/dynamic-array.cpp b/src/dynamic-array.cpp index 7dd15eb..c7a4ba8 100644 --- a/src/dynamic-array.cpp +++ b/src/dynamic-array.cpp @@ -5,10 +5,10 @@ void DynArrayReserve(DynArrayBase *arr, int64_t count) { assert(count != 0); if (arr->reservedCount >= count) return; char *a = nullptr; - a = Pke_New<char>(arr->elementSize * count, arr->bkt); + a = pk_new<char>(arr->elementSize * count, arr->bkt); if (arr->ptr != nullptr) { std::memcpy(a, arr->ptr, arr->elementSize * arr->reservedCount); - Pke_Delete<char>(arr->ptr, arr->elementSize * arr->reservedCount, arr->bkt); + pk_delete<char>(arr->ptr, arr->elementSize * arr->reservedCount, arr->bkt); } arr->reservedCount = count; arr->ptr = a; @@ -18,7 +18,7 @@ void DynArrayDestroy(DynArrayBase *arr) { if (arr->ptr == nullptr) return; if (arr->ptr == CAFE_BABE(char)) return; if (arr->reservedCount > 0) - Pke_Delete<char>(arr->ptr, arr->elementSize * arr->reservedCount, arr->bkt); + pk_delete<char>(arr->ptr, arr->elementSize * arr->reservedCount, arr->bkt); arr->ptr = CAFE_BABE(char); } diff --git a/src/dynamic-array.hpp b/src/dynamic-array.hpp index 4003b63..a676b40 100644 --- a/src/dynamic-array.hpp +++ b/src/dynamic-array.hpp @@ -1,18 +1,18 @@ #ifndef PKE_DYNAMIC_ARRAY_HPP #define PKE_DYNAMIC_ARRAY_HPP -#include "memory.hpp" -#include "macros.hpp" +#include "vendor/pk.h" #include <cstdint> #include <cstring> #include <cassert> #include <type_traits> +#include <new> #define BAKE_DYN_ARRAY(T) template struct DynArray<T>; struct DynArrayBase { - mutable MemBucket *bkt = nullptr; + mutable struct pk_membucket *bkt = nullptr; mutable char *ptr = nullptr; int64_t elementSize = 0; int64_t elementCount = 0; @@ -21,8 +21,8 @@ struct DynArrayBase { template <typename T> struct DynArray: DynArrayBase { - explicit DynArray(MemBucket *bucket = nullptr); - explicit DynArray(int64_t reserveCount, MemBucket *bucket = nullptr); + explicit DynArray(struct pk_membucket *bucket = nullptr); + explicit DynArray(int64_t reserveCount, struct pk_membucket *bucket = nullptr); DynArray(const DynArray<T> &other); DynArray(DynArray<T> &&other); DynArray &operator=(const DynArray<T> &other); @@ -51,7 +51,7 @@ struct DynArray: DynArrayBase { void DynArrayReserve(DynArrayBase *arr, int64_t count); void DynArrayDestroy(DynArrayBase *arr); -template <typename T> inline DynArray<T>::DynArray(int64_t count, MemBucket *bucket) { +template <typename T> inline DynArray<T>::DynArray(int64_t count, struct pk_membucket *bucket) { this->bkt = bucket; this->elementSize = sizeof(T); if (count > 0) DynArrayReserve(this, count); @@ -62,7 +62,7 @@ template <typename T> inline DynArray<T>::DynArray(int64_t count, MemBucket *buc } } -template <typename T> inline DynArray<T>::DynArray(MemBucket *bucket) { +template <typename T> inline DynArray<T>::DynArray(struct pk_membucket *bucket) { this->bkt = bucket; this->elementSize = sizeof(T); } @@ -194,10 +194,10 @@ template <typename T> inline void DynArray<T>::Remove(std::size_t index, int64_t this->elementCount = index; return; } - T *tmp = Pke_New<T>(moveCount, this->bkt); + T *tmp = pk_new<T>(moveCount, this->bkt); memcpy(tmp, this->ptr + (sizeof(T) * (index + count)), sizeof(T) * moveCount); memcpy(this->ptr + (sizeof(T) * index), tmp, sizeof(T) * moveCount); - Pke_Delete<T>(tmp, moveCount, this->bkt); + pk_delete<T>(tmp, moveCount, this->bkt); this->elementCount -= count; } diff --git a/src/ecs.cpp b/src/ecs.cpp index 80a4daf..d6bf8df 100644 --- a/src/ecs.cpp +++ b/src/ecs.cpp @@ -5,8 +5,6 @@ #include "bucketed-array.hpp" #include "game-settings.hpp" #include "math-helpers.hpp" -#include "memory-type-defs.hpp" -#include "memory.hpp" #include "physics.hpp" #include "vendor/glm_include.hpp" #include "window.hpp" @@ -16,16 +14,16 @@ #include <glm/gtc/type_ptr.hpp> constexpr struct { - const PkeHandleItemIndex_T generics = 256; - const PkeHandleItemIndex_T entityPtrs = 256; - const PkeHandleItemIndex_T grBinds = 64; - const PkeHandleItemIndex_T instances = 256; + const pk_handle_item_index_T generics = 256; + const pk_handle_item_index_T entityPtrs = 256; + const pk_handle_item_index_T grBinds = 64; + const pk_handle_item_index_T instances = 256; } bcSizes; struct ECS { - MemBucket *bkt = nullptr; + struct pk_membucket *bkt = nullptr; struct ECSBucketContainers { - BucketContainer<Entity_Base, PkeHandle, 4> generics{}; + BucketContainer<Entity_Base, pk_handle, 4> generics{}; BucketContainer<Entity_Base *, EntityHandle, 4> entityPtrs{}; BucketContainer<CompGrBinds, GrBindsHandle, 4> grBinds{}; BucketContainer<CompInstance, InstanceHandle, 4> instances{}; @@ -60,7 +58,7 @@ DynArray<Entity_Base *> entitiesYetToBeRemoved{0, nullptr}; DynArray<Entity_Base *> EntitiesWithExcessInstances{16}; void ECS_GetEntity_Inner(EntityHandle entHandle, Entity_Base*& ent) { - assert(ValidateHandle(entHandle, ecs.bc.entityPtrs.pkeHandle, ecs.bc.entityPtrs.limits.itemIndex) == PKE_HANDLE_VALIDATION_VALID); + assert(pk_handle_validate(entHandle, ecs.bc.entityPtrs.pkeHandle, ecs.bc.entityPtrs.limits.itemIndex) == PK_HANDLE_VALIDATION_VALID); ent = ecs.bc.entityPtrs.buckets[entHandle.bucketIndex][entHandle.itemIndex]; } @@ -72,7 +70,7 @@ void ECS_Init() { } Entity_Base *ECS_CreateGenericEntity() { - PkeHandle newHandle{Buckets_NewHandle(ecs.bc.generics)}; + pk_handle newHandle{Buckets_NewHandle(ecs.bc.generics)}; return &ecs.bc.generics.buckets[newHandle.bucketIndex][newHandle.itemIndex]; } @@ -87,7 +85,7 @@ EntityHandle ECS_CreateEntity(Entity_Base *entity, Entity_Base *parentEntity) { } Entity_Base *ECS_GetEntity(EntityHandle handle) { - ValidateHandle(handle, ecs.bc.entityPtrs.pkeHandle, ecs.bc.entityPtrs.limits.itemIndex); + pk_handle_validate(handle, ecs.bc.entityPtrs.pkeHandle, ecs.bc.entityPtrs.limits.itemIndex); return ecs.bc.entityPtrs.buckets[handle.bucketIndex][handle.itemIndex]; } @@ -108,9 +106,9 @@ void ECS_Tick_Early(double delta) { entitiesMarkedForRemoval.Resize(0); // this has the potential to be slow as balls - for (PkeHandleBucketIndex_T b = 0; b <= ecs.bc.entityPtrs.pkeHandle.bucketIndex; ++b) { - PkeHandleItemIndex_T entCount = b == ecs.bc.entityPtrs.pkeHandle.bucketIndex ? ecs.bc.entityPtrs.pkeHandle.itemIndex : ecs.bc.entityPtrs.limits.itemIndex; - for (PkeHandleItemIndex_T e = 0; e < entCount; ++e) { + for (pk_handle_bucket_index_T b = 0; b <= ecs.bc.entityPtrs.pkeHandle.bucketIndex; ++b) { + pk_handle_item_index_T entCount = b == ecs.bc.entityPtrs.pkeHandle.bucketIndex ? ecs.bc.entityPtrs.pkeHandle.itemIndex : ecs.bc.entityPtrs.limits.itemIndex; + for (pk_handle_item_index_T e = 0; e < entCount; ++e) { Entity_Base *ent = ecs.bc.entityPtrs.buckets[b][e]; if (ent->handle == EntityHandle_MAX) continue; Entity_Base *parentEnt = nullptr; @@ -144,7 +142,7 @@ void ECS_Tick(double delta) { int64_t entityRemovalCount = entitiesYetToBeRemoved.Count(); if (physicsTickCount == 0 && entityRemovalCount == 0) return; - DynArray<updateGrBindsAfter> *updateGrBindsPtr = Pke_New<DynArray<updateGrBindsAfter>>(pkeSettings.mem.bkt); + DynArray<updateGrBindsAfter> *updateGrBindsPtr = pk_new<DynArray<updateGrBindsAfter>>(pkeSettings.mem.bkt); DynArray<updateGrBindsAfter> &updateGrBinds = *updateGrBindsPtr; for (long b = 0; b <= ecs.bc.instances.pkeHandle.bucketIndex; ++b) { auto &bkt = ecs.bc.instances.buckets[b]; @@ -179,8 +177,8 @@ void ECS_Tick(double delta) { inst.instanceHandle = InstanceHandle_MAX; inst.isNeedingUpdated = false; BtDynamicsWorld->removeRigidBody(inst.bt.rigidBody); - Pke_Delete<btDefaultMotionState>(inst.bt.motionState, MemBkt_Bullet); - Pke_Delete<btRigidBody>(inst.bt.rigidBody, MemBkt_Bullet); + pk_delete<btDefaultMotionState>(inst.bt.motionState, MemBkt_Bullet); + pk_delete<btRigidBody>(inst.bt.rigidBody, MemBkt_Bullet); inst.bt.rigidBody = CAFE_BABE(btRigidBody); inst.bt.motionState = CAFE_BABE(btDefaultMotionState); continue; @@ -197,10 +195,10 @@ void ECS_Tick(double delta) { } if (entityRemovalCount > 0 || updateGrBinds.Count() > 0) { - for (PkeHandleBucketIndex_T b = 0; b <= ecs.bc.grBinds.pkeHandle.bucketIndex; ++b) { + for (pk_handle_bucket_index_T b = 0; b <= ecs.bc.grBinds.pkeHandle.bucketIndex; ++b) { auto &bkt = ecs.bc.grBinds.buckets[b]; long count = ecs.bc.grBinds.pkeHandle.bucketIndex == b ? ecs.bc.grBinds.pkeHandle.itemIndex : ecs.bc.grBinds.limits.itemIndex; - for (PkeHandleItemIndex_T i = 0; i < count; ++i) { + for (pk_handle_item_index_T i = 0; i < count; ++i) { auto &grBinds = bkt[i]; if (grBinds.entHandle == EntityHandle_MAX) { continue; @@ -241,7 +239,7 @@ struct InstanceBufferCopy { }; void ECS_Tick_Late(double delta) { // using a pointer here avoids calling the destructor when the object goes out of scope - DynArray<InstanceBufferCopy> *bufferUpdatesPtr = Pke_New<DynArray<InstanceBufferCopy>>(pkeSettings.mem.bkt); + DynArray<InstanceBufferCopy> *bufferUpdatesPtr = pk_new<DynArray<InstanceBufferCopy>>(pkeSettings.mem.bkt); new (bufferUpdatesPtr) DynArray<InstanceBufferCopy>(0, pkeSettings.mem.bkt); DynArray<InstanceBufferCopy> &bufferUpdates = *bufferUpdatesPtr; for (long b = 0; b <= ecs.bc.instances.pkeHandle.bucketIndex; ++b) { @@ -269,7 +267,7 @@ void ECS_Tick_Late(double delta) { .grBinds = &grBinds, }); bfrUpdate = &bufferUpdates[bufferUpdates.Count() - 1]; - bfrUpdate->chunks = Pke_New<DynArray<InstanceBufferCopyChunk>>(pkeSettings.mem.bkt); + bfrUpdate->chunks = pk_new<DynArray<InstanceBufferCopyChunk>>(pkeSettings.mem.bkt); new (bfrUpdate->chunks) DynArray<InstanceBufferCopyChunk>(4, pkeSettings.mem.bkt); } @@ -288,7 +286,7 @@ void ECS_Tick_Late(double delta) { }); chunk = &(*bfrUpdate->chunks)[bfrUpdate->chunks->Count() - 1]; chunk->dstBufferCopy.dstOffset = sizeof(glm::mat4) * inst.index; - chunk->mats = Pke_New<DynArray<glm::mat4>>(pkeSettings.mem.bkt); + chunk->mats = pk_new<DynArray<glm::mat4>>(pkeSettings.mem.bkt); new (chunk->mats) DynArray<glm::mat4>(0, pkeSettings.mem.bkt); } @@ -405,15 +403,15 @@ CompGrBinds *ECS_CreateGrBinds(Entity_Base *entity) { CompGrBinds *ECS_GetGrBinds(GrBindsHandle grBindsHandle) { if (grBindsHandle == GrBindsHandle_MAX) return nullptr; - assert(ValidateHandle(grBindsHandle, ecs.bc.grBinds.pkeHandle, ecs.bc.grBinds.limits.itemIndex) == PKE_HANDLE_VALIDATION_VALID); + assert(pk_handle_validate(grBindsHandle, ecs.bc.grBinds.pkeHandle, ecs.bc.grBinds.limits.itemIndex) == PK_HANDLE_VALIDATION_VALID); return &ecs.bc.grBinds.buckets[grBindsHandle.bucketIndex][grBindsHandle.itemIndex]; } void ECS_GetGrBinds(Entity_Base *entity, PkeArray<CompGrBinds *> &arr) { - for (PkeHandleBucketIndex_T b = 0; b <= ecs.bc.grBinds.pkeHandle.bucketIndex; ++b) { + for (pk_handle_bucket_index_T b = 0; b <= ecs.bc.grBinds.pkeHandle.bucketIndex; ++b) { auto &bkt = ecs.bc.grBinds.buckets[b]; long itemCount = ecs.bc.grBinds.pkeHandle.bucketIndex == b ? ecs.bc.grBinds.pkeHandle.itemIndex : ecs.bc.grBinds.limits.itemIndex; - for (PkeHandleItemIndex_T i = 0; i < itemCount; ++i) { + for (pk_handle_item_index_T i = 0; i < itemCount; ++i) { auto &grBinds = bkt[i]; if (grBinds.entHandle == entity->handle) { PkeArray_Add(&arr, &grBinds); @@ -461,17 +459,17 @@ CompInstance *ECS_CreateInstance(Entity_Base *entity, CompGrBinds *entityTypeGrB CompInstance *ECS_GetInstance(InstanceHandle instanceHandle ) { if (instanceHandle == InstanceHandle_MAX) return nullptr; - assert(ValidateHandle(instanceHandle, ecs.bc.instances.pkeHandle, ecs.bc.instances.limits.itemIndex) == PKE_HANDLE_VALIDATION_VALID); + assert(pk_handle_validate(instanceHandle, ecs.bc.instances.pkeHandle, ecs.bc.instances.limits.itemIndex) == PK_HANDLE_VALIDATION_VALID); auto *inst = &ecs.bc.instances.buckets[instanceHandle.bucketIndex][instanceHandle.itemIndex]; return inst; } void ECS_GetInstances(Entity_Base *entity, PkeArray<CompInstance *> &arr) { - for (PkeHandleBucketIndex_T b = 0; b <= ecs.bc.instances.pkeHandle.bucketIndex; ++b) { + for (pk_handle_bucket_index_T b = 0; b <= ecs.bc.instances.pkeHandle.bucketIndex; ++b) { auto &bkt = ecs.bc.instances.buckets[b]; long itemCount = ecs.bc.instances.pkeHandle.bucketIndex == b ? ecs.bc.instances.pkeHandle.itemIndex : ecs.bc.instances.limits.itemIndex; - for (PkeHandleItemIndex_T i = 0; i < itemCount; ++i) { + for (pk_handle_item_index_T i = 0; i < itemCount; ++i) { auto &inst = bkt[i]; if (inst.entHandle == entity->handle) { PkeArray_Add(&arr, &inst); diff --git a/src/ecs.hpp b/src/ecs.hpp index 2550487..07972d3 100644 --- a/src/ecs.hpp +++ b/src/ecs.hpp @@ -3,8 +3,7 @@ #include "array.hpp" #include "dynamic-array.hpp" -#include "macros.hpp" -#include "memory.hpp" +#include "vendor/pk.h" #include "components.hpp" #include "glm/vec3.hpp" diff --git a/src/entities.cpp b/src/entities.cpp index cb66cef..609fc51 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -3,10 +3,7 @@ #include "bucketed-array.hpp" #include "ecs.hpp" -#include "game-settings.hpp" -#include "level.hpp" #include "math-helpers.hpp" -#include "memory.hpp" #include "physics.hpp" #include "plugins.hpp" #include "static/missing-texture.hpp" @@ -15,7 +12,6 @@ #include <BulletCollision/CollisionShapes/btConvexHullShape.h> #include <BulletCollision/CollisionShapes/btConvexPolyhedron.h> #include <filesystem> -#include <type_traits> #include <vulkan/vulkan_core.h> BucketContainer<EntityType> EntityType_BC{}; @@ -74,10 +70,10 @@ Entity_Base *EntityType_CreateGenericInstance(EntityType *et, Entity_Base *level btVector3 localInertia(0, 0, 0); etd.bt.shape->calculateLocalInertia(mass, localInertia); - compInst->bt.motionState = Pke_New<btDefaultMotionState>(MemBkt_Bullet); + compInst->bt.motionState = pk_new<btDefaultMotionState>(MemBkt_Bullet); new (compInst->bt.motionState) btDefaultMotionState(posRot); - compInst->bt.rigidBody = Pke_New<btRigidBody>(MemBkt_Bullet); + compInst->bt.rigidBody = pk_new<btRigidBody>(MemBkt_Bullet); new (compInst->bt.rigidBody) btRigidBody(mass, compInst->bt.motionState, etd.bt.shape, localInertia); compInst->bt.rigidBody->setLinearVelocity(btVector3(0,0,0)); @@ -92,13 +88,13 @@ Entity_Base *EntityType_CreateGenericInstance(EntityType *et, Entity_Base *level } EntityType *EntityType_FindByTypeCode(const char *typeCode) { - for (PkeHandleBucketIndex_T b = 0; b <= EntityType_BC.pkeHandle.bucketIndex; ++b) { + for (pk_handle_bucket_index_T b = 0; b <= EntityType_BC.pkeHandle.bucketIndex; ++b) { auto &bkt = EntityType_BC.buckets[b]; long itemCount = EntityType_BC.pkeHandle.bucketIndex == b ? EntityType_BC.pkeHandle.itemIndex : EntityType_BC.limits.itemIndex; - for (PkeHandleItemIndex_T i = 0; i < itemCount; ++i) { + for (pk_handle_item_index_T i = 0; i < itemCount; ++i) { auto &entityType = bkt[i]; if (entityType.handle == EntityHandle_MAX) continue; - if (strcmp(typeCode, entityType.entityTypeCode) == 0) { + if (strcmp(typeCode, entityType.entityTypeCode.val) == 0) { return &entityType; } } @@ -108,10 +104,10 @@ EntityType *EntityType_FindByTypeCode(const char *typeCode) { EntityType *EntityType_FindByEntityHandle(EntityHandle handle) { if (handle == EntityHandle_MAX) return nullptr; - for (PkeHandleBucketIndex_T b = 0; b <= EntityType_BC.pkeHandle.bucketIndex; ++b) { + for (pk_handle_bucket_index_T b = 0; b <= EntityType_BC.pkeHandle.bucketIndex; ++b) { auto &bkt = EntityType_BC.buckets[b]; long itemCount = EntityType_BC.pkeHandle.bucketIndex == b ? EntityType_BC.pkeHandle.itemIndex : EntityType_BC.limits.itemIndex; - for (PkeHandleItemIndex_T i = 0; i < itemCount; ++i) { + for (pk_handle_item_index_T i = 0; i < itemCount; ++i) { auto &entityType = bkt[i]; if (entityType.handle == handle) { return &entityType; @@ -167,7 +163,7 @@ struct EntityTypeDetails_LoadHelperStruct { } physDbg; }; struct EntityType_LoadHelperStruct { - MemBucket *bkt = nullptr; + struct pk_membucket *bkt = nullptr; EntityType &et; DynArray<EntityTypeDetails_LoadHelperStruct> *etdHelpers = nullptr; const cgltf_data *gltfData = nullptr; @@ -220,21 +216,21 @@ void EntityType_PreLoad(EntityType_LoadHelperStruct &helper) { EntityTypeDetails_LoadHelperStruct &etdHelper = helper.etdHelpers->Push(); etdHelper.etd = &etd; etd.grBinds = ECS_CreateGrBinds(&helper.et);; - etdHelper.physDbg.vertexes = reinterpret_cast<DynArray<glm::vec3> *>(Pke_New(sizeof(DynArray<glm::vec3>), 64, helper.bkt)); - etdHelper.physDbg.normals = reinterpret_cast<DynArray<glm::vec3> *>(Pke_New(sizeof(DynArray<glm::vec3>), 64, helper.bkt)); - etdHelper.physDbg.uv = reinterpret_cast<DynArray<glm::vec2> *>(Pke_New(sizeof(DynArray<glm::vec2>), 64, helper.bkt)); - etdHelper.physDbg.indexes = reinterpret_cast<DynArray<uint16_t> *>(Pke_New(sizeof(DynArray<uint16_t>), 64, helper.bkt)); - new (etdHelper.physDbg.vertexes) DynArray<glm::vec3>(helper.bkt); - new (etdHelper.physDbg.normals) DynArray<glm::vec3>(helper.bkt); - new (etdHelper.physDbg.uv) DynArray<glm::vec2>(helper.bkt); - new (etdHelper.physDbg.indexes) DynArray<uint16_t>(helper.bkt); + etdHelper.physDbg.vertexes = pk_new<DynArray<glm::vec3>>(64, helper.bkt); + etdHelper.physDbg.normals = pk_new<DynArray<glm::vec3>>(64, helper.bkt); + etdHelper.physDbg.uv = pk_new<DynArray<glm::vec2>>(64, helper.bkt); + etdHelper.physDbg.indexes = pk_new<DynArray<uint16_t>>(64, helper.bkt); + // new (etdHelper.physDbg.vertexes) DynArray<glm::vec3>(helper.bkt); + // new (etdHelper.physDbg.normals) DynArray<glm::vec3>(helper.bkt); + // new (etdHelper.physDbg.uv) DynArray<glm::vec2>(helper.bkt); + // new (etdHelper.physDbg.indexes) DynArray<uint16_t>(helper.bkt); /* * phys */ btConvexHullShape *shape; { - shape = Pke_New<btConvexHullShape>(MemBkt_Bullet); + shape = pk_new<btConvexHullShape>(MemBkt_Bullet); btScalar *vertDataPointer = reinterpret_cast<btScalar *>(helper.modelBinAsset->ptr); /* TODO JCB - 2024-01-02 * we shouldn't assume that the first index is the vertexes @@ -641,7 +637,7 @@ void EntityType_LoadTexture(EntityType_LoadHelperStruct &helper, const int64_t i vkDescriptorSetAllocateInfo.descriptorSetCount = MAX_FRAMES_IN_FLIGHT; vkDescriptorSetAllocateInfo.pSetLayouts = descriptorSets; - etdHelper.etd->grBinds->vkDescriptorSets = Pke_New<VkDescriptorSet>(MAX_FRAMES_IN_FLIGHT); + etdHelper.etd->grBinds->vkDescriptorSets = pk_new<VkDescriptorSet>(MAX_FRAMES_IN_FLIGHT); for (long i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) { etdHelper.etd->grBinds->vkDescriptorSets[i] = VkDescriptorSet{}; } @@ -1055,23 +1051,23 @@ void EntityType_Load(EntityType &et) { AssetHandle modelBinHandle = AM_Register(gltfPath.c_str(), PKE_ASSET_TYPE_UNSET); const Asset *modelBinAsset = AM_Get(modelBinHandle); - MemBucket *entLoaderBkt = Pke_BeginTransientBucket(); + struct pk_membucket *entLoaderBkt = pk_bucket_create("entities", PK_DEFAULT_BUCKET_SIZE, false); EntityType_LoadHelperStruct helper { .bkt = entLoaderBkt, .et = et, - .etdHelpers = reinterpret_cast<DynArray<EntityTypeDetails_LoadHelperStruct> *>(Pke_New(sizeof(DynArray<EntityTypeDetails_LoadHelperStruct>), 64, entLoaderBkt)), + .etdHelpers = pk_new<DynArray<EntityTypeDetails_LoadHelperStruct>>(64, entLoaderBkt), .gltfData = gltfData, .modelBinAsset = modelBinAsset, - .vertMemoryRequirements = reinterpret_cast<DynArray<VkMemoryRequirements> *>(Pke_New(sizeof(DynArray<VkMemoryRequirements>), 64, entLoaderBkt)), - .instMemoryRequirements = reinterpret_cast<DynArray<VkMemoryRequirements> *>(Pke_New(sizeof(DynArray<VkMemoryRequirements>), 64, entLoaderBkt)), - .physVertMemoryRequirements = reinterpret_cast<DynArray<VkMemoryRequirements> *>(Pke_New(sizeof(DynArray<VkMemoryRequirements>), 64, entLoaderBkt)), - .textureMemoryRequirements = reinterpret_cast<DynArray<VkMemoryRequirements> *>(Pke_New(sizeof(DynArray<VkMemoryRequirements>), 64, entLoaderBkt)), + .vertMemoryRequirements = pk_new<DynArray<VkMemoryRequirements>>(64, entLoaderBkt), + .instMemoryRequirements = pk_new<DynArray<VkMemoryRequirements>>(64, entLoaderBkt), + .physVertMemoryRequirements = pk_new<DynArray<VkMemoryRequirements>>(64, entLoaderBkt), + .textureMemoryRequirements = pk_new<DynArray<VkMemoryRequirements>>(64, entLoaderBkt), }; - new (helper.etdHelpers) DynArray<EntityTypeDetails_LoadHelperStruct>{entLoaderBkt}; - new (helper.vertMemoryRequirements) DynArray<VkMemoryRequirements>{entLoaderBkt}; - new (helper.instMemoryRequirements) DynArray<VkMemoryRequirements>{entLoaderBkt}; - new (helper.physVertMemoryRequirements) DynArray<VkMemoryRequirements>{entLoaderBkt}; - new (helper.textureMemoryRequirements) DynArray<VkMemoryRequirements>{entLoaderBkt}; + // new (helper.etdHelpers) DynArray<EntityTypeDetails_LoadHelperStruct>{entLoaderBkt}; + // new (helper.vertMemoryRequirements) DynArray<VkMemoryRequirements>{entLoaderBkt}; + // new (helper.instMemoryRequirements) DynArray<VkMemoryRequirements>{entLoaderBkt}; + // new (helper.physVertMemoryRequirements) DynArray<VkMemoryRequirements>{entLoaderBkt}; + // new (helper.textureMemoryRequirements) DynArray<VkMemoryRequirements>{entLoaderBkt}; EntityType_PreLoad(helper); @@ -1097,7 +1093,7 @@ void EntityType_Load(EntityType &et) { // cleanup AM_Release(modelBinHandle); AM_Release(assetHandle); - Pke_EndTransientBucket(helper.bkt); + pk_bucket_destroy(helper.bkt); } void EntityType_Unload(EntityType &et, CompGrBinds *grBindsArr[1]) { @@ -1208,9 +1204,11 @@ void EntityType_Unload(EntityType &et, CompGrBinds *grBindsArr[1]) { vkFreeMemory(vkDevice, et.deviceMemoryTexture, vkAllocator); et.deviceMemoryTexture = VK_NULL_HANDLE; - if (et.entityTypeCode) - Pke_Delete<char>(et.entityTypeCode, strlen(et.entityTypeCode)); - et.entityTypeCode = CAFE_BABE(char); + if (et.entityTypeCode.reserved != 0) + pk_delete<char>(et.entityTypeCode.val, et.entityTypeCode.reserved); + et.entityTypeCode.val = CAFE_BABE(char); + et.entityTypeCode.length = 0; + et.entityTypeCode.reserved = 0; } void EntityType_Tick(double delta) { @@ -1349,11 +1347,11 @@ void EntityType_RolloverInstances(EntityType &et, CompGrBinds &grBinds) { vkFreeMemory(vkDevice, oldMemory, vkAllocator); } -PkeHandleBucketIndex_T EntityType_GetBucketCount() { +pk_handle_bucket_index_T EntityType_GetBucketCount() { return EntityType_BC.pkeHandle.bucketIndex + 1; } -EntityType *EntityType_GetEntityTypes(PkeHandleBucketIndex_T bucketIndex, PkeHandleItemIndex_T &itemCount) { +EntityType *EntityType_GetEntityTypes(pk_handle_bucket_index_T bucketIndex, pk_handle_item_index_T &itemCount) { assert(bucketIndex <= EntityType_BC.pkeHandle.bucketIndex); if (bucketIndex == EntityType_BC.pkeHandle.bucketIndex) { itemCount = EntityType_BC.pkeHandle.itemIndex; @@ -1365,10 +1363,10 @@ EntityType *EntityType_GetEntityTypes(PkeHandleBucketIndex_T bucketIndex, PkeHan void EntityType_Teardown() { - for (PkeHandleBucketIndex_T b = 0; b <= EntityType_BC.pkeHandle.bucketIndex; ++b) { + for (pk_handle_bucket_index_T b = 0; b <= EntityType_BC.pkeHandle.bucketIndex; ++b) { auto &bkt = EntityType_BC.buckets[b]; long itemCount = EntityType_BC.pkeHandle.bucketIndex == b ? EntityType_BC.pkeHandle.itemIndex : EntityType_BC.limits.itemIndex; - for (PkeHandleItemIndex_T i = 0; i < itemCount; ++i) { + for (pk_handle_item_index_T i = 0; i < itemCount; ++i) { auto &et = bkt[i]; if (et.modelAssetKey[0] == '\0') continue; CompGrBinds *grBindsArr[EntityTypeDetails_MAX] = {nullptr}; diff --git a/src/entities.hpp b/src/entities.hpp index 9907ab6..d81b90b 100644 --- a/src/entities.hpp +++ b/src/entities.hpp @@ -1,14 +1,13 @@ #ifndef PKE_ENTITIES_HPP #define PKE_ENTITIES_HPP -#include "memory-type-defs.hpp" #include "vendor/cgltf-include.hpp" #include "vendor/stb_image_include.hpp" #include "ecs.hpp" #include "components.hpp" #include "asset-manager.hpp" -#include "memory.hpp" #include "window.hpp" +#include "vendor/pk.h" #include <BulletCollision/CollisionShapes/btCollisionShape.h> #include <vulkan/vulkan_core.h> @@ -30,7 +29,7 @@ struct EntityTypeDetails { }; struct EntityType : public Entity_Base { AssetKey modelAssetKey; - const char *entityTypeCode = nullptr; + pk_str entityTypeCode; VkDeviceMemory deviceMemoryVert = VK_NULL_HANDLE; VkDeviceMemory deviceMemoryInst = VK_NULL_HANDLE; VkDeviceMemory deviceMemoryPhysVert = VK_NULL_HANDLE; @@ -41,8 +40,8 @@ struct EntityType : public Entity_Base { // PkeCallback serializeInstanceCallback; // TODO // PkeCallback parseInstanceCallback; // TODO }; -struct EntityTypeHandle : PkeHandle {}; -constexpr EntityTypeHandle EntityTypeHandle_MAX = EntityTypeHandle{}; +struct EntityTypeHandle : pk_handle {}; +constexpr EntityTypeHandle EntityTypeHandle_MAX = EntityTypeHandle{ pk_handle_MAX_constexpr }; void EntityType_Init(); EntityType *EntityType_FindByTypeCode(const char *typeCode); @@ -53,8 +52,8 @@ void EntityType_Load(EntityType &et); void EntityType_Tick(double delta); void EntityType_Tick_Late(double delta); void EntityType_RolloverInstances(EntityType &et, CompGrBinds &grBinds); -PkeHandleBucketIndex_T EntityType_GetBucketCount(); -EntityType *EntityType_GetEntityTypes(PkeHandleBucketIndex_T bucketIndex, PkeHandleItemIndex_T &itemCount); +pk_handle_bucket_index_T EntityType_GetBucketCount(); +EntityType *EntityType_GetEntityTypes(pk_handle_bucket_index_T bucketIndex, pk_handle_item_index_T &itemCount); void EntityType_Teardown(); #endif /* PKE_ENTITIES_HPP */ diff --git a/src/event.hpp b/src/event.hpp index 7eb48c2..d8f41be 100644 --- a/src/event.hpp +++ b/src/event.hpp @@ -1,7 +1,6 @@ #ifndef PKE_EVENT_HPP #define PKE_EVENT_HPP -#include "macros.hpp" #include "dynamic-array.hpp" #include <cassert> diff --git a/src/game-settings.hpp b/src/game-settings.hpp index 10be624..89862a8 100644 --- a/src/game-settings.hpp +++ b/src/game-settings.hpp @@ -2,7 +2,7 @@ #define PKE_GAME_SETTINGS_HPP #include "level-types.hpp" -#include "memory-type-defs.hpp" +#include "vendor/pk.h" #include <chrono> #include <cstdint> @@ -31,7 +31,7 @@ struct GameSettings { bool isWaitingForVsync = true; } graphicsSettings; struct memory { - MemBucket *bkt = nullptr; + struct pk_membucket *bkt = nullptr; } mem; struct engineArgs { const char *pluginPath = nullptr; diff --git a/src/game.cpp b/src/game.cpp index bca8bb2..8fb24e4 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -12,7 +12,6 @@ #include "imgui.h" #include "level-types.hpp" #include "level.hpp" -#include "macros.hpp" #include "math-helpers.hpp" #include "physics.hpp" #include "player-input.hpp" @@ -21,6 +20,7 @@ #include "thread_pool.hpp" #include "vendor/glm_include.hpp" #include "window.hpp" +#include "vendor/pk.h" #include <BulletCollision/CollisionShapes/btConvexHullShape.h> #include <BulletCollision/NarrowPhaseCollision/btRaycastCallback.h> @@ -74,7 +74,7 @@ const char *PKE_FILE_CAMERA_TARGET_INSTANCE_HANDLE = "Cam::TargetInstanceHandle: const char *PKE_FILE_CAMERA_IS_PRIMARY = "Cam::IsPrimary: "; void SerializeCamera(std::ostringstream &stream, const PkeCamera &cam) { - NULL_CHAR_ARR(handleStr, 19); + NULL_CHAR_ARR(handleStr, 22); PkeCamera c{}; if (cam.type != c.type) { stream << PKE_FILE_CAMERA_TYPE << int(static_cast<PkeCameraType_T>(cam.type)) << std::endl; @@ -83,11 +83,11 @@ void SerializeCamera(std::ostringstream &stream, const PkeCamera &cam) { stream << PKE_FILE_CAMERA_ORIENTATION << int(static_cast<PkeCameraView_T>(cam.view)) << std::endl; } if (cam.phys.inst != c.phys.inst && cam.phys.inst != CAFE_BABE(CompInstance)) { - snprintf(handleStr, 19, "0x%016lX", cam.phys.inst->instanceHandle.hash); + snprintf(handleStr, 21, "0x%08X 0x%08X", cam.phys.inst->instanceHandle.bucketIndex, cam.phys.inst->instanceHandle.itemIndex); stream << PKE_FILE_CAMERA_INSTANCE_HANDLE << handleStr << std::endl; } if (cam.phys.targetInst != c.phys.targetInst && cam.phys.targetInst != CAFE_BABE(CompInstance)) { - snprintf(handleStr, 19, "0x%016lX", cam.phys.targetInst->instanceHandle.hash); + snprintf(handleStr, 21, "0x%08X 0x%08X", cam.phys.targetInst->instanceHandle.bucketIndex, cam.phys.targetInst->instanceHandle.itemIndex); stream << PKE_FILE_CAMERA_TARGET_INSTANCE_HANDLE << handleStr << std::endl; } if (cam.isPrimary != c.isPrimary) { @@ -96,7 +96,7 @@ void SerializeCamera(std::ostringstream &stream, const PkeCamera &cam) { } void SerializeInstance(std::ostringstream &stream, const CompInstance &comp) { - NULL_CHAR_ARR(handleStr, 19); + NULL_CHAR_ARR(handleStr, 22); EntityType *et = nullptr; if (comp.grBindsHandle != GrBindsHandle_MAX) { et = EntityType_FindByEntityHandle(ECS_GetGrBinds(comp.grBindsHandle)->entHandle); @@ -108,15 +108,15 @@ void SerializeInstance(std::ostringstream &stream, const CompInstance &comp) { baseInst.scale = btVector3(1, 1, 1); baseInst.mass = 1; if (comp.entHandle != c.entHandle) { - snprintf(handleStr, 19, "0x%016lX", comp.entHandle.hash); + snprintf(handleStr, 21, "0x%08X 0x%08X", comp.entHandle.bucketIndex, comp.entHandle.itemIndex); stream << PKE_FILE_INSTANCE_ENTITY_HANDLE << handleStr << std::endl; } if (comp.entHandle != c.entHandle) { - snprintf(handleStr, 19, "0x%016lX", comp.instanceHandle.hash); + snprintf(handleStr, 21, "0x%08X 0x%08X", comp.instanceHandle.bucketIndex, comp.instanceHandle.itemIndex); stream << PKE_FILE_INSTANCE_HANDLE << handleStr << std::endl; } if (et != nullptr) { - stream << PKE_FILE_INSTANCE_ENTITY_TYPE_CODE << et->entityTypeCode << std::endl; + stream << PKE_FILE_INSTANCE_ENTITY_TYPE_CODE << et->entityTypeCode.val << std::endl; } else if (PkeCamera_Get(comp.entHandle)) { stream << PKE_FILE_INSTANCE_ENTITY_TYPE_CODE << PKE_FILE_INSTANCE_SPECIAL_ENTITY_TYPE_CODE_CAMERA << std::endl; } @@ -217,15 +217,21 @@ void ParseCamera(PkeLevel *level, std::ifstream &stream) { } if (strstr(readLine, PKE_FILE_CAMERA_INSTANCE_HANDLE)) { uint64_t prefixLen = strlen(PKE_FILE_CAMERA_INSTANCE_HANDLE); - STR2NUM_ERROR result = str2num(instanceHandle.hash, readLine + prefixLen); - assert(result == STR2NUM_ERROR::SUCCESS); + readLine[prefixLen + 10] = '\0'; + STR2NUM_ERROR result1 = str2num(instanceHandle.bucketIndex, readLine + prefixLen); + STR2NUM_ERROR result2 = str2num(instanceHandle.itemIndex, readLine + prefixLen + 11); + assert(result1 == STR2NUM_ERROR::SUCCESS); + assert(result2 == STR2NUM_ERROR::SUCCESS); // TODO add to global list continue; } if (strstr(readLine, PKE_FILE_CAMERA_TARGET_INSTANCE_HANDLE)) { uint64_t prefixLen = strlen(PKE_FILE_CAMERA_TARGET_INSTANCE_HANDLE); - STR2NUM_ERROR result = str2num(targetInstanceHandle.hash, readLine + prefixLen); - assert(result == STR2NUM_ERROR::SUCCESS); + readLine[prefixLen + 10] = '\0'; + STR2NUM_ERROR result1 = str2num(targetInstanceHandle.bucketIndex, readLine + prefixLen); + STR2NUM_ERROR result2 = str2num(targetInstanceHandle.itemIndex, readLine + prefixLen + 11); + assert(result1 == STR2NUM_ERROR::SUCCESS); + assert(result2 == STR2NUM_ERROR::SUCCESS); // TODO find and set continue; } @@ -293,14 +299,20 @@ void ParseInstance(Entity_Base *parentEntity, std::ifstream &stream) { } if (strstr(readLine, PKE_FILE_INSTANCE_ENTITY_HANDLE)) { uint64_t prefixLen = strlen(PKE_FILE_INSTANCE_ENTITY_HANDLE); - STR2NUM_ERROR result = str2num(comp.entHandle.hash, readLine + prefixLen); - assert(result == STR2NUM_ERROR::SUCCESS); + readLine[prefixLen + 10] = '\0'; + STR2NUM_ERROR result1 = str2num(comp.entHandle.bucketIndex, readLine + prefixLen); + STR2NUM_ERROR result2 = str2num(comp.entHandle.itemIndex, readLine + prefixLen + 11); + assert(result1 == STR2NUM_ERROR::SUCCESS); + assert(result2 == STR2NUM_ERROR::SUCCESS); continue; } if (strstr(readLine, PKE_FILE_INSTANCE_HANDLE)) { uint64_t prefixLen = strlen(PKE_FILE_INSTANCE_HANDLE); - STR2NUM_ERROR result = str2num(mapping.origHandle.hash, readLine + prefixLen); - assert(result == STR2NUM_ERROR::SUCCESS); + readLine[prefixLen + 10] = '\0'; + STR2NUM_ERROR result1 = str2num(mapping.origHandle.bucketIndex, readLine + prefixLen); + STR2NUM_ERROR result2 = str2num(mapping.origHandle.itemIndex, readLine + prefixLen + 11); + assert(result1 == STR2NUM_ERROR::SUCCESS); + assert(result2 == STR2NUM_ERROR::SUCCESS); continue; } if (strstr(readLine, PKE_FILE_INSTANCE_ENTITY_TYPE_CODE)) { @@ -519,7 +531,7 @@ void Game_RecordImGui() { } void Game_Tick(double delta) { - Pke_ResetBucket(pkeSettings.mem.bkt); + pk_bucket_reset(pkeSettings.mem.bkt); // TODO this should be removed in favor of storing the scene details inside a level definition if (pkeSettings.rt.shouldLoadScene && pkeSettings.rt.sceneName) { @@ -673,7 +685,7 @@ void Game_Main(PKEWindowProperties windowProps, const char *executablePath) { } fprintf(stdout, "Game_Main SHUTDOWN INITIATED\n"); #ifndef NDEBUG - Pke_DebugPrint(); + pk_memory_debug_print(); #endif const auto pluginCount = LoadedPkePlugins.Count(); for (long i = 0; i < pluginCount; ++i) { @@ -692,12 +704,12 @@ void Game_Main(PKEWindowProperties windowProps, const char *executablePath) { AM_DebugPrint(); AM_Teardown(); PkeThreads_Teardown(); - Pke_DebugPrint(); + pk_memory_debug_print(); fprintf(stdout, "Game_Main Exiting\n"); } void Game_Init() { - pkeSettings.mem.bkt = Pke_BeginTransientBucket(1UL << 26); + pkeSettings.mem.bkt = pk_bucket_create("game", 1UL << 26, true); for (long i = 0; i < consoleBufferCount; ++i) { memset(consoleBuffer[i], '\0', consoleLineLength); diff --git a/src/level-types.hpp b/src/level-types.hpp index 42c169b..a70282f 100644 --- a/src/level-types.hpp +++ b/src/level-types.hpp @@ -2,17 +2,16 @@ #define PKE_LEVEL_TYPES_HPP #include "array.hpp" -#include "macros.hpp" -#include "memory-type-defs.hpp" +#include "vendor/pk.h" #include "camera.hpp" #include "components.hpp" -TypeSafeInt_Const_Expr(LevelHandle, uint16_t, 0xFFFF); +TypeSafeInt_constexpr(LevelHandle, uint16_t, 0xFFFF); struct LvlCamArr : public PkeArray<CameraHandle> { }; struct PkeLevel : public Entity_Base { - MemBucket *bkt = nullptr; + struct pk_membucket *bkt = nullptr; char name[16] = {'\0'}; LevelHandle levelHandle = LevelHandle_MAX; LvlCamArr cameras; diff --git a/src/level.cpp b/src/level.cpp index 499051c..794626d 100644 --- a/src/level.cpp +++ b/src/level.cpp @@ -34,7 +34,7 @@ LevelHandle PkeLevel_Create(const char *levelName) { ECS_CreateEntity(lvl); if (lvl->bkt == nullptr) { - lvl->bkt = Pke_BeginTransientBucket(); + lvl->bkt = pk_bucket_create(levelName, PK_DEFAULT_BUCKET_SIZE, false); } lvl->levelHandle = nextHandle; ++nextHandle; @@ -81,6 +81,6 @@ void PkeLevel_Remove(LevelHandle handle) { PkeCamera_Destroy(lvl->cameras.data[i]); } PkeArray_HardReset<CameraHandle>(&lvl->cameras); - Pke_ResetBucket(lvl->bkt); + pk_bucket_reset(lvl->bkt); lvl->levelHandle = LevelHandle_MAX; } diff --git a/src/macros.hpp b/src/macros.hpp deleted file mode 100644 index 5fc7f3b..0000000 --- a/src/macros.hpp +++ /dev/null @@ -1,117 +0,0 @@ -#ifndef PKE_MACROS_HPP -#define PKE_MACROS_HPP - -#define Q(x) #x -#define QUOTE(x) Q(x) -#define CONCAT2(x, y) x##y -#define CONCAT(x, y) CONCAT2(x, y) - -#define CAFE_BABE(T) reinterpret_cast<T *>(0xCAFEBABE) - -#define NULL_CHAR_ARR(v, len) char v[len]; v[0] = '\0'; v[len-1] = '\0'; - -#define IS_CONSTRUCTIBLE(T) constexpr(std::is_default_constructible<T>::value && !std::is_integral<T>::value && !std::is_floating_point<T>::value) -#define IS_DESTRUCTIBLE(T) constexpr(std::is_destructible<T>::value && !std::is_integral<T>::value && !std::is_floating_point<T>::value && !std::is_array<T>::value) - -#define TypeSafeInt2_H(TypeName, Type, Max, TypeName_T, TypeName_MAX, TypeName_T_MAX)\ - using TypeName_T = Type; \ - enum class TypeName : TypeName_T; \ - constexpr TypeName_T TypeName_T_MAX = TypeName_T{Max}; \ - constexpr TypeName TypeName_MAX = TypeName{TypeName_T_MAX}; \ - TypeName operator+(const TypeName &a, const TypeName_T &i); \ - TypeName operator-(const TypeName &a, const TypeName_T &i); \ - TypeName operator+(const TypeName &a, const TypeName &b); \ - TypeName operator-(const TypeName &a, const TypeName &b); \ - TypeName operator&(const TypeName &a, const TypeName &b); \ - TypeName operator|(const TypeName &a, const TypeName &b); \ - TypeName operator^(const TypeName &a, const TypeName &b); \ - TypeName &operator++(TypeName &a); \ - TypeName &operator--(TypeName &a); \ - TypeName operator<<(const TypeName &a, const TypeName &b); \ - TypeName operator>>(const TypeName &a, const TypeName &b); -#define TypeSafeInt2_B(TypeName, TypeName_T) \ - inline TypeName operator+(const TypeName &a, const TypeName_T &i) { \ - return TypeName(static_cast<TypeName_T>(a) + i); \ - } \ - inline TypeName operator-(const TypeName &a, const TypeName_T &i) { \ - return TypeName(static_cast<TypeName_T>(a) - i); \ - } \ - inline TypeName operator+(const TypeName &a, const TypeName &b) { \ - return TypeName(static_cast<TypeName_T>(a) + static_cast<TypeName_T>(b)); \ - } \ - inline TypeName operator-(const TypeName &a, const TypeName &b) { \ - return TypeName(static_cast<TypeName_T>(a) - static_cast<TypeName_T>(b)); \ - } \ - inline TypeName operator&(const TypeName &a, const TypeName &b) { \ - return TypeName(static_cast<TypeName_T>(a) & static_cast<TypeName_T>(b)); \ - } \ - inline TypeName operator|(const TypeName &a, const TypeName &b) { \ - return TypeName(static_cast<TypeName_T>(a) | static_cast<TypeName_T>(b)); \ - } \ - inline TypeName operator^(const TypeName &a, const TypeName &b) { \ - return TypeName(static_cast<TypeName_T>(a) ^ static_cast<TypeName_T>(b)); \ - } \ - inline TypeName &operator++(TypeName &a) { \ - a = a + 1; \ - return a; \ - } \ - inline TypeName &operator--(TypeName &a) { \ - a = a - 1; \ - return a; \ - }; \ - inline TypeName operator<<(const TypeName &a, const TypeName &b) { \ - return TypeName(static_cast<TypeName_T>(a) << static_cast<TypeName_T>(b)); \ - }; \ - inline TypeName operator>>(const TypeName &a, const TypeName &b) { \ - return TypeName(static_cast<TypeName_T>(a) >> static_cast<TypeName_T>(b)); \ - }; -#define TypeSafeInt_H(TypeName, Type, Max) \ - TypeSafeInt2_H(TypeName, Type, Max, CONCAT(TypeName, _T), CONCAT(TypeName, _MAX), CONCAT(TypeName, _T_MAX)) -#define TypeSafeInt_B(TypeName) \ - TypeSafeInt2_B(TypeName, CONCAT(TypeName, _T)) - -#define TypeSafeInt2_H_constexpr(TypeName, Type, Max, TypeName_T, TypeName_MAX, TypeName_T_MAX)\ - using TypeName_T = Type; \ - enum class TypeName : TypeName_T; \ - constexpr TypeName_T TypeName_T_MAX = TypeName_T{Max}; \ - constexpr TypeName TypeName_MAX = TypeName{TypeName_T_MAX}; \ - constexpr TypeName operator+(const TypeName &a, const TypeName_T &b) { \ - return TypeName(static_cast<TypeName_T>(a) + static_cast<TypeName_T>(b)); \ - } \ - constexpr TypeName operator-(const TypeName &a, const TypeName_T &b) { \ - return TypeName(static_cast<TypeName_T>(a) - static_cast<TypeName_T>(b)); \ - } \ - constexpr TypeName operator+(const TypeName &a, const TypeName &b) { \ - return TypeName(static_cast<TypeName_T>(a) + static_cast<TypeName_T>(b)); \ - } \ - constexpr TypeName operator-(const TypeName &a, const TypeName &b) { \ - return TypeName(static_cast<TypeName_T>(a) - static_cast<TypeName_T>(b)); \ - } \ - constexpr TypeName operator&(const TypeName &a, const TypeName &b) { \ - return TypeName(static_cast<TypeName_T>(a) & static_cast<TypeName_T>(b)); \ - } \ - constexpr TypeName operator|(const TypeName &a, const TypeName &b) { \ - return TypeName(static_cast<TypeName_T>(a) | static_cast<TypeName_T>(b)); \ - } \ - constexpr TypeName operator^(const TypeName &a, const TypeName &b) { \ - return TypeName(static_cast<TypeName_T>(a) ^ static_cast<TypeName_T>(b)); \ - } \ - constexpr TypeName &operator++(TypeName &a) { \ - a = a + TypeName(1); \ - return a; \ - } \ - constexpr TypeName &operator--(TypeName &a) { \ - a = a - TypeName{1}; \ - return a; \ - }; \ - constexpr TypeName operator<<(const TypeName &a, const TypeName &b) { \ - return TypeName(static_cast<TypeName_T>(a) << static_cast<TypeName_T>(b)); \ - }; \ - constexpr TypeName operator>>(const TypeName &a, const TypeName &b) { \ - return TypeName(static_cast<TypeName_T>(a) >> static_cast<TypeName_T>(b)); \ - }; -#define TypeSafeInt_Const_Expr(TypeName, Type, Max) \ - TypeSafeInt2_H_constexpr(TypeName, Type, Max, CONCAT(TypeName, _T), CONCAT(TypeName, _MAX), CONCAT(TypeName, _T_MAX)) - - -#endif /* PKE_MACROS_HPP */ diff --git a/src/memory-allocator.hpp b/src/memory-allocator.hpp deleted file mode 100644 index c14304a..0000000 --- a/src/memory-allocator.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef PKE_MEMORY_ALLOCATOR_HPP -#define PKE_MEMORY_ALLOCATOR_HPP - -#include "memory.hpp" - -template <typename T, std::size_t SZ = DEFAULT_BUCKET_SIZE> class PkeTransAllocator { -public: - typedef T value_type; - MemBucket *transientBucket = nullptr; - - PkeTransAllocator() : transientBucket(Pke_BeginTransientBucket(SZ)) { - } - ~PkeTransAllocator() { - Pke_EndTransientBucket(this->transientBucket); - } - - template <class U> struct rebind {typedef PkeTransAllocator<U, SZ> other;}; - template <typename U> explicit PkeTransAllocator(const PkeTransAllocator<U> &other) { - (void)other; - } - - T *allocate(std::size_t n) { - auto *ptr = reinterpret_cast<T *>(Pke_New(sizeof(T) * n, this->transientBucket)); - if (ptr) return ptr; - throw "Pke-Allocator Failed to allocate"; - } - - void deallocate(const T *ptr, std::size_t n) { - Pke_Delete(ptr, sizeof(T) * n, this->transientBucket); - } -}; - -template <typename T> class PkeAllocator { -public: - typedef T value_type; - - PkeAllocator() = default; - - template <typename U> explicit PkeAllocator(const PkeAllocator<U> &other) { - (void)other; - } - - T *allocate(std::size_t n) { - auto *ptr = Pke_New<T>(n); - if (ptr) return ptr; - throw "Pke-Allocator Failed to allocate"; - } - - void deallocate(const T *ptr, std::size_t n) { - Pke_Delete<T>(ptr, n); - } -}; - -#endif /* PKE_MEMORY_ALLOCATOR_HPP */ diff --git a/src/memory-type-defs.hpp b/src/memory-type-defs.hpp deleted file mode 100644 index 181b89b..0000000 --- a/src/memory-type-defs.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef PKE_MEMORY_TYPE_DEFS_HPP -#define PKE_MEMORY_TYPE_DEFS_HPP - -#include <cstdint> - -using PkeHandleBucketIndex_T = uint32_t; -using PkeHandleItemIndex_T = uint32_t; - -const uint8_t PKE_HANDLE_VALIDATION_VALID = 0; -const uint8_t PKE_HANDLE_VALIDATION_BUCKET_INDEX_TOO_HIGH = 1; -const uint8_t PKE_HANDLE_VALIDATION_ITEM_INDEX_TOO_HIGH = 2; -const uint8_t PKE_HANDLE_VALIDATION_VALUE_MAX = 3; - -struct PkeHandle { - union { - struct { - PkeHandleBucketIndex_T bucketIndex; - PkeHandleItemIndex_T itemIndex; - }; - uint64_t hash = 0xFFFFFFFFFFFFFFFF; - }; -}; -constexpr PkeHandle PkeHandle_MAX = PkeHandle{}; - -constexpr bool operator==(const PkeHandle &a, const PkeHandle &b) { - return a.hash == b.hash; -} - -constexpr uint8_t ValidateHandle(PkeHandle handle, PkeHandle bucketHandle, uint64_t maxItems) { - if (handle == PkeHandle_MAX) - return PKE_HANDLE_VALIDATION_VALUE_MAX; - if (handle.bucketIndex > bucketHandle.bucketIndex) - return PKE_HANDLE_VALIDATION_BUCKET_INDEX_TOO_HIGH; - if (handle.itemIndex > maxItems) - return PKE_HANDLE_VALIDATION_ITEM_INDEX_TOO_HIGH; - if (handle.bucketIndex == bucketHandle.bucketIndex && handle.itemIndex > bucketHandle.itemIndex) - return PKE_HANDLE_VALIDATION_ITEM_INDEX_TOO_HIGH; - return PKE_HANDLE_VALIDATION_VALID; -} - -struct MemBucket; - -#endif /* PKE_MEMORY_TYPE_DEFS_HPP */ diff --git a/src/memory.cpp b/src/memory.cpp deleted file mode 100644 index 8fcc121..0000000 --- a/src/memory.cpp +++ /dev/null @@ -1,372 +0,0 @@ - -#include "memory.hpp" - -#include <mutex> - -const std::size_t MINIMUM_ALIGNMENT = 1; -const std::size_t MAXIMUM_ALIGNMENT = 64; - -struct MemBlock { - char *data; - std::size_t size; -}; - -struct MemBucket { - int64_t size; - int64_t head; - int64_t lostBytes; - int64_t allocs; - int64_t lastEmptyBlockIndex; - int64_t maxBlockCount; - char *blocks; - char *ptr; - std::mutex mtx; - bool transient; -}; - -MemBucket buckets[128]; -int64_t bucketHead = 0; - -int64_t InitNewBucket(int64_t sz, bool transient = false) { - int64_t blockCount = sz * 0.01; - auto &bkt = buckets[bucketHead]; - bkt.size = sz; - bkt.head = 0; - bkt.lostBytes = 0; - bkt.allocs = 0; - bkt.lastEmptyBlockIndex = -1; - bkt.maxBlockCount = blockCount < 10 ? 10 : blockCount; - bkt.blocks = reinterpret_cast<char *>(std::malloc(sz)); - assert(bkt.blocks != nullptr && "failed to allocate memory"); - bkt.ptr = bkt.blocks + (sizeof(MemBlock) * bkt.maxBlockCount); - size_t misalignment = reinterpret_cast<uint64_t>(bkt.ptr) % MAXIMUM_ALIGNMENT; - if (misalignment != 0) { - size_t moreBlocks = misalignment / sizeof(MemBlock); - bkt.maxBlockCount += moreBlocks; - bkt.ptr += (MAXIMUM_ALIGNMENT - misalignment); - } - bkt.transient = transient; - auto *memBlock = reinterpret_cast<MemBlock *>(bkt.blocks); - memBlock->data = bkt.ptr; - memBlock->size = sz - (sizeof(MemBlock) * bkt.maxBlockCount); - return bucketHead++; -} - -void Pke_ResetBucket(MemBucket *bkt) { - bkt->head = 0; - bkt->lostBytes = 0; - bkt->allocs = 0; - bkt->lastEmptyBlockIndex = -1; -} - -void DestroyBucket(MemBucket *bkt) { - std::free(bkt->blocks); - bkt->size = 0; - bkt->head = 0; - bkt->lostBytes = 0; - bkt->allocs = 0; - bkt->lastEmptyBlockIndex = -1; - bkt->maxBlockCount = 0; - bkt->blocks = CAFE_BABE(char); - bkt->ptr = CAFE_BABE(char); - bkt->transient = false; -} - -void *Pke_New(std::size_t sz, std::size_t alignment, MemBucket *bkt) { - MemBlock *blocks = reinterpret_cast<MemBlock *>(bkt->blocks); - std::size_t calculatedAlignment = alignment < MINIMUM_ALIGNMENT ? MINIMUM_ALIGNMENT : alignment; - std::size_t misalignment = 0; - long index = -1; - MemBlock *block = nullptr; - void *data = nullptr; - bkt->mtx.lock(); - for (int64_t i = 0; i <= bkt->lastEmptyBlockIndex; ++i) { - auto &blk = blocks[i]; - misalignment = reinterpret_cast<std::size_t>(blk.data) % calculatedAlignment; - misalignment = (calculatedAlignment - misalignment) % calculatedAlignment; - if (blk.size >= sz + misalignment) { - index = i; - block = &blk; - break; - } - } - if (block != nullptr) { - MemBlock *nextBlock = &blocks[index + 1]; - bool touchesValidNeighbor = index != bkt->lastEmptyBlockIndex && nextBlock->data == block->data + block->size; - data = block->data + misalignment; - if (misalignment) { - size_t afterSize = block->size - misalignment - sz; - block->size = misalignment; - if (afterSize) { - if (index == bkt->maxBlockCount) { - bkt->lostBytes += afterSize; - } else if (touchesValidNeighbor) { - nextBlock->data -= afterSize; - nextBlock->size += afterSize; - } else { - if (index != bkt->lastEmptyBlockIndex) { - long moveCount = bkt->lastEmptyBlockIndex - index; - if (moveCount > 0) { - char *srcPos = bkt->blocks + (sizeof(MemBlock) * (index + 1)); - char *dstPos = bkt->blocks + (sizeof(MemBlock) * (index + 2)); - memmove(dstPos, srcPos, sizeof(MemBlock) * moveCount); - } - } - bkt->lastEmptyBlockIndex += 1; - nextBlock->data = block->data + misalignment + sz; - nextBlock->size = afterSize; - } - } - } else { - size_t afterSize = block->size - sz; - if (afterSize && !touchesValidNeighbor) { - block->data += sz; - block->size -= sz; - } else { - if (afterSize && touchesValidNeighbor) { - nextBlock->data -= afterSize; - nextBlock->size += afterSize; - } - long moveCount = bkt->lastEmptyBlockIndex - index; - bkt->lastEmptyBlockIndex -= 1; - if (moveCount > 0) { - char *srcPos = bkt->blocks + (sizeof(MemBlock) * (index + 1)); - char *dstPos = bkt->blocks + (sizeof(MemBlock) * (index + 0)); - memmove(dstPos, srcPos, sizeof(MemBlock) * moveCount); - } - } - } - } else { - assert(bkt->head + sz <= bkt->size && "memory bucket specified, but full"); - misalignment = reinterpret_cast<std::size_t>(bkt->ptr + bkt->head) % calculatedAlignment; - misalignment = (calculatedAlignment - misalignment) % calculatedAlignment; - if (misalignment != 0) { - if (bkt->lastEmptyBlockIndex == bkt->maxBlockCount) { - bkt->lostBytes += misalignment; - } else { - bkt->lastEmptyBlockIndex += 1; - blocks[bkt->lastEmptyBlockIndex].data = bkt->ptr + bkt->head; - blocks[bkt->lastEmptyBlockIndex].size = misalignment; - } - bkt->head = bkt->head + misalignment; - } - data = bkt->ptr + bkt->head; - bkt->head = bkt->head + sz; - } - bkt->allocs++; - assert(data >= bkt->ptr && "allocated data is before bucket data"); - assert(data <= bkt->ptr + bkt->size && "allocated data is after bucket data"); - bkt->mtx.unlock(); - return data; -} - -void *Pke_New(std::size_t sz, std::size_t alignment) { - MemBucket *bkt = nullptr; - for (long i = 0; i < bucketHead; ++i) { - if (buckets[i].transient == false && buckets[i].size - buckets[i].head > sz + MAXIMUM_ALIGNMENT) { - bkt = &buckets[i]; - } - } - if (bkt == nullptr) { - bkt = &buckets[InitNewBucket(DEFAULT_BUCKET_SIZE)]; - } - return Pke_New(sz, alignment, bkt); -} - -void inline Pke_CollapseEmptyBlocksToHead(MemBucket *bkt) { - MemBlock *blocks = reinterpret_cast<MemBlock *>(bkt->blocks); - while (bkt->lastEmptyBlockIndex > -1) { - MemBlock *lastBlock = &blocks[bkt->lastEmptyBlockIndex]; - if (lastBlock->data + lastBlock->size != bkt->ptr + bkt->head) { - return; - } - bkt->head -= lastBlock->size; - lastBlock->data = 0; - lastBlock->size = 0; - bkt->lastEmptyBlockIndex -= 1; - } -} - -void inline Pke_CollapseBlocks(MemBucket *bkt) { - /* JCB 2023-11-21 - * After writing this, I realized that if the MemBlocks are sorted, - * one free should cause at most 1 memmove shift, and only if both - * the block before and after are identified. This method does not - * know when to stop and is therefore less efficient, especially - * considering it would find 1 instance to memmove at most if called - * on every free. - * Free has been refactored to handle the before+after block scenarios, - * so this method is no longer necessary, unless someday in the future - * we add a mechanism to toggle whether or not to resize blocks on free - * Example: if we don't enforce sorting, then this would be a good GC - * after a sort. However, in that case it might be better to rebuild - * the blocks into a new array and memcpy over the original, instead - * of performing memmove an unspecified number of times. - */ - assert(!"for reference use only"); - MemBlock *blocks = reinterpret_cast<MemBlock *>(bkt->blocks); - long skipDistance = 1; - long lastStartingIndex = 0; - for (long i = 0; i <= bkt->lastEmptyBlockIndex - 1; ++i) { - lastStartingIndex = i; - MemBlock &block = blocks[i]; - MemBlock &nextBlock = blocks[i + skipDistance]; - if (block.data + block.size == nextBlock.data) { - block.size += nextBlock.size; - nextBlock.size = 0; - skipDistance += 1; - i -= 1; - } else { - if (skipDistance > 1) { - char *srcPos = bkt->blocks + (sizeof(MemBlock) * (i + skipDistance)); - char *dstPos = bkt->blocks + (sizeof(MemBlock) * (i + 1)); - memmove(dstPos, srcPos, sizeof(MemBlock) * (skipDistance - 1)); - bkt->lastEmptyBlockIndex -= (skipDistance - 1); - } - i += skipDistance - 1; - skipDistance = 1; - } - } - if (skipDistance > 1) { - char *srcPos = bkt->blocks + (sizeof(MemBlock) * (lastStartingIndex + skipDistance)); - char *dstPos = bkt->blocks + (sizeof(MemBlock) * (lastStartingIndex + 1)); - memmove(dstPos, srcPos, sizeof(MemBlock) * (skipDistance - 1)); - bkt->lastEmptyBlockIndex -= (skipDistance - 1); - } -} - -bool Pke_InBucket(const void *ptr, const MemBucket *bkt) { - if (ptr >= bkt->ptr && ptr < bkt->ptr + bkt->size) return true; - return false; -} - -void Pke_Delete(const void *ptr, std::size_t sz, MemBucket *bkt) { - assert(ptr >= bkt->ptr && ptr < bkt->ptr + bkt->size && "pointer not in memory bucket range"); - bkt->allocs--; - if (bkt->allocs == 0) { - bkt->head = 0; - bkt->lastEmptyBlockIndex = -1; - return; - } - if (ptr == bkt->ptr + bkt->head - sz) { - bkt->head -= sz; - Pke_CollapseEmptyBlocksToHead(bkt); - return; - } - MemBlock *blocks = reinterpret_cast<MemBlock *>(bkt->blocks); - size_t prevBlockIndex = 0xFFFFFFFFFFFFFFFF; - void *prevPointer = reinterpret_cast<void *>(prevBlockIndex); - long beforeIndex = -1; - long afterIndex = -1; - for (int64_t i = 0; i <= bkt->lastEmptyBlockIndex; ++i) { - const auto &blk = blocks[i]; - if (blk.data < ptr && prevPointer < blk.data) { - prevBlockIndex = i; - prevPointer = blk.data; - } - if (reinterpret_cast<const char *>(ptr) == blk.data + blk.size ) { - beforeIndex = i; - continue; - } - if (blk.data == reinterpret_cast<const char *>(ptr) + sz) { - afterIndex = i; - break; - } - // we found beforeIndex on the previous loop, but then didn't find afterIndex on this loop - if (beforeIndex != -1) { - break; - } - } - if (beforeIndex != -1 && afterIndex != -1) { - MemBlock &beforeBlk = blocks[beforeIndex]; - MemBlock &afterBlk = blocks[afterIndex]; - beforeBlk.size += sz + afterBlk.size; - afterBlk.size = 0; - char *srcPos = bkt->blocks + (sizeof(MemBlock) * (afterIndex + 1)); - char *dstPos = bkt->blocks + (sizeof(MemBlock) * (afterIndex)); - memmove(dstPos, srcPos, sizeof(MemBlock) * (bkt->lastEmptyBlockIndex - afterIndex)); - bkt->lastEmptyBlockIndex -= 1; - } else if (beforeIndex != -1) { - MemBlock &beforeBlk = blocks[beforeIndex]; - beforeBlk.size += sz; - } else if (afterIndex != -1) { - MemBlock &afterBlk = blocks[afterIndex]; - afterBlk.data -= sz; - afterBlk.size += sz; - } else { - if (bkt->lastEmptyBlockIndex == bkt->maxBlockCount) { - bkt->lostBytes += sz; - } else { - MemBlock *targetBlock = nullptr; - if (prevBlockIndex < bkt->lastEmptyBlockIndex) { - long moveCount = bkt->lastEmptyBlockIndex - prevBlockIndex; - assert(moveCount > 0); - char *srcPos = bkt->blocks + (sizeof(MemBlock) * (prevBlockIndex + 1)); - char *dstPos = bkt->blocks + (sizeof(MemBlock) * (prevBlockIndex + 2)); - memmove(dstPos, srcPos, sizeof(MemBlock) * moveCount); - targetBlock = &blocks[prevBlockIndex + 1]; - } else { - targetBlock = &blocks[bkt->lastEmptyBlockIndex + 1]; - } - bkt->lastEmptyBlockIndex += 1; - targetBlock->data = reinterpret_cast<char *>(const_cast<void *>(ptr)); - targetBlock->size = sz; - } - } - Pke_CollapseEmptyBlocksToHead(bkt); -} - -void Pke_Delete(const void *ptr, std::size_t sz) { - MemBucket *bkt = nullptr; - for (long i = 0; i < bucketHead; ++i) { - bkt = &buckets[i]; - if (ptr >= bkt->ptr && ptr < bkt->ptr + bkt->size) break; - } - assert(bkt != nullptr && "failed to determine correct memory bucket"); - Pke_Delete(ptr, sz, bkt); -} - -MemBucket *Pke_BeginTransientBucket(int64_t sz) { - return &buckets[InitNewBucket(sz, true)]; -} - -void Pke_EndTransientBucket(MemBucket *bkt) { - int64_t foundIndex = -1; - for (int64_t i = 0; i < bucketHead; ++i) { - if (&buckets[i] == bkt) { - foundIndex = i; - DestroyBucket(&buckets[i]); - break; - } - } - if (foundIndex == bucketHead) { - bucketHead--; - } -} - -void Pke_MemoryFlush() { - for (long i = bucketHead - 2; i > -1; --i) { - if (buckets[i].head != 0) break; - if (buckets[i+1].head != 0) break; - if (buckets[i].transient == true) break; - if (buckets[i+1].transient == true) break; - bucketHead--; - DestroyBucket(&buckets[i + 1]); - } -} - -void Pke_DebugPrint() { - printf("Memory Manager printout:\nBucket count: %li\n", bucketHead); - for (long i = 0; i < bucketHead; ++i) { - printf("- bucket #%li\n", i); - printf("\tsize: %li\n", buckets[i].size); - printf("\thead: %li\n", buckets[i].head); - printf("\tlostBytes: %li\n", buckets[i].lostBytes); - printf("\tallocs: %li\n", buckets[i].allocs); - printf("\tlastEmptyBlockIndex: %li\n", buckets[i].lastEmptyBlockIndex); - printf("\tmaxBlockCount: %li\n", buckets[i].maxBlockCount); - printf("\tblocks: %p\n", buckets[i].blocks); - printf("\tptr: %p\n", buckets[i].ptr); - printf("\ttransient: %i\n", buckets[i].transient); - } -} diff --git a/src/memory.hpp b/src/memory.hpp deleted file mode 100644 index fe63318..0000000 --- a/src/memory.hpp +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef PKE_MEMORY_HPP -#define PKE_MEMORY_HPP - -#include "memory-type-defs.hpp" -#include "macros.hpp" - -#include <cstring> -#include <cstdint> -#include <cstdlib> -#include <cstdio> -#include <cassert> -#include <type_traits> -#include <new> - -// 256MB -#define DEFAULT_BUCKET_SIZE 1UL << 27 -extern const std::size_t MINIMUM_ALIGNMENT; -extern const std::size_t MAXIMUM_ALIGNMENT; - -void *Pke_New(std::size_t sz, std::size_t alignment); -void *Pke_New(std::size_t sz, std::size_t alignment, MemBucket *bkt); -void Pke_Delete(const void *ptr, std::size_t sz); -void Pke_Delete(const void *ptr, std::size_t sz, MemBucket *bkt); -bool Pke_InBucket(const void *ptr, const MemBucket *bkt); -void Pke_DebugPrint(); - -MemBucket *Pke_BeginTransientBucket(int64_t sz = DEFAULT_BUCKET_SIZE); -void Pke_EndTransientBucket(MemBucket *bkt); -void Pke_ResetBucket(MemBucket *bkt); -void Pke_MemoryFlush(); - -template <typename T> -inline T *Pke_New(MemBucket *bucket = nullptr) { - void *ptr = nullptr; - if (bucket) { - ptr = Pke_New(sizeof(T), alignof(T), bucket); - } else { - ptr = Pke_New(sizeof(T), alignof(T)); - } - if IS_CONSTRUCTIBLE(T) { - return new (ptr) T{}; - } - return reinterpret_cast<T *>(ptr); -} -template <typename T> -inline T *Pke_New(long count, MemBucket *bucket = nullptr) { - char *ptr = nullptr; - if (bucket) { - ptr = static_cast<char *>(Pke_New(sizeof(T) * count, alignof(T), bucket)); - } else { - ptr = static_cast<char *>(Pke_New(sizeof(T) * count, alignof(T))); - } - if IS_CONSTRUCTIBLE(T) { - for (long i = 0; i < count; ++i) { - new (ptr + (i * sizeof(T))) T{}; - } - } - return reinterpret_cast<T *>(ptr); -} -template <typename T> -inline void Pke_Delete(const void *ptr, MemBucket *bucket = nullptr) { - if IS_DESTRUCTIBLE(T) { - reinterpret_cast<const T *>(ptr)->~T(); - } - if (bucket) { - return Pke_Delete(ptr, sizeof(T), bucket); - } else { - return Pke_Delete(ptr, sizeof(T)); - } -} -template <typename T> -inline void Pke_Delete(const void *ptr, long count, MemBucket *bucket = nullptr) { - if IS_DESTRUCTIBLE(T) { - for (long i = 0; i < count; ++i) { - reinterpret_cast<const T *>(reinterpret_cast<const char *>(ptr) + (i * sizeof(T)))->~T(); - } - } - if (bucket) { - return Pke_Delete(ptr, sizeof(T) * count, bucket); - } else { - return Pke_Delete(ptr, sizeof(T) * count); - } -} - -#endif /* PKE_MEMORY_HPP */ diff --git a/src/physics.cpp b/src/physics.cpp index 88c8139..d939e21 100644 --- a/src/physics.cpp +++ b/src/physics.cpp @@ -13,7 +13,7 @@ TypeSafeInt_B(PhysicsCollision); -MemBucket *MemBkt_Bullet = nullptr; +struct pk_membucket *MemBkt_Bullet = nullptr; btDiscreteDynamicsWorld *BtDynamicsWorld = nullptr; struct AllocedData { @@ -33,7 +33,7 @@ struct EntityCollision { PkeArray<EntityCollision> collisionsThisTick{}; void *pke_btAlignedAllocFunc(size_t size, int alignment) { - void *ptr = Pke_New(size, alignment, MemBkt_Bullet); + void *ptr = pk_new_bkt(size, alignment, MemBkt_Bullet); bulletAllocs->Push({ptr, size}); return ptr; } @@ -48,11 +48,11 @@ void pke_btAlignedFreeFunc(void *memBlock) { } } assert(index != -1); - Pke_Delete(const_cast<void *>(memBlock), arr[index].size, MemBkt_Bullet); + pk_delete_bkt(memBlock, arr[index].size, MemBkt_Bullet); bulletAllocs->Remove(index); } void *pke_btAllocFunc(size_t size) { - void *ptr = Pke_New(size, MINIMUM_ALIGNMENT, MemBkt_Bullet); + void *ptr = pk_new_bkt(size, PK_MINIMUM_ALIGNMENT, MemBkt_Bullet); bulletAllocs->Push({ptr, size}); return ptr; } @@ -67,7 +67,7 @@ void pke_btFreeFunc(void *memBlock) { } } assert(index != -1); - Pke_Delete(const_cast<void *>(memBlock), arr[index].size, MemBkt_Bullet); + pk_delete_bkt(memBlock, arr[index].size, MemBkt_Bullet); bulletAllocs->Remove(index); } @@ -95,28 +95,28 @@ struct CollisionHandlerStruct : public btOverlapFilterCallback { } collisionHandlerStruct; void Physics_Init() { - MemBkt_Bullet = Pke_BeginTransientBucket(); - bulletAllocs = Pke_New<DynArray<AllocedData>>(MemBkt_Bullet); + MemBkt_Bullet = pk_bucket_create("physics", PK_DEFAULT_BUCKET_SIZE, false); + bulletAllocs = pk_new<DynArray<AllocedData>>(MemBkt_Bullet); new (bulletAllocs) DynArray<AllocedData>(MemBkt_Bullet); bulletAllocs->Reserve(1024); btAlignedAllocSetCustom(pke_btAllocFunc, pke_btFreeFunc); btAlignedAllocSetCustomAligned(pke_btAlignedAllocFunc, pke_btAlignedFreeFunc); - btConfiguration = Pke_New<btDefaultCollisionConfiguration>(MemBkt_Bullet); - btDispatcher = Pke_New<btCollisionDispatcher>(MemBkt_Bullet); + btConfiguration = pk_new<btDefaultCollisionConfiguration>(MemBkt_Bullet); + btDispatcher = pk_new<btCollisionDispatcher>(MemBkt_Bullet); new (btDispatcher) btCollisionDispatcher(btConfiguration); - btBroadphase = Pke_New<btDbvtBroadphase>(MemBkt_Bullet); + btBroadphase = pk_new<btDbvtBroadphase>(MemBkt_Bullet); #if 1 - btHashedOverlappingPairCache *overlappingPairCache = Pke_New<btHashedOverlappingPairCache>(MemBkt_Bullet); + btHashedOverlappingPairCache *overlappingPairCache = pk_new<btHashedOverlappingPairCache>(MemBkt_Bullet); overlappingPairCache->setOverlapFilterCallback(&collisionHandlerStruct); new (btBroadphase) btDbvtBroadphase(overlappingPairCache); #else new (btBroadphase) btDbvtBroadphase(); #endif - btSolver = Pke_New<btSequentialImpulseConstraintSolver>(MemBkt_Bullet); + btSolver = pk_new<btSequentialImpulseConstraintSolver>(MemBkt_Bullet); - BtDynamicsWorld = Pke_New<btDiscreteDynamicsWorld>(MemBkt_Bullet); + BtDynamicsWorld = pk_new<btDiscreteDynamicsWorld>(MemBkt_Bullet); new (BtDynamicsWorld) btDiscreteDynamicsWorld(btDispatcher, btBroadphase, btSolver, btConfiguration); } @@ -132,5 +132,5 @@ int32_t Physics_Tick(double delta) { } void Physics_Teardown() { - Pke_EndTransientBucket(MemBkt_Bullet); + pk_bucket_destroy(MemBkt_Bullet); } diff --git a/src/physics.hpp b/src/physics.hpp index 67ac60c..0cfe49a 100644 --- a/src/physics.hpp +++ b/src/physics.hpp @@ -1,14 +1,13 @@ #ifndef PKE_PHYSICS_HPP #define PKE_PHYSICS_HPP -#include "macros.hpp" -#include "memory.hpp" +#include "vendor/pk.h" #include <BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h> TypeSafeInt_H(PhysicsCollision, uint64_t, 0xFFFFFFFFFFFFFFFF); -extern MemBucket *MemBkt_Bullet; +extern struct pk_membucket *MemBkt_Bullet; extern btDiscreteDynamicsWorld *BtDynamicsWorld; void Physics_Init(); diff --git a/src/pkstr.cpp b/src/pkstr.cpp deleted file mode 100644 index 10e656c..0000000 --- a/src/pkstr.cpp +++ /dev/null @@ -1,31 +0,0 @@ - -#include "pkstr.hpp" -#include <cstring> - -pkstr to_pkstr(char *s) { - return pkstr { - .length = static_cast<int64_t>(strlen(s)), - .val = s, - }; -} - -pkstr to_pkstr(const cpkstr &s) { - return pkstr { - .length = s.length, - .val = const_cast<char *>(s.val), - }; -} - -cpkstr to_cpkstr(const char *s) { - return cpkstr { - .length = static_cast<int64_t>(strlen(s)), - .val = s, - }; -} - -cpkstr to_cpkstr(const pkstr &s) { - return cpkstr { - .length = s.length, - .val = s.val, - }; -} diff --git a/src/pkstr.hpp b/src/pkstr.hpp deleted file mode 100644 index 0f2fb0d..0000000 --- a/src/pkstr.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef PKE_STRING_HPP -#define PKE_STRING_HPP - -#include <cstdint> - -struct pkstr { - int64_t length = 0; - char *val = nullptr; -}; -struct cpkstr { - int64_t length = 0; - const char *val = nullptr; -}; - -pkstr to_pkstr(char *s); -pkstr to_pkstr(const cpkstr &s); -cpkstr to_cpkstr(const char *s); -cpkstr to_cpkstr(const pkstr &s); - -#endif /* PKE_STRING_HPP */ diff --git a/src/player-input.cpp b/src/player-input.cpp index 1e87093..84f5898 100644 --- a/src/player-input.cpp +++ b/src/player-input.cpp @@ -669,7 +669,7 @@ void PkeInput_UnregisterSet(InputActionSetHandle handle) { if (activeInputSetStack.Has(handle)) { PkeInput_DeactivateSet(handle); } - Pke_Delete<PkeInputAction>(set.actions, set.actionCount); + pk_delete<PkeInputAction>(set.actions, set.actionCount); registeredInputSets.Remove(index); } diff --git a/src/player-input.hpp b/src/player-input.hpp index 59d2c75..e3d3501 100644 --- a/src/player-input.hpp +++ b/src/player-input.hpp @@ -2,13 +2,13 @@ #define PKE_PLAYER_INPUT_HPP #include "game-type-defs.hpp" -#include "macros.hpp" +#include "vendor/pk.h" #include <cstdint> TypeSafeInt_H(InputActionSetHandle, uint8_t, 0xFF); -TypeSafeInt_Const_Expr(InputEventHash, uint16_t, 0xFFFF); +TypeSafeInt_constexpr(InputEventHash, uint16_t, 0xFFFF); const InputEventHash PKE_INPUT_HASH_EVENT_TYPE_CURSOR_ENTER = InputEventHash {0x0001}; const InputEventHash PKE_INPUT_HASH_EVENT_TYPE_CURSOR_POS = InputEventHash {0x0002}; diff --git a/src/plugins.cpp b/src/plugins.cpp index 5b0b817..ac07e93 100644 --- a/src/plugins.cpp +++ b/src/plugins.cpp @@ -2,7 +2,7 @@ #include "plugins.hpp" #include "array.hpp" -#include "macros.hpp" +#include "vendor/pk.h" #include <cassert> #include <cstdio> diff --git a/src/project-settings.hpp b/src/project-settings.hpp index 62ff7d8..d999948 100644 --- a/src/project-settings.hpp +++ b/src/project-settings.hpp @@ -2,12 +2,12 @@ #define PKE_PROJECT_SETTINGS_HPP #include "dynamic-array.hpp" -#include "pkstr.hpp" +#include "vendor/pk.h" #include <cstdint> struct PkeProjectSettings { const char *defaultSceneName = "default"; - DynArray<cpkstr> scenes{16}; + DynArray<pk_str> scenes{16}; }; extern PkeProjectSettings pkeProjectSettings; diff --git a/src/project.cpp b/src/project.cpp index 4412522..1c5572d 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -67,13 +67,13 @@ void Proj_SerializeEntityType(std::ofstream &stream, const EntityType &et) { NULL_CHAR_ARR(handleStr, 19); NULL_CHAR_ARR(modelAssetKey, AssetKeyLength + 1); NULL_CHAR_ARR(textureAssetKey, AssetKeyLength + 1); - snprintf(handleStr, 19, "0x%016lX", et.handle.hash); + snprintf(handleStr, 19, "0x%08X 0x%08X", et.handle.bucketIndex, et.handle.itemIndex); snprintf(modelAssetKey, AssetKeyLength + 1, "%s", et.modelAssetKey); EntityType e{}; if (modelAssetKey[0] != '\0') stream << PKE_PROJ_FILE_ENTITY_TYPE_MODEL_ASSET_KEY << modelAssetKey << std::endl; - if (et.entityTypeCode != e.entityTypeCode) - stream << PKE_PROJ_FILE_ENTITY_TYPE_ENTITY_TYPE_CODE << et.entityTypeCode << std::endl; + if (et.entityTypeCode.val != e.entityTypeCode.val) + stream << PKE_PROJ_FILE_ENTITY_TYPE_ENTITY_TYPE_CODE << et.entityTypeCode.val << std::endl; if (et.handle != e.handle) stream << PKE_PROJ_FILE_ENTITY_TYPE_ENTITY_HANDLE << handleStr << std::endl; if (et.createInstanceCallback.name[0] != '\0') { @@ -127,7 +127,7 @@ void Proj_ParseProjectSettings(std::ifstream &stream) { if (strncmp(projReadLine, PKE_PROJ_FILE_PROJ_SETTINGS_DEFAULT_SCENE_NAME, strlen(PKE_PROJ_FILE_PROJ_SETTINGS_DEFAULT_SCENE_NAME)) == 0) { uint64_t prefixLen = strlen(PKE_PROJ_FILE_PROJ_SETTINGS_DEFAULT_SCENE_NAME); uint64_t len = strlen(projReadLine + prefixLen) + 1; - char *val = Pke_New<char>(len); + char *val = pk_new<char>(len); memset(reinterpret_cast<void *>(val), '\0', len); memcpy(val, projReadLine + prefixLen, len); pkeProjectSettings.defaultSceneName = val; @@ -138,13 +138,13 @@ void Proj_ParseProjectSettings(std::ifstream &stream) { while (stream.getline(projReadLine, projReadLineLength)) { if (strcmp(PKE_PROJ_FILE_PROJ_SETTINGS_SCENES_END, projReadLine) == 0) { pkeProjectSettings.sceneCount = sceneFiles.Count(); - pkeProjectSettings.scenes = Pke_New<cpkstr>(sceneFiles.Count()); + pkeProjectSettings.scenes = pk_new<cpkstr>(sceneFiles.Count()); memcpy(reinterpret_cast<void *>(pkeProjectSettings.scenes), reinterpret_cast<void *>(sceneFiles.GetPtr()), sizeof(cpkstr) * sceneFiles.Count()); break; } pkeProjectSettings.sceneCount += 1; uint64_t len = strlen(projReadLine) + 1; - char *val = Pke_New<char>(len); + char *val = pk_new<char>(len); memset(val, '\0', len); memcpy(val, projReadLine, len - 1); auto &str = sceneFiles.Push(); @@ -165,7 +165,7 @@ void Proj_ParseEntityType(std::ifstream &stream) { int64_t detailCount = 0; while (stream.getline(projReadLine, projReadLineLength)) { if (strcmp(PKE_PROJ_FILE_OBJ_END, projReadLine) == 0) { - EntityType *existingPtr = EntityType_FindByTypeCode(et.entityTypeCode); + EntityType *existingPtr = EntityType_FindByTypeCode(et.entityTypeCode.val); if (existingPtr != nullptr) { // TODO leaks et.EntityTypeCode continue; @@ -203,16 +203,19 @@ void Proj_ParseEntityType(std::ifstream &stream) { if (strstr(projReadLine, PKE_PROJ_FILE_ENTITY_TYPE_ENTITY_TYPE_CODE)) { uint64_t prefixLen = strlen(PKE_PROJ_FILE_ENTITY_TYPE_ENTITY_TYPE_CODE); uint64_t len = strlen(projReadLine + prefixLen) + 1; - char *val = Pke_New<char>(len); + char *val = pk_new<char>(len); memset(reinterpret_cast<void *>(val), '\0', len); memcpy(val, projReadLine + prefixLen, len); - et.entityTypeCode = val; + et.entityTypeCode.val = val; continue; } if (strstr(projReadLine, PKE_PROJ_FILE_ENTITY_TYPE_ENTITY_HANDLE)) { uint64_t prefixLen = strlen(PKE_PROJ_FILE_ENTITY_TYPE_ENTITY_HANDLE); - STR2NUM_ERROR result = str2num(et.handle.hash, projReadLine + prefixLen); - assert(result == STR2NUM_ERROR::SUCCESS); + // 0x00000000 0x00000000 + STR2NUM_ERROR result1 = str2num(et.handle.bucketIndex, projReadLine + prefixLen); + STR2NUM_ERROR result2 = str2num(et.handle.itemIndex, projReadLine + prefixLen + 11); + assert(result1 == STR2NUM_ERROR::SUCCESS); + assert(result2 == STR2NUM_ERROR::SUCCESS); continue; } if (strstr(projReadLine, PKE_PROJ_FILE_ENTITY_TYPE_CREATE_INSTANCE_CALLBACK_SIGNATURE)) { @@ -372,10 +375,10 @@ void PkeProject_Save(const char *filePath) { } const auto entBucketCount = EntityType_GetBucketCount(); - for (PkeHandleBucketIndex_T b = 0; b < entBucketCount; ++b) { - PkeHandleItemIndex_T itemCount = 0; + for (pk_handle_bucket_index_T b = 0; b < entBucketCount; ++b) { + pk_handle_item_index_T itemCount = 0; auto *entities = EntityType_GetEntityTypes(b, itemCount); - for (PkeHandleItemIndex_T i = 0; i < itemCount; ++i) { + for (pk_handle_item_index_T i = 0; i < itemCount; ++i) { if (entities[i].modelAssetKey[0] == '\0') { continue; } diff --git a/src/thread_pool.cpp b/src/thread_pool.cpp index 0fc9880..e2ef3cd 100644 --- a/src/thread_pool.cpp +++ b/src/thread_pool.cpp @@ -15,10 +15,10 @@ struct ThreadPool { std::condition_variable condition; DynArray<std::packaged_task<void()> *> *jobQueue; DynArray<std::thread> *threads; - MemBucket *bkt = nullptr; + struct pk_membucket *bkt = nullptr; }; -const PkeHandleItemIndex_T MAX_THREADS_PER_BUCKET = 8; +const pk_handle_item_index_T MAX_THREADS_PER_BUCKET = 8; BucketContainer<ThreadPool, ThreadPoolHandle> ThreadPool_BucketContainer{}; @@ -45,7 +45,7 @@ void ThreadRun(ThreadPool *tp) { } assert(j != nullptr); (*j)(); - Pke_Delete<std::packaged_task<void()>>(j, tp->bkt); + pk_delete<std::packaged_task<void()>>(j, tp->bkt); tp->completedCount = tp->completedCount + 1; } } @@ -128,7 +128,7 @@ void PkeThreads_Init() { Buckets_Init(ThreadPool_BucketContainer, MAX_THREADS_PER_BUCKET); } -ThreadPoolHandle PkeThreads_Init(uint8_t threadCount, uint8_t maxQueueCount, MemBucket *bkt) { +ThreadPoolHandle PkeThreads_Init(uint8_t threadCount, uint8_t maxQueueCount, struct pk_membucket *bkt) { assert(threadCount > 0); ThreadPoolHandle newHandle{Buckets_NewHandle(ThreadPool_BucketContainer)}; @@ -139,8 +139,8 @@ ThreadPoolHandle PkeThreads_Init(uint8_t threadCount, uint8_t maxQueueCount, Mem tp->isPaused = false; tp->maxJobQueueCount = maxQueueCount; tp->completedCount = 0; - tp->jobQueue = Pke_New<DynArray<std::packaged_task<void()> *>>(bkt); - tp->threads = Pke_New<DynArray<std::thread>>(bkt); + tp->jobQueue = pk_new<DynArray<std::packaged_task<void()> *>>(bkt); + tp->threads = pk_new<DynArray<std::thread>>(bkt); tp->threads->Resize(threadCount); for (long l = 0; l < threadCount; ++l) { @@ -162,10 +162,10 @@ bool PkeThreads_Enqueue(ThreadPoolHandle handle, std::packaged_task<void()> *job if (tp->bkt != nullptr) { /* 2023-12-22 JCB * Note that if this becomes an issue we can change it. - * Technically speaking, if we call the right Pke_Delete - * we don't even need to worry about passing the MemBucket + * Technically speaking, if we call the right pk_delete + * we don't even need to worry about passing the struct pk_membucket */ - assert(Pke_InBucket(job, tp->bkt) == true && "cannot enqueue packaged task from a non-matching MemBucket"); + assert(pk_memory_is_in_bucket(job, tp->bkt) == true && "cannot enqueue packaged task from a non-matching struct pk_membucket"); } return PkeThreads_Enqueue_Inner(*tp, job); @@ -205,11 +205,11 @@ void PkeThreads_Teardown(ThreadPoolHandle handle) { PkeThreads_Shutdown_Inner(*tp); PkeThreads_JoinAll_Inner(*tp); PkeThreads_Reset_Inner(*tp); - Pke_Delete<DynArray<std::packaged_task<void()> *>>(tp->jobQueue, tp->bkt); - Pke_Delete<DynArray<std::thread>>(tp->threads, tp->bkt); + pk_delete<DynArray<std::packaged_task<void()> *>>(tp->jobQueue, tp->bkt); + pk_delete<DynArray<std::thread>>(tp->threads, tp->bkt); tp->jobQueue = CAFE_BABE(DynArray<std::packaged_task<void()> *>); tp->threads = CAFE_BABE(DynArray<std::thread>); - tp->bkt = CAFE_BABE(MemBucket); + tp->bkt = CAFE_BABE(struct pk_membucket); } void PkeThreads_Teardown() { diff --git a/src/thread_pool.hpp b/src/thread_pool.hpp index 4eb2fc8..30ee516 100644 --- a/src/thread_pool.hpp +++ b/src/thread_pool.hpp @@ -2,17 +2,17 @@ #define PKE_THREADING_HPP #include "dynamic-array.hpp" -#include "macros.hpp" +#include "vendor/pk.h" #include <cstdint> #include <future> -struct ThreadPoolHandle : public PkeHandle { }; +struct ThreadPoolHandle : public pk_handle { }; -constexpr ThreadPoolHandle ThreadPoolHandle_MAX = ThreadPoolHandle{}; +constexpr ThreadPoolHandle ThreadPoolHandle_MAX = ThreadPoolHandle{ pk_handle_MAX_constexpr }; void PkeThreads_Init(); -ThreadPoolHandle PkeThreads_Init (uint8_t threadCount, uint8_t maxQueueCount, MemBucket *bkt = nullptr); +ThreadPoolHandle PkeThreads_Init (uint8_t threadCount, uint8_t maxQueueCount, struct pk_membucket *bkt = nullptr); void PkeThreads_Reset (ThreadPoolHandle handle); bool PkeThreads_Enqueue (ThreadPoolHandle handle, std::packaged_task<void()> *job); int64_t PkeThreads_GetQueueCount (ThreadPoolHandle handle); diff --git a/src/vendor/pk.h b/src/vendor/pk.h new file mode 100644 index 0000000..8d788d1 --- /dev/null +++ b/src/vendor/pk.h @@ -0,0 +1,1246 @@ +#ifndef PK_SINGLE_HEADER_FILE_H +#define PK_SINGLE_HEADER_FILE_H +/****************************************************************************** +* PK Single-Header-Library V0.0.2 +* +* Author: Jonathan Bradley +* Copyright: © 2024-2024 Jonathan Bradley +* Description: +* +******************************************************************************* +* pkmacros.h: +* +******************************************************************************* +* pkmem-types.h: +* +******************************************************************************* +* pkmem.h: +* +******************************************************************************* +* pkstr.h: +* +******************************************************************************* +* pkev.h: +* +******************************************************************************/ + +#define PK_VERSION "0.0.2" + +#ifdef PK_IMPL_ALL +# ifndef PK_IMPL_MEM_TYPES +# define PK_IMPL_MEM_TYPES +# endif +# ifndef PK_IMPL_MEM +# define PK_IMPL_MEM +# endif +# ifndef PK_IMPL_STR +# define PK_IMPL_STR +# endif +# ifndef PK_IMPL_EV +# define PK_IMPL_EV +# endif +#endif +#ifndef PK_MACROS_H +#define PK_MACROS_H + +#ifndef PK_LOG_OVERRIDE +# ifdef NDEBUG +# define PK_LOG_ERR(str) (void)str +# define PK_LOG_INF(str) (void)str +# define PK_LOGV_ERR(str, ...) (void)str +# define PK_LOGV_INF(str, ...) (void)str +# else +# define PK_LOG_ERR(str, ...) fprintf(stderr, str) +# define PK_LOG_INF(str, ...) fprintf(stdout, str) +# define PK_LOGV_ERR(str, ...) fprintf(stderr, str, __VA_ARGS__) +# define PK_LOGV_INF(str, ...) fprintf(stdout, str, __VA_ARGS__) +# endif +#endif + +#define PK_Q(x) #x +#define PK_QUOTE(x) PK_Q(x) +#define PK_CONCAT2(x, y) x##y +#define PK_CONCAT(x, y) PK_CONCAT2(x, y) + +#define PK_HAS_FLAG(val, flag) ((val & flag) == flag) +#define PK_CLAMP(val, min, max) (val < min ? min : val > max ? max : val) +#define PK_MIN(val, min) (val < min ? val : min) +#define PK_MAX(val, max) (val > max ? val : max) + +#define PK_TO_BIN_PAT PK_Q(%c%c%c%c%c%c%c%c) +#define PK_TO_BIN_PAT_8 PK_TO_BIN_PAT +#define PK_TO_BIN_PAT_16 PK_TO_BIN_PAT PK_TO_BIN_PAT +#define PK_TO_BIN_PAT_32 PK_TO_BIN_PAT_16 PK_TO_BIN_PAT_16 +#define PK_TO_BIN_PAT_64 PK_TO_BIN_PAT_32 PK_TO_BIN_PAT_32 +#define PK_TO_BIN(byte) \ + ((byte) & 0x80 ? '1' : '0'), \ + ((byte) & 0x40 ? '1' : '0'), \ + ((byte) & 0x20 ? '1' : '0'), \ + ((byte) & 0x10 ? '1' : '0'), \ + ((byte) & 0x08 ? '1' : '0'), \ + ((byte) & 0x04 ? '1' : '0'), \ + ((byte) & 0x02 ? '1' : '0'), \ + ((byte) & 0x01 ? '1' : '0') +#define PK_TO_BIN_8(u8) PK_TO_BIN(u8) +#define PK_TO_BIN_16(u16) PK_TO_BIN((u16 >> 8)), PK_TO_BIN(u16 & 0x00FF) +#define PK_TO_BIN_32(u32) PK_TO_BIN_16((u32 >> 16)), PK_TO_BIN_16(u32 & 0x0000FFFF) +#define PK_TO_BIN_64(u64) PK_TO_BIN_32((u64 >> 32)), PK_TO_BIN_32(u64 & 0x00000000FFFFFFFF) + +#if defined(__cplusplus) +# define CAFE_BABE(T) reinterpret_cast<T *>(0xCAFEBABE) +#else +# define CAFE_BABE(T) (T *)(0xCAFEBABE) +#endif + +#define NULL_CHAR_ARR(v, len) char v[len]; v[0] = '\0'; v[len-1] = '\0'; + +#define IS_CONSTRUCTIBLE(T) constexpr(std::is_default_constructible<T>::value && !std::is_integral<T>::value && !std::is_floating_point<T>::value) +#define IS_DESTRUCTIBLE(T) constexpr(std::is_destructible<T>::value && !std::is_integral<T>::value && !std::is_floating_point<T>::value && !std::is_array<T>::value) + +#define TypeSafeInt2_H(TypeName, Type, Max, TypeName_T, TypeName_MAX, TypeName_T_MAX) \ + using TypeName_T = Type; \ + enum class TypeName : TypeName_T; \ + constexpr TypeName_T TypeName_T_MAX = TypeName_T{Max}; \ + constexpr TypeName TypeName_MAX = TypeName{TypeName_T_MAX}; \ + TypeName operator+(const TypeName& a, const TypeName& b); \ + TypeName operator-(const TypeName& a, const TypeName& b); \ + TypeName operator&(const TypeName& a, const TypeName& b); \ + TypeName operator|(const TypeName& a, const TypeName& b); \ + TypeName operator^(const TypeName& a, const TypeName& b); \ + TypeName& operator++(TypeName& a); \ + TypeName& operator--(TypeName& a); \ + TypeName operator++(TypeName& a, int); \ + TypeName operator--(TypeName& a, int); \ + TypeName operator<<(const TypeName& a, const TypeName& b); \ + TypeName operator>>(const TypeName& a, const TypeName& b); \ + TypeName operator+=(TypeName& a, const TypeName& b); \ + TypeName operator-=(TypeName& a, const TypeName& b); \ + TypeName operator&=(TypeName& a, const TypeName& b); \ + TypeName operator|=(TypeName& a, const TypeName& b); \ + TypeName operator^=(TypeName& a, const TypeName& b); \ + TypeName operator~(TypeName& a); +#define TypeSafeInt2_B(TypeName, TypeName_T) \ + inline TypeName operator+(const TypeName& a, const TypeName& b) { \ + return TypeName(static_cast<TypeName_T>(a) + static_cast<TypeName_T>(b)); \ + } \ + inline TypeName operator-(const TypeName& a, const TypeName& b) { \ + return TypeName(static_cast<TypeName_T>(a) - static_cast<TypeName_T>(b)); \ + } \ + inline TypeName operator&(const TypeName& a, const TypeName& b) { \ + return TypeName(static_cast<TypeName_T>(a) & static_cast<TypeName_T>(b)); \ + } \ + inline TypeName operator|(const TypeName& a, const TypeName& b) { \ + return TypeName(static_cast<TypeName_T>(a) | static_cast<TypeName_T>(b)); \ + } \ + inline TypeName operator^(const TypeName& a, const TypeName& b) { \ + return TypeName(static_cast<TypeName_T>(a) ^ static_cast<TypeName_T>(b)); \ + } \ + inline TypeName& operator++(TypeName& a) { \ + a = a + TypeName{1}; \ + return a; \ + } \ + inline TypeName& operator--(TypeName& a) { \ + a = a - TypeName{1}; \ + return a; \ + }; \ + inline TypeName operator++(TypeName& a, int) { \ + a = a + TypeName{1}; \ + return a; \ + } \ + inline TypeName operator--(TypeName& a, int) { \ + a = a - TypeName{1}; \ + return a; \ + }; \ + inline TypeName operator<<(const TypeName& a, const TypeName& b) { \ + return TypeName(static_cast<TypeName_T>(a) << static_cast<TypeName_T>(b)); \ + }; \ + inline TypeName operator>>(const TypeName& a, const TypeName& b) { \ + return TypeName(static_cast<TypeName_T>(a) >> static_cast<TypeName_T>(b)); \ + }; \ + inline TypeName operator+=(TypeName& a, const TypeName& b) { \ + a = TypeName{a + b}; \ + return a; \ + }; \ + inline TypeName operator-=(TypeName& a, const TypeName& b) { \ + a = TypeName{a - b}; \ + return a; \ + }; \ + inline TypeName operator&=(TypeName& a, const TypeName& b) { \ + a = TypeName{a & b}; \ + return a; \ + }; \ + inline TypeName operator|=(TypeName& a, const TypeName& b) { \ + a = TypeName{a | b}; \ + return a; \ + }; \ + inline TypeName operator^=(TypeName& a, const TypeName& b) { \ + a = TypeName{a ^ b}; \ + return a; \ + }; \ + inline TypeName operator~(TypeName& a) { \ + a = static_cast<TypeName>(~static_cast<TypeName_T>(a)); \ + return a; \ + }; +#define TypeSafeInt_H(TypeName, Type, Max) \ + TypeSafeInt2_H(TypeName, Type, Max, PK_CONCAT(TypeName, _T), PK_CONCAT(TypeName, _MAX), PK_CONCAT(TypeName, _T_MAX)) +#define TypeSafeInt_B(TypeName) \ + TypeSafeInt2_B(TypeName, PK_CONCAT(TypeName, _T)) + +#define TypeSafeInt2_H_constexpr(TypeName, Type, Max, TypeName_T, TypeName_MAX, TypeName_T_MAX) \ + using TypeName_T = Type; \ + enum class TypeName : TypeName_T; \ + constexpr TypeName_T TypeName_T_MAX = TypeName_T{Max}; \ + constexpr TypeName TypeName_MAX = TypeName{TypeName_T_MAX}; \ + constexpr TypeName operator+(const TypeName& a, const TypeName& b) { \ + return TypeName(static_cast<TypeName_T>(a) + static_cast<TypeName_T>(b)); \ + } \ + constexpr TypeName operator-(const TypeName& a, const TypeName& b) { \ + return TypeName(static_cast<TypeName_T>(a) - static_cast<TypeName_T>(b)); \ + } \ + constexpr TypeName operator&(const TypeName& a, const TypeName& b) { \ + return TypeName(static_cast<TypeName_T>(a) & static_cast<TypeName_T>(b)); \ + } \ + constexpr TypeName operator|(const TypeName& a, const TypeName& b) { \ + return TypeName(static_cast<TypeName_T>(a) | static_cast<TypeName_T>(b)); \ + } \ + constexpr TypeName operator^(const TypeName& a, const TypeName& b) { \ + return TypeName(static_cast<TypeName_T>(a) ^ static_cast<TypeName_T>(b)); \ + } \ + constexpr TypeName& operator++(TypeName& a) { \ + a = a + TypeName{1}; \ + return a; \ + } \ + constexpr TypeName& operator--(TypeName& a) { \ + a = a - TypeName{1}; \ + return a; \ + }; \ + constexpr TypeName operator++(TypeName& a, int) { \ + a = a + TypeName{1}; \ + return a; \ + } \ + constexpr TypeName operator--(TypeName& a, int) { \ + a = a - TypeName{1}; \ + return a; \ + }; \ + constexpr TypeName operator<<(const TypeName& a, const TypeName& b) { \ + return TypeName(static_cast<TypeName_T>(a) << static_cast<TypeName_T>(b)); \ + }; \ + constexpr TypeName operator>>(const TypeName& a, const TypeName& b) { \ + return TypeName(static_cast<TypeName_T>(a) >> static_cast<TypeName_T>(b)); \ + }; \ + constexpr TypeName operator+=(TypeName& a, const TypeName& b) { \ + a = TypeName{a + b}; \ + return a; \ + }; \ + constexpr TypeName operator-=(TypeName& a, const TypeName& b) { \ + a = TypeName{a - b}; \ + return a; \ + }; \ + constexpr TypeName operator&=(TypeName& a, const TypeName& b) { \ + a = TypeName{a & b}; \ + return a; \ + }; \ + constexpr TypeName operator|=(TypeName& a, const TypeName& b) { \ + a = TypeName{a | b}; \ + return a; \ + }; \ + constexpr TypeName operator^=(TypeName& a, const TypeName& b) { \ + a = TypeName{a ^ b}; \ + return a; \ + }; \ + constexpr TypeName operator~(const TypeName& a) { \ + return static_cast<TypeName>(~static_cast<TypeName_T>(a)); \ + }; +#define TypeSafeInt_constexpr(TypeName, Type, Max) \ + TypeSafeInt2_H_constexpr(TypeName, Type, Max, PK_CONCAT(TypeName, _T), PK_CONCAT(TypeName, _MAX), PK_CONCAT(TypeName, _T_MAX)) + +#endif /* PK_MACROS_H */ +#ifndef PK_MEM_TYPES_H +#define PK_MEM_TYPES_H + +#include <stdint.h> + +typedef uint32_t pk_handle_bucket_index_T; +typedef uint32_t pk_handle_item_index_T; + +enum PK_HANDLE_VALIDATION : uint8_t { + PK_HANDLE_VALIDATION_VALID = 0, + PK_HANDLE_VALIDATION_BUCKET_INDEX_TOO_HIGH = 1, + PK_HANDLE_VALIDATION_ITEM_INDEX_TOO_HIGH = 2, + PK_HANDLE_VALIDATION_VALUE_MAX = 3, +}; + +struct pk_handle { + pk_handle_bucket_index_T bucketIndex; + pk_handle_item_index_T itemIndex; +}; + +#define PK_HANDLE_MAX ((struct pk_handle){ .bucketIndex = 0xFFFFFFFF, .itemIndex = 0xFFFFFFFF }) + +enum PK_HANDLE_VALIDATION pk_handle_validate(const struct pk_handle handle, const struct pk_handle bucketHandle, const uint64_t maxItems); + + +#if defined(__cplusplus) + +constexpr struct pk_handle pk_handle_MAX_constexpr = (struct pk_handle){ .bucketIndex = 0xFFFFFFFF, .itemIndex = 0xFFFFFFFF }; + +inline constexpr bool +operator==(const pk_handle& lhs, const pk_handle& rhs) +{ + return lhs.bucketIndex == rhs.bucketIndex && lhs.itemIndex == rhs.itemIndex; +} + +template<const pk_handle handle, const pk_handle bucketHandle, const uint64_t maxItems> +inline constexpr enum PK_HANDLE_VALIDATION +pk_handle_validate_constexpr() +{ + if constexpr (handle == pk_handle_MAX_constexpr) + return PK_HANDLE_VALIDATION_VALUE_MAX; + if constexpr (handle.bucketIndex > bucketHandle.bucketIndex) + return PK_HANDLE_VALIDATION_BUCKET_INDEX_TOO_HIGH; + if constexpr (handle.itemIndex > maxItems) + return PK_HANDLE_VALIDATION_ITEM_INDEX_TOO_HIGH; + if constexpr (handle.bucketIndex == bucketHandle.bucketIndex && handle.itemIndex > bucketHandle.itemIndex) + return PK_HANDLE_VALIDATION_ITEM_INDEX_TOO_HIGH; + return PK_HANDLE_VALIDATION_VALID; +} +#endif /* __cplusplus */ + +struct pk_membucket; + +#endif /* PK_MEM_TYPES_H */ + +#ifdef PK_IMPL_MEM_TYPES + +enum PK_HANDLE_VALIDATION +pk_handle_validate(const struct pk_handle handle, const struct pk_handle bucketHandle, const uint64_t maxItems) +{ + if (handle.bucketIndex == PK_HANDLE_MAX.bucketIndex && handle.itemIndex == PK_HANDLE_MAX.itemIndex) + return PK_HANDLE_VALIDATION_VALUE_MAX; + if (handle.bucketIndex > bucketHandle.bucketIndex) + return PK_HANDLE_VALIDATION_BUCKET_INDEX_TOO_HIGH; + if (handle.itemIndex > maxItems) + return PK_HANDLE_VALIDATION_ITEM_INDEX_TOO_HIGH; + if (handle.bucketIndex == bucketHandle.bucketIndex && handle.itemIndex > bucketHandle.itemIndex) + return PK_HANDLE_VALIDATION_ITEM_INDEX_TOO_HIGH; + return PK_HANDLE_VALIDATION_VALID; +} + +#endif /* PK_IMPL_MEM_TYPES */ +#ifndef PK_MEM_H +#define PK_MEM_H + +#include <stdint.h> +#include <stdlib.h> + +#ifndef PK_DEFAULT_BUCKET_SIZE +# define PK_DEFAULT_BUCKET_SIZE (1ULL * 1024ULL * 1024ULL * 256ULL) +#endif +#ifndef PK_MINIMUM_ALIGNMENT +# define PK_MINIMUM_ALIGNMENT 1 +#endif +#ifndef PK_MAXIMUM_ALIGNMENT +# define PK_MAXIMUM_ALIGNMENT 64 +#endif + +struct pk_membucket* pk_bucket_create(const char* description, int64_t sz, bool transient); +void pk_bucket_destroy(struct pk_membucket* bkt); +void pk_bucket_reset(struct pk_membucket* bkt); + +void pk_memory_debug_print(); +void pk_memory_flush(); +void pk_memory_teardown_all(); +bool pk_memory_is_in_bucket(const void* ptr, const struct pk_membucket* bkt); + +void* pk_new_base(size_t sz, size_t alignment); +void* pk_new_bkt(size_t sz, size_t alignment, struct pk_membucket* bkt); +void pk_delete_base(const void* ptr, size_t sz); +void pk_delete_bkt(const void* ptr, size_t sz, struct pk_membucket* bkt); + +#if defined(__cplusplus) + +#include <type_traits> + +static inline void stupid_header_warnings_cpp() { (void)std::is_const<void>::value; } + +template <typename T> +inline T* +pk_new(pk_membucket* bucket = nullptr) +{ + void* ptr = nullptr; + if (bucket) { + ptr = pk_new_bkt(sizeof(T), alignof(T), bucket); + } else { + ptr = pk_new_base(sizeof(T), alignof(T)); + } + if IS_CONSTRUCTIBLE(T) { + return new (ptr) T{}; + } + return reinterpret_cast<T*>(ptr); +} + +template <typename T> +inline T* +pk_new(long count, pk_membucket* bucket = nullptr) +{ + char* ptr = nullptr; + if (bucket) { + ptr = static_cast<char*>(pk_new_bkt(sizeof(T) * count, alignof(T), bucket)); + } else { + ptr = static_cast<char*>(pk_new_base(sizeof(T) * count, alignof(T))); + } + if IS_CONSTRUCTIBLE(T) { + for (long i = 0; i < count; ++i) { + new (ptr + (i * sizeof(T))) T{}; + } + } + return reinterpret_cast<T*>(ptr); +} + +template <typename T> +inline void +pk_delete(const T* ptr, pk_membucket* bucket = nullptr) +{ + if IS_DESTRUCTIBLE(T) { + reinterpret_cast<const T*>(ptr)->~T(); + } + if (bucket) { + return pk_delete_bkt(static_cast<const void*>(ptr), sizeof(T), bucket); + } else { + return pk_delete_base(static_cast<const void*>(ptr), sizeof(T)); + } +} + +template <typename T> +inline void +pk_delete(const T* ptr, long count, pk_membucket* bucket = nullptr) +{ + if IS_DESTRUCTIBLE(T) { + for (long i = 0; i < count; ++i) { + reinterpret_cast<const T*>(reinterpret_cast<const char*>(ptr) + (i * sizeof(T)))->~T(); + } + } + if (bucket) { + return pk_delete_bkt(static_cast<const void*>(ptr), sizeof(T) * count, bucket); + } else { + return pk_delete_base(static_cast<const void*>(ptr), sizeof(T) * count); + } +} + +#endif /* __cplusplus */ + +#endif /* PK_MEM */ + +#ifdef PK_IMPL_MEM + +#include <string.h> +#include <stdio.h> +#include <threads.h> +#include <assert.h> + +static inline void pkmem_stupid_header_warnings() { (void)stdout; } + +#if defined(PK_MEMORY_DEBUGGER) +/* + * Note that certain aspects of this expect that you only have one non-transient bucket. + * If you need to track multiple non-transient buckets, these sections will need a refactor. + */ +#endif + +struct pk_memblock { + char* data; + size_t size; +}; + +struct pk_membucket { + // the total size of the bucket, `blocks+ptr` + int64_t size; + // the current head of the bucket: byte offset from `ptr`. + // All currently alloc'd data is before this offset + int64_t head; + // amount of lost bytes in this membucket, hopefully zero + int64_t lostBytes; + // the number of active allocations from this bucket + int64_t allocs; + // the index of the last empty block. + // Should always point to `pk_memblock{ .data = ptr+head, .size=size-head }` + int64_t lastEmptyBlockIndex; + // number of pk_memblocks in the `*blocks` array + int64_t maxBlockCount; + // ptr to an array of pk_memblock to track ALL free space between ptr and ptr+sz + struct pk_memblock* blocks; + // starting point for alloc'd data + union { + char* ptr; + void* raw; + }; + const char* description; + mtx_t mtx; + bool transient; +}; + +static struct pk_membucket pk_buckets[8]; +static int64_t pk_bucket_head = 0; + +#ifdef PK_MEMORY_DEBUGGER +struct pk_dbg_memblock { + struct pk_memblock blk; + struct pk_membucket *bkt; +}; +static struct pk_dbg_memblock debug_all_allocs[1024 * 1024]; +static int64_t debug_alloc_head = 0; +static bool has_init_debug = false; +#endif + +bool +pk_memory_is_in_bucket(const void* ptr, const struct pk_membucket* bkt) +{ + if (ptr >= bkt->raw && (const char*)ptr < bkt->ptr + bkt->size) return true; + return false; +} + +void +pk_memory_debug_print() +{ + PK_LOGV_INF("Memory Manager printout:\nBucket count: %li\n", pk_bucket_head); + for (long i = 0; i < pk_bucket_head; ++i) { + PK_LOGV_INF("- bucket #%li\n", i); + PK_LOGV_INF("\tdescription: %s\n", pk_buckets[i].description); + PK_LOGV_INF("\tsize: %li\n", pk_buckets[i].size); + PK_LOGV_INF("\thead: %li\n", pk_buckets[i].head); + PK_LOGV_INF("\tlostBytes: %li\n", pk_buckets[i].lostBytes); + PK_LOGV_INF("\tallocs: %li\n", pk_buckets[i].allocs); + PK_LOGV_INF("\tlastEmptyBlockIndex: %li\n", pk_buckets[i].lastEmptyBlockIndex); + PK_LOGV_INF("\tmaxBlockCount: %li\n", pk_buckets[i].maxBlockCount); + PK_LOGV_INF("\tblocks: %p\n", pk_buckets[i].blocks); + PK_LOGV_INF("\tptr: %p\n", pk_buckets[i].ptr); + PK_LOGV_INF("\ttransient: %i\n", pk_buckets[i].transient); +#ifdef PK_MEMORY_DEBUGGER + uint64_t count = 0; + for (int64_t d = 0; d < debug_alloc_head; ++d) { + if (debug_all_allocs[d].bkt == &pk_buckets[d] && debug_all_allocs[d].blk.size > 0) { + count += 1; + } + } + PK_LOGV_INF("\tdebug alloc count: %lu\n", count); + PK_LOGV_INF("\tdebug alloc last: %lu\n", debug_alloc_head); +#endif + } +} + +void +pk_memory_flush() +{ + for (long i = pk_bucket_head - 2; i > -1; --i) { + if (pk_buckets[i].head != 0) break; + if (pk_buckets[i+1].head != 0) break; + if (pk_buckets[i].transient == true) break; + if (pk_buckets[i+1].transient == true) break; + pk_bucket_head--; + pk_bucket_destroy(&pk_buckets[i + 1]); + } +} + +void +pk_memory_teardown_all() +{ + for (int64_t i = pk_bucket_head - 1; i > 0; --i) { + if (pk_buckets[i].ptr == nullptr) continue; + pk_bucket_destroy(&pk_buckets[i]); + } + pk_bucket_head = 0; +} + +static int64_t +pk_bucket_create_inner(int64_t sz, bool transient, const char* description) +{ +#ifdef PK_MEMORY_DEBUGGER + if (has_init_debug == false) { + has_init_debug = true; + memset(debug_all_allocs, 0, sizeof(struct pk_dbg_memblock) * 1024 * 1024); + } +#endif + int64_t blockCount = sz * 0.01; + struct pk_membucket* bkt = &pk_buckets[pk_bucket_head]; + bkt->size = sz; + bkt->head = 0; + bkt->lostBytes = 0; + bkt->allocs = 0; + bkt->lastEmptyBlockIndex = 0; + bkt->maxBlockCount = blockCount < 10 ? 10 : blockCount; + bkt->blocks = (struct pk_memblock*)malloc(sz); + assert(bkt->blocks != nullptr && "failed to allocate memory"); +#if 1 + memset(bkt->blocks, 0, sz); +#endif + bkt->ptr = ((char*)(bkt->blocks)) + (sizeof(struct pk_memblock) * bkt->maxBlockCount); + size_t misalignment = (uint64_t)(bkt->ptr) % PK_MAXIMUM_ALIGNMENT; + if (misalignment != 0) { + size_t moreBlocks = misalignment / sizeof(struct pk_memblock); + bkt->maxBlockCount += moreBlocks; + bkt->ptr += (PK_MAXIMUM_ALIGNMENT - misalignment); + } + bkt->description = description; + bkt->transient = transient; + struct pk_memblock* memBlock = (struct pk_memblock*)(bkt->blocks); + memBlock->data = bkt->ptr; + memBlock->size = sz - (sizeof(struct pk_memblock) * bkt->maxBlockCount); + return pk_bucket_head++; +} + +struct pk_membucket* +pk_bucket_create(const char* description, int64_t sz, bool transient) +{ + return &pk_buckets[pk_bucket_create_inner(sz, transient, description)]; +} + +void +pk_bucket_destroy(struct pk_membucket* bkt) +{ + int64_t i; + for (i = 0; i < pk_bucket_head; ++i) { + if (&pk_buckets[i] == bkt) { + if (pk_bucket_head == i) + pk_bucket_head--; + break; + } + } + free(bkt->blocks); + bkt->size = 0; + bkt->head = 0; + bkt->lostBytes = 0; + bkt->allocs = 0; + bkt->lastEmptyBlockIndex = -1; + bkt->maxBlockCount = 0; + bkt->blocks = CAFE_BABE(struct pk_memblock); + bkt->ptr = CAFE_BABE(char); + bkt->transient = false; +#ifdef PK_MEMORY_DEBUGGER + for (i = debug_alloc_head; i > -1; --i) { + if (debug_all_allocs[i].bkt == bkt) { + debug_all_allocs[i].blk.data = NULL; + debug_all_allocs[i].blk.size = 0u; + } + } +#endif +} + +void +pk_bucket_reset(struct pk_membucket* bkt) +{ + int64_t i; + if (bkt->transient != true) { + PK_LOG_ERR("WARNING: pk_bucket_reset called on non-transient pk_membucket\n"); + } + bkt->head = 0; + bkt->lostBytes = 0; + bkt->allocs = 0; + bkt->lastEmptyBlockIndex = 0; + bkt->blocks->data = bkt->ptr; + bkt->blocks->size = bkt->size - (sizeof(struct pk_memblock) * bkt->maxBlockCount); +#ifdef PK_MEMORY_DEBUGGER + for (i = debug_alloc_head; i > -1; --i) { + if (debug_all_allocs[i].bkt == bkt) { + debug_all_allocs[i].blk.data = NULL; + debug_all_allocs[i].blk.size = 0u; + } + } +#endif +} + +void +pk_bucket_insert_block(struct pk_membucket* bkt, const struct pk_memblock* block) +{ + int64_t index = bkt->lastEmptyBlockIndex; + while (index >= 0) { + struct pk_memblock* b = &bkt->blocks[index]; + struct pk_memblock* nb = &bkt->blocks[index + 1]; + if (b->data < block->data) { + break; + } + nb->data = b->data; + nb->size = b->size; + index -= 1; + } + struct pk_memblock *b = &bkt->blocks[index + 1]; + b->data = block->data; + b->size = block->size; + bkt->lastEmptyBlockIndex += 1; +} + +void +pk_bucket_collapse_empty_blocks(struct pk_membucket* bkt) { + for (int64_t i = bkt->lastEmptyBlockIndex; i > -1; --i) { + struct pk_memblock* block = &bkt->blocks[i]; + if (block->size == 0 && i == bkt->lastEmptyBlockIndex) { + block->data = nullptr; + bkt->lastEmptyBlockIndex -= 1; + continue; + } + if (block->size > 0) { + continue; + } + for (int64_t k = i; k < bkt->lastEmptyBlockIndex; ++k) { + bkt->blocks[k].data = bkt->blocks[k + 1].data; + bkt->blocks[k].size = bkt->blocks[k + 1].size; + } + bkt->lastEmptyBlockIndex -= 1; + } +} + +void* +pk_new_bkt(size_t sz, size_t alignment, struct pk_membucket* bkt) +{ +#ifdef PK_MEMORY_FORCE_MALLOC + return malloc(sz); +#endif + if (sz == 0) return nullptr; + size_t calculatedAlignment = alignment < PK_MINIMUM_ALIGNMENT ? PK_MINIMUM_ALIGNMENT : alignment; + size_t misalignment = 0; + struct pk_memblock* prevBlock = nullptr; + struct pk_memblock* block = nullptr; + struct pk_memblock* nextBlock = nullptr; + void* data = nullptr; + mtx_lock(&bkt->mtx); + for (int64_t i = 0; i <= bkt->lastEmptyBlockIndex; ++i) { + struct pk_memblock* blk = &bkt->blocks[i]; + misalignment = (size_t)(blk->data) % calculatedAlignment; + misalignment = (calculatedAlignment - misalignment) % calculatedAlignment; + if (blk->size >= sz + misalignment) { + block = blk; + if (i < bkt->lastEmptyBlockIndex && bkt->blocks[i + 1].data == block->data + block->size) { + nextBlock = &bkt->blocks[i + 1]; + } + if (i > 0 && i != bkt->lastEmptyBlockIndex && (bkt->blocks[i-1].data + bkt->blocks[i-1].size) == block->data) { + prevBlock = &bkt->blocks[i - 1]; + } + break; + } + } + assert(block != nullptr && "memory corruption: failed to find bucket with enough space"); + data = block->data + misalignment; +#ifdef PK_MEMORY_DEBUGGER + bool handled = bkt->transient; + if (handled == false) { + for (int64_t i = 0; i < debug_alloc_head; ++i) { + struct pk_dbg_memblock* mb = &debug_all_allocs[i]; + if (mb->bkt != NULL) continue; + assert((mb->blk.size == 0 || (void*)(mb->blk.data) != data) && "mem address alloc'd twice!"); + if (mb->blk.size == 0) { + mb->blk.data = (char*)(data); + mb->blk.size = sz; + mb->bkt = bkt; + handled = true; + break; + } + } + } + if (handled == false) { + debug_all_allocs[debug_alloc_head++] = (struct pk_dbg_memblock){ + .blk = (struct pk_memblock) { + .data = (char*)(data), + .size = sz, + }, + .bkt = bkt, + }; + } +#endif + int64_t afterSize = block->size - (misalignment + sz); + if (block->data == bkt->ptr + bkt->head) { + bkt->head += (sz + misalignment); + } + if (afterSize > 0 && nextBlock == nullptr) { + struct pk_memblock newBlock; + memset(&newBlock, 0, sizeof(struct pk_memblock)); + newBlock.data = block->data + misalignment + sz; + newBlock.size = afterSize; + pk_bucket_insert_block(bkt, &newBlock); + } + if (prevBlock == nullptr && nextBlock == nullptr) { + block->size = misalignment; + } else if (nextBlock != nullptr) { + block->size = misalignment; + nextBlock->data -= afterSize; + nextBlock->size += afterSize; + } else if (prevBlock != nullptr) { + prevBlock->size += misalignment; + block->data += misalignment + sz; + block->size = 0; // if you make it here, afterSize has already been handled + } + bkt->allocs++; + assert(data >= bkt->raw && "allocated data is before bucket data"); + assert((char*)data <= bkt->ptr + bkt->size && "allocated data is after bucket data"); + pk_bucket_collapse_empty_blocks(bkt); +#ifdef PK_MEMORY_DEBUGGER + if (!bkt->transient) { + int64_t debug_tracked_alloc_size = 0; + int64_t debug_bucket_alloc_size = bkt->size - (sizeof(struct pk_memblock) * bkt->maxBlockCount); + for (int64_t i = 0; i < debug_alloc_head; ++i) { + if (debug_all_allocs[i].bkt != bkt) continue; + debug_tracked_alloc_size += debug_all_allocs[i].blk.size; + } + for (int64_t i = 0; i <= bkt->lastEmptyBlockIndex; ++i) { + debug_bucket_alloc_size -= bkt->blocks[i].size; + } + assert(debug_tracked_alloc_size == debug_bucket_alloc_size && "allocation size mismatch!"); + } +#endif + mtx_unlock(&bkt->mtx); + return data; +} + +void* +pk_new_base(size_t sz, size_t alignment) +{ + struct pk_membucket* bkt = nullptr; + for (long i = 0; i < pk_bucket_head; ++i) { + if (pk_buckets[i].transient == false && pk_buckets[i].size - pk_buckets[i].head > sz + PK_MAXIMUM_ALIGNMENT) { + bkt = &pk_buckets[i]; + break; + } + } + if (bkt == nullptr) { + bkt = &pk_buckets[pk_bucket_create_inner(PK_DEFAULT_BUCKET_SIZE, false, "pk_bucket internally created")]; + } + return pk_new_bkt(sz, alignment, bkt); +} + +void +pk_delete_bkt(const void* ptr, size_t sz, struct pk_membucket* bkt) +{ +#ifdef PK_MEMORY_FORCE_MALLOC + return std::free(const_cast<void*>(ptr)); +#endif + mtx_lock(&bkt->mtx); + assert(ptr >= bkt->raw && (char*)ptr < bkt->ptr + bkt->size && "pointer not in memory bucket range"); + assert(sz > 0 && "attempted to free pointer of size 0"); +#ifdef PK_MEMORY_DEBUGGER + bool found = bkt->transient; + if (found == false) { + for (int64_t i = debug_alloc_head - 1; i > -1; --i) { + struct pk_dbg_memblock* mb = &debug_all_allocs[i]; + if (mb->bkt != bkt) continue; + if (mb->blk.size == 0) continue; + if ((void*)(mb->blk.data) == ptr) { + assert(mb->blk.size == sz && "[PK_MEMORY_HPP] incorrect free size"); + mb->blk.size = 0; + mb->bkt = NULL; + found = true; + if (i == (debug_alloc_head - 1)) { + debug_alloc_head--; + } + break; + } + } + } + assert(found && "[PK_MEMORY_HPP] double free or invalid ptr"); +#endif + bkt->allocs--; + if (bkt->allocs == 0) { + bkt->head = 0; + bkt->lastEmptyBlockIndex = 0; + bkt->blocks[0].data = bkt->ptr; + bkt->blocks[0].size = bkt->size - (sizeof(struct pk_memblock) * bkt->maxBlockCount); + return; + } + char* afterPtr = ((char*)(ptr))+sz; + struct pk_memblock* beforeBlk = nullptr; + struct pk_memblock* afterBlk = nullptr; + for (int64_t i = bkt->lastEmptyBlockIndex; i > 0; --i) { + if (bkt->blocks[i-1].data + bkt->blocks[i-1].size == ptr) { + beforeBlk = &bkt->blocks[i-1]; + } + if (bkt->blocks[i].data == afterPtr) { + afterBlk = &bkt->blocks[i]; + break; + } + if (bkt->blocks[i-1].data < (char*)ptr) { + break; + } + } + if (ptr == bkt->ptr && afterBlk == nullptr && bkt->blocks[0].data == afterPtr) { + afterBlk = &bkt->blocks[0]; + } + if (afterBlk != nullptr && afterBlk->data == bkt->ptr + bkt->head) { + bkt->head -= sz; + if (beforeBlk != nullptr) { + bkt->head -= beforeBlk->size; + } + } + if (beforeBlk == nullptr && afterBlk == nullptr) { + struct pk_memblock newBlock; + memset(&newBlock, 0, sizeof(struct pk_memblock)); + newBlock.data = (char*)ptr; + newBlock.size = sz; + pk_bucket_insert_block(bkt, &newBlock); + } else if (beforeBlk != nullptr && afterBlk != nullptr) { + beforeBlk->size += sz + afterBlk->size; + afterBlk->size = 0; + } else if (beforeBlk != nullptr) { + beforeBlk->size += sz; + } else if (afterBlk != nullptr) { + afterBlk->data -= sz; + afterBlk->size += sz; + } + pk_bucket_collapse_empty_blocks(bkt); +#ifdef PK_MEMORY_DEBUGGER + if (!bkt->transient) { + int64_t debug_tracked_alloc_size = 0; + int64_t debug_bucket_alloc_size = bkt->size - (sizeof(struct pk_memblock) * bkt->maxBlockCount); + for (int64_t i = 0; i < debug_alloc_head; ++i) { + if (debug_all_allocs[i].bkt != bkt) continue; + debug_tracked_alloc_size += debug_all_allocs[i].blk.size; + } + for (int64_t i = 0; i <= bkt->lastEmptyBlockIndex; ++i) { + debug_bucket_alloc_size -= bkt->blocks[i].size; + } + assert(debug_tracked_alloc_size == debug_bucket_alloc_size && "allocation size mismatch!"); + } +#endif + mtx_unlock(&bkt->mtx); +} + +void +pk_delete_base(const void* ptr, size_t sz) +{ + struct pk_membucket* bkt = nullptr; + for (long i = 0; i < pk_bucket_head; ++i) { + bkt = &pk_buckets[i]; + if (ptr >= bkt->raw && (char*)ptr < bkt->ptr + bkt->size) break; + } + assert(bkt != nullptr && "failed to determine correct memory bucket"); + pk_delete_bkt(ptr, sz, bkt); +} + +#endif /* PK_IMPL_MEM */ +#ifndef PK_STR_H +#define PK_STR_H + +#include <stdint.h> + +struct pk_str { + char *val; + uint32_t length; + uint32_t reserved; +}; +struct pk_cstr { + const char *val; + uint32_t length; + uint32_t reserved; +}; + +struct pk_str cstring_to_pk_str(char *s); +struct pk_cstr cstring_to_pk_cstr(const char *s); +struct pk_str pk_cstr_to_pk_str(const struct pk_cstr *s); +struct pk_cstr pk_str_to_pk_cstr(const struct pk_str *s); +int pk_compare_str(const struct pk_str *lhs, const struct pk_str *rhs); +int pk_compare_cstr(const struct pk_cstr *lhs, const struct pk_cstr *rhs); + +#endif /* PK_STR_H */ + +#ifdef PK_IMPL_STR + +#include <string.h> + +struct pk_str +cstring_to_pk_str(char *s) +{ + return (struct pk_str) { + .val = s, + .length = (uint32_t)(strlen(s)), + .reserved = 0, + }; +} + +struct pk_cstr +cstring_to_pk_cstr(const char *s) +{ + return (struct pk_cstr) { + .val = s, + .length = (uint32_t)(strlen(s)), + .reserved = 0, + }; +} + +struct pk_str +pk_cstr_to_pk_str(const struct pk_cstr *s) +{ + return (struct pk_str) { + .val = (char *)(s->val), + .length = s->length, + .reserved = s->reserved, + }; +} + +struct pk_cstr +pk_str_to_pk_cstr(const struct pk_str *s) +{ + return (struct pk_cstr) { + .val = (char *)(s->val), + .length = s->length, + .reserved = s->reserved, + }; +} + +int +pk_compare_str(const struct pk_str *lhs, const struct pk_str *rhs) +{ + return strncmp(lhs->val, rhs->val, PK_MIN(lhs->length, rhs->length)); +} + +int +pk_compare_cstr(const struct pk_cstr *lhs, const struct pk_cstr *rhs) +{ + return strncmp(lhs->val, rhs->val, PK_MIN(lhs->length, rhs->length)); +} + +#endif /* PK_IMPL_STR */ +#ifndef PK_EV_H +#define PK_EV_H + +#include <stdint.h> + +typedef uint64_t pk_ev_mgr_id_T; +typedef uint64_t pk_ev_id_T; + +// note: pk_ev_init() is NOT thread-safe +void pk_ev_init(); +// note: pk_ev_teardown() is NOT thread-safe +void pk_ev_teardown(); + +const pk_ev_mgr_id_T pk_ev_create_mgr(); +void pk_ev_destroy_mgr(pk_ev_mgr_id_T evmgr); + +typedef void (pk_ev_cb_fn)(void *user_event_data, void *user_cb_data, void *user_ev_data); + +const pk_ev_id_T pk_ev_register_ev(pk_ev_mgr_id_T evmgr, void *user_ev_data); +bool pk_ev_register_cb(pk_ev_mgr_id_T evmgr, pk_ev_id_T evid, pk_ev_cb_fn *cb, void *user_cb_data); +void pk_ev_emit(pk_ev_mgr_id_T evmgr, pk_ev_id_T evid, void *user_emit_data); + +#endif /* PK_EV_H */ + +#ifdef PK_IMPL_EV + +#include <assert.h> +#include <stdatomic.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <threads.h> +#include <string.h> + +#ifndef PK_EV_INIT_MGR_COUNT +# define PK_EV_INIT_MGR_COUNT 1 +#endif + +#ifndef PK_EV_INIT_EV_COUNT +# define PK_EV_INIT_EV_COUNT 16 +#endif + +#ifndef PK_EV_INIT_CB_COUNT +# define PK_EV_INIT_CB_COUNT 8 +#endif + +#ifndef PK_EV_GROW_RATIO +# define PK_EV_GROW_RATIO 1.5 +#endif + +struct pk_ev_cb { + pk_ev_cb_fn *cb; + void *user_cb_data; +}; + +struct pk_ev { + struct pk_ev_cb *ev_cbs; + void *user_ev_data; + atomic_uint_fast8_t n_ev_cbs; +}; + +struct pk_ev_mgr { + struct pk_ev *ev; + atomic_uint_fast8_t n_ev; + atomic_uint_fast8_t rn_ev; + atomic_uint_fast8_t rn_cb; +}; + +struct pk_ev_mstr { + atomic_uint_fast64_t flg_mgrs; + atomic_uint_fast64_t rn_mgrs; + struct pk_ev_mgr **mgrs; + mtx_t *mtxs; +}; + +struct pk_ev_mstr pk_ev_mstr; + +void +pk_ev_init() +{ + int i; + pk_ev_mstr.mgrs = (struct pk_ev_mgr **)malloc(sizeof(void *) * PK_EV_INIT_MGR_COUNT); + pk_ev_mstr.mtxs = (mtx_t*)malloc(sizeof(mtx_t) * PK_EV_INIT_MGR_COUNT); + memset(pk_ev_mstr.mgrs, 0, sizeof(void *) * PK_EV_INIT_MGR_COUNT); + memset(pk_ev_mstr.mtxs, 0, sizeof(mtx_t) * PK_EV_INIT_MGR_COUNT); + for (i = 0; i < PK_EV_INIT_MGR_COUNT; ++i) { + mtx_init(&pk_ev_mstr.mtxs[i], mtx_plain); + } + atomic_store(&pk_ev_mstr.flg_mgrs, 0); + atomic_store(&pk_ev_mstr.rn_mgrs, PK_EV_INIT_MGR_COUNT); +} + +void +pk_ev_teardown() +{ + int i; + for (i = 0; i < pk_ev_mstr.rn_mgrs; ++i) { + if ((atomic_load(&pk_ev_mstr.rn_mgrs) & (1lu << i)) == 0) continue; + mtx_lock(&pk_ev_mstr.mtxs[i]); + free(pk_ev_mstr.mgrs[i]); + pk_ev_mstr.mgrs[i] = NULL; + mtx_unlock(&pk_ev_mstr.mtxs[i]); + mtx_destroy(&pk_ev_mstr.mtxs[i]); + } + free(pk_ev_mstr.mgrs); + free(pk_ev_mstr.mtxs); + pk_ev_mstr.mgrs = NULL; + pk_ev_mstr.mtxs = NULL; +} + +static struct pk_ev_mgr* +pk_ev_inner_ev_mgr_create(uint64_t ev_count, uint64_t cb_count) +{ + int i; + struct pk_ev *ev; + size_t sz = sizeof(struct pk_ev_mgr) + ((sizeof(struct pk_ev) * ev_count)) + (sizeof (struct pk_ev_cb) * ev_count * cb_count); + size_t sz_ev = (sizeof(struct pk_ev_cb) * cb_count); + size_t sz_evs = sizeof(struct pk_ev) * ev_count; + + struct pk_ev_mgr *mgr = (struct pk_ev_mgr*)malloc(sz); + if (mgr == NULL) goto early_exit; + + memset(mgr, 0, sz); + mgr->ev = (struct pk_ev*)(((char *)mgr) + sizeof(struct pk_ev_mgr)); + atomic_init(&mgr->rn_ev, ev_count); + atomic_init(&mgr->rn_cb, cb_count); + atomic_init(&mgr->n_ev, 0); + for (i = 0; i < mgr->rn_ev; ++i) { + ev = &mgr->ev[i]; + atomic_init(&ev->n_ev_cbs, 0); + ev->ev_cbs = (struct pk_ev_cb*)(((char *)mgr) + sizeof(struct pk_ev_mgr) + sz_evs + (sz_ev * i)); + } + +early_exit: + return mgr; +} + +static void +pk_ev_inner_ev_mgr_clone(struct pk_ev_mgr *old, struct pk_ev_mgr *mgr) +{ + int i; + struct pk_ev *ev_old; + struct pk_ev *ev; + atomic_store(&mgr->n_ev, atomic_load(&old->n_ev)); + for (i = 0; i < old->n_ev; ++i) { + ev_old = &old->ev[i]; + ev = &mgr->ev[i]; + memcpy(ev->ev_cbs, ev_old->ev_cbs, sizeof(struct pk_ev_cb) * atomic_load(&ev_old->n_ev_cbs)); + atomic_store(&ev->n_ev_cbs, atomic_load(&ev_old->n_ev_cbs)); + } +} + +const pk_ev_mgr_id_T +pk_ev_create_mgr() +{ + uint64_t i; + pk_ev_mgr_id_T flg; + pk_ev_mgr_id_T flg_new; + pk_ev_mgr_id_T id; + struct pk_ev_mgr *mgr = pk_ev_inner_ev_mgr_create(PK_EV_INIT_EV_COUNT, PK_EV_INIT_CB_COUNT); + if (mgr == NULL) return -1; +start: + flg = atomic_load(&pk_ev_mstr.flg_mgrs); + while (1) { + flg_new = flg; + for (i = 0; i < atomic_load(&pk_ev_mstr.rn_mgrs); ++i) { + if ((flg & (1u << i)) == 0) break; + } + if (i == atomic_load(&pk_ev_mstr.rn_mgrs)) { + goto recreate; + } + id = i; + flg_new |= (1u << i); + if (atomic_compare_exchange_strong(&pk_ev_mstr.flg_mgrs, &flg, flg_new)) break; + thrd_yield(); + } + pk_ev_mstr.mgrs[id]= mgr; + return id; +recreate: + // TODO recreate mgr, out of space + assert(1 == 0 && "[pkev.h] Out of mgr space."); + exit(1); + goto start; +} + +void +pk_ev_destroy_mgr(pk_ev_mgr_id_T evmgr) +{ + assert(evmgr >= 0); + mtx_lock(&pk_ev_mstr.mtxs[evmgr]); + free(pk_ev_mstr.mgrs[evmgr]); + pk_ev_mstr.mgrs[evmgr] = NULL; + mtx_unlock(&pk_ev_mstr.mtxs[evmgr]); +} + +const pk_ev_id_T +pk_ev_register_ev(pk_ev_mgr_id_T evmgr, void *user_ev_data) +{ + assert(evmgr < 64); + pk_ev_id_T id; + struct pk_ev_mgr *mgr; + mtx_lock(&pk_ev_mstr.mtxs[evmgr]); + if (pk_ev_mstr.mgrs[evmgr]->n_ev == pk_ev_mstr.mgrs[evmgr]->rn_ev) { + mgr = pk_ev_inner_ev_mgr_create(pk_ev_mstr.mgrs[evmgr]->rn_ev * PK_EV_GROW_RATIO, pk_ev_mstr.mgrs[evmgr]->rn_cb); + pk_ev_inner_ev_mgr_clone(pk_ev_mstr.mgrs[evmgr], mgr); + free(pk_ev_mstr.mgrs[evmgr]); + pk_ev_mstr.mgrs[evmgr] = mgr; + } + id = pk_ev_mstr.mgrs[evmgr]->n_ev++; + pk_ev_mstr.mgrs[evmgr]->ev[id].user_ev_data = user_ev_data; + mtx_unlock(&pk_ev_mstr.mtxs[evmgr]); + return id; +} + +bool +pk_ev_register_cb(pk_ev_mgr_id_T evmgr, pk_ev_id_T evid, pk_ev_cb_fn *cb, void *user_cb_data) +{ + assert(evmgr < 64); + struct pk_ev_mgr *mgr; + uint8_t cb_index; + mtx_lock(&pk_ev_mstr.mtxs[evmgr]); + if (pk_ev_mstr.mgrs[evmgr]->ev[evid].n_ev_cbs == pk_ev_mstr.mgrs[evmgr]->rn_cb) { + mgr = pk_ev_inner_ev_mgr_create(pk_ev_mstr.mgrs[evmgr]->rn_ev, pk_ev_mstr.mgrs[evmgr]->rn_cb * PK_EV_GROW_RATIO); + pk_ev_inner_ev_mgr_clone(pk_ev_mstr.mgrs[evmgr], mgr); + free(pk_ev_mstr.mgrs[evmgr]); + pk_ev_mstr.mgrs[evmgr] = mgr; + } + cb_index = pk_ev_mstr.mgrs[evmgr]->ev[evid].n_ev_cbs++; + pk_ev_mstr.mgrs[evmgr]->ev[evid].ev_cbs[cb_index].cb = cb; + pk_ev_mstr.mgrs[evmgr]->ev[evid].ev_cbs[cb_index].user_cb_data = user_cb_data; + mtx_unlock(&pk_ev_mstr.mtxs[evmgr]); + return true; +} + +void +pk_ev_emit(pk_ev_mgr_id_T evmgr, pk_ev_id_T evid, void *user_emit_data) +{ + assert(evmgr < 64); + uint8_t i; + for (i = 0; i < pk_ev_mstr.mgrs[evmgr]->ev[evid].n_ev_cbs; ++i) { + (*pk_ev_mstr.mgrs[evmgr]->ev[evid].ev_cbs[i].cb)( + pk_ev_mstr.mgrs[evmgr]->ev[evid].user_ev_data, + pk_ev_mstr.mgrs[evmgr]->ev[evid].ev_cbs[i].user_cb_data, + user_emit_data); + } +} + +#endif /* PK_IMPL_EV */ +#endif /* PK_SINGLE_HEADER_FILE_H */ diff --git a/src/vendor/pkh_include.cpp b/src/vendor/pkh_include.cpp new file mode 100644 index 0000000..0d72dcb --- /dev/null +++ b/src/vendor/pkh_include.cpp @@ -0,0 +1,5 @@ + +#define PK_MEMORY_DEBUGGER +#define PK_IMPL_ALL + +#include "./pk.h" diff --git a/src/window.cpp b/src/window.cpp index db817e6..c7963eb 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -12,7 +12,6 @@ #include "event.hpp" #include "game-settings.hpp" #include "helpers.hpp" -#include "memory.hpp" #include "plugins.hpp" #include "static/cube.hpp" #include "window-types.hpp" @@ -23,7 +22,7 @@ #include <cstdint> #include <fstream> -MemBucket *MemBkt_Vulkan = nullptr; +struct pk_membucket *MemBkt_Vulkan = nullptr; struct pke_vkAllocData { void *data; std::size_t size; @@ -218,7 +217,7 @@ unsigned int FindQueueFamilyIndex(VkPhysicalDevice device, short hasPresentSuppo unsigned int queueFamilyPropertyCount = 0U; vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyPropertyCount, nullptr); - auto *queueFamilyProperties = Pke_New<VkQueueFamilyProperties>(queueFamilyPropertyCount); + auto *queueFamilyProperties = pk_new<VkQueueFamilyProperties>(queueFamilyPropertyCount); vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyPropertyCount, queueFamilyProperties); for (unsigned int i = 0; i < queueFamilyPropertyCount; i++) { @@ -236,11 +235,11 @@ unsigned int FindQueueFamilyIndex(VkPhysicalDevice device, short hasPresentSuppo continue; } } - Pke_Delete<VkQueueFamilyProperties>(queueFamilyProperties, queueFamilyPropertyCount); + pk_delete<VkQueueFamilyProperties>(queueFamilyProperties, queueFamilyPropertyCount); return i; } - Pke_Delete<VkQueueFamilyProperties>(queueFamilyProperties, queueFamilyPropertyCount); + pk_delete<VkQueueFamilyProperties>(queueFamilyProperties, queueFamilyPropertyCount); return 0xFFFFFFFF; } @@ -258,7 +257,7 @@ void PKE_vkFreeFunction(void *pUserData, void *pMemory) { } if (chunk != nullptr) { assert(chunk != nullptr); - Pke_Delete(chunk->data, chunk->size, MemBkt_Vulkan); + pk_delete_bkt(chunk->data, chunk->size, MemBkt_Vulkan); vulkanAllocs->Remove(index); } else { fprintf(stderr, "%s\n", "PKE_vkFreeFunction - untracked pointer"); @@ -269,7 +268,7 @@ void *PKE_vkAllocateFunction(void *pUserData, size_t size, size_t alignment, VkS if (size == 0) { return nullptr; } - void *ptr = Pke_New(size, alignment, MemBkt_Vulkan); + void *ptr = pk_new_bkt(size, alignment, MemBkt_Vulkan); vulkanAllocs->Push({ .data = ptr, .size = size, @@ -303,7 +302,7 @@ void *PKE_vkReallocationFunction(void *pUserData, void *pOriginal, size_t size, void *newPtr = PKE_vkAllocateFunction(pUserData, size, alignment, allocScope); if (chunk != nullptr) { memcpy(newPtr, chunk->data, (chunk->size < size ? chunk->size : size) - 1); - Pke_Delete(chunk->data, chunk->size, MemBkt_Vulkan); + pk_delete_bkt(chunk->data, chunk->size, MemBkt_Vulkan); vulkanAllocs->Remove(index); } else { @@ -320,7 +319,7 @@ void PKE_vkInternalFreeNotification(void *pUserData, size_t size, VkInternalAllo } void InitVulkan() { - vkAllocator = Pke_New<VkAllocationCallbacks>(MemBkt_Vulkan); + vkAllocator = pk_new<VkAllocationCallbacks>(MemBkt_Vulkan); vkAllocator->pUserData = nullptr; vkAllocator->pfnAllocation = PKE_vkAllocateFunction; vkAllocator->pfnReallocation = PKE_vkReallocationFunction; @@ -333,14 +332,14 @@ void InitVulkan() { unsigned int layerCount; vkResult = vkEnumerateInstanceLayerProperties(&layerCount, nullptr); assert(vkResult == VK_SUCCESS); - VkLayerProperties *availableLayerProperties = Pke_New<VkLayerProperties>(layerCount); + VkLayerProperties *availableLayerProperties = pk_new<VkLayerProperties>(layerCount); vkResult = vkEnumerateInstanceLayerProperties(&layerCount, availableLayerProperties); assert(vkResult == VK_SUCCESS); printf("Available Layers:\n"); for (long i = 0; i < layerCount; ++i) { printf("\t%s\n", availableLayerProperties[i].layerName); } - Pke_Delete<VkLayerProperties>(availableLayerProperties, layerCount); + pk_delete<VkLayerProperties>(availableLayerProperties, layerCount); } VkApplicationInfo appInfo; @@ -410,14 +409,14 @@ void InitVulkan() { unsigned int extensionCount = 0; vkResult = vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr); assert(vkResult == VK_SUCCESS); - auto *extensions = Pke_New<VkExtensionProperties>(extensionCount); + auto *extensions = pk_new<VkExtensionProperties>(extensionCount); vkResult = vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions); assert(vkResult == VK_SUCCESS); printf("Available Extensions:\n"); for (long i = 0; i < extensionCount; ++i) { printf("\t%s\n", extensions[i].extensionName); } - Pke_Delete<VkExtensionProperties>(extensions, extensionCount); + pk_delete<VkExtensionProperties>(extensions, extensionCount); } vkResult = vkCreateInstance(&createInfo, vkAllocator, &vkInstance); @@ -457,7 +456,7 @@ void InitVulkan() { vkResult = vkEnumeratePhysicalDevices(vkInstance, &physicalDeviceCount, nullptr); assert(vkResult == VK_SUCCESS); assert(physicalDeviceCount > 0); - auto *physicalDevices = Pke_New<VkPhysicalDevice>(physicalDeviceCount); + auto *physicalDevices = pk_new<VkPhysicalDevice>(physicalDeviceCount); vkResult = vkEnumeratePhysicalDevices(vkInstance, &physicalDeviceCount, physicalDevices); assert(vkResult == VK_SUCCESS); graphicsFamilyIndex = 0; @@ -477,7 +476,7 @@ void InitVulkan() { unsigned int extensionCount = 0; vkResult = vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr); assert(vkResult == VK_SUCCESS); - auto *extensionProperties = Pke_New<VkExtensionProperties>(extensionCount); + auto *extensionProperties = pk_new<VkExtensionProperties>(extensionCount); vkResult = vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, extensionProperties); assert(vkResult == VK_SUCCESS); for (long k = 0; k < extensionCount; ++k) { @@ -491,7 +490,7 @@ void InitVulkan() { } } } - Pke_Delete<VkExtensionProperties>(extensionProperties, extensionCount); + pk_delete<VkExtensionProperties>(extensionProperties, extensionCount); if (requiredExtensions.empty() == false) { continue; } @@ -520,7 +519,7 @@ void InitVulkan() { break; } assert(vkPhysicalDevice != nullptr && "Failed to find suitable physical device"); - Pke_Delete<VkPhysicalDevice>(physicalDevices, physicalDeviceCount); + pk_delete<VkPhysicalDevice>(physicalDevices, physicalDeviceCount); // Create logical device { @@ -694,7 +693,7 @@ void CreateSwapchain() { unsigned int surfaceFormatCounts; vkResult = vkGetPhysicalDeviceSurfaceFormatsKHR(vkPhysicalDevice, vkSurfaceKHR, &surfaceFormatCounts, nullptr); assert(vkResult == VK_SUCCESS); - VkSurfaceFormatKHR *surfaceFormats = Pke_New<VkSurfaceFormatKHR>(surfaceFormatCounts); + VkSurfaceFormatKHR *surfaceFormats = pk_new<VkSurfaceFormatKHR>(surfaceFormatCounts); vkResult = vkGetPhysicalDeviceSurfaceFormatsKHR(vkPhysicalDevice, vkSurfaceKHR, &surfaceFormatCounts, surfaceFormats); assert(vkResult == VK_SUCCESS); selectedSurfaceIndex = 0; @@ -707,7 +706,7 @@ void CreateSwapchain() { break; } - Pke_Delete<VkSurfaceFormatKHR>(surfaceFormats, surfaceFormatCounts); + pk_delete<VkSurfaceFormatKHR>(surfaceFormats, surfaceFormatCounts); } int width, height; @@ -725,7 +724,7 @@ void CreateSwapchain() { unsigned int presentModeCount = 0; vkResult = vkGetPhysicalDeviceSurfacePresentModesKHR(vkPhysicalDevice, vkSurfaceKHR, &presentModeCount, nullptr); assert(vkResult == VK_SUCCESS); - VkPresentModeKHR *presentModes = Pke_New<VkPresentModeKHR>(presentModeCount); + VkPresentModeKHR *presentModes = pk_new<VkPresentModeKHR>(presentModeCount); vkResult = vkGetPhysicalDeviceSurfacePresentModesKHR(vkPhysicalDevice, vkSurfaceKHR, &presentModeCount, presentModes); assert(vkResult == VK_SUCCESS); uint32_t immediateIndex = -1; @@ -762,7 +761,7 @@ void CreateSwapchain() { if (immediateIndex != -1) { vkPresentModeKHR = VK_PRESENT_MODE_IMMEDIATE_KHR; } - Pke_Delete<VkPresentModeKHR>(presentModes, presentModeCount); + pk_delete<VkPresentModeKHR>(presentModes, presentModeCount); } VkSwapchainCreateInfoKHR vkSwapchainCreateInfo; @@ -831,10 +830,10 @@ void CreateSwapchain() { vkResult = vkGetSwapchainImagesKHR(vkDevice, vkSwapchainKHR, &swapchainLength, nullptr); assert(vkResult == VK_SUCCESS); - swapchainImages = Pke_New<VkImage>(swapchainLength); + swapchainImages = pk_new<VkImage>(swapchainLength); vkResult = vkGetSwapchainImagesKHR(vkDevice, vkSwapchainKHR, &swapchainLength, swapchainImages); assert(vkResult == VK_SUCCESS); - swapchainImageViews = Pke_New<VkImageView>(swapchainLength); + swapchainImageViews = pk_new<VkImageView>(swapchainLength); for (long i = 0; i < swapchainLength; ++i) { vkImageViewCreateInfo.image = swapchainImages[i]; vkResult = vkCreateImageView(vkDevice, &vkImageViewCreateInfo, vkAllocator, &swapchainImageViews[i]); @@ -863,20 +862,20 @@ void CreateSwapchain() { renderTargetImageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; // render images - renderImages = Pke_New<VkImage>(MAX_FRAMES_IN_FLIGHT); - renderImageViews = Pke_New<VkImageView>(MAX_FRAMES_IN_FLIGHT); + renderImages = pk_new<VkImage>(MAX_FRAMES_IN_FLIGHT); + renderImageViews = pk_new<VkImageView>(MAX_FRAMES_IN_FLIGHT); CreateImageResources_Inner(&renderTargetImageCI, &vkImageViewCreateInfo, VkBufferUsageFlagBits(0), nullptr, renderImages, renderImageViews, &renderImagesMemory); // color images - colorImages = Pke_New<VkImage>(MAX_FRAMES_IN_FLIGHT); - colorImageViews = Pke_New<VkImageView>(MAX_FRAMES_IN_FLIGHT); + colorImages = pk_new<VkImage>(MAX_FRAMES_IN_FLIGHT); + colorImageViews = pk_new<VkImageView>(MAX_FRAMES_IN_FLIGHT); renderTargetImageCI.samples = renderSampleCount; renderTargetImageCI.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; CreateImageResources_Inner(&renderTargetImageCI, &vkImageViewCreateInfo, VkBufferUsageFlagBits(0), nullptr, colorImages, colorImageViews, &colorImagesMemory); // depth images - depthImages = Pke_New<VkImage>(MAX_FRAMES_IN_FLIGHT); - depthImageViews = Pke_New<VkImageView>(MAX_FRAMES_IN_FLIGHT); + depthImages = pk_new<VkImage>(MAX_FRAMES_IN_FLIGHT); + depthImageViews = pk_new<VkImageView>(MAX_FRAMES_IN_FLIGHT); renderTargetImageCI.format = depthFormat; vkImageViewCreateInfo.format = depthFormat; renderTargetImageCI.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; @@ -1306,8 +1305,8 @@ void CreatePresentPipeline() { void CreateFramebuffers() { assert(swapchainFramebuffers == nullptr || swapchainFramebuffers == CAFE_BABE(VkFramebuffer)); assert(renderImageFramebuffers == nullptr || renderImageFramebuffers == CAFE_BABE(VkFramebuffer)); - swapchainFramebuffers = Pke_New<VkFramebuffer>(swapchainLength); - renderImageFramebuffers = Pke_New<VkFramebuffer>(swapchainLength); + swapchainFramebuffers = pk_new<VkFramebuffer>(swapchainLength); + renderImageFramebuffers = pk_new<VkFramebuffer>(swapchainLength); VkFramebufferCreateInfo framebufferInfo; framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; @@ -2183,7 +2182,7 @@ void UpdateDebugGraphicsPipeline() { vkDescriptorSetAllocateInfo.descriptorSetCount = MAX_FRAMES_IN_FLIGHT; vkDescriptorSetAllocateInfo.pSetLayouts = descriptorSets; - pkeDebugHitbox.vkDescriptorSets = Pke_New<VkDescriptorSet>(MAX_FRAMES_IN_FLIGHT); + pkeDebugHitbox.vkDescriptorSets = pk_new<VkDescriptorSet>(MAX_FRAMES_IN_FLIGHT); for (long i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) { pkeDebugHitbox.vkDescriptorSets[i] = VkDescriptorSet{}; } @@ -2474,14 +2473,14 @@ void DestroySwapchain() { for (long i = 0; i < swapchainLength; ++i) { vkDestroyFramebuffer(vkDevice, renderImageFramebuffers[i], vkAllocator); } - Pke_Delete<VkFramebuffer>(renderImageFramebuffers, swapchainLength); + pk_delete<VkFramebuffer>(renderImageFramebuffers, swapchainLength); renderImageFramebuffers = CAFE_BABE(VkFramebuffer); } if (swapchainFramebuffers != nullptr && swapchainFramebuffers != CAFE_BABE(VkFramebuffer)) { for (long i = 0; i < swapchainLength; ++i) { vkDestroyFramebuffer(vkDevice, swapchainFramebuffers[i], vkAllocator); } - Pke_Delete<VkFramebuffer>(swapchainFramebuffers, swapchainLength); + pk_delete<VkFramebuffer>(swapchainFramebuffers, swapchainLength); swapchainFramebuffers = CAFE_BABE(VkFramebuffer); } if (renderImageViews!= nullptr && renderImageViews != CAFE_BABE(VkImageView)) { @@ -2495,17 +2494,17 @@ void DestroySwapchain() { vkDestroyImageView(vkDevice, renderImageViews[i], vkAllocator); vkDestroyImage(vkDevice, renderImages[i], vkAllocator); } - Pke_Delete<VkImageView>(depthImageViews, swapchainLength); + pk_delete<VkImageView>(depthImageViews, swapchainLength); depthImageViews = CAFE_BABE(VkImageView); - Pke_Delete<VkImage>(depthImages, swapchainLength); + pk_delete<VkImage>(depthImages, swapchainLength); depthImages = CAFE_BABE(VkImage); - Pke_Delete<VkImageView>(colorImageViews, swapchainLength); + pk_delete<VkImageView>(colorImageViews, swapchainLength); colorImageViews = CAFE_BABE(VkImageView); - Pke_Delete<VkImage>(colorImages, swapchainLength); + pk_delete<VkImage>(colorImages, swapchainLength); colorImages = CAFE_BABE(VkImage); - Pke_Delete<VkImageView>(renderImageViews, swapchainLength); + pk_delete<VkImageView>(renderImageViews, swapchainLength); renderImageViews = CAFE_BABE(VkImageView); - Pke_Delete<VkImage>(renderImages, swapchainLength); + pk_delete<VkImage>(renderImages, swapchainLength); renderImages = CAFE_BABE(VkImage); vkFreeMemory(vkDevice, depthImagesMemory, vkAllocator); vkFreeMemory(vkDevice, colorImagesMemory, vkAllocator); @@ -2515,9 +2514,9 @@ void DestroySwapchain() { for (long i = 0; i < swapchainLength; ++i) { vkDestroyImageView(vkDevice, swapchainImageViews[i], vkAllocator); } - Pke_Delete<VkImageView>(swapchainImageViews, swapchainLength); + pk_delete<VkImageView>(swapchainImageViews, swapchainLength); swapchainImageViews = CAFE_BABE(VkImageView); - Pke_Delete<VkImage>(swapchainImages, swapchainLength); + pk_delete<VkImage>(swapchainImages, swapchainLength); swapchainImages = CAFE_BABE(VkImage); } vkDestroySwapchainKHR(vkDevice, vkSwapchainKHR, vkAllocator); @@ -2568,8 +2567,8 @@ void FramebufferResizeCallback(GLFWwindow *window, int width, int height) { void CreateWindow(PKEWindowProperties wp) { if (vkInstance != nullptr) return; - MemBkt_Vulkan = Pke_BeginTransientBucket(); - vulkanAllocs = Pke_New<DynArray<pke_vkAllocData>>(MemBkt_Vulkan); + MemBkt_Vulkan = pk_bucket_create("vulkan", PK_DEFAULT_BUCKET_SIZE, false); + vulkanAllocs = pk_new<DynArray<pke_vkAllocData>>(MemBkt_Vulkan); new (vulkanAllocs) DynArray<pke_vkAllocData>(MemBkt_Vulkan); vulkanAllocs->Reserve(2048); glfwInit(); @@ -2602,7 +2601,7 @@ void DestroyWindow() { DestroySwapchain(); vkDestroyDescriptorPool(vkDevice, pkeDebugHitbox.vkDescriptorPool, vkAllocator); - Pke_Delete<VkDescriptorSet>(pkeDebugHitbox.vkDescriptorSets, MAX_FRAMES_IN_FLIGHT); + pk_delete<VkDescriptorSet>(pkeDebugHitbox.vkDescriptorSets, MAX_FRAMES_IN_FLIGHT); vkDestroyBuffer(vkDevice, pkeDebugHitbox.indexBuffer, vkAllocator); vkDestroyBuffer(vkDevice, pkeDebugHitbox.uvBuffer, vkAllocator); @@ -2654,7 +2653,7 @@ void DestroyWindow() { glfwTerminate(); vulkanAllocs->~DynArray(); - Pke_EndTransientBucket(MemBkt_Vulkan); + pk_bucket_destroy(MemBkt_Vulkan); } VkShaderModule UploadShader(AssetHandle handle) { diff --git a/src/window.hpp b/src/window.hpp index 73369d3..2ceebec 100644 --- a/src/window.hpp +++ b/src/window.hpp @@ -6,9 +6,9 @@ #include "backends/imgui_impl_vulkan.h" #include "event.hpp" #include "imgui.h" -#include "memory.hpp" #include "ecs.hpp" #include "window-types.hpp" +#include "vendor/pk.h" #include "glm/mat4x4.hpp" #include <cstring> @@ -21,7 +21,7 @@ // TODO replace me with something more elegant const unsigned int MAX_FRAMES_IN_FLIGHT = 3; -extern MemBucket *MemBkt_Vulkan; +extern struct pk_membucket *MemBkt_Vulkan; extern bool shouldRecreateSwapchain; extern GLFWwindow *window; |
