Skip to content

Commit

Permalink
Add rcNew/rcDelete, template functions that allocate/deallocate objec…
Browse files Browse the repository at this point in the history
…ts using rcAlloc/rcFree. (recastnavigation#324)

Add rcNew/rcDelete, template functions that allocate/deallocate objects using rcAlloc/rcNew.
The intention is to use these to move construction logic out of rcAllocateFooObject/rcFreeFooObject and into constructors/destructors, giving users flexbility in how objects are allocated. In particular, this allows stack allocation.
  • Loading branch information
mbabinski-at-google authored and jakobbotsch committed May 18, 2018
1 parent 1284a2b commit 9235b4a
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 14 deletions.
2 changes: 2 additions & 0 deletions Recast/Include/Recast.h
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,8 @@ struct rcCompactSpan
/// @ingroup recast
struct rcCompactHeightfield
{
rcCompactHeightfield();
~rcCompactHeightfield();
int width; ///< The width of the heightfield. (Along the x-axis in cell units.)
int height; ///< The height of the heightfield. (Along the z-axis in cell units.)
int spanCount; ///< The number of spans in the heightfield.
Expand Down
69 changes: 55 additions & 14 deletions Recast/Source/Recast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,34 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <new>
#include "Recast.h"
#include "RecastAlloc.h"
#include "RecastAssert.h"

namespace
{
/// Allocates and constructs an object of the given type, returning a pointer.
/// TODO: Support constructor args.
/// @param[in] hint Hint to the allocator.
template <typename T>
T* rcNew(rcAllocHint hint) {
T* ptr = (T*)rcAlloc(sizeof(T), hint);
::new(rcNewTag(), (void*)ptr) T();
return ptr;
}

/// Destroys and frees an object allocated with rcNew.
/// @param[in] ptr The object pointer to delete.
template <typename T>
void rcDelete(T* ptr) {
if (ptr) {
ptr->~T();
rcFree((void*)ptr);
}
}
} // namespace


float rcSqrt(float x)
{
return sqrtf(x);
Expand Down Expand Up @@ -73,7 +96,7 @@ void rcContext::log(const rcLogCategory category, const char* format, ...)

rcHeightfield* rcAllocHeightfield()
{
return new (rcAlloc(sizeof(rcHeightfield), RC_ALLOC_PERM)) rcHeightfield;
return rcNew<rcHeightfield>(RC_ALLOC_PERM);
}

rcHeightfield::rcHeightfield()
Expand Down Expand Up @@ -104,26 +127,44 @@ rcHeightfield::~rcHeightfield()

void rcFreeHeightField(rcHeightfield* hf)
{
if (!hf) return;
hf->~rcHeightfield();
rcFree(hf);
rcDelete(hf);
}

rcCompactHeightfield* rcAllocCompactHeightfield()
{
rcCompactHeightfield* chf = (rcCompactHeightfield*)rcAlloc(sizeof(rcCompactHeightfield), RC_ALLOC_PERM);
memset(chf, 0, sizeof(rcCompactHeightfield));
return chf;
return rcNew<rcCompactHeightfield>(RC_ALLOC_PERM);
}

void rcFreeCompactHeightfield(rcCompactHeightfield* chf)
{
if (!chf) return;
rcFree(chf->cells);
rcFree(chf->spans);
rcFree(chf->dist);
rcFree(chf->areas);
rcFree(chf);
rcDelete(chf);
}

rcCompactHeightfield::rcCompactHeightfield()
: width(0),
height(0),
spanCount(0),
walkableHeight(0),
walkableClimb(0),
borderSize(0),
maxDistance(0),
maxRegions(0),
bmin(),
bmax(),
cs(0),
ch(0),
cells(0),
spans(0),
dist(0),
areas(0)
{
}
rcCompactHeightfield::~rcCompactHeightfield()
{
rcFree(cells);
rcFree(spans);
rcFree(dist);
rcFree(areas);
}

rcHeightfieldLayerSet* rcAllocHeightfieldLayerSet()
Expand Down

0 comments on commit 9235b4a

Please sign in to comment.