Kaynağa Gözat

Ability to override memory allocations (#183)

* Override Allocate, Free, AlignedAllocate and AlignedFree if you have your own allocator
* Renamed vectors -> Array, unordered_map -> UnorderedMap,  unordered_set -> UnorderedSet, string -> String
* queue and deque using STLAllocator
* Removed usages of map
* Marked most classes as JPH_OVERRIDE_NEW_DELETE
* Removed 'mGetSupportFunctionGeometry' cache, was very rarely used and was not using the custom allocator
* Added memory allocation hook under windows that can validate that all allocations go through the custom allocator

Note: Define JPH_DISABLE_CUSTOM_ALLOCATOR to use the default allocator. In this case the standard STL types will be used again.
Jorrit Rouwe 3 yıl önce
ebeveyn
işleme
b68097f582
100 değiştirilmiş dosya ile 603 ekleme ve 282 silme
  1. 5 0
      Build/README.md
  2. 3 0
      HelloWorld/HelloWorld.cpp
  3. 1 1
      Jolt/AABBTree/AABBTreeBuilder.cpp
  4. 3 1
      Jolt/AABBTree/AABBTreeBuilder.h
  5. 6 4
      Jolt/AABBTree/AABBTreeToBuffer.h
  6. 1 1
      Jolt/AABBTree/NodeCodec/NodeCodecQuadTreeHalfFloat.h
  7. 3 7
      Jolt/AABBTree/TriangleCodec/TriangleCodecIndexed8BitPackSOA4Flags.h
  8. 2 2
      Jolt/Core/ByteBuffer.h
  9. 2 2
      Jolt/Core/Factory.cpp
  10. 6 7
      Jolt/Core/Factory.h
  11. 5 10
      Jolt/Core/FixedSizeFreeList.h
  12. 7 7
      Jolt/Core/FixedSizeFreeList.inl
  13. 6 0
      Jolt/Core/JobSystem.h
  14. 10 13
      Jolt/Core/JobSystemThreadPool.cpp
  15. 6 2
      Jolt/Core/JobSystemThreadPool.h
  16. 1 1
      Jolt/Core/LinearCurve.h
  17. 1 2
      Jolt/Core/LockFreeHashMap.h
  18. 4 4
      Jolt/Core/LockFreeHashMap.inl
  19. 37 4
      Jolt/Core/Memory.cpp
  20. 43 3
      Jolt/Core/Memory.h
  21. 2 0
      Jolt/Core/MutexArray.h
  22. 6 6
      Jolt/Core/Profiler.cpp
  23. 26 12
      Jolt/Core/Profiler.h
  24. 2 2
      Jolt/Core/Profiler.inl
  25. 2 0
      Jolt/Core/RTTI.h
  26. 1 1
      Jolt/Core/Reference.h
  27. 16 16
      Jolt/Core/Result.h
  28. 1 3
      Jolt/Core/STLAlignedAllocator.h
  29. 101 0
      Jolt/Core/STLAllocator.h
  30. 7 7
      Jolt/Core/StaticArray.h
  31. 6 5
      Jolt/Core/StreamIn.h
  32. 6 5
      Jolt/Core/StreamOut.h
  33. 11 11
      Jolt/Core/StringTools.cpp
  34. 8 7
      Jolt/Core/StringTools.h
  35. 9 4
      Jolt/Core/TempAllocator.h
  36. 1 1
      Jolt/Core/TickCounter.cpp
  37. 14 0
      Jolt/Core/UnorderedMap.h
  38. 14 0
      Jolt/Core/UnorderedSet.h
  39. 2 0
      Jolt/Geometry/AABox.h
  40. 8 8
      Jolt/Geometry/ConvexHullBuilder.cpp
  41. 10 6
      Jolt/Geometry/ConvexHullBuilder.h
  42. 3 3
      Jolt/Geometry/ConvexHullBuilder2D.cpp
  43. 6 4
      Jolt/Geometry/ConvexHullBuilder2D.h
  44. 2 0
      Jolt/Geometry/Ellipse.h
  45. 4 2
      Jolt/Geometry/IndexedTriangle.h
  46. 2 5
      Jolt/Geometry/Indexify.cpp
  47. 2 0
      Jolt/Geometry/OrientedBox.h
  48. 2 0
      Jolt/Geometry/Plane.h
  49. 2 0
      Jolt/Geometry/Sphere.h
  50. 3 1
      Jolt/Geometry/Triangle.h
  51. 4 1
      Jolt/Jolt.cmake
  52. 2 0
      Jolt/Jolt.h
  53. 2 0
      Jolt/Math/DVec3.h
  54. 2 0
      Jolt/Math/Float2.h
  55. 3 1
      Jolt/Math/Float3.h
  56. 2 0
      Jolt/Math/Float4.h
  57. 2 0
      Jolt/Math/Mat44.h
  58. 2 0
      Jolt/Math/Quat.h
  59. 2 0
      Jolt/Math/UVec4.h
  60. 2 0
      Jolt/Math/UVec8.h
  61. 1 5
      Jolt/Math/Vec3.cpp
  62. 2 0
      Jolt/Math/Vec3.h
  63. 2 0
      Jolt/Math/Vec4.h
  64. 2 0
      Jolt/Math/Vec8.h
  65. 2 2
      Jolt/ObjectStream/GetPrimitiveTypeOfType.h
  66. 7 7
      Jolt/ObjectStream/ObjectStream.h
  67. 2 2
      Jolt/ObjectStream/ObjectStreamBinaryIn.cpp
  68. 5 3
      Jolt/ObjectStream/ObjectStreamBinaryIn.h
  69. 3 3
      Jolt/ObjectStream/ObjectStreamBinaryOut.cpp
  70. 4 2
      Jolt/ObjectStream/ObjectStreamBinaryOut.h
  71. 7 10
      Jolt/ObjectStream/ObjectStreamIn.cpp
  72. 6 6
      Jolt/ObjectStream/ObjectStreamIn.h
  73. 8 6
      Jolt/ObjectStream/ObjectStreamOut.h
  74. 20 20
      Jolt/ObjectStream/ObjectStreamTextIn.cpp
  75. 5 3
      Jolt/ObjectStream/ObjectStreamTextIn.h
  76. 5 5
      Jolt/ObjectStream/ObjectStreamTextOut.cpp
  77. 3 1
      Jolt/ObjectStream/ObjectStreamTextOut.h
  78. 1 1
      Jolt/ObjectStream/ObjectStreamTypes.h
  79. 2 2
      Jolt/ObjectStream/SerializableAttribute.h
  80. 1 1
      Jolt/ObjectStream/TypeDeclarations.cpp
  81. 1 1
      Jolt/ObjectStream/TypeDeclarations.h
  82. 3 1
      Jolt/Physics/Body/Body.cpp
  83. 2 0
      Jolt/Physics/Body/Body.h
  84. 2 2
      Jolt/Physics/Body/BodyCreationSettings.h
  85. 1 1
      Jolt/Physics/Body/BodyFilter.h
  86. 2 0
      Jolt/Physics/Body/BodyID.h
  87. 3 1
      Jolt/Physics/Body/BodyManager.cpp
  88. 5 3
      Jolt/Physics/Body/BodyManager.h
  89. 2 0
      Jolt/Physics/Body/BodyPair.h
  90. 2 0
      Jolt/Physics/Body/MotionProperties.h
  91. 4 0
      Jolt/Physics/Character/Character.h
  92. 4 0
      Jolt/Physics/Character/CharacterBase.h
  93. 3 0
      Jolt/Physics/Character/CharacterVirtual.cpp
  94. 7 1
      Jolt/Physics/Character/CharacterVirtual.h
  95. 2 0
      Jolt/Physics/Collision/AABoxCast.h
  96. 1 1
      Jolt/Physics/Collision/BroadPhase/BroadPhaseBruteForce.cpp
  97. 3 1
      Jolt/Physics/Collision/BroadPhase/BroadPhaseBruteForce.h
  98. 4 0
      Jolt/Physics/Collision/BroadPhase/BroadPhaseQuadTree.h
  99. 3 3
      Jolt/Physics/Collision/BroadPhase/QuadTree.cpp
  100. 7 6
      Jolt/Physics/Collision/BroadPhase/QuadTree.h

+ 5 - 0
Build/README.md

@@ -24,6 +24,7 @@ There are a number of user configurable defines that turn on/off certain feature
 - JPH_EXTERNAL_PROFILE - Turns on the internal profiler but forwards the information to a user defined external system (see Profiler.h).
 - JPH_EXTERNAL_PROFILE - Turns on the internal profiler but forwards the information to a user defined external system (see Profiler.h).
 - JPH_DEBUG_RENDERER - Adds support to draw lines and triangles, used to be able to debug draw the state of the world.
 - JPH_DEBUG_RENDERER - Adds support to draw lines and triangles, used to be able to debug draw the state of the world.
 - JPH_DISABLE_TEMP_ALLOCATOR - Disables the temporary memory allocator, used mainly to allow ASAN to do its job.
 - JPH_DISABLE_TEMP_ALLOCATOR - Disables the temporary memory allocator, used mainly to allow ASAN to do its job.
+- JPH_DISABLE_CUSTOM_ALLOCATOR - Disables the ability to override the memory allocator.
 - JPH_FLOATING_POINT_EXCEPTIONS_ENABLED - Turns on division by zero and invalid floating point exception support in order to detect bugs (Windows only).
 - JPH_FLOATING_POINT_EXCEPTIONS_ENABLED - Turns on division by zero and invalid floating point exception support in order to detect bugs (Windows only).
 - JPH_USE_SSE4_1 - Enable SSE4.1 CPU instructions (x86/x64 only)
 - JPH_USE_SSE4_1 - Enable SSE4.1 CPU instructions (x86/x64 only)
 - JPH_USE_SSE4_2 - Enable SSE4.2 CPU instructions (x86/x64 only)
 - JPH_USE_SSE4_2 - Enable SSE4.2 CPU instructions (x86/x64 only)
@@ -38,6 +39,10 @@ There are a number of user configurable defines that turn on/off certain feature
 
 
 To override the default trace and assert mechanism install your own custom handlers in Trace and AssertFailed (see IssueReporting.h).
 To override the default trace and assert mechanism install your own custom handlers in Trace and AssertFailed (see IssueReporting.h).
 
 
+## Custom Memory Allocator
+
+To implement your custom memory allocator override Allocate, Free, AlignedAllocate and AlignedFree (see Memory.h).
+
 ## Building
 ## Building
 
 
 ### Windows 10+ (CL - Default compiler)
 ### Windows 10+ (CL - Default compiler)

+ 3 - 0
HelloWorld/HelloWorld.cpp

@@ -197,6 +197,9 @@ public:
 // Program entry point
 // Program entry point
 int main(int argc, char** argv)
 int main(int argc, char** argv)
 {
 {
+	// Register allocation hook
+	RegisterDefaultAllocator();
+
 	// Install callbacks
 	// Install callbacks
 	Trace = TraceImpl;
 	Trace = TraceImpl;
 	JPH_IF_ENABLE_ASSERTS(AssertFailed = AssertFailedImpl;)
 	JPH_IF_ENABLE_ASSERTS(AssertFailed = AssertFailedImpl;)

+ 1 - 1
Jolt/AABBTree/AABBTreeBuilder.cpp

@@ -84,7 +84,7 @@ float AABBTreeBuilder::Node::CalculateSAHCost(float inCostTraversal, float inCos
 	return surface_area > 0.0f? CalculateSAHCostInternal(inCostTraversal / surface_area, inCostLeaf / surface_area) : 0.0f;
 	return surface_area > 0.0f? CalculateSAHCostInternal(inCostTraversal / surface_area, inCostLeaf / surface_area) : 0.0f;
 }
 }
 
 
-void AABBTreeBuilder::Node::GetNChildren(uint inN, vector<const Node *> &outChildren) const
+void AABBTreeBuilder::Node::GetNChildren(uint inN, Array<const Node *> &outChildren) const
 {
 {
 	JPH_ASSERT(outChildren.empty());
 	JPH_ASSERT(outChildren.empty());
 
 

+ 3 - 1
Jolt/AABBTree/AABBTreeBuilder.h

@@ -38,6 +38,8 @@ public:
 	class Node : public NonCopyable
 	class Node : public NonCopyable
 	{
 	{
 	public:
 	public:
+		JPH_OVERRIDE_NEW_DELETE
+
 		/// Constructor
 		/// Constructor
 							Node();
 							Node();
 							~Node();
 							~Node();
@@ -70,7 +72,7 @@ public:
 		float				CalculateSAHCost(float inCostTraversal, float inCostLeaf) const;
 		float				CalculateSAHCost(float inCostTraversal, float inCostLeaf) const;
 
 
 		/// Recursively get children (breadth first) to get in total inN children (or less if there are no more)
 		/// Recursively get children (breadth first) to get in total inN children (or less if there are no more)
-		void				GetNChildren(uint inN, vector<const Node *> &outChildren) const;
+		void				GetNChildren(uint inN, Array<const Node *> &outChildren) const;
 
 
 		/// Bounding box
 		/// Bounding box
 		AABox				mBounds;
 		AABox				mBounds;

+ 6 - 4
Jolt/AABBTree/AABBTreeToBuffer.h

@@ -13,6 +13,8 @@ JPH_SUPPRESS_WARNINGS_STD_END
 
 
 JPH_NAMESPACE_BEGIN
 JPH_NAMESPACE_BEGIN
 
 
+template <class T> using Deque = deque<T, STLAllocator<T>>;
+
 /// Conversion algorithm that converts an AABB tree to an optimized binary buffer
 /// Conversion algorithm that converts an AABB tree to an optimized binary buffer
 template <class TriangleCodec, class NodeCodec>
 template <class TriangleCodec, class NodeCodec>
 class AABBTreeToBuffer
 class AABBTreeToBuffer
@@ -67,9 +69,9 @@ public:
 			uint *							mParentTrianglesStart = nullptr;			// Where to store mTriangleStart (to patch mChildTrianglesStart of my parent)
 			uint *							mParentTrianglesStart = nullptr;			// Where to store mTriangleStart (to patch mChildTrianglesStart of my parent)
 		};
 		};
 		
 		
-		deque<NodeData *> to_process;
-		deque<NodeData *> to_process_triangles;
-		vector<NodeData> node_list;
+		Deque<NodeData *> to_process;
+		Deque<NodeData *> to_process_triangles;
+		Array<NodeData> node_list;
 
 
 		node_list.reserve(node_count); // Needed to ensure that array is not reallocated, so we can keep pointers in the array
 		node_list.reserve(node_count); // Needed to ensure that array is not reallocated, so we can keep pointers in the array
 		
 		
@@ -81,7 +83,7 @@ public:
 		to_process.push_back(&node_list.back());
 		to_process.push_back(&node_list.back());
 
 
 		// Child nodes out of loop so we don't constantly realloc it
 		// Child nodes out of loop so we don't constantly realloc it
-		vector<const AABBTreeBuilder::Node *> child_nodes;
+		Array<const AABBTreeBuilder::Node *> child_nodes;
 		child_nodes.reserve(NumChildrenPerNode);
 		child_nodes.reserve(NumChildrenPerNode);
 
 
 		for (;;)
 		for (;;)

+ 1 - 1
Jolt/AABBTree/NodeCodec/NodeCodecQuadTreeHalfFloat.h

@@ -71,7 +71,7 @@ public:
 		/// Algorithm can enlarge the bounding boxes of the children during compression and returns these in outChildBoundsMin, outChildBoundsMax
 		/// Algorithm can enlarge the bounding boxes of the children during compression and returns these in outChildBoundsMin, outChildBoundsMax
 		/// inNodeBoundsMin, inNodeBoundsMax is the bounding box if inNode possibly widened by compressing the parent node
 		/// inNodeBoundsMin, inNodeBoundsMax is the bounding box if inNode possibly widened by compressing the parent node
 		/// Returns uint(-1) on error and reports the error in outError
 		/// Returns uint(-1) on error and reports the error in outError
-		uint							NodeAllocate(const AABBTreeBuilder::Node *inNode, Vec3Arg inNodeBoundsMin, Vec3Arg inNodeBoundsMax, vector<const AABBTreeBuilder::Node *> &ioChildren, Vec3 outChildBoundsMin[NumChildrenPerNode], Vec3 outChildBoundsMax[NumChildrenPerNode], ByteBuffer &ioBuffer, const char *&outError) const
+		uint							NodeAllocate(const AABBTreeBuilder::Node *inNode, Vec3Arg inNodeBoundsMin, Vec3Arg inNodeBoundsMax, Array<const AABBTreeBuilder::Node *> &ioChildren, Vec3 outChildBoundsMin[NumChildrenPerNode], Vec3 outChildBoundsMax[NumChildrenPerNode], ByteBuffer &ioBuffer, const char *&outError) const
 		{
 		{
 			// We don't emit nodes for leafs
 			// We don't emit nodes for leafs
 			if (!inNode->HasChildren())
 			if (!inNode->HasChildren())

+ 3 - 7
Jolt/AABBTree/TriangleCodec/TriangleCodecIndexed8BitPackSOA4Flags.h

@@ -5,10 +5,6 @@
 
 
 #include <Jolt/Geometry/RayTriangle.h>
 #include <Jolt/Geometry/RayTriangle.h>
 
 
-JPH_SUPPRESS_WARNINGS_STD_BEGIN
-#include <unordered_map>
-JPH_SUPPRESS_WARNINGS_STD_END
-
 JPH_NAMESPACE_BEGIN
 JPH_NAMESPACE_BEGIN
 
 
 /// Store vertices in 64 bits and indices in 8 bits + 8 bit of flags per triangle like this:
 /// Store vertices in 64 bits and indices in 8 bits + 8 bit of flags per triangle like this:
@@ -214,12 +210,12 @@ public:
 		}
 		}
 
 
 	private:
 	private:
-		using VertexMap = vector<uint32>;
+		using VertexMap = Array<uint32>;
 
 
 		uint						mNumTriangles = 0;
 		uint						mNumTriangles = 0;
-		vector<uint32>				mVertices;				///< Output vertices as an index into the original vertex list (inVertices), sorted according to occurrence
+		Array<uint32>				mVertices;				///< Output vertices as an index into the original vertex list (inVertices), sorted according to occurrence
 		VertexMap					mVertexMap;				///< Maps from the original mesh vertex index (inVertices) to the index in our output vertices (mVertices)
 		VertexMap					mVertexMap;				///< Maps from the original mesh vertex index (inVertices) to the index in our output vertices (mVertices)
-		vector<uint>				mOffsetsToPatch;		///< Offsets to the vertex buffer that need to be patched in once all nodes have been packed
+		Array<uint>					mOffsetsToPatch;		///< Offsets to the vertex buffer that need to be patched in once all nodes have been packed
 	};
 	};
 
 
 	/// This class is used to decode and decompress triangle data packed by the EncodingContext
 	/// This class is used to decode and decompress triangle data packed by the EncodingContext

+ 2 - 2
Jolt/Core/ByteBuffer.h

@@ -40,7 +40,7 @@ public:
 
 
 		// Construct elements
 		// Construct elements
 		for (Type *d = data, *d_end = data + inSize; d < d_end; ++d)
 		for (Type *d = data, *d_end = data + inSize; d < d_end; ++d)
-			new (d) Type;
+			::new (d) Type;
 
 
 		// Return pointer
 		// Return pointer
 		return data;
 		return data;
@@ -48,7 +48,7 @@ public:
 
 
 	/// Append inData to the buffer
 	/// Append inData to the buffer
 	template <class Type>
 	template <class Type>
-	void			AppendVector(const vector<Type> &inData)
+	void			AppendVector(const Array<Type> &inData)
 	{
 	{
 		size_t size = inData.size() * sizeof(Type);
 		size_t size = inData.size() * sizeof(Type);
 		uint8 *data = Allocate<uint8>(size);
 		uint8 *data = Allocate<uint8>(size);

+ 2 - 2
Jolt/Core/Factory.cpp

@@ -74,9 +74,9 @@ void Factory::Clear()
 	mClassHashMap.clear();
 	mClassHashMap.clear();
 }
 }
 
 
-vector<const RTTI *> Factory::GetAllClasses() const
+Array<const RTTI *> Factory::GetAllClasses() const
 {
 {
-	vector<const RTTI *> all_classes;
+	Array<const RTTI *> all_classes;
 	all_classes.reserve(mClassNameMap.size());
 	all_classes.reserve(mClassNameMap.size());
 	for (const ClassNameMap::value_type &c : mClassNameMap)
 	for (const ClassNameMap::value_type &c : mClassNameMap)
 		all_classes.push_back(c.second);
 		all_classes.push_back(c.second);

+ 6 - 7
Jolt/Core/Factory.h

@@ -4,10 +4,7 @@
 #pragma once
 #pragma once
 
 
 #include <Jolt/Core/RTTI.h>
 #include <Jolt/Core/RTTI.h>
-
-JPH_SUPPRESS_WARNINGS_STD_BEGIN
-#include <unordered_map>
-JPH_SUPPRESS_WARNINGS_STD_END
+#include <Jolt/Core/UnorderedMap.h>
 
 
 JPH_NAMESPACE_BEGIN
 JPH_NAMESPACE_BEGIN
 
 
@@ -15,6 +12,8 @@ JPH_NAMESPACE_BEGIN
 class Factory
 class Factory
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Create an object
 	/// Create an object
 	void *						CreateObject(const char *inName);
 	void *						CreateObject(const char *inName);
 
 
@@ -34,15 +33,15 @@ public:
 	void						Clear();
 	void						Clear();
 
 
 	/// Get all registered classes
 	/// Get all registered classes
-	vector<const RTTI *>		GetAllClasses() const;
+	Array<const RTTI *>			GetAllClasses() const;
 
 
 	/// Singleton factory instance
 	/// Singleton factory instance
 	static Factory *			sInstance;
 	static Factory *			sInstance;
 
 
 private:
 private:
-	using ClassNameMap = unordered_map<string_view, const RTTI *>;
+	using ClassNameMap = UnorderedMap<string_view, const RTTI *>;
 
 
-	using ClassHashMap = unordered_map<uint32, const RTTI *>;
+	using ClassHashMap = UnorderedMap<uint32, const RTTI *>;
 
 
 	/// Map of class names to type info
 	/// Map of class names to type info
 	ClassNameMap				mClassNameMap;
 	ClassNameMap				mClassNameMap;

+ 5 - 10
Jolt/Core/FixedSizeFreeList.h

@@ -5,7 +5,6 @@
 
 
 #include <Jolt/Core/NonCopyable.h>
 #include <Jolt/Core/NonCopyable.h>
 #include <Jolt/Core/Mutex.h>
 #include <Jolt/Core/Mutex.h>
-#include <Jolt/Core/Memory.h>
 
 
 JPH_SUPPRESS_WARNINGS_STD_BEGIN
 JPH_SUPPRESS_WARNINGS_STD_BEGIN
 #include <atomic>
 #include <atomic>
@@ -21,14 +20,10 @@ class FixedSizeFreeList : public NonCopyable
 {
 {
 private:
 private:
 	/// Storage type for an Object
 	/// Storage type for an Object
-	struct alignas(Object) ObjectStorage
+	struct ObjectStorage
 	{
 	{
-		/// Constructor to satisfy the vector class
-							ObjectStorage() = default;
-							ObjectStorage(const ObjectStorage &inRHS) : mNextFreeObject(inRHS.mNextFreeObject.load()) { memcpy(mData, inRHS.mData, sizeof(Object)); }
-
-		/// Storage space for the Object, stored as uninitialized data
-		uint8				mData[sizeof(Object)];
+		/// The object we're storing
+		Object				mObject;
 
 
 		/// When the object is freed (or in the process of being freed as a batch) this will contain the next free object
 		/// When the object is freed (or in the process of being freed as a batch) this will contain the next free object
 		/// When an object is in use it will contain the object's index in the free list
 		/// When an object is in use it will contain the object's index in the free list
@@ -116,10 +111,10 @@ public:
 	inline void				DestructObjectBatch(Batch &ioBatch);
 	inline void				DestructObjectBatch(Batch &ioBatch);
 
 
 	/// Access an object by index.
 	/// Access an object by index.
-	inline Object &			Get(uint32 inObjectIndex)				{ return reinterpret_cast<Object &>(GetStorage(inObjectIndex).mData); }
+	inline Object &			Get(uint32 inObjectIndex)				{ return GetStorage(inObjectIndex).mObject; }
 
 
 	/// Access an object by index.
 	/// Access an object by index.
-	inline const Object &	Get(uint32 inObjectIndex) const			{ return reinterpret_cast<const Object &>(GetStorage(inObjectIndex).mData); }
+	inline const Object &	Get(uint32 inObjectIndex) const			{ return GetStorage(inObjectIndex).mObject; }
 };
 };
 
 
 JPH_NAMESPACE_END
 JPH_NAMESPACE_END

+ 7 - 7
Jolt/Core/FixedSizeFreeList.inl

@@ -13,7 +13,7 @@ FixedSizeFreeList<Object>::~FixedSizeFreeList()
 	uint32 num_pages = mNumObjectsAllocated / mPageSize;
 	uint32 num_pages = mNumObjectsAllocated / mPageSize;
 	for (uint32 page = 0; page < num_pages; ++page)
 	for (uint32 page = 0; page < num_pages; ++page)
 		AlignedFree(mPages[page]);
 		AlignedFree(mPages[page]);
-	delete [] mPages;
+	Free(mPages);
 }
 }
 
 
 template <typename Object>
 template <typename Object>
@@ -31,7 +31,7 @@ void FixedSizeFreeList<Object>::Init(uint inMaxObjects, uint inPageSize)
 	JPH_IF_ENABLE_ASSERTS(mNumFreeObjects = mNumPages * inPageSize;)
 	JPH_IF_ENABLE_ASSERTS(mNumFreeObjects = mNumPages * inPageSize;)
 
 
 	// Allocate page table
 	// Allocate page table
-	mPages = new ObjectStorage * [mNumPages];
+	mPages = reinterpret_cast<ObjectStorage **>(Allocate(mNumPages * sizeof(ObjectStorage *)));
 
 
 	// We didn't yet use any objects of any page
 	// We didn't yet use any objects of any page
 	mNumObjectsAllocated = 0;
 	mNumObjectsAllocated = 0;
@@ -66,7 +66,7 @@ uint32 FixedSizeFreeList<Object>::ConstructObject(Parameters &&... inParameters)
 					uint32 next_page = mNumObjectsAllocated / mPageSize;
 					uint32 next_page = mNumObjectsAllocated / mPageSize;
 					if (next_page == mNumPages)
 					if (next_page == mNumPages)
 						return cInvalidObjectIndex; // Out of space!
 						return cInvalidObjectIndex; // Out of space!
-					mPages[next_page] = reinterpret_cast<ObjectStorage *>(AlignedAlloc(mPageSize * sizeof(ObjectStorage), JPH_CACHE_LINE_SIZE));
+					mPages[next_page] = reinterpret_cast<ObjectStorage *>(AlignedAllocate(mPageSize * sizeof(ObjectStorage), max<size_t>(alignof(ObjectStorage), JPH_CACHE_LINE_SIZE)));
 					mNumObjectsAllocated += mPageSize;
 					mNumObjectsAllocated += mPageSize;
 				}
 				}
 			}
 			}
