diff --git a/Recast/Include/Recast.h b/Recast/Include/Recast.h index e85c0d2..a5e22c8 100644 --- a/Recast/Include/Recast.h +++ b/Recast/Include/Recast.h @@ -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. diff --git a/Recast/Source/Recast.cpp b/Recast/Source/Recast.cpp index 8308d19..5d15c6b 100644 --- a/Recast/Source/Recast.cpp +++ b/Recast/Source/Recast.cpp @@ -23,11 +23,34 @@ #include #include #include -#include #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 +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 +void rcDelete(T* ptr) { + if (ptr) { + ptr->~T(); + rcFree((void*)ptr); + } +} +} // namespace + + float rcSqrt(float x) { return sqrtf(x); @@ -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(RC_ALLOC_PERM); } rcHeightfield::rcHeightfield() @@ -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(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()