#include "box2d/b2_common.h"
#include "box2d/b2_tracked_block.h"
#include <stddef.h>
#include <stdint.h>
#include <new>
b2TrackedBlock::b2TrackedBlock()
{
b2TrackedBlock** pointerToThis =
(b2TrackedBlock**)((uint8*)GetMemory() - sizeof(b2TrackedBlock**));
*pointerToThis = this;
}
void* b2TrackedBlock::GetMemory() const
{
static const uint32 kSizeOfThisWithNoPadding =
sizeof(*this) - sizeof(m_padding) + sizeof(b2TrackedBlock**);
b2Assert(((b2_mallocAlignment - 1) & b2_mallocAlignment) == 0);
uint8* const aligned = (uint8*)(
((uintptr_t)this + kSizeOfThisWithNoPadding + b2_mallocAlignment - 1) &
~((uintptr_t)b2_mallocAlignment - 1));
b2Assert((uintptr_t)aligned - (uintptr_t)this >= kSizeOfThisWithNoPadding);
return aligned;
}
void* b2TrackedBlock::Allocate(uint32 size)
{
void* memory = (b2TrackedBlock*)b2Alloc(sizeof(b2TrackedBlock) +
size);
if (!memory)
{
return nullptr;
}
return (new(memory) b2TrackedBlock)->GetMemory();
}
b2TrackedBlock* b2TrackedBlock::GetFromMemory(void *memory)
{
uint8* const aligned = (uint8*)memory;
b2Assert(memory);
b2TrackedBlock **blockPtr = (b2TrackedBlock**)(aligned -
sizeof(b2TrackedBlock**));
b2Assert(*blockPtr);
return *blockPtr;
}
void b2TrackedBlock::Free(void *memory)
{
Free(GetFromMemory(memory));
}
void b2TrackedBlock::Free(b2TrackedBlock *block)
{
b2Assert(block);
block->~b2TrackedBlock();
b2Free(block);
}
void* b2TrackedBlockAllocator::Allocate(uint32 size)
{
void *memory = b2TrackedBlock::Allocate(size);
m_blocks.InsertBefore(b2TrackedBlock::GetFromMemory(memory));
return memory;
}
void b2TrackedBlockAllocator::Free(void *memory)
{
b2TrackedBlock::Free(memory);
}
void b2TrackedBlockAllocator::FreeAll()
{
while (!m_blocks.IsEmpty())
{
b2TrackedBlock::Free(m_blocks.GetNext());
}
}