diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2024-01-09 20:30:05 -0500 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2024-01-10 11:30:41 -0500 |
| commit | 294c85f91ac5b2ff9e4ad3d99588ed0d1a72e6b7 (patch) | |
| tree | a92c28661e1ab4b15a9ac9e52816cc6a4c2d7b95 /src | |
| parent | 0a382e78b6cbc77156d78df4e7b0c2854cbb0cd1 (diff) | |
checkpoint - major ECS interface refactor
Diffstat (limited to 'src')
| -rw-r--r-- | src/components.hpp | 8 | ||||
| -rw-r--r-- | src/ecs.cpp | 373 | ||||
| -rw-r--r-- | src/ecs.hpp | 23 | ||||
| -rw-r--r-- | src/entities.cpp | 22 | ||||
| -rw-r--r-- | src/game.cpp | 4 |
5 files changed, 195 insertions, 235 deletions
diff --git a/src/components.hpp b/src/components.hpp index 86c5727..f014c9e 100644 --- a/src/components.hpp +++ b/src/components.hpp @@ -11,6 +11,7 @@ #include <vulkan/vulkan_core.h> const uint64_t ECS_UNSET_VAL = 0xFFFFFFFFFFFFFFFF; +const uint32_t ECS_UNSET_VAL_32 = 0xFFFFFFFF; struct EntityHandle : public PkeHandle { }; struct GrBindsHandle : public PkeHandle { }; @@ -20,12 +21,11 @@ constexpr EntityHandle EntityHandle_MAX = EntityHandle{}; constexpr GrBindsHandle GrBindsHandle_MAX = GrBindsHandle{}; constexpr InstanceHandle InstanceHandle_MAX = InstanceHandle{}; -struct Entity { +struct Entity_Base { EntityHandle handle = EntityHandle_MAX; EntityHandle parentHandle = EntityHandle_MAX; - GrBindsHandle grBindsHandle = GrBindsHandle_MAX; - InstanceHandle instanceHandle = InstanceHandle_MAX; bool isMarkedForRemoval = false; + bool isReadyForTeardown = false; }; struct BufferBindingDetails { @@ -82,7 +82,7 @@ struct CompInstance { EntityHandle entHandle = EntityHandle_MAX; GrBindsHandle grBindsHandle = GrBindsHandle_MAX; InstanceHandle instanceHandle = InstanceHandle_MAX; - uint64_t index = ECS_UNSET_VAL; + uint32_t index = ECS_UNSET_VAL_32; PhysicsCollision physicsLayer = PhysicsCollision{1}; PhysicsCollision physicsMask = PhysicsCollision{1}; InstBt bt; diff --git a/src/ecs.cpp b/src/ecs.cpp index 1e62988..02f00d3 100644 --- a/src/ecs.cpp +++ b/src/ecs.cpp @@ -4,6 +4,7 @@ #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" @@ -20,31 +21,31 @@ constexpr PkeHandleItemIndex_T maxBucketItemCount = 256; * * Used to build the other "removal" lists. */ -DynArray<EntityHandle> entitiesMarkedForRemoval{16}; +DynArray<Entity_Base *> entitiesMarkedForRemoval{16}; /* * Public list of entities that will be removed next tick * * Entity or child of entity that had ECS_MarkForRemoval called */ -DynArray<EntityHandle> EntitiesToBeRemoved{16}; // public +DynArray<Entity_Base *> EntitiesToBeRemoved{16}; // public /* * The entities being removed this tick * * Each of these entities has gone a full tick in the "to be removed" state */ -DynArray<Entity> entitiesYetToBeRemoved{0, nullptr}; +DynArray<Entity_Base *> entitiesYetToBeRemoved{0, nullptr}; -DynArray<EntityHandle> EntitiesWithExcessInstances{16}; +DynArray<Entity_Base *> EntitiesWithExcessInstances{16}; -BucketContainer<Entity, EntityHandle> Entities_BucketContainer{}; +BucketContainer<Entity_Base *, GrBindsHandle> Entities_BucketContainer{}; BucketContainer<CompGrBinds, GrBindsHandle> Comp_GrBinds_BucketContainer{}; BucketContainer<CompInstance, InstanceHandle> Comp_Instance_BucketContainer{}; -void ECS_GetEntity_Inner(EntityHandle entHandle, Entity*& ent) { - assert(entHandle != EntityHandle_MAX && "Unknown entity handle"); - ent = &Entities_BucketContainer.buckets[entHandle.bucketIndex][entHandle.itemIndex]; +void ECS_GetEntity_Inner(EntityHandle entHandle, Entity_Base*& ent) { + assert(ValidateHandle(entHandle, Entities_BucketContainer.pkeHandle, Entities_BucketContainer.limits.itemIndex) == PKE_HANDLE_VALIDATION_VALID); + ent = Entities_BucketContainer.buckets[entHandle.bucketIndex][entHandle.itemIndex]; } void ECS_Init() { @@ -53,143 +54,145 @@ void ECS_Init() { Buckets_Init(Comp_Instance_BucketContainer, maxBucketItemCount); } -uint64_t ECS_GetEntities_BucketCount() { - return Entities_BucketContainer.pkeHandle.bucketIndex + 1; -} -Entity *ECS_GetEntities(uint64_t bucketIndex, uint64_t &itemCount) { - assert(bucketIndex <= Entities_BucketContainer.pkeHandle.bucketIndex); - itemCount = bucketIndex == Entities_BucketContainer.pkeHandle.bucketIndex ? Entities_BucketContainer.pkeHandle.itemIndex : maxBucketItemCount; - return Entities_BucketContainer.buckets[bucketIndex]; -} - -EntityHandle ECS_CreateEntity_Inner(EntityHandle parentEntHandle) { - EntityHandle entityHandle{Buckets_NewHandle<Entity>(Entities_BucketContainer)}; - - Entity *entity = &Entities_BucketContainer.buckets[entityHandle.bucketIndex][entityHandle.itemIndex]; - entity = new (entity) Entity{}; +EntityHandle ECS_CreateEntity(Entity_Base *entity, Entity_Base *parentEntity) { + assert(entity != nullptr); + EntityHandle entityHandle{Buckets_NewHandle(Entities_BucketContainer)}; entity->handle = entityHandle; - entity->parentHandle = parentEntHandle; - + entity->parentHandle = parentEntity->handle; + Entities_BucketContainer.buckets[entityHandle.bucketIndex][entityHandle.itemIndex] = entity; return entityHandle; } -EntityHandle ECS_CreateEntity(EntityHandle parentEntHandle) { - return ECS_CreateEntity_Inner(parentEntHandle); -} - -void ECS_MarkForRemoval(EntityHandle entityHandle) { - const Entity *ent = &Entities_BucketContainer.buckets[entityHandle.bucketIndex][entityHandle.itemIndex]; - assert(ent->isMarkedForRemoval == false && "Entity already marked for removal"); - entitiesMarkedForRemoval.Push(entityHandle); +void ECS_MarkForRemoval(Entity_Base *entity) { + assert(entity->isMarkedForRemoval == false && "Entity already marked for removal"); + entitiesMarkedForRemoval.Push(entity); } void ECS_Tick_Early(double delta) { // these reserves might happen 1 tick early, but that's fine entitiesYetToBeRemoved.Reserve(entitiesMarkedForRemoval.Count()); EntitiesToBeRemoved.Resize(entitiesMarkedForRemoval.Count()); - memcpy(EntitiesToBeRemoved.GetPtr(), entitiesMarkedForRemoval.GetPtr(), sizeof(EntityHandle) * entitiesMarkedForRemoval.Count()); + memcpy(EntitiesToBeRemoved.GetPtr(), entitiesMarkedForRemoval.GetPtr(), sizeof(void *) * entitiesMarkedForRemoval.Count()); entitiesYetToBeRemoved.Resize(0); + if (entitiesMarkedForRemoval.Count() == 0) return; + + // this has the potential to be slow as balls for (long b = 0; b <= Entities_BucketContainer.pkeHandle.bucketIndex; ++b) { uint64_t entCount = b == Entities_BucketContainer.pkeHandle.bucketIndex ? Entities_BucketContainer.pkeHandle.itemIndex : maxBucketItemCount; for (long e = 0; e < entCount; ++e) { - Entity *ent = &Entities_BucketContainer.buckets[b][e]; + Entity_Base *ent = Entities_BucketContainer.buckets[b][e]; if (ent->handle == EntityHandle_MAX) continue; if (ent->isMarkedForRemoval) { - entitiesYetToBeRemoved.Push(*ent); + entitiesYetToBeRemoved.Push(ent); ent->handle = EntityHandle_MAX; ent->parentHandle = EntityHandle_MAX; ent->isMarkedForRemoval = false; - } else if (EntitiesToBeRemoved.Has(ent->handle)) { + } else if (EntitiesToBeRemoved.Has(ent)) { ent->isMarkedForRemoval = true; - } else if (EntitiesToBeRemoved.Has(ent->parentHandle)) { + } else if (EntitiesToBeRemoved.Has(ent)) { ent->isMarkedForRemoval = true; - EntitiesToBeRemoved.Push(ent->handle); + EntitiesToBeRemoved.Push(ent); } } } - for (long e = 0; e < entitiesYetToBeRemoved.Count(); ++e) { - Entity &clonedEnt = entitiesYetToBeRemoved[e]; - CompGrBinds *grBinds = nullptr; - CompInstance *instBucket = nullptr; - CompInstance *inst = nullptr; - uint64_t instBucketIndex = 0; - if (clonedEnt.instanceHandle != InstanceHandle_MAX) { - instBucketIndex = clonedEnt.instanceHandle.bucketIndex; - instBucket = Comp_Instance_BucketContainer.buckets[instBucketIndex]; - inst = &instBucket[clonedEnt.instanceHandle.itemIndex]; - if (inst->grBindsHandle != GrBindsHandle_MAX) { - grBinds = &Comp_GrBinds_BucketContainer.buckets[inst->grBindsHandle.bucketIndex][inst->grBindsHandle.itemIndex]; +} + +bool DynArrayFindComponent(Entity_Base *const &entity, const EntityHandle &handle) { + return entity->handle == handle; +} + +struct updateGrBindsAfter { + GrBindsHandle grBindsHandle = GrBindsHandle_MAX; + uint32_t count = 0; +}; +bool DynArrayFindGrBinds(updateGrBindsAfter const &after, const GrBindsHandle &handle) { + return after.grBindsHandle == handle; +} +void ECS_Tick(double delta) { + int32_t physicsTickCount = Physics_Tick(delta); + + int64_t entityRemovalCount = entitiesYetToBeRemoved.Count(); + if (physicsTickCount == 0 && entityRemovalCount == 0) return; + + DynArray<updateGrBindsAfter> *updateGrBindsPtr = Pke_New<DynArray<updateGrBindsAfter>>(pkeSettings.mem.bkt); + DynArray<updateGrBindsAfter> &updateGrBinds = *updateGrBindsPtr; + for (long b = 0; b <= Comp_Instance_BucketContainer.pkeHandle.bucketIndex; ++b) { + auto &bkt = Comp_Instance_BucketContainer.buckets[b]; + long count = Comp_Instance_BucketContainer.pkeHandle.bucketIndex == b ? Comp_Instance_BucketContainer.pkeHandle.itemIndex : maxBucketItemCount; + for (uint32_t i = 0; i < count; ++i) { + auto &inst = bkt[i]; + if (inst.entHandle == EntityHandle_MAX) + continue; + auto activationState = inst.bt.rigidBody->getActivationState(); + if (activationState == ISLAND_SLEEPING || activationState == DISABLE_SIMULATION || activationState == WANTS_DEACTIVATION) { + // do nothing + } else { + inst.isNeedingUpdated = true; } - } - if (grBinds == nullptr && clonedEnt.grBindsHandle != GrBindsHandle_MAX) { - grBinds = &Comp_GrBinds_BucketContainer.buckets[clonedEnt.grBindsHandle.bucketIndex][clonedEnt.grBindsHandle.itemIndex]; - } - if (inst != nullptr) { - assert(grBinds != nullptr); - for (long bi = instBucketIndex; bi <= Comp_Instance_BucketContainer.pkeHandle.bucketIndex; ++bi) { - uint64_t instCounter = 0; - if (bi == Comp_Instance_BucketContainer.pkeHandle.bucketIndex) { - instCounter = Comp_Instance_BucketContainer.pkeHandle.itemIndex; - } else { - instCounter = maxBucketItemCount; - } - auto &bucket = Comp_Instance_BucketContainer.buckets[bi]; - for (long ii = 0; ii < instCounter; ++ii) { - if (bucket[ii].entHandle == EntityHandle_MAX) { - continue; + if (entityRemovalCount > 0) { + int64_t removeIndex = entitiesYetToBeRemoved.FindFirstIndex(DynArrayFindComponent, inst.entHandle); + if (removeIndex != -1) { + int64_t afterIndex = updateGrBinds.FindFirstIndex(DynArrayFindGrBinds, inst.grBindsHandle); + updateGrBindsAfter *after = nullptr; + if (afterIndex != -1) { + after = &updateGrBinds[afterIndex]; + } else { + after = &updateGrBinds.Push(); + after->grBindsHandle = inst.grBindsHandle; } - if (bucket[ii].grBindsHandle != inst->grBindsHandle) { - continue; - } - if (bucket[ii].instanceHandle.itemIndex < clonedEnt.instanceHandle.itemIndex) { - continue; - } - bucket[ii].index -= 1; - bucket[ii].isNeedingUpdated = true; + after->count += 1; + + inst.entHandle = EntityHandle_MAX; + inst.grBindsHandle = GrBindsHandle_MAX; + inst.index = ECS_UNSET_VAL_32; + 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); + inst.bt.rigidBody = CAFE_BABE(btRigidBody); + inst.bt.motionState = CAFE_BABE(btDefaultMotionState); + continue; + } + } + if (updateGrBinds.Count() > 0) { + int64_t afterIndex = updateGrBinds.FindFirstIndex(DynArrayFindGrBinds, inst.grBindsHandle); + if (afterIndex > -1) { + auto &after = updateGrBinds[afterIndex]; + inst.index -= after.count; + inst.isNeedingUpdated = true; } } - grBinds->instanceCounter -= 1; - inst->entHandle = EntityHandle_MAX; - inst->grBindsHandle = GrBindsHandle_MAX; - inst->index = ECS_UNSET_VAL; - 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); - inst->bt.rigidBody = CAFE_BABE(btRigidBody); - inst->bt.motionState = CAFE_BABE(btDefaultMotionState); - } else if (grBinds != nullptr) { - grBinds->entHandle = EntityHandle_MAX; - grBinds->grBindsHandle = GrBindsHandle_MAX; - grBinds->vkPipelineLayout = VK_NULL_HANDLE; - grBinds->graphicsPipeline = VK_NULL_HANDLE; - grBinds->collisionCallback = PkeCallback{}; - /* - * 2023-09-05 JB note - the Vulkan assets (device memory, buffers, - * pipeline layout, and descriptor set) are unloaded elsewhere, just, - * as they were created elsewhere. - */ } } - entitiesMarkedForRemoval.Resize(0); -} -void ECS_Tick(double delta) { - int32_t physicsTickCount = Physics_Tick(delta); - if (physicsTickCount != 0) { - for (long b = 0; b <= Comp_Instance_BucketContainer.pkeHandle.bucketIndex; ++b) { - auto &bkt = Comp_Instance_BucketContainer.buckets[b]; - long count = Comp_Instance_BucketContainer.pkeHandle.bucketIndex == b ? Comp_Instance_BucketContainer.pkeHandle.itemIndex : maxBucketItemCount; - for (uint32_t i = 0; i < count; ++i) { - auto &inst = bkt[i]; - if (inst.entHandle == EntityHandle_MAX) - continue; - auto activationState = inst.bt.rigidBody->getActivationState(); - if (activationState == ISLAND_SLEEPING || activationState == DISABLE_SIMULATION || activationState == WANTS_DEACTIVATION) { + if (entityRemovalCount > 0 || updateGrBinds.Count() > 0) { + for (PkeHandleBucketIndex_T b = 0; b <= Comp_GrBinds_BucketContainer.pkeHandle.bucketIndex; ++b) { + auto &bkt = Comp_GrBinds_BucketContainer.buckets[b]; + long count = Comp_GrBinds_BucketContainer.pkeHandle.bucketIndex == b ? Comp_GrBinds_BucketContainer.pkeHandle.itemIndex : Comp_GrBinds_BucketContainer.limits.itemIndex; + for (PkeHandleItemIndex_T i = 0; i < count; ++i) { + auto &grBinds = bkt[i]; + if (grBinds.entHandle == EntityHandle_MAX) { continue; } - inst.isNeedingUpdated = true; + auto removalIndex = entitiesYetToBeRemoved.FindFirstIndex(DynArrayFindComponent, grBinds.entHandle); + auto afterIndex = updateGrBinds.FindFirstIndex(DynArrayFindGrBinds, grBinds.grBindsHandle); + if (removalIndex != -1) { + grBinds.entHandle = EntityHandle_MAX; + grBinds.grBindsHandle = GrBindsHandle_MAX; + grBinds.vkPipelineLayout = VK_NULL_HANDLE; + grBinds.graphicsPipeline = VK_NULL_HANDLE; + grBinds.collisionCallback = PkeCallback{}; + /* + * 2023-09-05 JB note - the Vulkan assets (device memory, buffers, + * pipeline layout, and descriptor set) are unloaded elsewhere, just, + * as they were created elsewhere. + */ + } + if (afterIndex != -1) { + auto &after = updateGrBinds[afterIndex]; + grBinds.instanceCounter -= after.count; + } } } } @@ -324,47 +327,34 @@ void ECS_Tick_Late(double delta) { } } -void FindComponents(EntityHandle handle, Entity *&ent, CompInstance *&compInst, CompGrBinds *&grBinds) { - ECS_GetEntity_Inner(handle, ent); - if (ent == nullptr) - return; - GrBindsHandle grBindsHandle = ent->grBindsHandle; - if (ent->instanceHandle != InstanceHandle_MAX) { - compInst = &Comp_Instance_BucketContainer.buckets[ent->instanceHandle.bucketIndex][ent->instanceHandle.itemIndex]; - if (grBindsHandle == GrBindsHandle_MAX) - grBindsHandle = compInst->grBindsHandle; - } - if (grBindsHandle != GrBindsHandle_MAX) { - grBinds = &Comp_GrBinds_BucketContainer.buckets[grBindsHandle.bucketIndex][grBindsHandle.itemIndex]; - } -} - -void ECS_HandleCollision(EntityHandle lhs, EntityHandle rhs) { - Entity *lhsEnt = nullptr; - CompInstance *lhsInst = nullptr; +void ECS_HandleCollision(InstanceHandle lhs, InstanceHandle rhs) { + CompInstance *lhsInst = ECS_GetInstance(lhs); CompGrBinds *lhsGrBinds = nullptr; - FindComponents(lhs, lhsEnt, lhsInst, lhsGrBinds); + if (lhsInst != nullptr) { + lhsGrBinds = ECS_GetGrBinds(lhsInst->grBindsHandle); + } - Entity *rhsEnt = nullptr; - CompInstance *rhsInst = nullptr; + CompInstance *rhsInst = ECS_GetInstance(rhs); CompGrBinds *rhsGrBinds = nullptr; - FindComponents(rhs, rhsEnt, rhsInst, rhsGrBinds); + if (rhsInst != nullptr) { + rhsGrBinds = ECS_GetGrBinds(rhsInst->grBindsHandle); + } - void (*lhsColFunc)(EntityHandle, EntityHandle) = nullptr; - void (*rhsColFunc)(EntityHandle, EntityHandle) = nullptr; + void (*lhsColFunc)(InstanceHandle, InstanceHandle) = nullptr; + void (*rhsColFunc)(InstanceHandle, InstanceHandle) = nullptr; if (lhsInst && lhsInst->collisionCallback.func != nullptr) { - lhsColFunc = reinterpret_cast<void (*)(EntityHandle, EntityHandle)>(lhsInst->collisionCallback.func); + lhsColFunc = reinterpret_cast<void (*)(InstanceHandle, InstanceHandle)>(lhsInst->collisionCallback.func); } if (lhsColFunc == nullptr && lhsGrBinds && lhsGrBinds->collisionCallback.func) { - lhsColFunc = reinterpret_cast<void (*)(EntityHandle, EntityHandle)>(lhsGrBinds->collisionCallback.func); + lhsColFunc = reinterpret_cast<void (*)(InstanceHandle, InstanceHandle)>(lhsGrBinds->collisionCallback.func); } if (rhsInst && rhsInst->collisionCallback.func != nullptr) { - rhsColFunc = reinterpret_cast<void (*)(EntityHandle, EntityHandle)>(rhsInst->collisionCallback.func); + rhsColFunc = reinterpret_cast<void (*)(InstanceHandle, InstanceHandle)>(rhsInst->collisionCallback.func); } if (rhsColFunc == nullptr && rhsGrBinds && rhsGrBinds->collisionCallback.func) { - rhsColFunc = reinterpret_cast<void (*)(EntityHandle, EntityHandle)>(rhsGrBinds->collisionCallback.func); + rhsColFunc = reinterpret_cast<void (*)(InstanceHandle, InstanceHandle)>(rhsGrBinds->collisionCallback.func); } if (lhsColFunc) { @@ -375,30 +365,21 @@ void ECS_HandleCollision(EntityHandle lhs, EntityHandle rhs) { } } -CompGrBinds &ECS_CreateGrBinds(EntityHandle entHandle) { - assert(entHandle != EntityHandle_MAX); - - Entity *ent = nullptr; - ECS_GetEntity_Inner(entHandle, ent); +CompGrBinds *ECS_CreateGrBinds(Entity_Base *entity) { + assert(entity != nullptr && entity != CAFE_BABE(Entity_Base)); - assert(ent->grBindsHandle == GrBindsHandle_MAX); - - ent->grBindsHandle = Buckets_NewHandle(Comp_GrBinds_BucketContainer); - auto *comp = &Comp_GrBinds_BucketContainer.buckets[ent->grBindsHandle.bucketIndex][ent->grBindsHandle.itemIndex]; + GrBindsHandle grBindsHandle{Buckets_NewHandle(Comp_GrBinds_BucketContainer)}; + auto *comp = &Comp_GrBinds_BucketContainer.buckets[grBindsHandle.bucketIndex][grBindsHandle.itemIndex]; comp = new (comp) CompGrBinds{}; - comp->entHandle = entHandle; - comp->grBindsHandle = ent->grBindsHandle; - return *comp; + comp->entHandle = entity->handle; + comp->grBindsHandle = grBindsHandle; + return comp; } -CompGrBinds *ECS_GetGrBinds(EntityHandle entHandle) { - Entity *ent = nullptr; - ECS_GetEntity_Inner(entHandle, ent); - if (ent->grBindsHandle == GrBindsHandle_MAX) return nullptr; - return &Comp_GrBinds_BucketContainer.buckets[ent->grBindsHandle.bucketIndex][ent->grBindsHandle.itemIndex]; -} CompGrBinds *ECS_GetGrBinds(GrBindsHandle grBindsHandle) { if (grBindsHandle == GrBindsHandle_MAX) return nullptr; + + assert(ValidateHandle(grBindsHandle, Comp_GrBinds_BucketContainer.pkeHandle, Comp_GrBinds_BucketContainer.limits.itemIndex) == PKE_HANDLE_VALIDATION_VALID); return &Comp_GrBinds_BucketContainer.buckets[grBindsHandle.bucketIndex][grBindsHandle.itemIndex]; } @@ -415,71 +396,49 @@ CompGrBinds *ECS_GetGrBinds(uint64_t bucketIndex, uint64_t &itemCount) { return Comp_GrBinds_BucketContainer.buckets[bucketIndex]; } -CompInstance &ECS_CreateInstance(EntityHandle entHandle, EntityHandle entityTypeEntityHandle) { - assert(entHandle != EntityHandle_MAX); - assert(entityTypeEntityHandle != EntityHandle_MAX); +CompInstance *ECS_CreateInstance(Entity_Base *entity, CompGrBinds *entityTypeGrBinds) { + assert(entity != nullptr && entity != CAFE_BABE(Entity_Base)); + assert(entityTypeGrBinds != nullptr && entityTypeGrBinds != CAFE_BABE(CompGrBinds)); - Entity *ent = nullptr; - Entity *entTypeEnt = nullptr; - ECS_GetEntity_Inner(entHandle, ent); - ECS_GetEntity_Inner(entityTypeEntityHandle, entTypeEnt); + InstanceHandle instanceHandle{Buckets_NewHandle(Comp_Instance_BucketContainer)}; - assert(ent->grBindsHandle == GrBindsHandle_MAX); - assert(entTypeEnt->grBindsHandle != GrBindsHandle_MAX); - - ent->instanceHandle = Buckets_NewHandle(Comp_Instance_BucketContainer); - - auto *instBkt = Comp_Instance_BucketContainer.buckets[ent->instanceHandle.bucketIndex]; - auto *comp = &instBkt[ent->instanceHandle.itemIndex]; + auto *instBkt = Comp_Instance_BucketContainer.buckets[instanceHandle.bucketIndex]; + auto *comp = &instBkt[instanceHandle.itemIndex]; new (comp) CompInstance{}; - comp->entHandle = entHandle; - - auto *grBinds = &Comp_GrBinds_BucketContainer.buckets[entTypeEnt->grBindsHandle.bucketIndex][entTypeEnt->grBindsHandle.itemIndex]; - - comp->grBindsHandle = grBinds->grBindsHandle; - comp->instanceHandle = ent->instanceHandle; - comp->index = grBinds->instanceCounter++; + comp->entHandle = entity->handle; + comp->grBindsHandle = entityTypeGrBinds->grBindsHandle; + comp->instanceHandle = instanceHandle; + comp->index = entityTypeGrBinds->instanceCounter++; comp->isNeedingUpdated = true; - if (grBinds->instanceCounter > grBinds->instanceBufferMaxCount) { - EntitiesWithExcessInstances.Push(grBinds->entHandle); + if (entityTypeGrBinds->instanceCounter > entityTypeGrBinds->instanceBufferMaxCount) { + EntitiesWithExcessInstances.Push(ECS_GetEntity(entityTypeGrBinds->entHandle)); } - return *comp; + return comp; } -CompInstance *ECS_GetInstance(EntityHandle entHandle) { - Entity *ent = nullptr; - ECS_GetEntity_Inner(entHandle, ent); - - if (ent->instanceHandle == InstanceHandle_MAX) - return nullptr; +CompInstance *ECS_GetInstance(InstanceHandle instanceHandle ) { + if (instanceHandle == InstanceHandle_MAX) return nullptr; - auto *inst = &Comp_Instance_BucketContainer.buckets[ent->instanceHandle.bucketIndex][ent->instanceHandle.itemIndex]; + assert(ValidateHandle(instanceHandle, Comp_Instance_BucketContainer.pkeHandle, Comp_Instance_BucketContainer.limits.itemIndex) == PKE_HANDLE_VALIDATION_VALID); + auto *inst = &Comp_Instance_BucketContainer.buckets[instanceHandle.bucketIndex][instanceHandle.itemIndex]; return inst; } -void ECS_UpdateInstance(EntityHandle entHandle, const InstPos &instPos, bool overridePhysics) { - Entity *ent = nullptr; - ECS_GetEntity_Inner(entHandle, ent); - - if (ent->instanceHandle == InstanceHandle_MAX) - return; - - auto *inst = &Comp_Instance_BucketContainer.buckets[ent->instanceHandle.bucketIndex][ent->instanceHandle.itemIndex]; - +void ECS_UpdateInstance(CompInstance *instance, const InstPos &instPos, bool overridePhysics) { if (BtDynamicsWorld && overridePhysics) { btVector3 localInertia(0, 0, 0); - inst->bt.rigidBody->getCollisionShape()->calculateLocalInertia(instPos.mass, localInertia); - inst->bt.rigidBody->setMassProps(instPos.mass, localInertia); - inst->bt.rigidBody->getMotionState()->setWorldTransform(instPos.posRot); - inst->bt.rigidBody->setWorldTransform(instPos.posRot); - inst->bt.rigidBody->getCollisionShape()->setLocalScaling(instPos.scale); - inst->bt.rigidBody->setLinearVelocity(btVector3(0,0,0)); - inst->bt.rigidBody->setAngularVelocity(btVector3(0,0,0)); - inst->bt.rigidBody->activate(); - inst->isNeedingUpdated = true; + instance->bt.rigidBody->getCollisionShape()->calculateLocalInertia(instPos.mass, localInertia); + instance->bt.rigidBody->setMassProps(instPos.mass, localInertia); + instance->bt.rigidBody->getMotionState()->setWorldTransform(instPos.posRot); + instance->bt.rigidBody->setWorldTransform(instPos.posRot); + instance->bt.rigidBody->getCollisionShape()->setLocalScaling(instPos.scale); + instance->bt.rigidBody->setLinearVelocity(btVector3(0,0,0)); + instance->bt.rigidBody->setAngularVelocity(btVector3(0,0,0)); + instance->bt.rigidBody->activate(); + instance->isNeedingUpdated = true; } } diff --git a/src/ecs.hpp b/src/ecs.hpp index 4deacaf..567f6df 100644 --- a/src/ecs.hpp +++ b/src/ecs.hpp @@ -8,8 +8,8 @@ #include "glm/vec3.hpp" -extern DynArray<EntityHandle> EntitiesToBeRemoved; -extern DynArray<EntityHandle> EntitiesWithExcessInstances; +extern DynArray<Entity_Base *> EntitiesToBeRemoved; +extern DynArray<Entity_Base *> EntitiesWithExcessInstances; static struct { uint64_t Entity = 1ULL << 0; @@ -22,22 +22,21 @@ void ECS_Teardown(); void ECS_Tick_Early(double delta); void ECS_Tick(double delta); void ECS_Tick_Late(double delta); -EntityHandle ECS_CreateEntity(EntityHandle parentEntHandle = EntityHandle{}); -void ECS_MarkForRemoval(EntityHandle entHandle); -uint64_t ECS_GetEntities_BucketCount(); -Entity *ECS_GetEntities(uint64_t bucketIndex, uint64_t &itemCount); -void ECS_HandleCollision(EntityHandle lhs, EntityHandle rhs); +EntityHandle ECS_CreateEntity(Entity_Base *entity, Entity_Base *parentEnt = nullptr); +Entity_Base *ECS_GetEntity(EntityHandle handle); +void ECS_MarkForRemoval(Entity_Base *entity); -CompGrBinds &ECS_CreateGrBinds(EntityHandle entHandle); -CompGrBinds *ECS_GetGrBinds(EntityHandle entHandle); +void ECS_HandleCollision(Entity_Base *lhs, Entity_Base *rhs); + +CompGrBinds *ECS_CreateGrBinds(Entity_Base *); CompGrBinds *ECS_GetGrBinds(GrBindsHandle grBindsHandle); uint64_t ECS_GetGrBinds_BucketCount(); CompGrBinds *ECS_GetGrBinds(uint64_t bucketIndex, uint64_t &itemCount); -CompInstance &ECS_CreateInstance(EntityHandle entHandle, EntityHandle entityTypeEntityHandle); -CompInstance *ECS_GetInstance(EntityHandle entHandle); -void ECS_UpdateInstance(EntityHandle entHandle, const InstPos &instPos, bool overridePhysics = false); +CompInstance *ECS_CreateInstance(Entity_Base *entity, CompGrBinds *entityTypeGrBinds); +CompInstance *ECS_GetInstance(InstanceHandle instanceHandle); +void ECS_UpdateInstance(CompInstance *instance, const InstPos &instPos, bool overridePhysics = false); uint64_t ECS_GetInstances_BucketCount(); CompInstance *ECS_GetInstances(uint64_t bucketIndex, uint64_t &itemCount); diff --git a/src/entities.cpp b/src/entities.cpp index 496874a..91c94d8 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -38,15 +38,16 @@ int64_t EntityType_FindByTypeCode(const char *typeCode) { return -1; } -int64_t EntityType_FindByEntityHandle(EntityHandle handle, int64_t &detailIndex) { +int64_t EntityType_FindByEntity(Entity_Base *entity, int64_t &detailIndex) { + assert(entity != nullptr); for (int64_t i = 0; i < GlobalEntityTypes.Count(); ++i) { for (int64_t k = 0; k < GlobalEntityTypes[i].detailsCount; ++k) { - if (GlobalEntityTypes[i].details[k].entityHandle == handle) { + if (GlobalEntityTypes[i].details[k].entityHandle == entity->handle) { detailIndex = k; return i; } } - if (GlobalEntityTypes[i].entityHandle == handle) { + if (GlobalEntityTypes[i].entityHandle == entity->handle) { detailIndex = -1; return i; } @@ -1152,10 +1153,11 @@ void EntityType_Tick(double delta) { const auto count = EntitiesToBeRemoved.Count(); int64_t detailIndex = -1; for (long i = 0; i < count; ++i) { - if (auto index = EntityType_FindByEntityHandle(EntitiesToBeRemoved[i], detailIndex); index > -1) { - if (auto *grBinds = ECS_GetGrBinds(EntitiesToBeRemoved[i]); grBinds != nullptr) { + if (auto index = EntityType_FindByEntity(EntitiesToBeRemoved[i], detailIndex); index > -1) { + auto &entType = GlobalEntityTypes[index]; + if (auto *grBinds = ECS_GetGrBinds(entType.details[detailIndex].grBindsHandle); grBinds != nullptr) { auto &td = EntityTypesToTeardown.Push(); - td.handle = EntitiesToBeRemoved[i]; + td.handle = EntitiesToBeRemoved[i]->handle; td.ticksToWait = 1; for (long k = 0; k < GlobalEntityTypes[index].detailsCount; ++k) { td.grBinds[k] = grBinds; @@ -1167,13 +1169,13 @@ void EntityType_Tick(double delta) { void EntityType_Tick_Late(double delta) { while (EntitiesWithExcessInstances.Count() != 0) { - auto entHandle = EntitiesWithExcessInstances.Pop(); + auto *entity = EntitiesWithExcessInstances.Pop(); int64_t detailIndex = 0; - auto index = EntityType_FindByEntityHandle(entHandle, detailIndex); + auto index = EntityType_FindByEntity(entity, detailIndex); auto &et = GlobalEntityTypes[index]; auto &etd = GlobalEntityTypes[index].details[detailIndex]; - auto &grBinds = *ECS_GetGrBinds(etd.entityHandle); - EntityType_RolloverInstances(et, grBinds); + auto *grBinds = ECS_GetGrBinds(etd.grBindsHandle); + EntityType_RolloverInstances(et, *grBinds); } for (int64_t i = EntityTypesToTeardown.Count() - 1; i >= 0; --i) { auto &td = EntityTypesToTeardown[i]; diff --git a/src/game.cpp b/src/game.cpp index da8f7e0..dc32b2a 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -508,13 +508,13 @@ void Game_Tick(double delta) { } /* - * ECS_Tick() gets called first because it updates the public + * ECS_Tick_Early() gets called first because it updates the public * `EntitiesToBeRemoved` for all other ticks to use. */ ECS_Tick_Early(delta); - ECS_Tick(delta); EntityType_Tick(delta); + ECS_Tick(delta); PkeInput_Tick(delta); const auto pluginCount = LoadedPkePlugins.Count(); |