@@ -74,7 +74,7 @@ uint32 FixedSizeFreeList<Object>::ConstructObject(Parameters &&... inParameters)
 			// Allocation successful
 			// Allocation successful
 			JPH_IF_ENABLE_ASSERTS(mNumFreeObjects.fetch_sub(1, memory_order_relaxed);)
 			JPH_IF_ENABLE_ASSERTS(mNumFreeObjects.fetch_sub(1, memory_order_relaxed);)
 			ObjectStorage &storage = GetStorage(first_free);
 			ObjectStorage &storage = GetStorage(first_free);
-			new (&storage.mData) Object(forward<Parameters>(inParameters)...);
+			::new (&storage.mObject) Object(forward<Parameters>(inParameters)...);
 			storage.mNextFreeObject.store(first_free, memory_order_release);
 			storage.mNextFreeObject.store(first_free, memory_order_release);
 			return first_free;
 			return first_free;
 		}
 		}
@@ -92,7 +92,7 @@ uint32 FixedSizeFreeList<Object>::ConstructObject(Parameters &&... inParameters)
 				// Allocation successful
 				// Allocation successful
 				JPH_IF_ENABLE_ASSERTS(mNumFreeObjects.fetch_sub(1, memory_order_relaxed);)
 				JPH_IF_ENABLE_ASSERTS(mNumFreeObjects.fetch_sub(1, memory_order_relaxed);)
 				ObjectStorage &storage = GetStorage(first_free);
 				ObjectStorage &storage = GetStorage(first_free);
-				new (&storage.mData) Object(forward<Parameters>(inParameters)...);
+				::new (&storage.mObject) Object(forward<Parameters>(inParameters)...);
 				storage.mNextFreeObject.store(first_free, memory_order_release);
 				storage.mNextFreeObject.store(first_free, memory_order_release);
 				return first_free;
 				return first_free;
 			}
 			}
@@ -127,7 +127,7 @@ void FixedSizeFreeList<Object>::DestructObjectBatch(Batch &ioBatch)
 			do
 			do
 			{
 			{
 				ObjectStorage &storage = GetStorage(object_idx);
 				ObjectStorage &storage = GetStorage(object_idx);
-				reinterpret_cast<Object &>(storage.mData).~Object();
+				storage.mObject.~Object();
 				object_idx = storage.mNextFreeObject.load(memory_order_relaxed);
 				object_idx = storage.mNextFreeObject.load(memory_order_relaxed);
 			}
 			}
 			while (object_idx != cInvalidObjectIndex);
 			while (object_idx != cInvalidObjectIndex);
@@ -170,7 +170,7 @@ void FixedSizeFreeList<Object>::DestructObject(uint32 inObjectIndex)
 
 
 	// Call destructor
 	// Call destructor
 	ObjectStorage &storage = GetStorage(inObjectIndex); 
 	ObjectStorage &storage = GetStorage(inObjectIndex); 
-	reinterpret_cast<Object &>(storage.mData).~Object();
+	storage.mObject.~Object();
 
 
 	// Add to object free list
 	// Add to object free list
 	for (;;)
 	for (;;)

+ 6 - 0
Jolt/Core/JobSystem.h

@@ -47,6 +47,8 @@ protected:
 	class Job;
 	class Job;
 
 
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// A job handle contains a reference to a job. The job will be deleted as soon as there are no JobHandles.
 	/// A job handle contains a reference to a job. The job will be deleted as soon as there are no JobHandles.
 	/// referring to the job and when it is not in the job queue / being processed.
 	/// referring to the job and when it is not in the job queue / being processed.
 	class JobHandle : private Ref<Job>
 	class JobHandle : private Ref<Job>
@@ -95,6 +97,8 @@ public:
 	class Barrier : public NonCopyable
 	class Barrier : public NonCopyable
 	{
 	{
 	public:
 	public:
+		JPH_OVERRIDE_NEW_DELETE
+
 		/// Add a job to this barrier
 		/// Add a job to this barrier
 		/// Note that jobs can keep being added to the barrier while waiting for the barrier
 		/// Note that jobs can keep being added to the barrier while waiting for the barrier
 		virtual void		AddJob(const JobHandle &inJob) = 0;
 		virtual void		AddJob(const JobHandle &inJob) = 0;
@@ -141,6 +145,8 @@ protected:
 	class Job
 	class Job
 	{
 	{
 	public:
 	public:
+		JPH_OVERRIDE_NEW_DELETE
+
 		/// Constructor
 		/// Constructor
 							Job([[maybe_unused]] const char *inJobName, [[maybe_unused]] ColorArg inColor, JobSystem *inJobSystem, const JobFunction &inJobFunction, uint32 inNumDependencies) : 
 							Job([[maybe_unused]] const char *inJobName, [[maybe_unused]] ColorArg inColor, JobSystem *inJobSystem, const JobFunction &inJobFunction, uint32 inNumDependencies) : 
 		#if defined(JPH_EXTERNAL_PROFILE) || defined(JPH_PROFILE_ENABLED)
 		#if defined(JPH_EXTERNAL_PROFILE) || defined(JPH_PROFILE_ENABLED)

+ 10 - 13
Jolt/Core/JobSystemThreadPool.cpp

@@ -266,7 +266,7 @@ void JobSystemThreadPool::StartThreads(int inNumThreads)
 	mQuit = false;
 	mQuit = false;
 
 
 	// Allocate heads
 	// Allocate heads
-	mHeads = new atomic<uint> [inNumThreads];
+	mHeads = reinterpret_cast<atomic<uint> *>(Allocate(sizeof(atomic<uint>) * inNumThreads));
 	for (int i = 0; i < inNumThreads; ++i)
 	for (int i = 0; i < inNumThreads; ++i)
 		mHeads[i] = 0;
 		mHeads[i] = 0;
 
 
@@ -274,14 +274,7 @@ void JobSystemThreadPool::StartThreads(int inNumThreads)
 	JPH_ASSERT(mThreads.empty());
 	JPH_ASSERT(mThreads.empty());
 	mThreads.reserve(inNumThreads);
 	mThreads.reserve(inNumThreads);
 	for (int i = 0; i < inNumThreads; ++i)
 	for (int i = 0; i < inNumThreads; ++i)
-	{
-		// Name the thread
-		char name[64];
-		snprintf(name, sizeof(name), "Worker %d", int(i + 1));
-
-		// Create thread
-		mThreads.emplace_back([this, name, i] { ThreadMain(name, i); });
-	}
+		mThreads.emplace_back([this, i] { ThreadMain(i); });
 }
 }
 
 
 JobSystemThreadPool::~JobSystemThreadPool()
 JobSystemThreadPool::~JobSystemThreadPool()
@@ -328,7 +321,7 @@ void JobSystemThreadPool::StopThreads()
 	}
 	}
 
 
 	// Destroy heads and reset tail
 	// Destroy heads and reset tail
-	delete [] mHeads;
+	Free(mHeads);
 	mHeads = nullptr;
 	mHeads = nullptr;
 	mTail = 0;
 	mTail = 0;
 }
 }
@@ -523,17 +516,21 @@ static void SetThreadName(const char *inName)
 
 
 #endif
 #endif
 
 
-void JobSystemThreadPool::ThreadMain([[maybe_unused]] const char *inName, int inThreadIndex)
+void JobSystemThreadPool::ThreadMain(int inThreadIndex)
 {
 {
+	// Name the thread
+	char name[64];
+	snprintf(name, sizeof(name), "Worker %d", int(inThreadIndex + 1));
+
 #ifdef JPH_PLATFORM_WINDOWS
 #ifdef JPH_PLATFORM_WINDOWS
-	SetThreadName(inName);
+	SetThreadName(name);
 #endif
 #endif
 
 
 	// Enable floating point exceptions
 	// Enable floating point exceptions
 	FPExceptionsEnable enable_exceptions;
 	FPExceptionsEnable enable_exceptions;
 	JPH_UNUSED(enable_exceptions);
 	JPH_UNUSED(enable_exceptions);
 
 
-	JPH_PROFILE_THREAD_START(inName);
+	JPH_PROFILE_THREAD_START(name);
 
 
 	atomic<uint> &head = mHeads[inThreadIndex];
 	atomic<uint> &head = mHeads[inThreadIndex];
 
 

+ 6 - 2
Jolt/Core/JobSystemThreadPool.h

@@ -22,6 +22,8 @@ JPH_NAMESPACE_BEGIN
 class JobSystemThreadPool final : public JobSystem
 class JobSystemThreadPool final : public JobSystem
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Creates a thread pool.
 	/// Creates a thread pool.
 	/// @see JobSystemThreadPool::Init
 	/// @see JobSystemThreadPool::Init
 							JobSystemThreadPool(uint inMaxJobs, uint inMaxBarriers, int inNumThreads = -1);
 							JobSystemThreadPool(uint inMaxJobs, uint inMaxBarriers, int inNumThreads = -1);
@@ -84,6 +86,8 @@ private:
 	class BarrierImpl : public Barrier
 	class BarrierImpl : public Barrier
 	{
 	{
 	public:
 	public:
+		JPH_OVERRIDE_NEW_DELETE
+
 		/// Constructor
 		/// Constructor
 							BarrierImpl();
 							BarrierImpl();
 		virtual				~BarrierImpl() override;
 		virtual				~BarrierImpl() override;
@@ -120,7 +124,7 @@ private:
 	void					StopThreads();
 	void					StopThreads();
 	
 	
 	/// Entry point for a thread
 	/// Entry point for a thread
-	void					ThreadMain(const char *inName, int inThreadIndex);
+	void					ThreadMain(int inThreadIndex);
 
 
 	/// Get the head of the thread that has processed the least amount of jobs
 	/// Get the head of the thread that has processed the least amount of jobs
 	inline uint				GetHead() const;
 	inline uint				GetHead() const;
@@ -137,7 +141,7 @@ private:
 	BarrierImpl *			mBarriers = nullptr;							///< List of the actual barriers
 	BarrierImpl *			mBarriers = nullptr;							///< List of the actual barriers
 
 
 	/// Threads running jobs
 	/// Threads running jobs
-	vector<thread>			mThreads;
+	Array<thread>			mThreads;
 
 
 	// The job queue
 	// The job queue
 	static constexpr uint32 cQueueLength = 1024;
 	static constexpr uint32 cQueueLength = 1024;

+ 1 - 1
Jolt/Core/LinearCurve.h

@@ -58,7 +58,7 @@ public:
 	void				RestoreBinaryState(StreamIn &inStream);
 	void				RestoreBinaryState(StreamIn &inStream);
 
 
 	/// The points on the curve, should be sorted ascending by x
 	/// The points on the curve, should be sorted ascending by x
-	using Points = vector<Point>;
+	using Points = Array<Point>;
 	Points				mPoints;
 	Points				mPoints;
 };
 };
 
 

+ 1 - 2
Jolt/Core/LockFreeHashMap.h

@@ -3,7 +3,6 @@
 
 
 #pragma once
 #pragma once
 
 
-#include <Jolt/Core/Memory.h>
 #include <Jolt/Core/NonCopyable.h>
 #include <Jolt/Core/NonCopyable.h>
 
 
 JPH_SUPPRESS_WARNINGS_STD_BEGIN
 JPH_SUPPRESS_WARNINGS_STD_BEGIN
@@ -137,7 +136,7 @@ public:
 #endif // JPH_ENABLE_ASSERTS
 #endif // JPH_ENABLE_ASSERTS
 
 
 	/// Get all key/value pairs
 	/// Get all key/value pairs
-	inline void				GetAllKeyValues(vector<const KeyValue *> &outAll) const;
+	inline void				GetAllKeyValues(Array<const KeyValue *> &outAll) const;
 
 
 	/// Non-const iterator
 	/// Non-const iterator
 	struct Iterator
 	struct Iterator

+ 4 - 4
Jolt/Core/LockFreeHashMap.inl

@@ -11,7 +11,7 @@ JPH_NAMESPACE_BEGIN
 
 
 inline LFHMAllocator::~LFHMAllocator()
 inline LFHMAllocator::~LFHMAllocator()
 {
 {
-	delete [] mObjectStore;
+	Free(mObjectStore);
 }
 }
 
 
 inline void LFHMAllocator::Init(uint inObjectStoreSizeBytes)
 inline void LFHMAllocator::Init(uint inObjectStoreSizeBytes)
@@ -19,7 +19,7 @@ inline void LFHMAllocator::Init(uint inObjectStoreSizeBytes)
 	JPH_ASSERT(mObjectStore == nullptr);
 	JPH_ASSERT(mObjectStore == nullptr);
 
 
 	mObjectStoreSizeBytes = inObjectStoreSizeBytes;
 	mObjectStoreSizeBytes = inObjectStoreSizeBytes;
-	mObjectStore = new uint8 [inObjectStoreSizeBytes];
+	mObjectStore = reinterpret_cast<uint8 *>(JPH::Allocate(inObjectStoreSizeBytes));
 }
 }
 
 
 inline void LFHMAllocator::Clear()
 inline void LFHMAllocator::Clear()
@@ -114,7 +114,7 @@ void LockFreeHashMap<Key, Value>::Init(uint32 inMaxBuckets)
 	mNumBuckets = inMaxBuckets;
 	mNumBuckets = inMaxBuckets;
 	mMaxBuckets = inMaxBuckets;
 	mMaxBuckets = inMaxBuckets;
 
 
-	mBuckets = reinterpret_cast<atomic<uint32> *>(AlignedAlloc(inMaxBuckets * sizeof(atomic<uint32>), 16));
+	mBuckets = reinterpret_cast<atomic<uint32> *>(AlignedAllocate(inMaxBuckets * sizeof(atomic<uint32>), 16));
 
 
 	Clear();
 	Clear();
 }
 }
@@ -231,7 +231,7 @@ inline const typename LockFreeHashMap<Key, Value>::KeyValue *LockFreeHashMap<Key
 }
 }
 
 
 template <class Key, class Value>
 template <class Key, class Value>
