Allocate memory for a given number of components
| 41 | |
| 42 | // Allocate memory for a given number of components |
| 43 | void BodyComponents::allocate(uint32 nbComponentsToAllocate) { |
| 44 | |
| 45 | assert(nbComponentsToAllocate > mNbAllocatedComponents); |
| 46 | |
| 47 | // Make sure capacity is an integral multiple of alignment |
| 48 | nbComponentsToAllocate = std::ceil(nbComponentsToAllocate / float(GLOBAL_ALIGNMENT)) * GLOBAL_ALIGNMENT; |
| 49 | |
| 50 | // Size for the data of a single component (in bytes) |
| 51 | const size_t totalSizeBytes = nbComponentsToAllocate * mComponentDataSize + mAlignmentMarginSize; |
| 52 | |
| 53 | // Allocate memory |
| 54 | void* newBuffer = mMemoryAllocator.allocate(totalSizeBytes); |
| 55 | assert(newBuffer != nullptr); |
| 56 | assert(reinterpret_cast<uintptr_t>(newBuffer) % GLOBAL_ALIGNMENT == 0); |
| 57 | |
| 58 | // New pointers to components data |
| 59 | Entity* newBodiesEntities = static_cast<Entity*>(newBuffer); |
| 60 | assert(reinterpret_cast<uintptr_t>(newBodiesEntities) % GLOBAL_ALIGNMENT == 0); |
| 61 | Body** newBodies = reinterpret_cast<Body**>(MemoryAllocator::alignAddress(newBodiesEntities + nbComponentsToAllocate, GLOBAL_ALIGNMENT)); |
| 62 | assert(reinterpret_cast<uintptr_t>(newBodies) % GLOBAL_ALIGNMENT == 0); |
| 63 | Array<Entity>* newColliders = reinterpret_cast<Array<Entity>*>(MemoryAllocator::alignAddress(newBodies + nbComponentsToAllocate, GLOBAL_ALIGNMENT)); |
| 64 | assert(reinterpret_cast<uintptr_t>(newColliders) % GLOBAL_ALIGNMENT == 0); |
| 65 | bool* newIsActive = reinterpret_cast<bool*>(MemoryAllocator::alignAddress(newColliders + nbComponentsToAllocate, GLOBAL_ALIGNMENT)); |
| 66 | assert(reinterpret_cast<uintptr_t>(newIsActive) % GLOBAL_ALIGNMENT == 0); |
| 67 | void** newUserData = reinterpret_cast<void**>(MemoryAllocator::alignAddress(newIsActive + nbComponentsToAllocate, GLOBAL_ALIGNMENT)); |
| 68 | assert(reinterpret_cast<uintptr_t>(newUserData) % GLOBAL_ALIGNMENT == 0); |
| 69 | bool* newHasSimulationCollider = reinterpret_cast<bool*>(MemoryAllocator::alignAddress(newUserData + nbComponentsToAllocate, GLOBAL_ALIGNMENT)); |
| 70 | assert(reinterpret_cast<uintptr_t>(newHasSimulationCollider) % GLOBAL_ALIGNMENT == 0); |
| 71 | assert(reinterpret_cast<uintptr_t>(newHasSimulationCollider + nbComponentsToAllocate) <= reinterpret_cast<uintptr_t>(newBuffer) + totalSizeBytes); |
| 72 | |
| 73 | // If there was already components before |
| 74 | if (mNbComponents > 0) { |
| 75 | |
| 76 | // Copy component data from the previous buffer to the new one |
| 77 | memcpy(newBodiesEntities, mBodiesEntities, mNbComponents * sizeof(Entity)); |
| 78 | memcpy(newBodies, mBodies, mNbComponents * sizeof(Body*)); |
| 79 | memcpy(newColliders, mColliders, mNbComponents * sizeof(Array<Entity>)); |
| 80 | memcpy(newIsActive, mIsActive, mNbComponents * sizeof(bool)); |
| 81 | memcpy(newUserData, mUserData, mNbComponents * sizeof(void*)); |
| 82 | memcpy(newHasSimulationCollider, mHasSimulationCollider, mNbComponents * sizeof(bool)); |
| 83 | |
| 84 | // Deallocate previous memory |
| 85 | mMemoryAllocator.release(mBuffer, mNbAllocatedComponents * mComponentDataSize); |
| 86 | } |
| 87 | |
| 88 | mBuffer = newBuffer; |
| 89 | mBodiesEntities = newBodiesEntities; |
| 90 | mBodies = newBodies; |
| 91 | mColliders = newColliders; |
| 92 | mIsActive = newIsActive; |
| 93 | mUserData = newUserData; |
| 94 | mHasSimulationCollider = newHasSimulationCollider; |
| 95 | mNbAllocatedComponents = nbComponentsToAllocate; |
| 96 | } |
| 97 | |
| 98 | // Add a component |
| 99 | void BodyComponents::addComponent(Entity bodyEntity, bool isDisabled, const BodyComponent& component) { |
no test coverage detected