You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openmw/components/detournavigator/recasttempallocator.hpp

67 lines
1.9 KiB
C++

#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_RECASTTEMPALLOCATOR_H
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_RECASTTEMPALLOCATOR_H
#include "recastallocutils.hpp"
#include <RecastAlloc.h>
#include <cassert>
#include <memory>
#include <vector>
namespace DetourNavigator
{
class RecastTempAllocator
{
public:
RecastTempAllocator(std::size_t capacity)
: mStack(capacity)
, mTop(mStack.data())
, mPrev(nullptr)
{
}
void* alloc(std::size_t size)
{
std::size_t space = mStack.size() - getUsedSize();
void* top = mTop;
const auto itemSize = 2 * sizeof(std::size_t) + size;
if (rcUnlikely(!std::align(sizeof(std::size_t), itemSize, top, space)))
return nullptr;
setTempPtrBufferType(top, BufferType_temp);
setTempPtrPrev(top, mPrev);
mTop = static_cast<char*>(top) + itemSize;
mPrev = static_cast<char*>(top);
return getTempPtrDataPtr(top);
}
void free(void* ptr)
{
if (rcUnlikely(!ptr))
return;
assert(BufferType_temp == getDataPtrBufferType(ptr));
if (!mPrev || getTempDataPtrStackPtr(ptr) != mPrev)
{
setDataPtrBufferType(ptr, BufferType_unused);
return;
}
mTop = getTempDataPtrStackPtr(ptr);
mPrev = getTempPtrPrev(mTop);
while (mPrev && BufferType_unused == getTempPtrBufferType(mPrev))
{
mTop = mPrev;
mPrev = getTempPtrPrev(mTop);
}
}
private:
std::vector<char> mStack;
void* mTop;
void* mPrev;
std::size_t getUsedSize() const { return static_cast<std::size_t>(static_cast<char*>(mTop) - mStack.data()); }
};
}
#endif