-inline void LockFreeHashMap<Key, Value>::GetAllKeyValues(vector<const KeyValue *> &outAll) const
+inline void LockFreeHashMap<Key, Value>::GetAllKeyValues(Array<const KeyValue *> &outAll) const
 {
 {
 	for (const atomic<uint32> *bucket = mBuckets; bucket < mBuckets + mNumBuckets; ++bucket)
 	for (const atomic<uint32> *bucket = mBuckets; bucket < mBuckets + mNumBuckets; ++bucket)
 	{
 	{

+ 37 - 4
Jolt/Core/Memory.cpp

@@ -3,8 +3,6 @@
 
 
 #include <Jolt/Jolt.h>
 #include <Jolt/Jolt.h>
 
 
-#include <Jolt/Core/Memory.h>
-
 JPH_SUPPRESS_WARNINGS_STD_BEGIN
 JPH_SUPPRESS_WARNINGS_STD_BEGIN
 #include <cstdlib>
 #include <cstdlib>
 JPH_SUPPRESS_WARNINGS_STD_END
 JPH_SUPPRESS_WARNINGS_STD_END
@@ -12,7 +10,25 @@ JPH_SUPPRESS_WARNINGS_STD_END
 
 
 JPH_NAMESPACE_BEGIN
 JPH_NAMESPACE_BEGIN
 
 
-void *AlignedAlloc(size_t inSize, size_t inAlignment)
+#ifdef JPH_DISABLE_CUSTOM_ALLOCATOR
+	#define JPH_ALLOC_FN(x)	x
+	#define JPH_ALLOC_SCOPE
+#else
+	#define JPH_ALLOC_FN(x)	x##Impl
+	#define JPH_ALLOC_SCOPE static
+#endif
+
+JPH_ALLOC_SCOPE void *JPH_ALLOC_FN(Allocate)(size_t inSize)
+{
+	return malloc(inSize);
+}
+
+JPH_ALLOC_SCOPE void JPH_ALLOC_FN(Free)(void *inBlock)
+{
+	free(inBlock);
+}
+
+JPH_ALLOC_SCOPE void *JPH_ALLOC_FN(AlignedAllocate)(size_t inSize, size_t inAlignment)
 {
 {
 #if defined(JPH_PLATFORM_WINDOWS)
 #if defined(JPH_PLATFORM_WINDOWS)
 	// Microsoft doesn't implement C++17 std::aligned_alloc
 	// Microsoft doesn't implement C++17 std::aligned_alloc
@@ -24,7 +40,7 @@ void *AlignedAlloc(size_t inSize, size_t inAlignment)
 #endif
 #endif
 }
 }
 
 
-void AlignedFree(void *inBlock)
+JPH_ALLOC_SCOPE void JPH_ALLOC_FN(AlignedFree)(void *inBlock)
 {
 {
 #if defined(JPH_PLATFORM_WINDOWS)
 #if defined(JPH_PLATFORM_WINDOWS)
 	_aligned_free(inBlock);
 	_aligned_free(inBlock);
@@ -35,4 +51,21 @@ void AlignedFree(void *inBlock)
 #endif
 #endif
 }
 }
 
 
+#ifndef JPH_DISABLE_CUSTOM_ALLOCATOR
+
+AllocateFunction Allocate = nullptr;
+FreeFunction Free = nullptr;
+AlignedAllocateFunction AlignedAllocate = nullptr;
+AlignedFreeFunction AlignedFree = nullptr;
+
+void RegisterDefaultAllocator()
+{
+	Allocate = AllocateImpl;
+	Free = FreeImpl;
+	AlignedAllocate = AlignedAllocateImpl;
+	AlignedFree = AlignedFreeImpl;
+}
+
+#endif // JPH_DISABLE_CUSTOM_ALLOCATOR
+
 JPH_NAMESPACE_END
 JPH_NAMESPACE_END

+ 43 - 3
Jolt/Core/Memory.h

@@ -5,10 +5,50 @@
 
 
 JPH_NAMESPACE_BEGIN
 JPH_NAMESPACE_BEGIN
 
 
-/// Allocate a block of memory aligned to inAlignment bytes of size inSize
-void *AlignedAlloc(size_t inSize, size_t inAlignment);
+#ifndef JPH_DISABLE_CUSTOM_ALLOCATOR
 
 
-/// Free memory block allocated with AlignedAlloc
+// Normal memory allocation, must be at least 8 byte aligned on 32 bit platform and 16 byte aligned on 64 bit platform
+using AllocateFunction = void *(*)(size_t inSize);
+using FreeFunction = void (*)(void *inBlock);
+
+// Aligned memory allocation
+using AlignedAllocateFunction = void *(*)(size_t inSize, size_t inAlignment);
+using AlignedFreeFunction = void (*)(void *inBlock);
+
+// User defined allocation / free functions
+extern AllocateFunction Allocate;
+extern FreeFunction Free;
+extern AlignedAllocateFunction AlignedAllocate;
+extern AlignedFreeFunction AlignedFree;
+
+/// Register platform default allocation / free functions
+void RegisterDefaultAllocator();
+
+/// Macro to override the new and delete functions
+#define JPH_OVERRIDE_NEW_DELETE \
+	JPH_INLINE void *operator new (size_t inCount)											{ return JPH::Allocate(inCount); } \
+	JPH_INLINE void operator delete (void *inPointer) noexcept								{ JPH::Free(inPointer); } \
+	JPH_INLINE void *operator new[] (size_t inCount)										{ return JPH::Allocate(inCount); } \
+	JPH_INLINE void operator delete[] (void *inPointer) noexcept							{ JPH::Free(inPointer); } \
+	JPH_INLINE void *operator new (size_t inCount, align_val_t inAlignment)					{ return JPH::AlignedAllocate(inCount, static_cast<size_t>(inAlignment)); } \
+	JPH_INLINE void operator delete (void *inPointer, align_val_t inAlignment) noexcept		{ JPH::AlignedFree(inPointer); } \
+	JPH_INLINE void *operator new[] (size_t inCount, align_val_t inAlignment)				{ return JPH::AlignedAllocate(inCount, static_cast<size_t>(inAlignment)); } \
+	JPH_INLINE void operator delete[] (void *inPointer, align_val_t inAlignment) noexcept	{ JPH::AlignedFree(inPointer); }
+
+#else
+
+// Directly define the allocation functions
+void *Allocate(size_t inSize);
+void Free(void *inBlock);
+void *AlignedAllocate(size_t inSize, size_t inAlignment);
 void AlignedFree(void *inBlock);
 void AlignedFree(void *inBlock);
 
 
+// Don't implement allocator registering
+inline void RegisterDefaultAllocator() { }
+
+// Don't override new/delete
+#define JPH_OVERRIDE_NEW_DELETE
+
+#endif // !JPH_DISABLE_CUSTOM_ALLOCATOR
+
 JPH_NAMESPACE_END
 JPH_NAMESPACE_END

+ 2 - 0
Jolt/Core/MutexArray.h

@@ -84,6 +84,8 @@ private:
 	/// Align the mutex to a cache line to ensure there is no false sharing (this is platform dependent, we do this to be safe)
 	/// Align the mutex to a cache line to ensure there is no false sharing (this is platform dependent, we do this to be safe)
 	struct alignas(JPH_CACHE_LINE_SIZE) MutexStorage
 	struct alignas(JPH_CACHE_LINE_SIZE) MutexStorage
 	{
 	{
+		JPH_OVERRIDE_NEW_DELETE
+
 		MutexType			mMutex;
 		MutexType			mMutex;
 	};
 	};
 
 

+ 6 - 6
Jolt/Core/Profiler.cpp

@@ -19,7 +19,7 @@ JPH_NAMESPACE_BEGIN
 // Profiler
 // Profiler
 //////////////////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////////////////
 
 
-Profiler Profiler::sInstance;
+Profiler *Profiler::sInstance = nullptr;
 thread_local ProfileThread *ProfileThread::sInstance = nullptr;
 thread_local ProfileThread *ProfileThread::sInstance = nullptr;
 
 
 bool ProfileMeasurement::sOutOfSamplesReported = false;
 bool ProfileMeasurement::sOutOfSamplesReported = false;
@@ -55,7 +55,7 @@ void Profiler::RemoveThread(ProfileThread *inThread)
 { 
 { 
 	lock_guard lock(mLock); 
 	lock_guard lock(mLock); 
 	
 	
-	vector<ProfileThread *>::iterator i = find(mThreads.begin(), mThreads.end(), inThread); 
+	Array<ProfileThread *>::iterator i = find(mThreads.begin(), mThreads.end(), inThread); 
 	JPH_ASSERT(i != mThreads.end()); 
 	JPH_ASSERT(i != mThreads.end()); 
 	mThreads.erase(i); 
 	mThreads.erase(i); 
 }
 }
@@ -138,7 +138,7 @@ void Profiler::DumpInternal()
 		}
 		}
 
 
 	// Determine tag of this profile
 	// Determine tag of this profile
-	string tag;
+	String tag;
 	if (mDumpTag.empty())
 	if (mDumpTag.empty())
 	{
 	{
 		// Next sequence number
 		// Next sequence number
@@ -167,9 +167,9 @@ void Profiler::DumpInternal()
 	DumpChart(tag.c_str(), threads, key_to_aggregators, aggregators);
 	DumpChart(tag.c_str(), threads, key_to_aggregators, aggregators);
 }
 }
 
 
-static string sHTMLEncode(const char *inString)
+static String sHTMLEncode(const char *inString)
 {
 {
-	string str(inString);
+	String str(inString);
 	StringReplace(str, "<", "&lt;");
 	StringReplace(str, "<", "&lt;");
 	StringReplace(str, ">", "&gt;");
 	StringReplace(str, ">", "&gt;");
 	return str;
 	return str;
@@ -345,7 +345,7 @@ void Profiler::DumpChart(const char *inTag, const Threads &inThreads, const KeyT
 		if (!first)
 		if (!first)
 			f << ",";
 			f << ",";
 		first = false;
 		first = false;
-		string name = "\"" + sHTMLEncode(a.mName) + "\"";
+		String name = "\"" + sHTMLEncode(a.mName) + "\"";
 		f << name;
 		f << name;
 	}
 	}
 	f << "],\ncalls: [";
 	f << "],\ncalls: [";

+ 26 - 12
Jolt/Core/Profiler.h

@@ -5,11 +5,11 @@
 
 
 JPH_SUPPRESS_WARNINGS_STD_BEGIN
 JPH_SUPPRESS_WARNINGS_STD_BEGIN
 #include <mutex>
 #include <mutex>
-#include <unordered_map>
 JPH_SUPPRESS_WARNINGS_STD_END
 JPH_SUPPRESS_WARNINGS_STD_END
 
 
 #include <Jolt/Core/NonCopyable.h>
 #include <Jolt/Core/NonCopyable.h>
 #include <Jolt/Core/TickCounter.h>
 #include <Jolt/Core/TickCounter.h>
+#include <Jolt/Core/UnorderedMap.h>
 
 
 #if defined(JPH_EXTERNAL_PROFILE)
 #if defined(JPH_EXTERNAL_PROFILE)
 
 
@@ -76,6 +76,8 @@ class ProfileThread;
 class Profiler : public NonCopyable
 class Profiler : public NonCopyable
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Increments the frame counter to provide statistics per frame
 	/// Increments the frame counter to provide statistics per frame
 	void						NextFrame();
 	void						NextFrame();
 
 
@@ -90,13 +92,13 @@ public:
 	void						RemoveThread(ProfileThread *inThread);
 	void						RemoveThread(ProfileThread *inThread);
 
 
 	/// Singleton instance
 	/// Singleton instance
-	static Profiler				sInstance;
+	static Profiler *			sInstance;
 								
 								
 private:
 private:
 	/// Helper class to freeze ProfileSamples per thread while processing them
 	/// Helper class to freeze ProfileSamples per thread while processing them
 	struct ThreadSamples
 	struct ThreadSamples
 	{
 	{
-		string					mThreadName;
+		String					mThreadName;
 		ProfileSample *			mSamplesBegin;
 		ProfileSample *			mSamplesBegin;
 		ProfileSample *			mSamplesEnd;
 		ProfileSample *			mSamplesEnd;
 	};
 	};
@@ -135,9 +137,9 @@ private:
 		uint64					mMaxCyclesInCallWithChildren = 0;									///< Maximum amount of cycles spent per call
 		uint64					mMaxCyclesInCallWithChildren = 0;									///< Maximum amount of cycles spent per call
 	};							
 	};							
 
 
-	using Threads = vector<ThreadSamples>;
-	using Aggregators = vector<Aggregator>;
-	using KeyToAggregator = unordered_map<const char *, size_t>;
+	using Threads = Array<ThreadSamples>;
+	using Aggregators = Array<Aggregator>;
+	using KeyToAggregator = UnorderedMap<const char *, size_t>;
 
 
 	/// Helper function to aggregate profile sample data
 	/// Helper function to aggregate profile sample data
 	static void					sAggregate(int inDepth, uint32 inColor, ProfileSample *&ioSample, const ProfileSample *inEnd, Aggregators &ioAggregators, KeyToAggregator &ioKeyToAggregator);
 	static void					sAggregate(int inDepth, uint32 inColor, ProfileSample *&ioSample, const ProfileSample *inEnd, Aggregators &ioAggregators, KeyToAggregator &ioKeyToAggregator);
@@ -148,15 +150,17 @@ private:
 	void						DumpChart(const char *inTag, const Threads &inThreads, const KeyToAggregator &inKeyToAggregators, const Aggregators &inAggregators);
 	void						DumpChart(const char *inTag, const Threads &inThreads, const KeyToAggregator &inKeyToAggregators, const Aggregators &inAggregators);
 
 
 	mutex						mLock;																///< Lock that protects mThreads
 	mutex						mLock;																///< Lock that protects mThreads
-	vector<ProfileThread *>		mThreads;															///< List of all active threads
+	Array<ProfileThread *>		mThreads;															///< List of all active threads
 	bool						mDump = false;														///< When true, the samples are dumped next frame
 	bool						mDump = false;														///< When true, the samples are dumped next frame
-	string						mDumpTag;															///< When not empty, this overrides the auto incrementing number of the dump filename
+	String						mDumpTag;															///< When not empty, this overrides the auto incrementing number of the dump filename
 };							
 };							
 
 
 // Class that contains the information of a single scoped measurement
 // Class that contains the information of a single scoped measurement
 class alignas(16) ProfileSample : public NonCopyable
 class alignas(16) ProfileSample : public NonCopyable
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	const char *				mName;																///< User defined name of this item
 	const char *				mName;																///< User defined name of this item
 	uint32						mColor;																///< Color to use for this sample
 	uint32						mColor;																///< Color to use for this sample
 	uint8						mDepth;																///< Calculated depth
 	uint8						mDepth;																///< Calculated depth
@@ -169,13 +173,15 @@ public:
 class ProfileThread : public NonCopyable
 class ProfileThread : public NonCopyable
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Constructor
 	/// Constructor
 	inline						ProfileThread(const string_view &inThreadName);
 	inline						ProfileThread(const string_view &inThreadName);
 	inline						~ProfileThread();
 	inline						~ProfileThread();
 
 
 	static const uint cMaxSamples = 65536;
 	static const uint cMaxSamples = 65536;
 
 
-	string						mThreadName;														///< Name of the thread that we're collecting information for
+	String						mThreadName;														///< Name of the thread that we're collecting information for
 	ProfileSample				mSamples[cMaxSamples];												///< Buffer of samples
 	ProfileSample				mSamples[cMaxSamples];												///< Buffer of samples
 	uint						mCurrentSample = 0;													///< Next position to write a sample to
 	uint						mCurrentSample = 0;													///< Next position to write a sample to
 
 
@@ -208,8 +214,14 @@ JPH_NAMESPACE_END
 JPH_SUPPRESS_WARNING_PUSH
 JPH_SUPPRESS_WARNING_PUSH
 JPH_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic")
 JPH_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic")
 
 
+/// Start instrumenting program
+#define JPH_PROFILE_START(name)			do { Profiler::sInstance = new Profiler; JPH_PROFILE_THREAD_START(name); } while (false)
+
+/// End instrumenting program
+#define JPH_PROFILE_END()				do { JPH_PROFILE_THREAD_END(); delete Profiler::sInstance; Profiler::sInstance = nullptr; } while (false)
+
 /// Start instrumenting a thread
 /// Start instrumenting a thread
-#define JPH_PROFILE_THREAD_START(name)	ProfileThread::sInstance = new ProfileThread(name)
+#define JPH_PROFILE_THREAD_START(name)	do { if (Profiler::sInstance) ProfileThread::sInstance = new ProfileThread(name); } while (false)
 
 
 /// End instrumenting a thread
 /// End instrumenting a thread
 #define JPH_PROFILE_THREAD_END()		do { delete ProfileThread::sInstance; ProfileThread::sInstance = nullptr; } while (false)
 #define JPH_PROFILE_THREAD_END()		do { delete ProfileThread::sInstance; ProfileThread::sInstance = nullptr; } while (false)
@@ -223,10 +235,10 @@ JPH_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic")
 #define JPH_PROFILE_FUNCTION()			JPH_PROFILE(JPH_FUNCTION_NAME)
 #define JPH_PROFILE_FUNCTION()			JPH_PROFILE(JPH_FUNCTION_NAME)
 								
 								
 /// Update frame counter								
 /// Update frame counter								
-#define JPH_PROFILE_NEXTFRAME()			Profiler::sInstance.NextFrame()
+#define JPH_PROFILE_NEXTFRAME()			Profiler::sInstance->NextFrame()
 
 
 /// Dump profiling info
 /// Dump profiling info
-#define JPH_PROFILE_DUMP(...)			Profiler::sInstance.Dump(__VA_ARGS__)
+#define JPH_PROFILE_DUMP(...)			Profiler::sInstance->Dump(__VA_ARGS__)
 
 
 JPH_SUPPRESS_WARNING_POP
 JPH_SUPPRESS_WARNING_POP
 
 
@@ -239,6 +251,8 @@ JPH_SUPPRESS_WARNING_POP
 JPH_SUPPRESS_WARNING_PUSH
 JPH_SUPPRESS_WARNING_PUSH
 JPH_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic")
 JPH_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic")
 
 
+#define JPH_PROFILE_START(name)
+#define JPH_PROFILE_END()
 #define JPH_PROFILE_THREAD_START(name)
 #define JPH_PROFILE_THREAD_START(name)
 #define JPH_PROFILE_THREAD_END()
 #define JPH_PROFILE_THREAD_END()
 #define JPH_PROFILE(...)
 #define JPH_PROFILE(...)

+ 2 - 2
Jolt/Core/Profiler.inl

@@ -10,12 +10,12 @@ JPH_NAMESPACE_BEGIN
 ProfileThread::ProfileThread(const string_view &inThreadName) :
 ProfileThread::ProfileThread(const string_view &inThreadName) :
 	mThreadName(inThreadName)
 	mThreadName(inThreadName)
 {
 {
-	Profiler::sInstance.AddThread(this);
+	Profiler::sInstance->AddThread(this);
 }
 }
 
 
 ProfileThread::~ProfileThread()
 ProfileThread::~ProfileThread()
 {
 {
-	Profiler::sInstance.RemoveThread(this);
+	Profiler::sInstance->RemoveThread(this);
 }
 }
 
 
 //////////////////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////////////////

+ 2 - 0
Jolt/Core/RTTI.h

@@ -189,6 +189,7 @@ protected:
 // JPH_DECLARE_RTTI_NON_VIRTUAL
 // JPH_DECLARE_RTTI_NON_VIRTUAL
 #define JPH_DECLARE_RTTI_NON_VIRTUAL(class_name)																	\
 #define JPH_DECLARE_RTTI_NON_VIRTUAL(class_name)																	\
 public:																												\
 public:																												\
+	JPH_OVERRIDE_NEW_DELETE																							\
 	friend RTTI *				GetRTTIOfType(class_name *);														\
 	friend RTTI *				GetRTTIOfType(class_name *);														\
 	friend inline const RTTI *	GetRTTI(const class_name *inObject) { return GetRTTIOfType((class_name *)nullptr); }\
 	friend inline const RTTI *	GetRTTI(const class_name *inObject) { return GetRTTIOfType((class_name *)nullptr); }\
 	static void					sCreateRTTI(RTTI &inRTTI);															\
 	static void					sCreateRTTI(RTTI &inRTTI);															\
@@ -228,6 +229,7 @@ public:																												\
 
 
 #define JPH_DECLARE_RTTI_HELPER(class_name, modifier)																\
 #define JPH_DECLARE_RTTI_HELPER(class_name, modifier)																\
 public:																												\
 public:																												\
+	JPH_OVERRIDE_NEW_DELETE																							\
 	friend RTTI *				GetRTTIOfType(class_name *);														\
 	friend RTTI *				GetRTTIOfType(class_name *);														\
 	friend inline const RTTI *	GetRTTI(const class_name *inObject) { return inObject->GetRTTI(); }					\
 	friend inline const RTTI *	GetRTTI(const class_name *inObject) { return inObject->GetRTTI(); }					\
 	virtual const RTTI *		GetRTTI() const modifier;															\
 	virtual const RTTI *		GetRTTI() const modifier;															\

+ 1 - 1
Jolt/Core/Reference.h

@@ -43,7 +43,7 @@ public:
 	/// Mark this class as embedded, this means the type can be used in a compound or constructed on the stack.
 	/// Mark this class as embedded, this means the type can be used in a compound or constructed on the stack.
 	/// The Release function will never destruct the object, it is assumed the destructor will be called by whoever allocated
 	/// The Release function will never destruct the object, it is assumed the destructor will be called by whoever allocated
 	/// the object and at that point in time it is checked that no references are left to the structure.
 	/// the object and at that point in time it is checked that no references are left to the structure.
-	inline void				SetEmbedded()									{ JPH_IF_ENABLE_ASSERTS(uint32 old = ) mRefCount.fetch_add(cEmbedded, memory_order_relaxed); JPH_ASSERT(old < cEmbedded); }
+	inline void				SetEmbedded() const								{ JPH_IF_ENABLE_ASSERTS(uint32 old = ) mRefCount.fetch_add(cEmbedded, memory_order_relaxed); JPH_ASSERT(old < cEmbedded); }
 
 
 	/// Assignment operator
 	/// Assignment operator
 	inline RefTarget &		operator = (const RefTarget &)					{ /* Don't copy refcount */ return *this; }
 	inline RefTarget &		operator = (const RefTarget &)					{ /* Don't copy refcount */ return *this; }

+ 16 - 16
Jolt/Core/Result.h

