diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2023-10-06 14:42:03 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2023-10-06 17:20:20 -0400 |
| commit | 791c153aabd579f518a9b00613459cba13734797 (patch) | |
| tree | 858ec6f9a8398398a8a53ec5a886bca5825c62e0 /src | |
| parent | 286bf5539527500429cfca4ded0bb78406f6364b (diff) | |
Memory management - ctors and dtors
Diffstat (limited to 'src')
| -rw-r--r-- | src/asset-manager.cpp | 2 | ||||
| -rw-r--r-- | src/dynamic-array.hpp | 28 | ||||
| -rw-r--r-- | src/ecs.cpp | 8 | ||||
| -rw-r--r-- | src/ecs.hpp | 1 | ||||
| -rw-r--r-- | src/entities.cpp | 8 | ||||
| -rw-r--r-- | src/event.cpp | 4 | ||||
| -rw-r--r-- | src/event.hpp | 1 | ||||
| -rw-r--r-- | src/game.cpp | 14 | ||||
| -rw-r--r-- | src/macros.hpp | 3 | ||||
| -rw-r--r-- | src/main.cpp | 2 | ||||
| -rw-r--r-- | src/memory.cpp | 2 | ||||
| -rw-r--r-- | src/memory.hpp | 23 | ||||
| -rw-r--r-- | src/window.cpp | 1 |
13 files changed, 81 insertions, 16 deletions
diff --git a/src/asset-manager.cpp b/src/asset-manager.cpp index ff20360..fab26f7 100644 --- a/src/asset-manager.cpp +++ b/src/asset-manager.cpp @@ -82,7 +82,7 @@ const Asset *AM_Get(AssetHandle assetHandle) { } void AM_DebugPrint() { - printf("Asset Manager printout\n"); + printf("Asset Manager printout:\n"); for (uint64_t b = 0; b <= Asset_BucketContainer.bucketCounter; ++b) { auto &bkt = Asset_BucketContainer.buckets[b]; long counter = b == Asset_BucketContainer.bucketCounter ? Asset_BucketContainer.itemCounter >> 32 : maxAssetItemsPerBucket; diff --git a/src/dynamic-array.hpp b/src/dynamic-array.hpp index 6b22f6b..284ddcc 100644 --- a/src/dynamic-array.hpp +++ b/src/dynamic-array.hpp @@ -7,6 +7,7 @@ #include <cstdint> #include <cstring> #include <cassert> +#include <type_traits> #define BAKE_DYN_ARRAY(T) template struct DynArray<T>; @@ -48,6 +49,11 @@ void DynArrayDestroy(DynArrayBase *arr); template <typename T> inline DynArray<T>::DynArray(int64_t count) { this->elementSize = sizeof(T); if (count > 0) DynArrayReserve(this, count); + if IS_CONSTRUCTIBLE(T) { + for (long i = 0; i < count; ++i) { + new (this->ptr + (i * sizeof(T))) T{}; + } + } } template <typename T> inline DynArray<T>::DynArray() { @@ -89,6 +95,12 @@ template <typename T> inline DynArray<T> &DynArray<T>::operator=(DynArray<T> &&r } template <typename T> inline DynArray<T>::~DynArray() { + if (this->ptr == nullptr || this->ptr == CAFE_BABE(char)) return; + if IS_DESTRUCTIBLE(T) { + for (long i = 0; i < this->elementCount; ++i) { + reinterpret_cast<T *>(this->ptr + (i * sizeof(T)))->~T(); + } + } DynArrayDestroy(this); } @@ -136,9 +148,12 @@ template <typename T> inline void DynArray<T>::Remove(std::size_t index) { assert(index >= this->elementCount && "Invalid DynArray<T>::Remove() - Out of bounds"); uint64_t moveCount = (this->elementCount - index - 1); auto *tmp = Pke_New(this->elementSize * moveCount); + if IS_DESTRUCTIBLE(T) { + reinterpret_cast<T>(this->ptr + (index * sizeof(T))).~T(); + } memcpy(tmp, this->ptr + (this->elementSize * (index + 1)), this->elementSize * moveCount); memcpy(this->ptr + (this->elementSize * index), tmp, this->elementSize * moveCount); - Pke_Delete(tmp, moveCount * this->elementSize); + Pke_Delete<T>(tmp, moveCount * this->elementSize); this->elementCount -= 1; } @@ -150,8 +165,19 @@ template <typename T> inline void DynArray<T>::Reserve(int64_t count) { } template <typename T> inline void DynArray<T>::Resize(int64_t count) { + int64_t beforeCount = this->elementCount; + if IS_DESTRUCTIBLE(T) { + for (long i = count; i > beforeCount; --i) { + reinterpret_cast<T *>(this->ptr + (i * sizeof(T)))->~T(); + } + } if (count > 0) { DynArrayReserve(this, count); + if IS_CONSTRUCTIBLE(T) { + for (long i = beforeCount; i < count; ++i) { + new (this->ptr + (i * sizeof(T))) T{}; + } + } } this->elementCount = count; } diff --git a/src/ecs.cpp b/src/ecs.cpp index 03596f3..88088f5 100644 --- a/src/ecs.cpp +++ b/src/ecs.cpp @@ -18,6 +18,7 @@ struct InstanceBucket { }; DynArray<EntityHandle> EntitiesToBeRemoved{16}; // public +DynArray<Entity> entitiesYetToBeRemoved{0}; DynArray<EntityHandle> entitiesMarkedForRemoval{16}; BucketContainer<EntityBucket, EntityHandle_T> Entities_BucketContainer{}; @@ -74,7 +75,6 @@ void ECS_MarkForRemoval(EntityHandle entityHandle) { } void ECS_Tick_Early(double delta) { - static DynArray<Entity> entitiesYetToBeRemoved{0}; entitiesYetToBeRemoved.Resize(EntitiesToBeRemoved.Count()); EntitiesToBeRemoved.Resize(0); for (long b = 0; b <= Entities_BucketContainer.bucketCounter; ++b) { @@ -392,3 +392,9 @@ CompInstance *ECS_GetInstances(uint64_t bucketIndex, uint64_t &itemCount) { } return Comp_Instance_BucketContainer.buckets[bucketIndex].instances; } + +void ECS_Teardown() { + entitiesYetToBeRemoved.~DynArray(); + EntitiesToBeRemoved.~DynArray(); + entitiesMarkedForRemoval.~DynArray(); +} diff --git a/src/ecs.hpp b/src/ecs.hpp index a7fd2ac..83646af 100644 --- a/src/ecs.hpp +++ b/src/ecs.hpp @@ -17,6 +17,7 @@ static struct { } ComponentTypes; void ECS_Init(); +void ECS_Teardown(); void ECS_Tick_Early(double delta); void ECS_Tick_Late(double delta); EntityHandle ECS_CreateEntity(EntityHandle parentEntHandle = EntityHandle{EntityHandle_T{0xFFFFFFFFFFFFFFFF}}); diff --git a/src/entities.cpp b/src/entities.cpp index efa22ae..9b088ec 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -921,7 +921,7 @@ void EntityType_Teardown() { // If we switch to a global pool, we will need to free here, and // destroy the pool outside of this loop vkDestroyDescriptorPool(vkDevice, et->vkDescriptorPool, vkAllocator); - Pke_Delete(grBinds->vkDescriptorSets, MAX_FRAMES_IN_FLIGHT); + Pke_Delete<VkDescriptorSet>(grBinds->vkDescriptorSets, MAX_FRAMES_IN_FLIGHT); } if (grBinds->vertexBuffer != VK_NULL_HANDLE) vkDestroyBuffer(vkDevice, grBinds->vertexBuffer, vkAllocator); @@ -944,6 +944,12 @@ void EntityType_Teardown() { vkFreeMemory(vkDevice, et->deviceMemoryVert, vkAllocator); if (et->deviceMemoryTexture != VK_NULL_HANDLE) vkFreeMemory(vkDevice, et->deviceMemoryTexture, vkAllocator); + if (et->modelsDir) + Pke_Delete<char>(et->modelsDir, strlen(et->modelsDir)); + if (et->modelFile) + Pke_Delete<char>(et->modelFile, strlen(et->modelFile)); + if (et->entityTypeCode) + Pke_Delete<char>(et->entityTypeCode, strlen(et->entityTypeCode)); } if (vkSampler_Texture != VK_NULL_HANDLE) vkDestroySampler(vkDevice, vkSampler_Texture, vkAllocator); diff --git a/src/event.cpp b/src/event.cpp index a129490..62ebd88 100644 --- a/src/event.cpp +++ b/src/event.cpp @@ -57,3 +57,7 @@ void Event_Dispatch(const char *name) { } } +void Event_Teardown() { + eventBuckets.~DynArray(); +} + diff --git a/src/event.hpp b/src/event.hpp index b7a5ffa..defa588 100644 --- a/src/event.hpp +++ b/src/event.hpp @@ -13,5 +13,6 @@ typedef void (*EventHandler)(); void Event_RegisterCallback(const char *name, EventHandler handler); void Event_UnregisterCallback(const char *name, EventHandler handler); void Event_Dispatch(const char *name); +void Event_Teardown(); #endif /* PKE_EVENT_HPP */ diff --git a/src/game.cpp b/src/game.cpp index f464c41..2345d72 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -483,17 +483,9 @@ void RecordImGuiUBO() { void RecordImGuiModalCreateEntityType() { if (ImGui::BeginPopupModal("CreateEntityType", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { - static bool needsReset = true; static char modelsDir[64]; static char modelFile[64]; static char entityTypeCode[32]; - if (needsReset) { - memset(modelsDir, '\0', 64); - memset(modelFile, '\0', 64); - memset(entityTypeCode, '\0', 32); - entityTypeToCreate = Pke_New<EntityType>(); - needsReset = false; - } ImGui::InputText("Models Dir", modelsDir, 63); ImGui::InputText("Model File", modelFile, 63); @@ -508,6 +500,11 @@ void RecordImGuiModalCreateEntityType() { if (ImGui::Button("Create")) { // TODO some type of validation + memset(modelsDir, '\0', 64); + memset(modelFile, '\0', 64); + memset(entityTypeCode, '\0', 32); + assert(entityTypeToCreate == nullptr || entityTypeToCreate == CAFE_BABE(EntityType)); + entityTypeToCreate = Pke_New<EntityType>(); char *sModelsDir = Pke_New<char>(strlen(modelsDir) + 1); strncpy(sModelsDir, modelsDir, 63); @@ -522,7 +519,6 @@ void RecordImGuiModalCreateEntityType() { entityTypeToCreate->entityTypeCode = sEntityTypeCode; shouldCreateEntityType = true; - needsReset = true; ImGui::CloseCurrentPopup(); } ImGui::SameLine(); diff --git a/src/macros.hpp b/src/macros.hpp index 33d942a..02ebb3d 100644 --- a/src/macros.hpp +++ b/src/macros.hpp @@ -8,6 +8,9 @@ #define CAFE_BABE(T) reinterpret_cast<T *>(0xCAFEBABE) +#define IS_CONSTRUCTIBLE(T) constexpr(std::is_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) + #define TypeSafeInt2_H(TypeName, Type, Max, TypeName_T, TypeName_MAX, TypeName_T_MAX)\ using TypeName_T = Type; \ enum class TypeName : TypeName_T; \ diff --git a/src/main.cpp b/src/main.cpp index d3ddd1c..5026013 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -97,7 +97,9 @@ int main() { printf("UNHANDLED EXCEPTION\n"); } printf("PKE SHUTDOWN INITIATED\n"); + Event_Teardown(); EntityType_Teardown(); + ECS_Teardown(); DestroyWindow(); Pke_DebugPrint(); AM_DebugPrint(); diff --git a/src/memory.cpp b/src/memory.cpp index 87d5eca..360e2e2 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -126,7 +126,7 @@ uint64_t Buckets_NewHandle(std::size_t bucketBytes, uint64_t bucketItemCount, ui void Pke_DebugPrint() { printf("Memory Manager printout:\nBucket count: %li\n", bucketHead + 1); - for (long i = 0; i < bucketHead + 1; ++i) { + 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); diff --git a/src/memory.hpp b/src/memory.hpp index bde3f2b..6d431fc 100644 --- a/src/memory.hpp +++ b/src/memory.hpp @@ -8,6 +8,8 @@ #include <cstdlib> #include <cstdio> #include <cassert> +#include <type_traits> +#include <new> // 256MB #define DEFAULT_BUCKET_SIZE 1UL << 27 @@ -35,18 +37,35 @@ void Pke_MemoryFlush(); template <typename T> inline T *Pke_New() { void *ptr = Pke_New(sizeof(T)); - return new (ptr) T{}; + if IS_CONSTRUCTIBLE(T) { + return new (ptr) T{}; + } + return reinterpret_cast<T *>(ptr); } template <typename T> inline T *Pke_New(long count) { - return reinterpret_cast<T *>(Pke_New(sizeof(T) * count)); + char *ptr = static_cast<char *>(Pke_New(sizeof(T) * count)); + 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) { + if IS_DESTRUCTIBLE(T) { + reinterpret_cast<const T *>(ptr)->~T(); + } return Pke_Delete(ptr, sizeof(T)); } template <typename T> inline void Pke_Delete(const void *ptr, long count) { + if IS_DESTRUCTIBLE(T) { + for (long i = 0; i < count; ++i) { + reinterpret_cast<const T *>(reinterpret_cast<const char *>(ptr) + (i * sizeof(T)))->~T(); + } + } return Pke_Delete(ptr, sizeof(T) * count); } diff --git a/src/window.cpp b/src/window.cpp index 2f97be6..0bd1140 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -203,6 +203,7 @@ unsigned int FindQueueFamilyIndex(VkPhysicalDevice device, short hasPresentSuppo continue; } } + Pke_Delete<VkQueueFamilyProperties>(queueFamilyProperties, queueFamilyPropertyCount); return i; } |