@@ -20,11 +20,11 @@ public:
 		switch (inRHS.mState)
 		switch (inRHS.mState)
 		{
 		{
 		case EState::Valid:
 		case EState::Valid:
-			new (&mResult) Type (inRHS.mResult);
+			::new (&mResult) Type (inRHS.mResult);
 			break;
 			break;
 
 
 		case EState::Error:
 		case EState::Error:
-			new (&mError) string(inRHS.mError);
+			::new (&mError) String(inRHS.mError);
 			break;
 			break;
 
 
 		case EState::Invalid:
 		case EState::Invalid:
@@ -39,11 +39,11 @@ public:
 		switch (inRHS.mState)
 		switch (inRHS.mState)
 		{
 		{
 		case EState::Valid:
 		case EState::Valid:
-			new (&mResult) Type (move(inRHS.mResult));
+			::new (&mResult) Type (move(inRHS.mResult));
 			break;
 			break;
 
 
 		case EState::Error:
 		case EState::Error:
-			new (&mError) string(move(inRHS.mError));
+			::new (&mError) String(move(inRHS.mError));
 			break;
 			break;
 
 
 		case EState::Invalid:
 		case EState::Invalid:
@@ -66,11 +66,11 @@ public:
 		switch (inRHS.mState)
 		switch (inRHS.mState)
 		{
 		{
 		case EState::Valid:
 		case EState::Valid:
-			new (&mResult) Type (inRHS.mResult);
+			::new (&mResult) Type (inRHS.mResult);
 			break;
 			break;
 
 
 		case EState::Error:
 		case EState::Error:
-			new (&mError) string(inRHS.mError);
+			::new (&mError) String(inRHS.mError);
 			break;
 			break;
 
 
 		case EState::Invalid:
 		case EState::Invalid:
@@ -90,11 +90,11 @@ public:
 		switch (inRHS.mState)
 		switch (inRHS.mState)
 		{
 		{
 		case EState::Valid:
 		case EState::Valid:
-			new (&mResult) Type (move(inRHS.mResult));
+			::new (&mResult) Type (move(inRHS.mResult));
 			break;
 			break;
 
 
 		case EState::Error:
 		case EState::Error:
-			new (&mError) string(move(inRHS.mError));
+			::new (&mError) String(move(inRHS.mError));
 			break;
 			break;
 
 
 		case EState::Invalid:
 		case EState::Invalid:
@@ -116,7 +116,7 @@ public:
 			break; 
 			break; 
 
 
 		case EState::Error:
 		case EState::Error:
-			mError.~string();
+			mError.~String();
 			break;
 			break;
 
 
 		case EState::Invalid:
 		case EState::Invalid:
@@ -136,27 +136,27 @@ public:
 	const Type &		Get() const									{ JPH_ASSERT(IsValid()); return mResult; }
 	const Type &		Get() const									{ JPH_ASSERT(IsValid()); return mResult; }
 
 
 	/// Set the result value
 	/// Set the result value
-	void				Set(const Type &inResult)					{ Clear(); new (&mResult) Type(inResult); mState = EState::Valid; }
+	void				Set(const Type &inResult)					{ Clear(); ::new (&mResult) Type(inResult); mState = EState::Valid; }
 
 
 	/// Set the result value (move value)
 	/// Set the result value (move value)
-	void				Set(const Type &&inResult)					{ Clear(); new (&mResult) Type(move(inResult)); mState = EState::Valid; }
+	void				Set(const Type &&inResult)					{ Clear(); ::new (&mResult) Type(move(inResult)); mState = EState::Valid; }
 
 
 	/// Check if we had an error
 	/// Check if we had an error
 	bool				HasError() const							{ return mState == EState::Error; }
 	bool				HasError() const							{ return mState == EState::Error; }
 
 
 	/// Get the error value
 	/// Get the error value
-	const string &		GetError() const							{ JPH_ASSERT(HasError()); return mError; }
+	const String &		GetError() const							{ JPH_ASSERT(HasError()); return mError; }
 
 
 	/// Set an error value
 	/// Set an error value
-	void				SetError(const char *inError)				{ Clear(); new (&mError) string(inError); mState = EState::Error; }
-	void				SetError(const string_view &inError)		{ Clear(); new (&mError) string(inError); mState = EState::Error; }
-	void				SetError(string &&inError)					{ Clear(); new (&mError) string(move(inError)); mState = EState::Error; }
+	void				SetError(const char *inError)				{ Clear(); ::new (&mError) String(inError); mState = EState::Error; }
+	void				SetError(const string_view &inError)		{ Clear(); ::new (&mError) String(inError); mState = EState::Error; }
+	void				SetError(String &&inError)					{ Clear(); ::new (&mError) String(move(inError)); mState = EState::Error; }
 
 
 private:
 private:
 	union
 	union
 	{
 	{
 		Type			mResult;									///< The actual result object
 		Type			mResult;									///< The actual result object
-		string			mError;										///< The error description if the result failed
+		String			mError;										///< The error description if the result failed
 	};
 	};
 
 
 	/// State of the result
 	/// State of the result

+ 1 - 3
Jolt/Core/STLAlignedAllocator.h

@@ -3,8 +3,6 @@
 
 
 #pragma once
 #pragma once
 
 
-#include <Jolt/Core/Memory.h>
-
 JPH_NAMESPACE_BEGIN
 JPH_NAMESPACE_BEGIN
 
 
 /// STL allocator that takes care that memory is aligned to N bytes
 /// STL allocator that takes care that memory is aligned to N bytes
@@ -36,7 +34,7 @@ public:
 	/// Allocate memory
 	/// Allocate memory
 	inline pointer			allocate(size_type inN)
 	inline pointer			allocate(size_type inN)
 	{
 	{
-		return (pointer)AlignedAlloc(inN * sizeof(value_type), N);
+		return (pointer)AlignedAllocate(inN * sizeof(value_type), N);
 	}
 	}
 
 
 	/// Free memory
 	/// Free memory

+ 101 - 0
Jolt/Core/STLAllocator.h

@@ -0,0 +1,101 @@
+// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
+// SPDX-License-Identifier: MIT
+
+#pragma once
+
+JPH_NAMESPACE_BEGIN
+
+#ifndef JPH_DISABLE_CUSTOM_ALLOCATOR
+
+/// STL allocator that forwards to our allocation functions
+template <typename T>
+class STLAllocator
+{
+public:
+	using value_type = T;
+
+	/// Pointer to type
+	using pointer = T *;
+	using const_pointer = const T *;
+
+	/// Reference to type.
+	/// Can be removed in C++20.
+	using reference = T &;
+	using const_reference = const T &;
+
+	using size_type = size_t;
+	using difference_type = ptrdiff_t;
+
+	/// Constructor
+	inline					STLAllocator() = default;
+
+	/// Constructor from other allocator
+	template <typename T2>
+	inline					STLAllocator(const STLAllocator<T2> &) { }
+
+	/// Allocate memory
+	inline pointer			allocate(size_type inN)
+	{
+		if constexpr (alignof(T) > (JPH_CPU_ADDRESS_BITS == 32? 8 : 16))
+			return (pointer)AlignedAllocate(inN * sizeof(value_type), alignof(T));
+		else
+			return (pointer)Allocate(inN * sizeof(value_type));
+	}
+
+	/// Free memory
+	inline void				deallocate(pointer inPointer, size_type)
+	{
+		if constexpr (alignof(T) > (JPH_CPU_ADDRESS_BITS == 32? 8 : 16))
+			AlignedFree(inPointer);
+		else
+			Free(inPointer);
+	}
+
+	/// Allocators are stateless so assumed to be equal
+	inline bool				operator == (const STLAllocator<T> &) const
+	{
+		return true;
+	}
+
+	inline bool				operator != (const STLAllocator<T> &) const
+	{
+		return false;
+	}
+
+	/// Converting to allocator for other type
+	template <typename T2>
+	struct rebind
+	{
+		using other = STLAllocator<T2>;
+	};
+};
+
+#else
+
+template <typename T> using STLAllocator = allocator<T>;
+
+#endif // !JPH_DISABLE_CUSTOM_ALLOCATOR
+
+// Declare STL containers that use our allocator
+template <class T> using Array = vector<T, STLAllocator<T>>;
+using String = basic_string<char, char_traits<char>, STLAllocator<char>>;
+using IStringStream = basic_istringstream<char, char_traits<char>, STLAllocator<char>>;
+
+JPH_NAMESPACE_END
+
+#if !defined(JPH_PLATFORM_WINDOWS) && !defined(JPH_DISABLE_CUSTOM_ALLOCATOR)
+
+namespace std
+{
+	/// Declare std::hash for String, for some reason on Linux based platforms template deduction takes the wrong variant
+	template <> 
+	struct hash<JPH::String>
+	{
+		inline size_t operator () (const JPH::String &inRHS) const
+		{
+			return hash<string_view> { } (inRHS);
+		}
+	};
+}
+
+#endif // !JPH_PLATFORM_WINDOWS && !JPH_DISABLE_CUSTOM_ALLOCATOR

+ 7 - 7
Jolt/Core/StaticArray.h

@@ -22,7 +22,7 @@ public:
 	{
 	{
 		JPH_ASSERT(inList.size() <= N);
 		JPH_ASSERT(inList.size() <= N);
 		for (typename initializer_list<T>::iterator i = inList.begin(); i != inList.end(); ++i)
 		for (typename initializer_list<T>::iterator i = inList.begin(); i != inList.end(); ++i)
-			new (reinterpret_cast<T *>(&mElements[mSize++])) T(*i);
+			::new (reinterpret_cast<T *>(&mElements[mSize++])) T(*i);
 	}
 	}
 
 
 	/// Copy constructor
 	/// Copy constructor
@@ -30,7 +30,7 @@ public:
 	{
 	{
 		while (mSize < inRHS.mSize)
 		while (mSize < inRHS.mSize)
 		{
 		{
-			new (&mElements[mSize]) T(inRHS[mSize]);
+			::new (&mElements[mSize]) T(inRHS[mSize]);
 			++mSize;
 			++mSize;
 		}
 		}
 	}
 	}
@@ -56,7 +56,7 @@ public:
 	void				push_back(const T &inElement)
 	void				push_back(const T &inElement)
 	{
 	{
 		JPH_ASSERT(mSize < N);
 		JPH_ASSERT(mSize < N);
-		new (&mElements[mSize++]) T(inElement);
+		::new (&mElements[mSize++]) T(inElement);
 	}
 	}
 
 
 	/// Construct element at the back of the array
 	/// Construct element at the back of the array
@@ -64,7 +64,7 @@ public:
 	void				emplace_back(A &&... inElement)
 	void				emplace_back(A &&... inElement)
 	{	
 	{	
 		JPH_ASSERT(mSize < N);
 		JPH_ASSERT(mSize < N);
-		new (&mElements[mSize++]) T(forward<A>(inElement)...);
+		::new (&mElements[mSize++]) T(forward<A>(inElement)...);
 	}
 	}
 
 
 	/// Remove element from the back of the array
 	/// Remove element from the back of the array
@@ -98,7 +98,7 @@ public:
 		JPH_ASSERT(inNewSize <= N);
 		JPH_ASSERT(inNewSize <= N);
 		if (!is_trivially_constructible<T>() && mSize < inNewSize)
 		if (!is_trivially_constructible<T>() && mSize < inNewSize)
 			for (T *element = reinterpret_cast<T *>(mElements) + mSize, *element_end = reinterpret_cast<T *>(mElements) + inNewSize; element < element_end; ++element)
 			for (T *element = reinterpret_cast<T *>(mElements) + mSize, *element_end = reinterpret_cast<T *>(mElements) + inNewSize; element < element_end; ++element)
-				new (element) T;
+				::new (element) T;
 		else if (!is_trivially_destructible<T>() && mSize > inNewSize)
 		else if (!is_trivially_destructible<T>() && mSize > inNewSize)
 			for (T *element = reinterpret_cast<T *>(mElements) + inNewSize, *element_end = reinterpret_cast<T *>(mElements) + mSize; element < element_end; ++element)
 			for (T *element = reinterpret_cast<T *>(mElements) + inNewSize, *element_end = reinterpret_cast<T *>(mElements) + mSize; element < element_end; ++element)
 				element->~T();
 				element->~T();
@@ -214,7 +214,7 @@ public:
 
 
 			while (mSize < rhs_size)
 			while (mSize < rhs_size)
 			{
 			{
-				new (&mElements[mSize]) T(inRHS[mSize]);
+				::new (&mElements[mSize]) T(inRHS[mSize]);
 				++mSize;
 				++mSize;
 			}
 			}
 		}
 		}
@@ -235,7 +235,7 @@ public:
 
 
 			while (mSize < rhs_size)
 			while (mSize < rhs_size)
 			{
 			{
-				new (&mElements[mSize]) T(inRHS[mSize]);
+				::new (&mElements[mSize]) T(inRHS[mSize]);
 				++mSize;
 				++mSize;
 			}
 			}
 		}
 		}

+ 6 - 5
Jolt/Core/StreamIn.h

@@ -32,12 +32,12 @@ public:
 	template <class T, class A>
 	template <class T, class A>
 	void				Read(vector<T, A> &outT)
 	void				Read(vector<T, A> &outT)
 	{
 	{
-		typename vector<T>::size_type len = outT.size(); // Initialize to previous array size, this is used for validation in the StateRecorder class
+		typename Array<T>::size_type len = outT.size(); // Initialize to previous array size, this is used for validation in the StateRecorder class
 		Read(len);
 		Read(len);
 		if (!IsEOF() && !IsFailed())
 		if (!IsEOF() && !IsFailed())
 		{
 		{
 			outT.resize(len);
 			outT.resize(len);
-			for (typename vector<T>::size_type i = 0; i < len; ++i)
+			for (typename Array<T>::size_type i = 0; i < len; ++i)
 				Read(outT[i]);
 				Read(outT[i]);
 		}
 		}
 		else
 		else
@@ -45,14 +45,15 @@ public:
 	}
 	}
 
 
 	/// Read a string from the binary stream (reads the number of characters and then the characters)
 	/// Read a string from the binary stream (reads the number of characters and then the characters)
-	void				Read(string &outString)
+	template <class Type, class Traits, class Allocator>
+	void				Read(basic_string<Type, Traits, Allocator> &outString)
 	{
 	{
-		string::size_type len = 0;
+		typename basic_string<Type, Traits, Allocator>::size_type len = 0;
 		Read(len);
 		Read(len);
 		if (!IsEOF() && !IsFailed())
 		if (!IsEOF() && !IsFailed())
 		{
 		{
 			outString.resize(len);
 			outString.resize(len);
-			ReadBytes(outString.data(), len);
+			ReadBytes(outString.data(), len * sizeof(Type));
 		}
 		}
 		else
 		else
 			outString.clear();
 			outString.clear();

+ 6 - 5
Jolt/Core/StreamOut.h

@@ -29,20 +29,21 @@ public:
 	template <class T, class A>
 	template <class T, class A>
 	void				Write(const vector<T, A> &inT)
 	void				Write(const vector<T, A> &inT)
 	{
 	{
-		typename vector<T>::size_type len = inT.size();
+		typename Array<T>::size_type len = inT.size();
 		Write(len);
 		Write(len);
 		if (!IsFailed())
 		if (!IsFailed())
-			for (typename vector<T>::size_type i = 0; i < len; ++i)
+			for (typename Array<T>::size_type i = 0; i < len; ++i)
 				Write(inT[i]);
 				Write(inT[i]);
 	}
 	}
 
 
 	/// Write a string to the binary stream (writes the number of characters and then the characters)
 	/// Write a string to the binary stream (writes the number of characters and then the characters)
-	void				Write(const string &inString)
+	template <class Type, class Traits, class Allocator>
+	void				Write(const basic_string<Type, Traits, Allocator> &inString)
 	{
 	{
-		string::size_type len = inString.size();
+		typename basic_string<Type, Traits, Allocator>::size_type len = inString.size();
 		Write(len);
 		Write(len);
 		if (!IsFailed())
 		if (!IsFailed())
-			WriteBytes(inString.data(), len);
+			WriteBytes(inString.data(), len * sizeof(Type));
 	}
 	}
 
 
 	/// Write a Vec3 (don't write W)
 	/// Write a Vec3 (don't write W)

+ 11 - 11
Jolt/Core/StringTools.cpp

@@ -11,7 +11,7 @@ JPH_SUPPRESS_WARNINGS_STD_END
 
 
 JPH_NAMESPACE_BEGIN
 JPH_NAMESPACE_BEGIN
 
 
-string StringFormat(const char *inFMT, ...)
+String StringFormat(const char *inFMT, ...)
 {
 {
 	char buffer[1024];
 	char buffer[1024];
 
 
@@ -20,16 +20,16 @@ string StringFormat(const char *inFMT, ...)
 	va_start(list, inFMT);
 	va_start(list, inFMT);
 	vsnprintf(buffer, sizeof(buffer), inFMT, list);
 	vsnprintf(buffer, sizeof(buffer), inFMT, list);
 
 
-	return string(buffer);
+	return String(buffer);
 }
 }
 
 
-void StringReplace(string &ioString, const string_view &inSearch, const string_view &inReplace)
+void StringReplace(String &ioString, const string_view &inSearch, const string_view &inReplace)
 {
 {
 	size_t index = 0;
 	size_t index = 0;
 	for (;;)
 	for (;;)
 	{
 	{
 		 index = ioString.find(inSearch, index);
 		 index = ioString.find(inSearch, index);
-		 if (index == std::string::npos) 
+		 if (index == String::npos) 
 			 break;
 			 break;
 
 
 		 ioString.replace(index, inSearch.size(), inReplace);
 		 ioString.replace(index, inSearch.size(), inReplace);
@@ -38,7 +38,7 @@ void StringReplace(string &ioString, const string_view &inSearch, const string_v
 	}
 	}
 }
 }
 
 
-void StringToVector(const string_view &inString, vector<string> &outVector, const string_view &inDelimiter, bool inClearVector)
+void StringToVector(const string_view &inString, Array<String> &outVector, const string_view &inDelimiter, bool inClearVector)
 {
 {
 	JPH_ASSERT(inDelimiter.size() > 0);
 	JPH_ASSERT(inDelimiter.size() > 0);
 
 
@@ -51,11 +51,11 @@ void StringToVector(const string_view &inString, vector<string> &outVector, cons
 		return;
 		return;
 
 
 	// Start with initial string
 	// Start with initial string
-	string s(inString);
+	String s(inString);
 
 
 	// Add to vector while we have a delimiter
 	// Add to vector while we have a delimiter
 	size_t i;
 	size_t i;
-	while (!s.empty() && (i = s.find(inDelimiter)) != string::npos)
+	while (!s.empty() && (i = s.find(inDelimiter)) != String::npos)
 	{
 	{
 		outVector.push_back(s.substr(0, i));
 		outVector.push_back(s.substr(0, i));
 		s.erase(0, i + inDelimiter.length());
 		s.erase(0, i + inDelimiter.length());
@@ -65,12 +65,12 @@ void StringToVector(const string_view &inString, vector<string> &outVector, cons
 	outVector.push_back(s);
 	outVector.push_back(s);
 }
 }
 
 
-void VectorToString(const vector<string> &inVector, string &outString, const string_view &inDelimiter)
+void VectorToString(const Array<String> &inVector, String &outString, const string_view &inDelimiter)
 {
 {
 	// Ensure string empty
 	// Ensure string empty
 	outString.clear();
 	outString.clear();
 
 
-	for (const string &s : inVector)
+	for (const String &s : inVector)
 	{
 	{
 		// Add delimiter if not first element
 		// Add delimiter if not first element
 		if (!outString.empty())
 		if (!outString.empty())
@@ -81,9 +81,9 @@ void VectorToString(const vector<string> &inVector, string &outString, const str
 	}
 	}
 }
 }
 
 
-string ToLower(const string_view &inString)
+String ToLower(const string_view &inString)
 {
 {
-	string out;
+	String out;
 	out.reserve(inString.length());
 	out.reserve(inString.length());
 	for (char c : inString)
 	for (char c : inString)
 		out.push_back((char)tolower(c));
 		out.push_back((char)tolower(c));

+ 8 - 7
Jolt/Core/StringTools.h

@@ -7,13 +7,14 @@ JPH_NAMESPACE_BEGIN
 
 
 /// Create a formatted text string for debugging purposes.
 /// Create a formatted text string for debugging purposes.
 /// Note that this function has an internal buffer of 1024 characters, so long strings will be trimmed.
 /// Note that this function has an internal buffer of 1024 characters, so long strings will be trimmed.
-string StringFormat(const char *inFMT, ...);
+String StringFormat(const char *inFMT, ...);
 
 
 /// Convert type to string
 /// Convert type to string
 template<typename T>
 template<typename T>
-string ConvertToString(const T &inValue)
+String ConvertToString(const T &inValue)
 {
 {
-    ostringstream oss;
+	using OStringStream = basic_ostringstream<char, char_traits<char>, STLAllocator<char>>;
+    OStringStream oss;
     oss << inValue;
     oss << inValue;
     return oss.str();
     return oss.str();
 }
 }
@@ -32,16 +33,16 @@ constexpr uint64 HashString(const char *inString)
 }
 }
 
 
 /// Replace substring with other string
 /// Replace substring with other string
-void StringReplace(string &ioString, const string_view &inSearch, const string_view &inReplace);
+void StringReplace(String &ioString, const string_view &inSearch, const string_view &inReplace);
 
 
 /// Convert a delimited string to an array of strings
 /// Convert a delimited string to an array of strings
-void StringToVector(const string_view &inString, vector<string> &outVector, const string_view &inDelimiter = ",", bool inClearVector = true);
+void StringToVector(const string_view &inString, Array<String> &outVector, const string_view &inDelimiter = ",", bool inClearVector = true);
 
 
 /// Convert an array strings to a delimited string
 /// Convert an array strings to a delimited string
-void VectorToString(const vector<string> &inVector, string &outString, const string_view &inDelimiter = ",");
+void VectorToString(const Array<String> &inVector, String &outString, const string_view &inDelimiter = ",");
 
 
 /// Convert a string to lower case
 /// Convert a string to lower case
-string ToLower(const string_view &inString);
+String ToLower(const string_view &inString);
 
 
 /// Converts the lower 4 bits of inNibble to a string that represents the number in binary format
 /// Converts the lower 4 bits of inNibble to a string that represents the number in binary format
 const char *NibbleToBinary(uint32 inNibble);
 const char *NibbleToBinary(uint32 inNibble);

+ 9 - 4
Jolt/Core/TempAllocator.h

@@ -4,7 +4,6 @@
 #pragma once
 #pragma once
 
 
 #include <Jolt/Core/NonCopyable.h>
 #include <Jolt/Core/NonCopyable.h>
-#include <Jolt/Core/Memory.h>
 
 
 JPH_NAMESPACE_BEGIN
 JPH_NAMESPACE_BEGIN
 
 
@@ -15,6 +14,8 @@ JPH_NAMESPACE_BEGIN
 class TempAllocator : public NonCopyable
 class TempAllocator : public NonCopyable
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Destructor
 	/// Destructor
 	virtual							~TempAllocator() = default;
 	virtual							~TempAllocator() = default;
 
 
@@ -29,9 +30,11 @@ public:
 class TempAllocatorImpl final : public TempAllocator
 class TempAllocatorImpl final : public TempAllocator
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Constructs the allocator with a maximum allocatable size of inSize
 	/// Constructs the allocator with a maximum allocatable size of inSize
 	explicit						TempAllocatorImpl(uint inSize) :
 	explicit						TempAllocatorImpl(uint inSize) :
-		mBase(static_cast<uint8 *>(malloc(inSize))),
+		mBase(static_cast<uint8 *>(JPH::Allocate(inSize))),
 		mSize(inSize)
 		mSize(inSize)
 	{
 	{
 	}
 	}
@@ -40,7 +43,7 @@ public:
 	virtual							~TempAllocatorImpl() override
 	virtual							~TempAllocatorImpl() override
 	{
 	{
 		JPH_ASSERT(mTop == 0);
 		JPH_ASSERT(mTop == 0);
-		free(mBase);
+		JPH::Free(mBase);
 	}
 	}
 
 
 	// See: TempAllocator
 	// See: TempAllocator
@@ -93,10 +96,12 @@ private:
 class TempAllocatorMalloc final : public TempAllocator
 class TempAllocatorMalloc final : public TempAllocator
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	// See: TempAllocator
 	// See: TempAllocator
 	virtual void *					Allocate(uint inSize) override
 	virtual void *					Allocate(uint inSize) override
 	{
 	{
-		return AlignedAlloc(inSize, 16);
+		return AlignedAllocate(inSize, 16);
 	}
 	}
 
 
 	// See: TempAllocator
 	// See: TempAllocator

+ 1 - 1
Jolt/Core/TickCounter.cpp

@@ -79,7 +79,7 @@ static const uint64 sProcessorTicksPerSecond = []() {
 			{
 			{
 				// Find ':'
 				// Find ':'
 				string::size_type pos = line.find(':', num_chars);
 				string::size_type pos = line.find(':', num_chars);
-				if (pos != string::npos)
+				if (pos != String::npos)
 				{		
 				{		
 					// Convert to number
 					// Convert to number
 					string freq = line.substr(pos + 1);
 					string freq = line.substr(pos + 1);

+ 14 - 0
Jolt/Core/UnorderedMap.h

@@ -0,0 +1,14 @@
+// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
+// SPDX-License-Identifier: MIT
+
+#pragma once
+
+JPH_SUPPRESS_WARNINGS_STD_BEGIN
+#include <unordered_map>
+JPH_SUPPRESS_WARNINGS_STD_END
+
+JPH_NAMESPACE_BEGIN
+
+template <class Key, class T, class Hash = hash<Key>, class KeyEqual = equal_to<Key>> using UnorderedMap = unordered_map<Key, T, Hash, KeyEqual, STLAllocator<pair<const Key, T>>>;
+
+JPH_NAMESPACE_END

+ 14 - 0
Jolt/Core/UnorderedSet.h

@@ -0,0 +1,14 @@
+// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
+// SPDX-License-Identifier: MIT
+
+#pragma once
+
+JPH_SUPPRESS_WARNINGS_STD_BEGIN
+#include <unordered_set>
+JPH_SUPPRESS_WARNINGS_STD_END
+
+JPH_NAMESPACE_BEGIN
+
+template <class Key, class Hash = hash<Key>, class KeyEqual = equal_to<Key>> using UnorderedSet = unordered_set<Key, Hash, KeyEqual, STLAllocator<Key>>;
+
+JPH_NAMESPACE_END

+ 2 - 0
Jolt/Geometry/AABox.h

@@ -14,6 +14,8 @@ JPH_NAMESPACE_BEGIN
 class [[nodiscard]] AABox
 class [[nodiscard]] AABox
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Constructor
 	/// Constructor
 					AABox()												: mMin(Vec3::sReplicate(FLT_MAX)), mMax(Vec3::sReplicate(-FLT_MAX)) { }
 					AABox()												: mMin(Vec3::sReplicate(FLT_MAX)), mMax(Vec3::sReplicate(-FLT_MAX)) { }
 					AABox(Vec3Arg inMin, Vec3Arg inMax)					: mMin(inMin), mMax(inMax) { }
 					AABox(Vec3Arg inMin, Vec3Arg inMax)					: mMin(inMin), mMax(inMax) { }

+ 8 - 8
Jolt/Geometry/ConvexHullBuilder.cpp

@@ -7,9 +7,9 @@
 #include <Jolt/Geometry/ConvexHullBuilder2D.h>
 #include <Jolt/Geometry/ConvexHullBuilder2D.h>
 #include <Jolt/Geometry/ClosestPoint.h>
 #include <Jolt/Geometry/ClosestPoint.h>
 #include <Jolt/Core/StringTools.h>
 #include <Jolt/Core/StringTools.h>
+#include <Jolt/Core/UnorderedSet.h>
 
 
 JPH_SUPPRESS_WARNINGS_STD_BEGIN
 JPH_SUPPRESS_WARNINGS_STD_BEGIN
-#include <unordered_set>
 #include <fstream>
 #include <fstream>
 JPH_SUPPRESS_WARNINGS_STD_END
 JPH_SUPPRESS_WARNINGS_STD_END
 
 
@@ -246,7 +246,7 @@ float ConvexHullBuilder::DetermineCoplanarDistance() const
 
 
 int ConvexHullBuilder::GetNumVerticesUsed() const
 int ConvexHullBuilder::GetNumVerticesUsed() const
 {
 {
-	unordered_set<int> used_verts;
+	UnorderedSet<int> used_verts;
 	for (Face *f : mFaces)
 	for (Face *f : mFaces)
 	{
 	{
 		Edge *e = f->mFirstEdge;
 		Edge *e = f->mFirstEdge;
@@ -259,12 +259,12 @@ int ConvexHullBuilder::GetNumVerticesUsed() const
 	return (int)used_verts.size();
 	return (int)used_verts.size();
 }
 }
 
 
-bool ConvexHullBuilder::ContainsFace(const vector<int> &inIndices) const
+bool ConvexHullBuilder::ContainsFace(const Array<int> &inIndices) const
 {
 {
 	for (Face *f : mFaces)
 	for (Face *f : mFaces)
 	{
 	{
 		Edge *e = f->mFirstEdge;
 		Edge *e = f->mFirstEdge;
-		vector<int>::const_iterator index = find(inIndices.begin(), inIndices.end(), e->mStartIdx);
+		Array<int>::const_iterator index = find(inIndices.begin(), inIndices.end(), e->mStartIdx);
 		if (index != inIndices.end())
 		if (index != inIndices.end())
 		{
 		{
 			size_t matches = 0;
 			size_t matches = 0;
@@ -404,13 +404,13 @@ ConvexHullBuilder::EResult ConvexHullBuilder::Initialize(int inMaxVertices, floa
 		// First project all points in 2D space
 		// First project all points in 2D space
 		Vec3 base1 = initial_plane_normal.GetNormalizedPerpendicular();
 		Vec3 base1 = initial_plane_normal.GetNormalizedPerpendicular();
 		Vec3 base2 = initial_plane_normal.Cross(base1);
 		Vec3 base2 = initial_plane_normal.Cross(base1);
-		vector<Vec3> positions_2d;
+		Array<Vec3> positions_2d;
 		positions_2d.reserve(mPositions.size());
 		positions_2d.reserve(mPositions.size());
 		for (Vec3 v : mPositions)
 		for (Vec3 v : mPositions)
 			positions_2d.push_back(Vec3(base1.Dot(v), base2.Dot(v), 0));
 			positions_2d.push_back(Vec3(base1.Dot(v), base2.Dot(v), 0));
 
 
 		// Build hull
 		// Build hull
-		vector<int> edges_2d;
+		Array<int> edges_2d;
 		ConvexHullBuilder2D builder_2d(positions_2d);
 		ConvexHullBuilder2D builder_2d(positions_2d);
 		ConvexHullBuilder2D::EResult result = builder_2d.Initialize(idx1, idx2, idx3, inMaxVertices, inTolerance, edges_2d);
 		ConvexHullBuilder2D::EResult result = builder_2d.Initialize(idx1, idx2, idx3, inMaxVertices, inTolerance, edges_2d);
 
 
@@ -419,7 +419,7 @@ ConvexHullBuilder::EResult ConvexHullBuilder::Initialize(int inMaxVertices, floa
 		Face *f2 = CreateFace();
 		Face *f2 = CreateFace();
 
 
 		// Create edges for face 1
 		// Create edges for face 1
-		vector<Edge *> edges_f1;
+		Array<Edge *> edges_f1;
 		edges_f1.reserve(edges_2d.size());
 		edges_f1.reserve(edges_2d.size());
 		for (int start_idx : edges_2d)
 		for (int start_idx : edges_2d)
 		{
 		{
@@ -433,7 +433,7 @@ ConvexHullBuilder::EResult ConvexHullBuilder::Initialize(int inMaxVertices, floa
 		edges_f1.back()->mNextEdge = f1->mFirstEdge;
 		edges_f1.back()->mNextEdge = f1->mFirstEdge;
 
 
 		// Create edges for face 2
 		// Create edges for face 2
-		vector<Edge *> edges_f2;
+		Array<Edge *> edges_f2;
 		edges_f2.reserve(edges_2d.size());
 		edges_f2.reserve(edges_2d.size());
 		for (int i = (int)edges_2d.size() - 1; i >= 0; --i)
 		for (int i = (int)edges_2d.size() - 1; i >= 0; --i)
 		{
 		{

+ 10 - 6
Jolt/Geometry/ConvexHullBuilder.h

@@ -26,6 +26,8 @@ public:
 	class Edge : public NonCopyable
 	class Edge : public NonCopyable
 	{
 	{
 	public:
 	public:
+		JPH_OVERRIDE_NEW_DELETE
+
 		/// Constructor
 		/// Constructor
 						Edge(Face *inFace, int inStartIdx)	: mFace(inFace), mStartIdx(inStartIdx) { }
 						Edge(Face *inFace, int inStartIdx)	: mFace(inFace), mStartIdx(inStartIdx) { }
 
 
@@ -44,12 +46,14 @@ public:
 		int				mStartIdx;							///< Vertex index in mPositions that indicates the start vertex of this edge
 		int				mStartIdx;							///< Vertex index in mPositions that indicates the start vertex of this edge
 	};
 	};
 
 
-	using ConflictList = vector<int>;
+	using ConflictList = Array<int>;
 
 
 	/// Class that holds the information of one face
 	/// Class that holds the information of one face
 	class Face : public NonCopyable
 	class Face : public NonCopyable
 	{
 	{
 	public:
 	public:
+		JPH_OVERRIDE_NEW_DELETE
+
 		/// Destructor
 		/// Destructor
 						~Face();
 						~Face();
 
 
@@ -78,8 +82,8 @@ public:
 	};
 	};
 
 
 	// Typedefs
 	// Typedefs
-	using Positions = vector<Vec3>;
-	using Faces = vector<Face *>;
+	using Positions = Array<Vec3>;
+	using Faces = Array<Face *>;
 
 
 	/// Constructor
 	/// Constructor
 	explicit			ConvexHullBuilder(const Positions &inPositions);
 	explicit			ConvexHullBuilder(const Positions &inPositions);
@@ -108,7 +112,7 @@ public:
 	int					GetNumVerticesUsed() const;
 	int					GetNumVerticesUsed() const;
 
 
 	/// Returns true if the hull contains a polygon with inIndices (counter clockwise indices in mPositions)
 	/// Returns true if the hull contains a polygon with inIndices (counter clockwise indices in mPositions)
-	bool				ContainsFace(const vector<int> &inIndices) const;
+	bool				ContainsFace(const Array<int> &inIndices) const;
 
 
 	/// Calculate the center of mass and the volume of the current convex hull
 	/// Calculate the center of mass and the volume of the current convex hull
 	void				GetCenterOfMassAndVolume(Vec3 &outCenterOfMass, float &outVolume) const;
 	void				GetCenterOfMassAndVolume(Vec3 &outCenterOfMass, float &outVolume) const;
@@ -142,7 +146,7 @@ private:
 	};
 	};
 
 
 	// Private typedefs
 	// Private typedefs
-	using FullEdges = vector<FullEdge>;
+	using FullEdges = Array<FullEdge>;
 
 
 	// Determine a suitable tolerance for detecting that points are coplanar
 	// Determine a suitable tolerance for detecting that points are coplanar
 	float				DetermineCoplanarDistance() const;
 	float				DetermineCoplanarDistance() const;
@@ -256,7 +260,7 @@ private:
 		int				mPositionIdx;						///< Index in mPositions
 		int				mPositionIdx;						///< Index in mPositions
 		float			mDistanceSq;						///< Distance to the edge of closest face (should be > 0)
 		float			mDistanceSq;						///< Distance to the edge of closest face (should be > 0)
 	};
 	};
-	using CoplanarList = vector<Coplanar>;
+	using CoplanarList = Array<Coplanar>;
 
 
 	CoplanarList		mCoplanarList;						///< List of positions that are coplanar to a face but outside of the face, these are added to the hull at the end
 	CoplanarList		mCoplanarList;						///< List of positions that are coplanar to a face but outside of the face, these are added to the hull at the end
 
 

+ 3 - 3
Jolt/Geometry/ConvexHullBuilder2D.cpp

@@ -106,7 +106,7 @@ void ConvexHullBuilder2D::ValidateEdges() const
 
 
 #endif // JPH_ENABLE_ASSERTS
 #endif // JPH_ENABLE_ASSERTS
 
 
-void ConvexHullBuilder2D::AssignPointToEdge(int inPositionIdx, const vector<Edge *> &inEdges) const
+void ConvexHullBuilder2D::AssignPointToEdge(int inPositionIdx, const Array<Edge *> &inEdges) const
 {
 {
 	Vec3 point = mPositions[inPositionIdx];
 	Vec3 point = mPositions[inPositionIdx];
 
 
@@ -185,7 +185,7 @@ ConvexHullBuilder2D::EResult ConvexHullBuilder2D::Initialize(int inIdx1, int inI
 	mNumEdges = 3;
 	mNumEdges = 3;
 
 
 	// Build the initial conflict lists
 	// Build the initial conflict lists
-	vector<Edge *> edges { e1, e2, e3 };
+	Array<Edge *> edges { e1, e2, e3 };
 	for (Edge *edge : edges)
 	for (Edge *edge : edges)
 		edge->CalculateNormalAndCenter(mPositions.data());
 		edge->CalculateNormalAndCenter(mPositions.data());
 	for (int idx = 0; idx < (int)mPositions.size(); ++idx)
 	for (int idx = 0; idx < (int)mPositions.size(); ++idx)
@@ -262,7 +262,7 @@ ConvexHullBuilder2D::EResult ConvexHullBuilder2D::Initialize(int inIdx1, int inI
 		mNumEdges += 2;
 		mNumEdges += 2;
 
 
 		// Calculate normals
 		// Calculate normals
-		vector<Edge *> new_edges { e1, e2 };
+		Array<Edge *> new_edges { e1, e2 };
 		for (Edge *new_edge : new_edges)
 		for (Edge *new_edge : new_edges)
 			new_edge->CalculateNormalAndCenter(mPositions.data());
 			new_edge->CalculateNormalAndCenter(mPositions.data());
 
 

+ 6 - 4
Jolt/Geometry/ConvexHullBuilder2D.h

@@ -13,8 +13,8 @@ JPH_NAMESPACE_BEGIN
 class ConvexHullBuilder2D : public NonCopyable
 class ConvexHullBuilder2D : public NonCopyable
 {
 {
 public:
 public:
-	using Positions = vector<Vec3>; 
-	using Edges = vector<int>;
+	using Positions = Array<Vec3>; 
+	using Edges = Array<int>;
 
 
 	/// Constructor
 	/// Constructor
 	/// @param inPositions Positions used to make the hull. Uses X and Y component of Vec3 only!
 	/// @param inPositions Positions used to make the hull. Uses X and Y component of Vec3 only!
@@ -53,7 +53,7 @@ private:
 	/// Assigns a position to one of the supplied edges based on which edge is closest.
 	/// Assigns a position to one of the supplied edges based on which edge is closest.
 	/// @param inPositionIdx Index of the position to add
 	/// @param inPositionIdx Index of the position to add
 	/// @param inEdges List of edges to consider
 	/// @param inEdges List of edges to consider
-	void				AssignPointToEdge(int inPositionIdx, const vector<Edge *> &inEdges) const;
+	void				AssignPointToEdge(int inPositionIdx, const Array<Edge *> &inEdges) const;
 
 
 #ifdef JPH_CONVEX_BUILDER_2D_DEBUG
 #ifdef JPH_CONVEX_BUILDER_2D_DEBUG
 	/// Draw state of algorithm
 	/// Draw state of algorithm
@@ -65,12 +65,14 @@ private:
 	void				ValidateEdges() const;
 	void				ValidateEdges() const;
 #endif
 #endif
 
 
-	using ConflictList = vector<int>;
+	using ConflictList = Array<int>;
 
 
 	/// Linked list of edges
 	/// Linked list of edges
 	class Edge
 	class Edge
 	{
 	{
 	public:
 	public:
+		JPH_OVERRIDE_NEW_DELETE
+
 		/// Constructor
 		/// Constructor
 		explicit		Edge(int inStartIdx)						: mStartIdx(inStartIdx) { }
 		explicit		Edge(int inStartIdx)						: mStartIdx(inStartIdx) { }
 
 

+ 2 - 0
Jolt/Geometry/Ellipse.h

@@ -12,6 +12,8 @@ JPH_NAMESPACE_BEGIN
 class Ellipse
 class Ellipse
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Construct ellipse with radius A along the X-axis and B along the Y-axis
 	/// Construct ellipse with radius A along the X-axis and B along the Y-axis
 					Ellipse(float inA, float inB) : mA(inA), mB(inB) { JPH_ASSERT(inA > 0.0f); JPH_ASSERT(inB > 0.0f); }
 					Ellipse(float inA, float inB) : mA(inA), mB(inB) { JPH_ASSERT(inA > 0.0f); JPH_ASSERT(inB > 0.0f); }
 
 

+ 4 - 2
Jolt/Geometry/IndexedTriangle.h

@@ -11,6 +11,8 @@ JPH_NAMESPACE_BEGIN
 class IndexedTriangleNoMaterial
 class IndexedTriangleNoMaterial
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Constructor
 	/// Constructor
 					IndexedTriangleNoMaterial() = default;
 					IndexedTriangleNoMaterial() = default;
 					IndexedTriangleNoMaterial(uint32 inI1, uint32 inI2, uint32 inI3)	{ mIdx[0] = inI1; mIdx[1] = inI2; mIdx[2] = inI3; }
 					IndexedTriangleNoMaterial(uint32 inI1, uint32 inI2, uint32 inI3)	{ mIdx[0] = inI1; mIdx[1] = inI2; mIdx[2] = inI3; }
@@ -98,8 +100,8 @@ public:
 	uint32			mMaterialIndex = 0;
 	uint32			mMaterialIndex = 0;
 };
 };
 
 
-using IndexedTriangleNoMaterialList = vector<IndexedTriangleNoMaterial>;
-using IndexedTriangleList = vector<IndexedTriangle>;
+using IndexedTriangleNoMaterialList = Array<IndexedTriangleNoMaterial>;
+using IndexedTriangleList = Array<IndexedTriangle>;
 
 
 JPH_NAMESPACE_END
 JPH_NAMESPACE_END
 
 

+ 2 - 5
Jolt/Geometry/Indexify.cpp

@@ -3,12 +3,9 @@
 
 
 #include <Jolt/Jolt.h>
 #include <Jolt/Jolt.h>
 
 
+#include <Jolt/Core/UnorderedMap.h>
 #include <Jolt/Geometry/Indexify.h>
 #include <Jolt/Geometry/Indexify.h>
 
 
-JPH_SUPPRESS_WARNINGS_STD_BEGIN
-#include <unordered_map>
-JPH_SUPPRESS_WARNINGS_STD_END
-
 JPH_NAMESPACE_BEGIN
 JPH_NAMESPACE_BEGIN
 
 
 void Indexify(const TriangleList &inTriangles, VertexList &outVertices, IndexedTriangleList &outTriangles, float inVertexWeldDistance)
 void Indexify(const TriangleList &inTriangles, VertexList &outVertices, IndexedTriangleList &outTriangles, float inVertexWeldDistance)
@@ -19,7 +16,7 @@ void Indexify(const TriangleList &inTriangles, VertexList &outVertices, IndexedT
 	outVertices.clear();
 	outVertices.clear();
 
 
 	// Find unique vertices
 	// Find unique vertices
-	unordered_map<Float3, uint32> vertex_map;
+	UnorderedMap<Float3, uint32> vertex_map;
 	for (const Triangle &t : inTriangles)
 	for (const Triangle &t : inTriangles)
 		for (const Float3 &v : t.mV)
 		for (const Float3 &v : t.mV)
 		{
 		{

+ 2 - 0
Jolt/Geometry/OrientedBox.h

@@ -16,6 +16,8 @@ class AABox;
 class [[nodiscard]] OrientedBox
 class [[nodiscard]] OrientedBox
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Constructor
 	/// Constructor
 					OrientedBox() = default;
 					OrientedBox() = default;
 					OrientedBox(Mat44Arg inOrientation, Vec3Arg inHalfExtents)			: mOrientation(inOrientation), mHalfExtents(inHalfExtents) { }
 					OrientedBox(Mat44Arg inOrientation, Vec3Arg inHalfExtents)			: mOrientation(inOrientation), mHalfExtents(inHalfExtents) { }

+ 2 - 0
Jolt/Geometry/Plane.h

@@ -9,6 +9,8 @@ JPH_NAMESPACE_BEGIN
 class [[nodiscard]] Plane
 class [[nodiscard]] Plane
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Constructor
 	/// Constructor
 					Plane() = default;
 					Plane() = default;
 	explicit		Plane(Vec4Arg inNormalAndConstant)										: mNormalAndConstant(inNormalAndConstant) { }
 	explicit		Plane(Vec4Arg inNormalAndConstant)										: mNormalAndConstant(inNormalAndConstant) { }

+ 2 - 0
Jolt/Geometry/Sphere.h

@@ -10,6 +10,8 @@ JPH_NAMESPACE_BEGIN
 class [[nodiscard]] Sphere
 class [[nodiscard]] Sphere
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Constructor
 	/// Constructor
 	inline				Sphere() = default;
 	inline				Sphere() = default;
 	inline				Sphere(const Float3 &inCenter, float inRadius)			: mCenter(inCenter), mRadius(inRadius) { }
 	inline				Sphere(const Float3 &inCenter, float inRadius)			: mCenter(inCenter), mRadius(inRadius) { }

+ 3 - 1
Jolt/Geometry/Triangle.h

@@ -9,6 +9,8 @@ JPH_NAMESPACE_BEGIN
 class Triangle
 class Triangle
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Constructor
 	/// Constructor
 					Triangle() = default;
 					Triangle() = default;
 					Triangle(const Float3 &inV1, const Float3 &inV2, const Float3 &inV3) : mV { inV1, inV2, inV3 } { }
 					Triangle(const Float3 &inV1, const Float3 &inV2, const Float3 &inV3) : mV { inV1, inV2, inV3 } { }
@@ -26,6 +28,6 @@ public:
 	uint32			mMaterialIndex = 0;			///< Follows mV[3] so that we can read mV as 4 vectors
 	uint32			mMaterialIndex = 0;			///< Follows mV[3] so that we can read mV as 4 vectors
 };
 };
 
 
-using TriangleList = vector<Triangle>;
+using TriangleList = Array<Triangle>;
 
 
 JPH_NAMESPACE_END
 JPH_NAMESPACE_END

+ 4 - 1
Jolt/Jolt.cmake

@@ -50,10 +50,13 @@ set(JOLT_PHYSICS_SRC_FILES
 	${JOLT_PHYSICS_ROOT}/Core/StringTools.cpp
 	${JOLT_PHYSICS_ROOT}/Core/StringTools.cpp
 	${JOLT_PHYSICS_ROOT}/Core/StringTools.h
 	${JOLT_PHYSICS_ROOT}/Core/StringTools.h
 	${JOLT_PHYSICS_ROOT}/Core/STLAlignedAllocator.h
 	${JOLT_PHYSICS_ROOT}/Core/STLAlignedAllocator.h
+	${JOLT_PHYSICS_ROOT}/Core/STLAllocator.h
 	${JOLT_PHYSICS_ROOT}/Core/STLTempAllocator.h
 	${JOLT_PHYSICS_ROOT}/Core/STLTempAllocator.h
 	${JOLT_PHYSICS_ROOT}/Core/TempAllocator.h
 	${JOLT_PHYSICS_ROOT}/Core/TempAllocator.h
 	${JOLT_PHYSICS_ROOT}/Core/TickCounter.cpp
 	${JOLT_PHYSICS_ROOT}/Core/TickCounter.cpp
 	${JOLT_PHYSICS_ROOT}/Core/TickCounter.h
 	${JOLT_PHYSICS_ROOT}/Core/TickCounter.h
+	${JOLT_PHYSICS_ROOT}/Core/UnorderedMap.h
+	${JOLT_PHYSICS_ROOT}/Core/UnorderedSet.h
 	${JOLT_PHYSICS_ROOT}/Geometry/AABox.h
 	${JOLT_PHYSICS_ROOT}/Geometry/AABox.h
 	${JOLT_PHYSICS_ROOT}/Geometry/AABox4.h
 	${JOLT_PHYSICS_ROOT}/Geometry/AABox4.h
 	${JOLT_PHYSICS_ROOT}/Geometry/ClipPoly.h
 	${JOLT_PHYSICS_ROOT}/Geometry/ClipPoly.h
@@ -401,6 +404,6 @@ target_precompile_headers(Jolt PRIVATE ${JOLT_PHYSICS_ROOT}/Jolt.h)
 target_compile_definitions(Jolt PUBLIC "$<$<CONFIG:Debug>:_DEBUG;JPH_PROFILE_ENABLED;JPH_DEBUG_RENDERER>")
 target_compile_definitions(Jolt PUBLIC "$<$<CONFIG:Debug>:_DEBUG;JPH_PROFILE_ENABLED;JPH_DEBUG_RENDERER>")
 target_compile_definitions(Jolt PUBLIC "$<$<CONFIG:Release>:NDEBUG;JPH_PROFILE_ENABLED;JPH_DEBUG_RENDERER>")
 target_compile_definitions(Jolt PUBLIC "$<$<CONFIG:Release>:NDEBUG;JPH_PROFILE_ENABLED;JPH_DEBUG_RENDERER>")
 target_compile_definitions(Jolt PUBLIC "$<$<CONFIG:Distribution>:NDEBUG>")
 target_compile_definitions(Jolt PUBLIC "$<$<CONFIG:Distribution>:NDEBUG>")
-target_compile_definitions(Jolt PUBLIC "$<$<CONFIG:ReleaseASAN>:NDEBUG;JPH_PROFILE_ENABLED;JPH_DISABLE_TEMP_ALLOCATOR;JPH_DEBUG_RENDERER>")
+target_compile_definitions(Jolt PUBLIC "$<$<CONFIG:ReleaseASAN>:NDEBUG;JPH_PROFILE_ENABLED;JPH_DISABLE_TEMP_ALLOCATOR;JPH_DISABLE_CUSTOM_ALLOCATOR;JPH_DEBUG_RENDERER>")
 target_compile_definitions(Jolt PUBLIC "$<$<CONFIG:ReleaseUBSAN>:NDEBUG;JPH_PROFILE_ENABLED;JPH_DEBUG_RENDERER>")
 target_compile_definitions(Jolt PUBLIC "$<$<CONFIG:ReleaseUBSAN>:NDEBUG;JPH_PROFILE_ENABLED;JPH_DEBUG_RENDERER>")
 target_compile_definitions(Jolt PUBLIC "$<$<CONFIG:ReleaseCoverage>:NDEBUG>")
 target_compile_definitions(Jolt PUBLIC "$<$<CONFIG:ReleaseCoverage>:NDEBUG>")

+ 2 - 0
Jolt/Jolt.h

@@ -5,6 +5,8 @@
 
 
 // Project includes
 // Project includes
 #include <Jolt/Core/Core.h>
 #include <Jolt/Core/Core.h>
+#include <Jolt/Core/Memory.h>
+#include <Jolt/Core/STLAllocator.h>
 #include <Jolt/Core/IssueReporting.h>
 #include <Jolt/Core/IssueReporting.h>
 #include <Jolt/Math/Math.h>
 #include <Jolt/Math/Math.h>
 #include <Jolt/Math/Vec4.h>
 #include <Jolt/Math/Vec4.h>

+ 2 - 0
Jolt/Math/DVec3.h

@@ -14,6 +14,8 @@ JPH_NAMESPACE_BEGIN
 class [[nodiscard]] DVec3
 class [[nodiscard]] DVec3
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 #ifdef JPH_FLOATING_POINT_EXCEPTIONS_ENABLED
 #ifdef JPH_FLOATING_POINT_EXCEPTIONS_ENABLED
 	/// Internal helper function that checks that W is equal to Z, so e.g. dividing by it should not generate div by 0
 	/// Internal helper function that checks that W is equal to Z, so e.g. dividing by it should not generate div by 0
 	JPH_INLINE void				CheckW() const									{ JPH_ASSERT(reinterpret_cast<const uint64 *>(mD32)[2] == reinterpret_cast<const uint64 *>(mD32)[3]); } // Avoid asserts when both components are NaN
 	JPH_INLINE void				CheckW() const									{ JPH_ASSERT(reinterpret_cast<const uint64 *>(mD32)[2] == reinterpret_cast<const uint64 *>(mD32)[3]); } // Avoid asserts when both components are NaN

+ 2 - 0
Jolt/Math/Float2.h

@@ -9,6 +9,8 @@ JPH_NAMESPACE_BEGIN
 class [[nodiscard]] Float2
 class [[nodiscard]] Float2
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 						Float2() = default; ///< Intentionally not initialized for performance reasons
 						Float2() = default; ///< Intentionally not initialized for performance reasons
 						Float2(const Float2 &inRHS) = default;
 						Float2(const Float2 &inRHS) = default;
 						Float2(float inX, float inY)					: x(inX), y(inY) { }
 						Float2(float inX, float inY)					: x(inX), y(inY) { }

+ 3 - 1
Jolt/Math/Float3.h

@@ -11,6 +11,8 @@ JPH_NAMESPACE_BEGIN
 class [[nodiscard]] Float3
 class [[nodiscard]] Float3
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 				Float3() = default; ///< Intentionally not initialized for performance reasons
 				Float3() = default; ///< Intentionally not initialized for performance reasons
 				Float3(const Float3 &inRHS) = default;
 				Float3(const Float3 &inRHS) = default;
 				Float3(float inX, float inY, float inZ) : x(inX), y(inY), z(inZ) { }
 				Float3(float inX, float inY, float inZ) : x(inX), y(inY), z(inZ) { }
@@ -36,7 +38,7 @@ public:
 	float		z;
 	float		z;
 };
 };
 
 
-using VertexList = vector<Float3>;
+using VertexList = Array<Float3>;
 
 
 static_assert(is_trivial<Float3>(), "Is supposed to be a trivial type!");
 static_assert(is_trivial<Float3>(), "Is supposed to be a trivial type!");
 
 

+ 2 - 0
Jolt/Math/Float4.h

@@ -9,6 +9,8 @@ JPH_NAMESPACE_BEGIN
 class [[nodiscard]] Float4
 class [[nodiscard]] Float4
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 				Float4() = default; ///< Intentionally not initialized for performance reasons
 				Float4() = default; ///< Intentionally not initialized for performance reasons
 				Float4(const Float4 &inRHS) = default;
 				Float4(const Float4 &inRHS) = default;
 				Float4(float inX, float inY, float inZ, float inW) : x(inX), y(inY), z(inZ), w(inW) { }
 				Float4(float inX, float inY, float inZ, float inW) : x(inX), y(inY), z(inZ), w(inW) { }

+ 2 - 0
Jolt/Math/Mat44.h

@@ -11,6 +11,8 @@ JPH_NAMESPACE_BEGIN
 class [[nodiscard]] alignas(16) Mat44
 class [[nodiscard]] alignas(16) Mat44
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	// Underlying column type
 	// Underlying column type
 	using Type = Vec4::Type;
 	using Type = Vec4::Type;
 
 

+ 2 - 0
Jolt/Math/Quat.h

@@ -31,6 +31,8 @@ JPH_NAMESPACE_BEGIN
 class [[nodiscard]] alignas(16) Quat
 class [[nodiscard]] alignas(16) Quat
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	///@name Constructors
 	///@name Constructors
 	///@{
 	///@{
 	inline						Quat() = default; ///< Intentionally not initialized for performance reasons
 	inline						Quat() = default; ///< Intentionally not initialized for performance reasons

+ 2 - 0
Jolt/Math/UVec4.h

@@ -10,6 +10,8 @@ JPH_NAMESPACE_BEGIN
 class [[nodiscard]] alignas(16) UVec4
 class [[nodiscard]] alignas(16) UVec4
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	// Underlying vector type
 	// Underlying vector type
 #if defined(JPH_USE_SSE)
 #if defined(JPH_USE_SSE)
 	using Type = __m128i;
 	using Type = __m128i;

+ 2 - 0
Jolt/Math/UVec8.h

@@ -10,6 +10,8 @@ JPH_NAMESPACE_BEGIN
 class [[nodiscard]] UVec8
 class [[nodiscard]] UVec8
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 								UVec8() = default; ///< Intentionally not initialized for performance reasons
 								UVec8() = default; ///< Intentionally not initialized for performance reasons
 								UVec8(const UVec8 &inRHS) = default;
 								UVec8(const UVec8 &inRHS) = default;
 	JPH_INLINE					UVec8(__m256i inRHS) : mValue(inRHS)				{ }
 	JPH_INLINE					UVec8(__m256i inRHS) : mValue(inRHS)				{ }

+ 1 - 5
Jolt/Math/Vec3.cpp

@@ -3,13 +3,9 @@
 
 
 #include <Jolt/Jolt.h>
 #include <Jolt/Jolt.h>
 
 
+#include <Jolt/Core/UnorderedSet.h>
 #include <Jolt/Math/Vec3.h>
 #include <Jolt/Math/Vec3.h>
 
 
-JPH_SUPPRESS_WARNINGS_STD_BEGIN
-#include <unordered_set>
-JPH_SUPPRESS_WARNINGS_STD_END
-
-
 JPH_NAMESPACE_BEGIN
 JPH_NAMESPACE_BEGIN
 
 
 static void sCreateVertices(unordered_set<Vec3> &ioVertices, Vec3Arg inDir1, Vec3Arg inDir2, Vec3Arg inDir3, int inLevel)
 static void sCreateVertices(unordered_set<Vec3> &ioVertices, Vec3Arg inDir1, Vec3Arg inDir2, Vec3Arg inDir3, int inLevel)

+ 2 - 0
Jolt/Math/Vec3.h

@@ -14,6 +14,8 @@ JPH_NAMESPACE_BEGIN
 class [[nodiscard]] alignas(16) Vec3
 class [[nodiscard]] alignas(16) Vec3
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	// Underlying vector type
 	// Underlying vector type
 #if defined(JPH_USE_SSE)
 #if defined(JPH_USE_SSE)
 	using Type = __m128;
 	using Type = __m128;

+ 2 - 0
Jolt/Math/Vec4.h

@@ -12,6 +12,8 @@ JPH_NAMESPACE_BEGIN
 class [[nodiscard]] alignas(16) Vec4
 class [[nodiscard]] alignas(16) Vec4
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	// Underlying vector type
 	// Underlying vector type
 #if defined(JPH_USE_SSE)
 #if defined(JPH_USE_SSE)
 	using Type = __m128;
 	using Type = __m128;

+ 2 - 0
Jolt/Math/Vec8.h

@@ -10,6 +10,8 @@ JPH_NAMESPACE_BEGIN
 class [[nodiscard]] Vec8
 class [[nodiscard]] Vec8
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Constructor
 	/// Constructor
 								Vec8() = default; ///< Intentionally not initialized for performance reasons
 								Vec8() = default; ///< Intentionally not initialized for performance reasons
 								Vec8(const Vec8 &inRHS) = default;
 								Vec8(const Vec8 &inRHS) = default;

+ 2 - 2
Jolt/ObjectStream/GetPrimitiveTypeOfType.h

@@ -7,7 +7,7 @@
 
 
 JPH_NAMESPACE_BEGIN
 JPH_NAMESPACE_BEGIN
 
 
-/// Helper functions to get the underlying RTTI type of a type (so e.g. vector<sometype> will return sometype)
+/// Helper functions to get the underlying RTTI type of a type (so e.g. Array<sometype> will return sometype)
 template <class T>				
 template <class T>				
 const RTTI *GetPrimitiveTypeOfType(T *)
 const RTTI *GetPrimitiveTypeOfType(T *)
 { 
 { 
@@ -33,7 +33,7 @@ const RTTI *GetPrimitiveTypeOfType(RefConst<T> *)
 }
 }
 
 
 template <class T>				
 template <class T>				
-const RTTI *GetPrimitiveTypeOfType(vector<T> *)
+const RTTI *GetPrimitiveTypeOfType(Array<T> *)
 { 
 { 
 	return GetPrimitiveTypeOfType((T *)nullptr);
 	return GetPrimitiveTypeOfType((T *)nullptr);
 }
 }

+ 7 - 7
Jolt/ObjectStream/ObjectStream.h

@@ -39,7 +39,7 @@ class IObjectStreamIn : public ObjectStream
 public:
 public:
 	///@name Input type specific operations
 	///@name Input type specific operations
 	virtual bool				ReadDataType(EOSDataType &outType) = 0;
 	virtual bool				ReadDataType(EOSDataType &outType) = 0;
-	virtual bool				ReadName(string &outName) = 0;
+	virtual bool				ReadName(String &outName) = 0;
 	virtual bool				ReadIdentifier(Identifier &outIdentifier) = 0;
 	virtual bool				ReadIdentifier(Identifier &outIdentifier) = 0;
 	virtual bool				ReadCount(uint32 &outCount) = 0;
 	virtual bool				ReadCount(uint32 &outCount) = 0;
 
 
@@ -51,7 +51,7 @@ public:
 	virtual bool				ReadPrimitiveData(uint64 &outPrimitive) = 0;
 	virtual bool				ReadPrimitiveData(uint64 &outPrimitive) = 0;
 	virtual bool				ReadPrimitiveData(float &outPrimitive) = 0;
 	virtual bool				ReadPrimitiveData(float &outPrimitive) = 0;
 	virtual bool				ReadPrimitiveData(bool &outPrimitive) = 0;
 	virtual bool				ReadPrimitiveData(bool &outPrimitive) = 0;
-	virtual bool				ReadPrimitiveData(string &outPrimitive) = 0;
+	virtual bool				ReadPrimitiveData(String &outPrimitive) = 0;
 	virtual bool				ReadPrimitiveData(Float3 &outPrimitive) = 0;
 	virtual bool				ReadPrimitiveData(Float3 &outPrimitive) = 0;
 	virtual bool				ReadPrimitiveData(Vec3 &outPrimitive) = 0;
 	virtual bool				ReadPrimitiveData(Vec3 &outPrimitive) = 0;
 	virtual bool				ReadPrimitiveData(Vec4 &outPrimitive) = 0;
 	virtual bool				ReadPrimitiveData(Vec4 &outPrimitive) = 0;
@@ -81,7 +81,7 @@ public:
 	virtual void				WritePrimitiveData(const uint64 &inPrimitive) = 0;
 	virtual void				WritePrimitiveData(const uint64 &inPrimitive) = 0;
 	virtual void				WritePrimitiveData(const float &inPrimitive) = 0;
 	virtual void				WritePrimitiveData(const float &inPrimitive) = 0;
 	virtual void				WritePrimitiveData(const bool &inPrimitive) = 0;
 	virtual void				WritePrimitiveData(const bool &inPrimitive) = 0;
-	virtual void				WritePrimitiveData(const string &inPrimitive) = 0;
+	virtual void				WritePrimitiveData(const String &inPrimitive) = 0;
 	virtual void				WritePrimitiveData(const Float3 &inPrimitive) = 0;
 	virtual void				WritePrimitiveData(const Float3 &inPrimitive) = 0;
 	virtual void				WritePrimitiveData(const Vec3 &inPrimitive) = 0;
 	virtual void				WritePrimitiveData(const Vec3 &inPrimitive) = 0;
 	virtual void				WritePrimitiveData(const Vec4 &inPrimitive) = 0;
 	virtual void				WritePrimitiveData(const Vec4 &inPrimitive) = 0;
@@ -110,7 +110,7 @@ public:
 
 
 // Define serialization templates
 // Define serialization templates
 template <class T>
 template <class T>
-bool OSIsType(vector<T> *, int inArrayDepth, EOSDataType inDataType, const char *inClassName)	
+bool OSIsType(Array<T> *, int inArrayDepth, EOSDataType inDataType, const char *inClassName)	
 { 
 { 
 	return (inArrayDepth > 0 && OSIsType((T *)nullptr, inArrayDepth - 1, inDataType, inClassName)); 
 	return (inArrayDepth > 0 && OSIsType((T *)nullptr, inArrayDepth - 1, inDataType, inClassName)); 
 }
 }
@@ -141,7 +141,7 @@ bool OSIsType(RefConst<T> *, int inArrayDepth, EOSDataType inDataType, const cha
 
 
 /// Define serialization templates for dynamic arrays
 /// Define serialization templates for dynamic arrays
 template <class T>
 template <class T>
-bool OSReadData(IObjectStreamIn &ioStream, vector<T> &inArray)
+bool OSReadData(IObjectStreamIn &ioStream, Array<T> &inArray)
 {
 {
 	bool continue_reading = true;
 	bool continue_reading = true;
 
 
@@ -219,14 +219,14 @@ bool OSReadData(IObjectStreamIn &ioStream, RefConst<T> &inRef)
 
 
 // Define serialization templates for dynamic arrays
 // Define serialization templates for dynamic arrays
 template <class T>
 template <class T>
-void OSWriteDataType(IObjectStreamOut &ioStream, vector<T> *)		
+void OSWriteDataType(IObjectStreamOut &ioStream, Array<T> *)		
 { 
 { 
 	ioStream.WriteDataType(EOSDataType::Array); 
 	ioStream.WriteDataType(EOSDataType::Array); 
 	OSWriteDataType(ioStream, (T *)nullptr); 
 	OSWriteDataType(ioStream, (T *)nullptr); 
 }
 }
 
 
 template <class T>
 template <class T>
-void OSWriteData(IObjectStreamOut &ioStream, const vector<T> &inArray)
+void OSWriteData(IObjectStreamOut &ioStream, const Array<T> &inArray)
 {
 {
 	// Write size of array
 	// Write size of array
 	ioStream.HintNextItem();
 	ioStream.HintNextItem();

+ 2 - 2
Jolt/ObjectStream/ObjectStreamBinaryIn.cpp

@@ -21,7 +21,7 @@ bool ObjectStreamBinaryIn::ReadDataType(EOSDataType &outType)
 	return true;
 	return true;
 }
 }
 
 
-bool ObjectStreamBinaryIn::ReadName(string &outName)
+bool ObjectStreamBinaryIn::ReadName(String &outName)
 {
 {
 	return ReadPrimitiveData(outName);
 	return ReadPrimitiveData(outName);
 }
 }
@@ -107,7 +107,7 @@ bool ObjectStreamBinaryIn::ReadPrimitiveData(bool &outPrimitive)
 	return true;
 	return true;
 }
 }
 
 
-bool ObjectStreamBinaryIn::ReadPrimitiveData(string &outPrimitive)
+bool ObjectStreamBinaryIn::ReadPrimitiveData(String &outPrimitive)
 {
 {
 	// Read length or ID of string
 	// Read length or ID of string
 	uint32 len;
 	uint32 len;

+ 5 - 3
Jolt/ObjectStream/ObjectStreamBinaryIn.h

@@ -11,12 +11,14 @@ JPH_NAMESPACE_BEGIN
 class ObjectStreamBinaryIn : public ObjectStreamIn
 class ObjectStreamBinaryIn : public ObjectStreamIn
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Constructor
 	/// Constructor
 	explicit 					ObjectStreamBinaryIn(istream &inStream);
 	explicit 					ObjectStreamBinaryIn(istream &inStream);
 
 
 	///@name Input type specific operations
 	///@name Input type specific operations
 	virtual bool				ReadDataType(EOSDataType &outType) override;
 	virtual bool				ReadDataType(EOSDataType &outType) override;
-	virtual bool				ReadName(string &outName) override;
+	virtual bool				ReadName(String &outName) override;
 	virtual bool				ReadIdentifier(Identifier &outIdentifier) override;
 	virtual bool				ReadIdentifier(Identifier &outIdentifier) override;
 	virtual bool				ReadCount(uint32 &outCount) override;
 	virtual bool				ReadCount(uint32 &outCount) override;
 
 
@@ -27,7 +29,7 @@ public:
 	virtual bool				ReadPrimitiveData(uint64 &outPrimitive) override;
 	virtual bool				ReadPrimitiveData(uint64 &outPrimitive) override;
 	virtual bool				ReadPrimitiveData(float &outPrimitive) override;
 	virtual bool				ReadPrimitiveData(float &outPrimitive) override;
 	virtual bool				ReadPrimitiveData(bool &outPrimitive) override;
 	virtual bool				ReadPrimitiveData(bool &outPrimitive) override;
-	virtual bool				ReadPrimitiveData(string &outPrimitive) override;
+	virtual bool				ReadPrimitiveData(String &outPrimitive) override;
 	virtual bool				ReadPrimitiveData(Float3 &outPrimitive) override;
 	virtual bool				ReadPrimitiveData(Float3 &outPrimitive) override;
 	virtual bool				ReadPrimitiveData(Vec3 &outPrimitive) override;
 	virtual bool				ReadPrimitiveData(Vec3 &outPrimitive) override;
 	virtual bool				ReadPrimitiveData(Vec4 &outPrimitive) override;
 	virtual bool				ReadPrimitiveData(Vec4 &outPrimitive) override;
@@ -35,7 +37,7 @@ public:
 	virtual bool				ReadPrimitiveData(Mat44 &outPrimitive) override;
 	virtual bool				ReadPrimitiveData(Mat44 &outPrimitive) override;
 
 
 private:
 private:
-	using StringTable = unordered_map<uint32, string>;
+	using StringTable = UnorderedMap<uint32, String>;
 
 
 	StringTable					mStringTable;
 	StringTable					mStringTable;
 	uint32						mNextStringID = 0x80000000;
 	uint32						mNextStringID = 0x80000000;

+ 3 - 3
Jolt/ObjectStream/ObjectStreamBinaryOut.cpp

@@ -11,7 +11,7 @@ JPH_NAMESPACE_BEGIN
 ObjectStreamBinaryOut::ObjectStreamBinaryOut(ostream &inStream) :
 ObjectStreamBinaryOut::ObjectStreamBinaryOut(ostream &inStream) :
 	ObjectStreamOut(inStream)
 	ObjectStreamOut(inStream)
 {
 {
-	string header;
+	String header;
 	header = StringFormat("BOS%2d.%02d", ObjectStream::sVersion, ObjectStream::sRevision);
 	header = StringFormat("BOS%2d.%02d", ObjectStream::sVersion, ObjectStream::sRevision);
 	mStream.write(header.c_str(), header.size());
 	mStream.write(header.c_str(), header.size());
 }
 }
@@ -23,7 +23,7 @@ void ObjectStreamBinaryOut::WriteDataType(EOSDataType inType)
 
 
 void ObjectStreamBinaryOut::WriteName(const char *inName)
 void ObjectStreamBinaryOut::WriteName(const char *inName)
 {
 {
-	WritePrimitiveData(string(inName));
+	WritePrimitiveData(String(inName));
 }
 }
 
 
 void ObjectStreamBinaryOut::WriteIdentifier(Identifier inIdentifier)
 void ObjectStreamBinaryOut::WriteIdentifier(Identifier inIdentifier)
@@ -71,7 +71,7 @@ void ObjectStreamBinaryOut::WritePrimitiveData(const bool &inPrimitive)
 	mStream.write((const char *)&inPrimitive, sizeof(inPrimitive));
 	mStream.write((const char *)&inPrimitive, sizeof(inPrimitive));
 }
 }
 
 
-void ObjectStreamBinaryOut::WritePrimitiveData(const string &inPrimitive)
+void ObjectStreamBinaryOut::WritePrimitiveData(const String &inPrimitive)
 {
 {
 	// Empty strings are trivial
 	// Empty strings are trivial
 	if (inPrimitive.empty())
 	if (inPrimitive.empty())

+ 4 - 2
Jolt/ObjectStream/ObjectStreamBinaryOut.h

@@ -11,6 +11,8 @@ JPH_NAMESPACE_BEGIN
 class ObjectStreamBinaryOut : public ObjectStreamOut
 class ObjectStreamBinaryOut : public ObjectStreamOut
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Constructor and destructor
 	/// Constructor and destructor
 	explicit 					ObjectStreamBinaryOut(ostream &inStream);
 	explicit 					ObjectStreamBinaryOut(ostream &inStream);
 
 
@@ -27,7 +29,7 @@ public:
 	virtual void				WritePrimitiveData(const uint64 &inPrimitive) override;
 	virtual void				WritePrimitiveData(const uint64 &inPrimitive) override;
 	virtual void				WritePrimitiveData(const float &inPrimitive) override;
 	virtual void				WritePrimitiveData(const float &inPrimitive) override;
 	virtual void				WritePrimitiveData(const bool &inPrimitive) override;
 	virtual void				WritePrimitiveData(const bool &inPrimitive) override;
-	virtual void				WritePrimitiveData(const string &inPrimitive) override;
+	virtual void				WritePrimitiveData(const String &inPrimitive) override;
 	virtual void				WritePrimitiveData(const Float3 &inPrimitive) override;
 	virtual void				WritePrimitiveData(const Float3 &inPrimitive) override;
 	virtual void				WritePrimitiveData(const Vec3 &inPrimitive) override;
 	virtual void				WritePrimitiveData(const Vec3 &inPrimitive) override;
 	virtual void				WritePrimitiveData(const Vec4 &inPrimitive) override;
 	virtual void				WritePrimitiveData(const Vec4 &inPrimitive) override;
@@ -35,7 +37,7 @@ public:
 	virtual void				WritePrimitiveData(const Mat44 &inPrimitive) override;
 	virtual void				WritePrimitiveData(const Mat44 &inPrimitive) override;
 
 
 private:
 private:
-	using StringTable = unordered_map<string, uint32>;
+	using StringTable = UnorderedMap<String, uint32>;
 
 
 	StringTable					mStringTable;
 	StringTable					mStringTable;
 	uint32						mNextStringID = 0x80000000;
 	uint32						mNextStringID = 0x80000000;

+ 7 - 10
Jolt/ObjectStream/ObjectStreamIn.cpp

@@ -4,15 +4,12 @@
 #include <Jolt/Jolt.h>
 #include <Jolt/Jolt.h>
 
 
 #include <Jolt/Core/Factory.h>
 #include <Jolt/Core/Factory.h>
+#include <Jolt/Core/UnorderedSet.h>
 #include <Jolt/ObjectStream/ObjectStreamIn.h>
 #include <Jolt/ObjectStream/ObjectStreamIn.h>
 #include <Jolt/ObjectStream/ObjectStreamTextIn.h>
 #include <Jolt/ObjectStream/ObjectStreamTextIn.h>
 #include <Jolt/ObjectStream/ObjectStreamBinaryIn.h>
 #include <Jolt/ObjectStream/ObjectStreamBinaryIn.h>
 #include <Jolt/ObjectStream/SerializableObject.h>
 #include <Jolt/ObjectStream/SerializableObject.h>
 
 
-JPH_SUPPRESS_WARNINGS_STD_BEGIN
-#include <unordered_set>
-JPH_SUPPRESS_WARNINGS_STD_END
-
 JPH_NAMESPACE_BEGIN
 JPH_NAMESPACE_BEGIN
 
 
 ObjectStreamIn::ObjectStreamIn(istream &inStream) :
 ObjectStreamIn::ObjectStreamIn(istream &inStream) :
@@ -79,7 +76,7 @@ ObjectStreamIn *ObjectStreamIn::Open(istream &inStream)
 
 
 void *ObjectStreamIn::Read(const RTTI *inRTTI)
 void *ObjectStreamIn::Read(const RTTI *inRTTI)
 {
 {
-	using ObjectSet = unordered_set<void *>;
+	using ObjectSet = UnorderedSet<void *>;
 
 
 	// Read all information on the stream
 	// Read all information on the stream
 	void *main_object = nullptr;
 	void *main_object = nullptr;
@@ -196,7 +193,7 @@ void *ObjectStreamIn::ReadObject(const RTTI *& outRTTI)
 {
 {
 	// Read the object class
 	// Read the object class
 	void *object = nullptr;
 	void *object = nullptr;
-	string class_name;
+	String class_name;
 	if (ReadName(class_name)) 
 	if (ReadName(class_name)) 
 	{
 	{
 		// Get class description
 		// Get class description
@@ -253,7 +250,7 @@ void *ObjectStreamIn::ReadObject(const RTTI *& outRTTI)
 bool ObjectStreamIn::ReadRTTI()
 bool ObjectStreamIn::ReadRTTI()
 {
 {
 	// Read class name and find it's attribute info
 	// Read class name and find it's attribute info
-	string class_name;
+	String class_name;
 	if (!ReadName(class_name)) 
 	if (!ReadName(class_name)) 
 		return false;
 		return false;
 
 
@@ -276,7 +273,7 @@ bool ObjectStreamIn::ReadRTTI()
 		AttributeDescription attribute;
 		AttributeDescription attribute;
 		
 		
 		// Read name
 		// Read name
-		string attribute_name;
+		String attribute_name;
 		if (!ReadName(attribute_name)) 
 		if (!ReadName(attribute_name)) 
 			return false;
 			return false;
 		
 		
@@ -488,9 +485,9 @@ bool ObjectStreamIn::SkipAttributeData(int inArrayDepth, EOSDataType inDataType,
 						break;
 						break;
 					}
 					}
 				
 				
-				case EOSDataType::T_string:
+				case EOSDataType::T_String:
 					{	
 					{	
-						string temporary;
+						String temporary;
 						continue_reading = ReadPrimitiveData(temporary);
 						continue_reading = ReadPrimitiveData(temporary);
 						break;
 						break;
 					}
 					}

+ 6 - 6
Jolt/ObjectStream/ObjectStreamIn.h

@@ -6,10 +6,10 @@
 #include <Jolt/ObjectStream/ObjectStream.h>
 #include <Jolt/ObjectStream/ObjectStream.h>
 #include <Jolt/Core/Reference.h>
 #include <Jolt/Core/Reference.h>
 #include <Jolt/Core/RTTI.h>
 #include <Jolt/Core/RTTI.h>
+#include <Jolt/Core/UnorderedMap.h>
 
 
 JPH_SUPPRESS_WARNINGS_STD_BEGIN
 JPH_SUPPRESS_WARNINGS_STD_BEGIN
 #include <fstream>
 #include <fstream>
-#include <unordered_map>
 JPH_SUPPRESS_WARNINGS_STD_END
 JPH_SUPPRESS_WARNINGS_STD_END
 
 
 JPH_NAMESPACE_BEGIN
 JPH_NAMESPACE_BEGIN
@@ -101,7 +101,7 @@ private:
 	{
 	{
 		int						mArrayDepth = 0;
 		int						mArrayDepth = 0;
 		EOSDataType				mDataType = EOSDataType::Invalid;
 		EOSDataType				mDataType = EOSDataType::Invalid;
-		string					mClassName;
+		String					mClassName;
 		int						mIndex = -1;
 		int						mIndex = -1;
 	};
 	};
 
 
@@ -111,7 +111,7 @@ private:
 		explicit 				ClassDescription(const RTTI *inRTTI)					: mRTTI(inRTTI) { }
 		explicit 				ClassDescription(const RTTI *inRTTI)					: mRTTI(inRTTI) { }
 
 
 		const RTTI *			mRTTI = nullptr;
 		const RTTI *			mRTTI = nullptr;
-		vector<AttributeDescription>	mAttributes;
+		Array<AttributeDescription>	mAttributes;
 	};
 	};
 	
 	
 	struct ObjectInfo
 	struct ObjectInfo
@@ -131,12 +131,12 @@ private:
 		const RTTI *			mRTTI;
 		const RTTI *			mRTTI;
 	};
 	};
 	
 	
-	using IdentifierMap = unordered_map<Identifier, ObjectInfo>;
-	using ClassDescriptionMap = unordered_map<string, ClassDescription>;
+	using IdentifierMap = UnorderedMap<Identifier, ObjectInfo>;
+	using ClassDescriptionMap = UnorderedMap<String, ClassDescription>;
 
 
 	ClassDescriptionMap			mClassDescriptionMap;
 	ClassDescriptionMap			mClassDescriptionMap;
 	IdentifierMap				mIdentifierMap;											///< Links identifier to an object pointer
 	IdentifierMap				mIdentifierMap;											///< Links identifier to an object pointer
-	vector<Link>				mUnresolvedLinks;										///< All pointers (links) are resolved after reading the entire file, e.g. when all object exist
+	Array<Link>					mUnresolvedLinks;										///< All pointers (links) are resolved after reading the entire file, e.g. when all object exist
 };
 };
 
 
 JPH_NAMESPACE_END
 JPH_NAMESPACE_END

+ 8 - 6
Jolt/ObjectStream/ObjectStreamOut.h

@@ -5,16 +5,18 @@
 
 
 #include <Jolt/ObjectStream/ObjectStream.h>
 #include <Jolt/ObjectStream/ObjectStream.h>
 #include <Jolt/Core/RTTI.h>
 #include <Jolt/Core/RTTI.h>
+#include <Jolt/Core/UnorderedMap.h>
+#include <Jolt/Core/UnorderedSet.h>
 
 
 JPH_SUPPRESS_WARNINGS_STD_BEGIN
 JPH_SUPPRESS_WARNINGS_STD_BEGIN
 #include <queue>
 #include <queue>
 #include <fstream>
 #include <fstream>
-#include <unordered_set>
-#include <unordered_map>
 JPH_SUPPRESS_WARNINGS_STD_END
 JPH_SUPPRESS_WARNINGS_STD_END
 
 
 JPH_NAMESPACE_BEGIN
 JPH_NAMESPACE_BEGIN
 
 
+template <class T> using Queue = queue<T, deque<T, STLAllocator<T>>>;
+
 /// ObjectStreamOut contains all logic for writing an object to disk. It is the base 
 /// ObjectStreamOut contains all logic for writing an object to disk. It is the base 
 /// class for the text and binary output streams (ObjectStreamTextOut and ObjectStreamBinaryOut).
 /// class for the text and binary output streams (ObjectStreamTextOut and ObjectStreamBinaryOut).
 class ObjectStreamOut : public IObjectStreamOut
 class ObjectStreamOut : public IObjectStreamOut
@@ -82,10 +84,10 @@ private:
 		const RTTI *			mRTTI;
 		const RTTI *			mRTTI;
 	};
 	};
 
 
-	using IdentifierMap = unordered_map<const void *, ObjectInfo>;
-	using ClassSet = unordered_set<const RTTI *>;
-	using ObjectQueue = queue<const void *>;
-	using ClassQueue = queue<const RTTI *>;
+	using IdentifierMap = UnorderedMap<const void *, ObjectInfo>;
+	using ClassSet = UnorderedSet<const RTTI *>;
+	using ObjectQueue = Queue<const void *>;
+	using ClassQueue = Queue<const RTTI *>;
 
 
 	Identifier					mNextIdentifier = sNullIdentifier + 1;						///< Next free identifier for this stream
 	Identifier					mNextIdentifier = sNullIdentifier + 1;						///< Next free identifier for this stream
 	IdentifierMap				mIdentifierMap;												///< Links object pointer to an identifier
 	IdentifierMap				mIdentifierMap;												///< Links object pointer to an identifier

+ 20 - 20
Jolt/ObjectStream/ObjectStreamTextIn.cpp

@@ -14,7 +14,7 @@ ObjectStreamTextIn::ObjectStreamTextIn(istream &inStream) :
 
 
 bool ObjectStreamTextIn::ReadDataType(EOSDataType &outType)
 bool ObjectStreamTextIn::ReadDataType(EOSDataType &outType)
 {
 {
-	string token;
+	String token;
 	if (ReadWord(token)) 
 	if (ReadWord(token)) 
 	{
 	{
 		transform(token.begin(), token.end(), token.begin(), [](char inValue) { return (char)tolower(inValue); });
 		transform(token.begin(), token.end(), token.begin(), [](char inValue) { return (char)tolower(inValue); });
@@ -43,7 +43,7 @@ bool ObjectStreamTextIn::ReadDataType(EOSDataType &outType)
 		else if (token == "bool")
 		else if (token == "bool")
 			outType  = EOSDataType::T_bool;
 			outType  = EOSDataType::T_bool;
 		else if (token == "string")
 		else if (token == "string")
-			outType  = EOSDataType::T_string;
+			outType  = EOSDataType::T_String;
 		else if (token == "float3")
 		else if (token == "float3")
 			outType  = EOSDataType::T_Float3;
 			outType  = EOSDataType::T_Float3;
 		else if (token == "vec3")
 		else if (token == "vec3")
@@ -64,14 +64,14 @@ bool ObjectStreamTextIn::ReadDataType(EOSDataType &outType)
 	return false;
 	return false;
 }
 }
 
 
-bool ObjectStreamTextIn::ReadName(string &outName)
+bool ObjectStreamTextIn::ReadName(String &outName)
 {
 {
 	return ReadWord(outName);
 	return ReadWord(outName);
 }
 }
 
 
 bool ObjectStreamTextIn::ReadIdentifier(Identifier &outIdentifier)
 bool ObjectStreamTextIn::ReadIdentifier(Identifier &outIdentifier)
 {
 {
-	string token;
+	String token;
 	if (!ReadWord(token))
 	if (!ReadWord(token))
 		return false;
 		return false;
 	outIdentifier = (uint32)std::strtoul(token.c_str(), nullptr, 16);
 	outIdentifier = (uint32)std::strtoul(token.c_str(), nullptr, 16);
@@ -90,11 +90,11 @@ bool ObjectStreamTextIn::ReadCount(uint32 &outCount)
 
 
 bool ObjectStreamTextIn::ReadPrimitiveData(uint8 &outPrimitive)
 bool ObjectStreamTextIn::ReadPrimitiveData(uint8 &outPrimitive)
 {
 {
-	string token;
+	String token;
 	if (!ReadWord(token))
 	if (!ReadWord(token))
 		return false;
 		return false;
 	uint32 temporary;
 	uint32 temporary;
-	istringstream stream(token);
+	IStringStream stream(token);
 	stream >> temporary;
 	stream >> temporary;
 	if (!stream.fail())
 	if (!stream.fail())
 	{
 	{
@@ -106,11 +106,11 @@ bool ObjectStreamTextIn::ReadPrimitiveData(uint8 &outPrimitive)
 
 
 bool ObjectStreamTextIn::ReadPrimitiveData(uint16 &outPrimitive)
 bool ObjectStreamTextIn::ReadPrimitiveData(uint16 &outPrimitive)
 {
 {
-	string token;
+	String token;
 	if (!ReadWord(token))
 	if (!ReadWord(token))
 		return false;
 		return false;
 	uint32 temporary;
 	uint32 temporary;
-	istringstream stream(token);
+	IStringStream stream(token);
 	stream >> temporary;
 	stream >> temporary;
 	if (!stream.fail())
 	if (!stream.fail())
 	{
 	{
@@ -122,47 +122,47 @@ bool ObjectStreamTextIn::ReadPrimitiveData(uint16 &outPrimitive)
 
 
 bool ObjectStreamTextIn::ReadPrimitiveData(int &outPrimitive)
 bool ObjectStreamTextIn::ReadPrimitiveData(int &outPrimitive)
 {
 {
-	string token;
+	String token;
 	if (!ReadWord(token))
 	if (!ReadWord(token))
 		return false;
 		return false;
-	istringstream stream(token);
+	IStringStream stream(token);
 	stream >> outPrimitive;
 	stream >> outPrimitive;
 	return !stream.fail();
 	return !stream.fail();
 }
 }
 
 
 bool ObjectStreamTextIn::ReadPrimitiveData(uint32 &outPrimitive)
 bool ObjectStreamTextIn::ReadPrimitiveData(uint32 &outPrimitive)
 {
 {
-	string token;
+	String token;
 	if (!ReadWord(token))
 	if (!ReadWord(token))
 		return false;
 		return false;
-	istringstream stream(token);
+	IStringStream stream(token);
 	stream >> outPrimitive;
 	stream >> outPrimitive;
 	return !stream.fail();
 	return !stream.fail();
 }
 }
 
 
 bool ObjectStreamTextIn::ReadPrimitiveData(uint64 &outPrimitive)
 bool ObjectStreamTextIn::ReadPrimitiveData(uint64 &outPrimitive)
 {
 {
-	string token;
+	String token;
 	if (!ReadWord(token))
 	if (!ReadWord(token))
 		return false;
 		return false;
-	istringstream stream(token);
+	IStringStream stream(token);
 	stream >> outPrimitive;
 	stream >> outPrimitive;
 	return !stream.fail();
 	return !stream.fail();
 }
 }
 
 
 bool ObjectStreamTextIn::ReadPrimitiveData(float &outPrimitive)
 bool ObjectStreamTextIn::ReadPrimitiveData(float &outPrimitive)
 {
 {
-	string token;
+	String token;
 	if (!ReadWord(token))
 	if (!ReadWord(token))
 		return false;
 		return false;
-	istringstream stream(token);
+	IStringStream stream(token);
 	stream >> outPrimitive;
 	stream >> outPrimitive;
 	return !stream.fail();
 	return !stream.fail();
 }
 }
 
 
 bool ObjectStreamTextIn::ReadPrimitiveData(bool &outPrimitive)
 bool ObjectStreamTextIn::ReadPrimitiveData(bool &outPrimitive)
 {
 {
-	string token;
+	String token;
 	if (!ReadWord(token))
 	if (!ReadWord(token))
 		return false;
 		return false;
 	transform(token.begin(), token.end(), token.begin(), [](char inValue) { return (char)tolower(inValue); });
 	transform(token.begin(), token.end(), token.begin(), [](char inValue) { return (char)tolower(inValue); });
@@ -170,7 +170,7 @@ bool ObjectStreamTextIn::ReadPrimitiveData(bool &outPrimitive)
 	return outPrimitive || token == "false";
 	return outPrimitive || token == "false";
 }
 }
 
 
-bool ObjectStreamTextIn::ReadPrimitiveData(string &outPrimitive)
+bool ObjectStreamTextIn::ReadPrimitiveData(String &outPrimitive)
 {
 {
 	outPrimitive.clear();
 	outPrimitive.clear();
 
 
@@ -191,7 +191,7 @@ bool ObjectStreamTextIn::ReadPrimitiveData(string &outPrimitive)
 		return false;
 		return false;
 
 
 	// Read string and interpret special characters
 	// Read string and interpret special characters
-	string	result;
+	String result;
 	bool escaped = false;
 	bool escaped = false;
 	for (;;) 
 	for (;;) 
 	{
 	{
@@ -311,7 +311,7 @@ bool ObjectStreamTextIn::ReadChar(char &outChar)
 	return !mStream.eof();
 	return !mStream.eof();
 }
 }
 
 
-bool ObjectStreamTextIn::ReadWord(string &outWord)
+bool ObjectStreamTextIn::ReadWord(String &outWord)
 {
 {
 	outWord.clear();
 	outWord.clear();
 
 

+ 5 - 3
Jolt/ObjectStream/ObjectStreamTextIn.h

@@ -11,12 +11,14 @@ JPH_NAMESPACE_BEGIN
 class ObjectStreamTextIn : public ObjectStreamIn
 class ObjectStreamTextIn : public ObjectStreamIn
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Constructor
 	/// Constructor
 	explicit					ObjectStreamTextIn(istream &inStream);
 	explicit					ObjectStreamTextIn(istream &inStream);
 
 
 	///@name Input type specific operations
 	///@name Input type specific operations
 	virtual bool				ReadDataType(EOSDataType &outType) override;
 	virtual bool				ReadDataType(EOSDataType &outType) override;
-	virtual bool				ReadName(string &outName) override;
+	virtual bool				ReadName(String &outName) override;
 	virtual bool				ReadIdentifier(Identifier &outIdentifier) override;
 	virtual bool				ReadIdentifier(Identifier &outIdentifier) override;
 	virtual bool				ReadCount(uint32 &outCount) override;
 	virtual bool				ReadCount(uint32 &outCount) override;
 
 
@@ -27,7 +29,7 @@ public:
 	virtual bool				ReadPrimitiveData(uint64 &outPrimitive) override;
 	virtual bool				ReadPrimitiveData(uint64 &outPrimitive) override;
 	virtual bool				ReadPrimitiveData(float &outPrimitive) override;
 	virtual bool				ReadPrimitiveData(float &outPrimitive) override;
 	virtual bool				ReadPrimitiveData(bool &outPrimitive) override;
 	virtual bool				ReadPrimitiveData(bool &outPrimitive) override;
-	virtual bool				ReadPrimitiveData(string &outPrimitive) override;
+	virtual bool				ReadPrimitiveData(String &outPrimitive) override;
 	virtual bool				ReadPrimitiveData(Float3 &outPrimitive) override;
 	virtual bool				ReadPrimitiveData(Float3 &outPrimitive) override;
 	virtual bool				ReadPrimitiveData(Vec3 &outPrimitive) override;
 	virtual bool				ReadPrimitiveData(Vec3 &outPrimitive) override;
 	virtual bool				ReadPrimitiveData(Vec4 &outPrimitive) override;
 	virtual bool				ReadPrimitiveData(Vec4 &outPrimitive) override;
@@ -36,7 +38,7 @@ public:
 
 
 private:
 private:
 	bool						ReadChar(char &outChar);
 	bool						ReadChar(char &outChar);
-	bool						ReadWord(string &outWord);
+	bool						ReadWord(String &outWord);
 };
 };
 
 
 JPH_NAMESPACE_END
 JPH_NAMESPACE_END

+ 5 - 5
Jolt/ObjectStream/ObjectStreamTextOut.cpp

@@ -30,7 +30,7 @@ void ObjectStreamTextOut::WriteDataType(EOSDataType inType)
 	case EOSDataType::T_uint64:		WriteWord("uint64");		break;
 	case EOSDataType::T_uint64:		WriteWord("uint64");		break;
 	case EOSDataType::T_float:		WriteWord("float");			break;
 	case EOSDataType::T_float:		WriteWord("float");			break;
 	case EOSDataType::T_bool:		WriteWord("bool");			break;
 	case EOSDataType::T_bool:		WriteWord("bool");			break;
-	case EOSDataType::T_string:		WriteWord("string");		break;
+	case EOSDataType::T_String:		WriteWord("string");		break;
 	case EOSDataType::T_Float3:		WriteWord("float3");		break;
 	case EOSDataType::T_Float3:		WriteWord("float3");		break;
 	case EOSDataType::T_Vec3:		WriteWord("vec3");			break;
 	case EOSDataType::T_Vec3:		WriteWord("vec3");			break;
 	case EOSDataType::T_Vec4:		WriteWord("vec4");			break;
 	case EOSDataType::T_Vec4:		WriteWord("vec4");			break;
@@ -43,7 +43,7 @@ void ObjectStreamTextOut::WriteDataType(EOSDataType inType)
 
 
 void ObjectStreamTextOut::WriteName(const char *inName)
 void ObjectStreamTextOut::WriteName(const char *inName)
 {
 {
-	WriteWord(string(inName) + " ");
+	WriteWord(String(inName) + " ");
 }
 }
 
 
 void ObjectStreamTextOut::WriteIdentifier(Identifier inIdentifier)
 void ObjectStreamTextOut::WriteIdentifier(Identifier inIdentifier)
@@ -145,14 +145,14 @@ void ObjectStreamTextOut::WritePrimitiveData(const Mat44 &inPrimitive)
 	WritePrimitiveData(inPrimitive.GetColumn4(3));
 	WritePrimitiveData(inPrimitive.GetColumn4(3));
 }
 }
 
 
-void ObjectStreamTextOut::WritePrimitiveData(const string &inPrimitive)
+void ObjectStreamTextOut::WritePrimitiveData(const String &inPrimitive)
 {
 {
-	string temporary(inPrimitive);
+	String temporary(inPrimitive);
 	StringReplace(temporary, "\\", "\\\\");
 	StringReplace(temporary, "\\", "\\\\");
 	StringReplace(temporary, "\n", "\\n");
 	StringReplace(temporary, "\n", "\\n");
 	StringReplace(temporary, "\t", "\\t");
 	StringReplace(temporary, "\t", "\\t");
 	StringReplace(temporary, "\"", "\\\"");
 	StringReplace(temporary, "\"", "\\\"");
-	WriteWord(string("\"") + temporary + string("\""));
+	WriteWord(String("\"") + temporary + String("\""));
 }
 }
 
 
 void ObjectStreamTextOut::HintNextItem()
 void ObjectStreamTextOut::HintNextItem()

+ 3 - 1
Jolt/ObjectStream/ObjectStreamTextOut.h

@@ -11,6 +11,8 @@ JPH_NAMESPACE_BEGIN
 class ObjectStreamTextOut : public ObjectStreamOut
 class ObjectStreamTextOut : public ObjectStreamOut
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Constructor and destructor
 	/// Constructor and destructor
 	explicit					ObjectStreamTextOut(ostream &inStream);
 	explicit					ObjectStreamTextOut(ostream &inStream);
 
 
@@ -27,7 +29,7 @@ public:
 	virtual void				WritePrimitiveData(const uint64 &inPrimitive) override;
 	virtual void				WritePrimitiveData(const uint64 &inPrimitive) override;
 	virtual void				WritePrimitiveData(const float &inPrimitive) override;
 	virtual void				WritePrimitiveData(const float &inPrimitive) override;
 	virtual void				WritePrimitiveData(const bool &inPrimitive) override;
 	virtual void				WritePrimitiveData(const bool &inPrimitive) override;
-	virtual void				WritePrimitiveData(const string &inPrimitive) override;
+	virtual void				WritePrimitiveData(const String &inPrimitive) override;
 	virtual void				WritePrimitiveData(const Float3 &inPrimitive) override;
 	virtual void				WritePrimitiveData(const Float3 &inPrimitive) override;
 	virtual void				WritePrimitiveData(const Vec3 &inPrimitive) override;
 	virtual void				WritePrimitiveData(const Vec3 &inPrimitive) override;
 	virtual void				WritePrimitiveData(const Vec4 &inPrimitive) override;
 	virtual void				WritePrimitiveData(const Vec4 &inPrimitive) override;

+ 1 - 1
Jolt/ObjectStream/ObjectStreamTypes.h

@@ -8,7 +8,7 @@ JPH_DECLARE_PRIMITIVE(uint32)
 JPH_DECLARE_PRIMITIVE(uint64)
 JPH_DECLARE_PRIMITIVE(uint64)
 JPH_DECLARE_PRIMITIVE(float)
 JPH_DECLARE_PRIMITIVE(float)
 JPH_DECLARE_PRIMITIVE(bool)
 JPH_DECLARE_PRIMITIVE(bool)
-JPH_DECLARE_PRIMITIVE(string)
+JPH_DECLARE_PRIMITIVE(String)
 JPH_DECLARE_PRIMITIVE(Float3)
 JPH_DECLARE_PRIMITIVE(Float3)
 JPH_DECLARE_PRIMITIVE(Vec3)
 JPH_DECLARE_PRIMITIVE(Vec3)
 JPH_DECLARE_PRIMITIVE(Vec4)
 JPH_DECLARE_PRIMITIVE(Vec4)

+ 2 - 2
Jolt/ObjectStream/SerializableAttribute.h

@@ -50,7 +50,7 @@ public:
 	void						SetName(const char *inName)							{ mName = inName; }
 	void						SetName(const char *inName)							{ mName = inName; }
 	const char *				GetName() const										{ return mName; }
 	const char *				GetName() const										{ return mName; }
 
 
-	/// In case this attribute contains an RTTI type, return it (note that a vector<sometype> will return the rtti of sometype)
+	/// In case this attribute contains an RTTI type, return it (note that a Array<sometype> will return the rtti of sometype)
 	const RTTI *				GetMemberPrimitiveType() const
 	const RTTI *				GetMemberPrimitiveType() const
 	{
 	{
 		return mGetMemberPrimitiveType();
 		return mGetMemberPrimitiveType();
@@ -87,7 +87,7 @@ private:
 	// Offset of the member relative to the class
 	// Offset of the member relative to the class
 	uint						mMemberOffset;
 	uint						mMemberOffset;
 
 
-	// In case this attribute contains an RTTI type, return it (note that a vector<sometype> will return the rtti of sometype)
+	// In case this attribute contains an RTTI type, return it (note that a Array<sometype> will return the rtti of sometype)
 	pGetMemberPrimitiveType		mGetMemberPrimitiveType;
 	pGetMemberPrimitiveType		mGetMemberPrimitiveType;
 
 
 	// Serialization operations
 	// Serialization operations

+ 1 - 1
Jolt/ObjectStream/TypeDeclarations.cpp

@@ -14,7 +14,7 @@ JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(uint32)		{ }
 JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(uint64)		{ }
 JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(uint64)		{ }
 JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(float)			{ }
 JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(float)			{ }
 JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(bool)			{ }
 JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(bool)			{ }
-JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(string)		{ }
+JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(String)		{ }
 JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(Float3)		{ }
 JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(Float3)		{ }
 JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(Vec3)			{ }
 JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(Vec3)			{ }
 JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(Vec4)			{ }
 JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(Vec4)			{ }

+ 1 - 1
Jolt/ObjectStream/TypeDeclarations.h

@@ -18,7 +18,7 @@ JPH_DECLARE_RTTI_OUTSIDE_CLASS(uint32);
 JPH_DECLARE_RTTI_OUTSIDE_CLASS(uint64);
 JPH_DECLARE_RTTI_OUTSIDE_CLASS(uint64);
 JPH_DECLARE_RTTI_OUTSIDE_CLASS(float);
 JPH_DECLARE_RTTI_OUTSIDE_CLASS(float);
 JPH_DECLARE_RTTI_OUTSIDE_CLASS(bool);
 JPH_DECLARE_RTTI_OUTSIDE_CLASS(bool);
-JPH_DECLARE_RTTI_OUTSIDE_CLASS(string);
+JPH_DECLARE_RTTI_OUTSIDE_CLASS(String);
 JPH_DECLARE_RTTI_OUTSIDE_CLASS(Float3);
 JPH_DECLARE_RTTI_OUTSIDE_CLASS(Float3);
 JPH_DECLARE_RTTI_OUTSIDE_CLASS(Vec3);
 JPH_DECLARE_RTTI_OUTSIDE_CLASS(Vec3);
 JPH_DECLARE_RTTI_OUTSIDE_CLASS(Vec4);
 JPH_DECLARE_RTTI_OUTSIDE_CLASS(Vec4);

+ 3 - 1
Jolt/Physics/Body/Body.cpp

@@ -16,17 +16,19 @@
 
 
 JPH_NAMESPACE_BEGIN
 JPH_NAMESPACE_BEGIN
 
 
+static const SphereShape sFixedToWorldShape(FLT_EPSILON);
 Body Body::sFixedToWorld(false);
 Body Body::sFixedToWorld(false);
 
 
 Body::Body(bool) :
 Body::Body(bool) :
 	mPosition(Vec3::sZero()),
 	mPosition(Vec3::sZero()),
 	mRotation(Quat::sIdentity()),
 	mRotation(Quat::sIdentity()),
-	mShape(new SphereShape(FLT_EPSILON)), // Dummy shape
+	mShape(&sFixedToWorldShape), // Dummy shape
 	mFriction(0.0f),
 	mFriction(0.0f),
 	mRestitution(0.0f),
 	mRestitution(0.0f),
 	mObjectLayer(cObjectLayerInvalid),
 	mObjectLayer(cObjectLayerInvalid),
 	mMotionType(EMotionType::Static)
 	mMotionType(EMotionType::Static)
 {
 {
+	sFixedToWorldShape.SetEmbedded();
 }
 }
 
 
 void Body::SetMotionType(EMotionType inMotionType)
 void Body::SetMotionType(EMotionType inMotionType)

+ 2 - 0
Jolt/Physics/Body/Body.h

@@ -31,6 +31,8 @@ class BodyCreationSettings;
 class Body : public NonCopyable
 class Body : public NonCopyable
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Default constructor
 	/// Default constructor
 							Body() = default;
 							Body() = default;
 
 

+ 2 - 2
Jolt/Physics/Body/BodyCreationSettings.h

@@ -57,8 +57,8 @@ public:
 	/// Restore the state of this object from inStream. Doesn't restore the shape nor the group filter.
 	/// Restore the state of this object from inStream. Doesn't restore the shape nor the group filter.
 	void					RestoreBinaryState(StreamIn &inStream);
 	void					RestoreBinaryState(StreamIn &inStream);
 
 
-	using GroupFilterToIDMap = unordered_map<const GroupFilter *, uint32>;
-	using IDToGroupFilterMap = vector<RefConst<GroupFilter>>;
+	using GroupFilterToIDMap = UnorderedMap<const GroupFilter *, uint32>;
+	using IDToGroupFilterMap = Array<RefConst<GroupFilter>>;
 	using ShapeToIDMap = Shape::ShapeToIDMap;
 	using ShapeToIDMap = Shape::ShapeToIDMap;
 	using IDToShapeMap = Shape::IDToShapeMap;
 	using IDToShapeMap = Shape::IDToShapeMap;
 	using MaterialToIDMap = Shape::MaterialToIDMap;
 	using MaterialToIDMap = Shape::MaterialToIDMap;

+ 1 - 1
Jolt/Physics/Body/BodyFilter.h

@@ -79,7 +79,7 @@ public:
 	}
 	}
 
 
 private:
 private:
-	vector<BodyID>			mBodyIDs;
+	Array<BodyID>			mBodyIDs;
 };
 };
 
 
 JPH_NAMESPACE_END
 JPH_NAMESPACE_END

+ 2 - 0
Jolt/Physics/Body/BodyID.h

@@ -11,6 +11,8 @@ JPH_NAMESPACE_BEGIN
 class BodyID
 class BodyID
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	static constexpr uint32	cInvalidBodyID = 0xffffffff;	///< The value for an invalid body ID
 	static constexpr uint32	cInvalidBodyID = 0xffffffff;	///< The value for an invalid body ID
 	static constexpr uint32	cBroadPhaseBit = 0x00800000;	///< This bit is used by the broadphase
 	static constexpr uint32	cBroadPhaseBit = 0x00800000;	///< This bit is used by the broadphase
 	static constexpr uint32	cMaxBodyIndex = 0x7fffff;		///< Maximum value for body index (also the maximum amount of bodies supported - 1)
 	static constexpr uint32	cMaxBodyIndex = 0x7fffff;		///< Maximum value for body index (also the maximum amount of bodies supported - 1)

+ 3 - 1
Jolt/Physics/Body/BodyManager.cpp

@@ -25,6 +25,8 @@ JPH_NAMESPACE_BEGIN
 class BodyWithMotionProperties : public Body
 class BodyWithMotionProperties : public Body
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	MotionProperties		mMotionProperties;
 	MotionProperties		mMotionProperties;
 };
 };
 
 
@@ -718,7 +720,7 @@ void BodyManager::Draw(const DrawSettings &inDrawSettings, const PhysicsSettings
 			if (inDrawSettings.mDrawSleepStats && body->IsDynamic() && body->IsActive())
 			if (inDrawSettings.mDrawSleepStats && body->IsDynamic() && body->IsActive())
 			{
 			{
 				// Draw stats to know which bodies could go to sleep
 				// Draw stats to know which bodies could go to sleep
-				string text = StringFormat("t: %.1f", (double)body->mMotionProperties->mSleepTestTimer);
+				String text = StringFormat("t: %.1f", (double)body->mMotionProperties->mSleepTestTimer);
 				uint8 g = uint8(Clamp(255.0f * body->mMotionProperties->mSleepTestTimer / inPhysicsSettings.mTimeBeforeSleep, 0.0f, 255.0f));
 				uint8 g = uint8(Clamp(255.0f * body->mMotionProperties->mSleepTestTimer / inPhysicsSettings.mTimeBeforeSleep, 0.0f, 255.0f));
 				Color sleep_color = Color(0, 255 - g, g);
 				Color sleep_color = Color(0, 255 - g, g);
 				inRenderer->DrawText3D(body->GetCenterOfMassPosition(), text, sleep_color, 0.2f);
 				inRenderer->DrawText3D(body->GetCenterOfMassPosition(), text, sleep_color, 0.2f);

+ 5 - 3
Jolt/Physics/Body/BodyManager.h

@@ -18,15 +18,17 @@ class DebugRenderer;
 #endif // JPH_DEBUG_RENDERER
 #endif // JPH_DEBUG_RENDERER
 
 
 /// Array of bodies
 /// Array of bodies
-using BodyVector = vector<Body *>;
+using BodyVector = Array<Body *>;
 
 
 /// Array of body ID's
 /// Array of body ID's
-using BodyIDVector = vector<BodyID>;
+using BodyIDVector = Array<BodyID>;
 
 
 /// Class that contains all bodies
 /// Class that contains all bodies
 class BodyManager : public NonCopyable
 class BodyManager : public NonCopyable
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Destructor
 	/// Destructor
 									~BodyManager();
 									~BodyManager();
 
 
@@ -248,7 +250,7 @@ private:
 	mutable BodyMutexes				mBodyMutexes;
 	mutable BodyMutexes				mBodyMutexes;
 
 
 	/// List of next sequence number for a body ID
 	/// List of next sequence number for a body ID
-	vector<uint8>					mBodySequenceNumbers;
+	Array<uint8>					mBodySequenceNumbers;
 
 
 	/// Mutex that protects the mActiveBodies array
 	/// Mutex that protects the mActiveBodies array
 	mutable Mutex					mActiveBodiesMutex;
 	mutable Mutex					mActiveBodiesMutex;

+ 2 - 0
Jolt/Physics/Body/BodyPair.h

@@ -11,6 +11,8 @@ JPH_NAMESPACE_BEGIN
 /// Structure that holds a body pair
 /// Structure that holds a body pair
 struct BodyPair
 struct BodyPair
 {
 {
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Constructor
 	/// Constructor
 							BodyPair() = default;
 							BodyPair() = default;
 							BodyPair(BodyID inA, BodyID inB)							: mBodyA(inA), mBodyB(inB) { }
 							BodyPair(BodyID inA, BodyID inB)							: mBodyA(inA), mBodyB(inB) { }

+ 2 - 0
Jolt/Physics/Body/MotionProperties.h

@@ -17,6 +17,8 @@ class StateRecorder;
 class MotionProperties
 class MotionProperties
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Motion quality, or how well it detects collisions when it has a high velocity
 	/// Motion quality, or how well it detects collisions when it has a high velocity
 	EMotionQuality			GetMotionQuality() const										{ return mMotionQuality; }
 	EMotionQuality			GetMotionQuality() const										{ return mMotionQuality; }
 	void					SetMotionQuality(EMotionQuality inQuality)						{ mMotionQuality = inQuality; }
 	void					SetMotionQuality(EMotionQuality inQuality)						{ mMotionQuality = inQuality; }

+ 4 - 0
Jolt/Physics/Character/Character.h

@@ -12,6 +12,8 @@ JPH_NAMESPACE_BEGIN
 class CharacterSettings : public CharacterBaseSettings
 class CharacterSettings : public CharacterBaseSettings
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Layer that this character will be added to
 	/// Layer that this character will be added to
 	ObjectLayer							mLayer = 0;
 	ObjectLayer							mLayer = 0;
 
 
@@ -32,6 +34,8 @@ public:
 class Character : public CharacterBase
 class Character : public CharacterBase
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Constructor
 	/// Constructor
 	/// @param inSettings The settings for the character
 	/// @param inSettings The settings for the character
 	/// @param inPosition Initial position for the character
 	/// @param inPosition Initial position for the character

+ 4 - 0
Jolt/Physics/Character/CharacterBase.h

@@ -19,6 +19,8 @@ class StateRecorder;
 class CharacterBaseSettings : public RefTarget<CharacterBaseSettings>
 class CharacterBaseSettings : public RefTarget<CharacterBaseSettings>
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Virtual destructor
 	/// Virtual destructor
 	virtual								~CharacterBaseSettings() = default;
 	virtual								~CharacterBaseSettings() = default;
 
 
@@ -34,6 +36,8 @@ public:
 class CharacterBase : public RefTarget<CharacterBase>, public NonCopyable
 class CharacterBase : public RefTarget<CharacterBase>, public NonCopyable
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Constructor
 	/// Constructor
 										CharacterBase(const CharacterBaseSettings *inSettings, PhysicsSystem *inSystem);
 										CharacterBase(const CharacterBaseSettings *inSettings, PhysicsSystem *inSystem);
 
 

+ 3 - 0
Jolt/Physics/Character/CharacterVirtual.cpp

@@ -8,6 +8,9 @@
 #include <Jolt/Physics/PhysicsSystem.h>
 #include <Jolt/Physics/PhysicsSystem.h>
 #include <Jolt/Physics/Collision/ShapeCast.h>
 #include <Jolt/Physics/Collision/ShapeCast.h>
 #include <Jolt/Physics/Collision/CollideShape.h>
 #include <Jolt/Physics/Collision/CollideShape.h>
+#ifdef JPH_DEBUG_RENDERER
+	#include <Jolt/Renderer/DebugRenderer.h>
+#endif // JPH_DEBUG_RENDERER
 
 
 JPH_NAMESPACE_BEGIN
 JPH_NAMESPACE_BEGIN
 
 

+ 7 - 1
Jolt/Physics/Character/CharacterVirtual.h

@@ -18,6 +18,8 @@ class CharacterVirtual;
 class CharacterVirtualSettings : public CharacterBaseSettings
 class CharacterVirtualSettings : public CharacterBaseSettings
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Vector indicating the up direction of the character
 	/// Vector indicating the up direction of the character
 	Vec3								mUp = Vec3::sAxisY();
 	Vec3								mUp = Vec3::sAxisY();
 
 
@@ -50,6 +52,8 @@ public:
 class CharacterContactListener
 class CharacterContactListener
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Destructor
 	/// Destructor
 	virtual								~CharacterContactListener() = default;
 	virtual								~CharacterContactListener() = default;
 
 
@@ -68,6 +72,8 @@ public:
 class CharacterVirtual : public CharacterBase
 class CharacterVirtual : public CharacterBase
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Constructor
 	/// Constructor
 	/// @param inSettings The settings for the character
 	/// @param inSettings The settings for the character
 	/// @param inPosition Initial position for the character
 	/// @param inPosition Initial position for the character
@@ -195,7 +201,7 @@ private:
 	};
 	};
 
 
 	using TempContactList = vector<Contact, STLTempAllocator<Contact>>;
 	using TempContactList = vector<Contact, STLTempAllocator<Contact>>;
-	using ContactList = vector<Contact>;
+	using ContactList = Array<Contact>;
 
 
 	// A contact that needs to be ignored
 	// A contact that needs to be ignored
 	struct IgnoredContact
 	struct IgnoredContact

+ 2 - 0
Jolt/Physics/Collision/AABoxCast.h

@@ -10,6 +10,8 @@ JPH_NAMESPACE_BEGIN
 /// Structure that holds AABox moving linearly through 3d space
 /// Structure that holds AABox moving linearly through 3d space
 struct AABoxCast
 struct AABoxCast
 {
 {
+	JPH_OVERRIDE_NEW_DELETE
+
 	AABox						mBox;						///< Axis aligned box at starting location
 	AABox						mBox;						///< Axis aligned box at starting location
 	Vec3						mDirection;					///< Direction and length of the cast (anything beyond this length will not be reported as a hit)
 	Vec3						mDirection;					///< Direction and length of the cast (anything beyond this length will not be reported as a hit)
 };
 };

+ 1 - 1
Jolt/Physics/Collision/BroadPhase/BroadPhaseBruteForce.cpp

@@ -62,7 +62,7 @@ void BroadPhaseBruteForce::RemoveBodies(BodyID *ioBodies, int inNumber)
 		JPH_ASSERT(body.IsInBroadPhase());
 		JPH_ASSERT(body.IsInBroadPhase());
 
 
 		// Find body id
 		// Find body id
-		vector<BodyID>::iterator it = lower_bound(mBodyIDs.begin(), mBodyIDs.end(), body.GetID());
+		Array<BodyID>::iterator it = lower_bound(mBodyIDs.begin(), mBodyIDs.end(), body.GetID());
 		JPH_ASSERT(it != mBodyIDs.end());
 		JPH_ASSERT(it != mBodyIDs.end());
 
 
 		// Remove element
 		// Remove element

+ 3 - 1
Jolt/Physics/Collision/BroadPhase/BroadPhaseBruteForce.h

@@ -12,6 +12,8 @@ JPH_NAMESPACE_BEGIN
 class BroadPhaseBruteForce final : public BroadPhase
 class BroadPhaseBruteForce final : public BroadPhase
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	// Implementing interface of BroadPhase (see BroadPhase for documentation)
 	// Implementing interface of BroadPhase (see BroadPhase for documentation)
 	virtual void		AddBodiesFinalize(BodyID *ioBodies, int inNumber, AddState inAddState) override;
 	virtual void		AddBodiesFinalize(BodyID *ioBodies, int inNumber, AddState inAddState) override;
 	virtual void		RemoveBodies(BodyID *ioBodies, int inNumber) override;
 	virtual void		RemoveBodies(BodyID *ioBodies, int inNumber) override;
@@ -27,7 +29,7 @@ public:
 	virtual void		FindCollidingPairs(BodyID *ioActiveBodies, int inNumActiveBodies, float inSpeculativeContactDistance, ObjectVsBroadPhaseLayerFilter inObjectVsBroadPhaseLayerFilter, ObjectLayerPairFilter inObjectLayerPairFilter, BodyPairCollector &ioPairCollector) const override;
 	virtual void		FindCollidingPairs(BodyID *ioActiveBodies, int inNumActiveBodies, float inSpeculativeContactDistance, ObjectVsBroadPhaseLayerFilter inObjectVsBroadPhaseLayerFilter, ObjectLayerPairFilter inObjectLayerPairFilter, BodyPairCollector &ioPairCollector) const override;
 
 
 private:
 private:
-	vector<BodyID>		mBodyIDs;
+	Array<BodyID>		mBodyIDs;
 	mutable SharedMutex	mMutex;
 	mutable SharedMutex	mMutex;
 };
 };
 
 

+ 4 - 0
Jolt/Physics/Collision/BroadPhase/BroadPhaseQuadTree.h

@@ -12,6 +12,8 @@ JPH_NAMESPACE_BEGIN
 class BroadPhaseQuadTree final : public BroadPhase
 class BroadPhaseQuadTree final : public BroadPhase
 {
 {
 public:
 public:
+	JPH_OVERRIDE_NEW_DELETE
+
 	/// Destructor
 	/// Destructor
 	virtual					~BroadPhaseQuadTree() override;
 	virtual					~BroadPhaseQuadTree() override;
 
 
@@ -45,6 +47,8 @@ private:
 	/// Helper struct for AddBodies handle
 	/// Helper struct for AddBodies handle
 	struct LayerState
 	struct LayerState
 	{
 	{
+		JPH_OVERRIDE_NEW_DELETE
+
 		BodyID *			mBodyStart = nullptr;
 		BodyID *			mBodyStart = nullptr;
 		BodyID *			mBodyEnd;
 		BodyID *			mBodyEnd;
 		QuadTree::AddState	mAddState;
 		QuadTree::AddState	mAddState;

+ 3 - 3
Jolt/Physics/Collision/BroadPhase/QuadTree.cpp

@@ -1549,7 +1549,7 @@ void QuadTree::DumpTree(const NodeID &inRoot, const char *inFileNamePrefix) cons
 		if (node_id.IsBody())
 		if (node_id.IsBody())
 		{
 		{
 			// Output body
 			// Output body
-			string body_id = ConvertToString(node_id.GetBodyID().GetIndex());
+			String body_id = ConvertToString(node_id.GetBodyID().GetIndex());
 			f << "body" << body_id << "[label = \"Body " << body_id << "\"]\n";
 			f << "body" << body_id << "[label = \"Body " << body_id << "\"]\n";
 		}
 		}
 		else
 		else
@@ -1563,7 +1563,7 @@ void QuadTree::DumpTree(const NodeID &inRoot, const char *inFileNamePrefix) cons
 			node.GetNodeBounds(bounds);
 			node.GetNodeBounds(bounds);
 
 
 			// Output node
 			// Output node
-			string node_str = ConvertToString(node_idx);
+			String node_str = ConvertToString(node_idx);
 			f << "node" << node_str << "[label = \"Node " << node_str << "\nVolume: " << ConvertToString(bounds.GetVolume()) << "\" color=" << (node.mIsChanged? "red" : "black") << "]\n";
 			f << "node" << node_str << "[label = \"Node " << node_str << "\nVolume: " << ConvertToString(bounds.GetVolume()) << "\" color=" << (node.mIsChanged? "red" : "black") << "]\n";
 
 
 			// Recurse and get all children
 			// Recurse and get all children
@@ -1592,7 +1592,7 @@ void QuadTree::DumpTree(const NodeID &inRoot, const char *inFileNamePrefix) cons
 	f.close();
 	f.close();
 
 
 	// Convert to svg file
 	// Convert to svg file
-	string cmd = StringFormat("dot %s.dot -Tsvg -o %s.svg", inFileNamePrefix, inFileNamePrefix);
+	String cmd = StringFormat("dot %s.dot -Tsvg -o %s.svg", inFileNamePrefix, inFileNamePrefix);
 	system(cmd.c_str());
 	system(cmd.c_str());
 }
 }
 
 

+ 7 - 6
Jolt/Physics/Collision/BroadPhase/QuadTree.h

@@ -9,10 +9,6 @@
 #include <Jolt/Physics/Body/BodyManager.h>
 #include <Jolt/Physics/Body/BodyManager.h>
 #include <Jolt/Physics/Collision/BroadPhase/BroadPhase.h>
 #include <Jolt/Physics/Collision/BroadPhase/BroadPhase.h>
 
 
-#ifdef JPH_TRACK_BROADPHASE_STATS
-	#include <map>
-#endif // JPH_TRACK_BROADPHASE_STATS
-
 //#define JPH_DUMP_BROADPHASE_TREE
 //#define JPH_DUMP_BROADPHASE_TREE
 
 
 JPH_NAMESPACE_BEGIN
 JPH_NAMESPACE_BEGIN
@@ -22,6 +18,9 @@ JPH_NAMESPACE_BEGIN
 /// During the UpdatePrepare/Finalize() call the tree is rebuilt to achieve a tight fit again.
 /// During the UpdatePrepare/Finalize() call the tree is rebuilt to achieve a tight fit again.
 class QuadTree : public NonCopyable
 class QuadTree : public NonCopyable
 {
 {
+public:
+	JPH_OVERRIDE_NEW_DELETE
+
 private:
 private:
 	// Forward declare
 	// Forward declare
 	class AtomicNodeID;
 	class AtomicNodeID;
@@ -30,6 +29,8 @@ private:
 	class NodeID
 	class NodeID
 	{
 	{
 	public:
 	public:
+		JPH_OVERRIDE_NEW_DELETE
+
 		/// Default constructor does not initialize
 		/// Default constructor does not initialize
 		inline 					NodeID() = default;
 		inline 					NodeID() = default;
 
 
@@ -164,7 +165,7 @@ public:
 		atomic<uint32>			mBodyLocation { cInvalidBodyLocation };
 		atomic<uint32>			mBodyLocation { cInvalidBodyLocation };
 	};
 	};
 
 
-	using TrackingVector = vector<Tracking>;
+	using TrackingVector = Array<Tracking>;
 
 
 	/// Destructor
 	/// Destructor
 								~QuadTree();
 								~QuadTree();
@@ -331,7 +332,7 @@ private:
 		uint64					mCollectorTicks = 0;
 		uint64					mCollectorTicks = 0;
 	};
 	};
 	
 	
-	using LayerToStats = map<string, Stat>;
+	using LayerToStats = UnorderedMap<String, Stat>;
 
 
 	/// Trace the stats of a single query type to the TTY
 	/// Trace the stats of a single query type to the TTY
 	void						ReportStats(const char *inName, const LayerToStats &inLayer) const;
 	void						ReportStats(const char *inName, const LayerToStats &inLayer) const;

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor