Browse Source

Add ReleaseMemoryPools to free up any memory pools and free the ObserverPtrBlock pool. (#265)

Jack Powell 3 years ago
parent
commit
ab90eea5b8
3 changed files with 29 additions and 4 deletions
  1. 3 0
      Include/RmlUi/Core/Core.h
  2. 17 0
      Source/Core/Core.cpp
  3. 9 4
      Source/Core/ObserverPtr.cpp

+ 3 - 0
Include/RmlUi/Core/Core.h

@@ -154,6 +154,9 @@ RMLUICORE_API void ReleaseTextures(RenderInterface* render_interface = nullptr);
 /// Forces all compiled geometry handles generated by RmlUi to be released.
 RMLUICORE_API void ReleaseCompiledGeometry();
 
+/// Forces all memory pools used by RmlUi to be released.
+RMLUICORE_API void ReleaseMemoryPools();
+
 } // namespace Rml
 
 #endif

+ 17 - 0
Source/Core/Core.cpp

@@ -59,6 +59,8 @@
 #include "../SVG/SVGPlugin.h"
 #endif
 
+#include "Pool.h"
+
 
 namespace Rml {
 
@@ -80,6 +82,9 @@ static bool initialised = false;
 using ContextMap = UnorderedMap< String, ContextPtr >;
 static ContextMap contexts;
 
+// The ObserverPtrBlock pool
+extern Pool<ObserverPtrBlock>* observerPtrBlockPool;
+
 #ifndef RMLUI_VERSION
 	#define RMLUI_VERSION "custom"
 #endif
@@ -178,6 +183,9 @@ void Shutdown()
 	default_file_interface.reset();
 
 	Log::Shutdown();
+
+	// Release any memory pools
+	ReleaseMemoryPools();
 }
 
 // Returns the version of this RmlUi library.
@@ -371,4 +379,13 @@ void ReleaseCompiledGeometry()
 	return GeometryDatabase::ReleaseAll();
 }
 
+void ReleaseMemoryPools()
+{
+	if (observerPtrBlockPool && observerPtrBlockPool->GetNumAllocatedObjects() <= 0)
+	{
+		delete observerPtrBlockPool;
+		observerPtrBlockPool = nullptr;
+	}
+}
+
 } // namespace Rml

+ 9 - 4
Source/Core/ObserverPtr.cpp

@@ -31,17 +31,22 @@
 
 namespace Rml {
 
-static Pool< ObserverPtrBlock >& GetPool()
+// The ObserverPtrBlock pool
+Pool<ObserverPtrBlock>* observerPtrBlockPool = nullptr;
+
+static Pool<ObserverPtrBlock>& GetPool()
 {
 	// Wrap pool in a function to ensure it is initialized before use.
 	// This pool must outlive all other global variables that derive from EnableObserverPtr. This even includes
 	// user variables which we have no control over. For this reason, we intentionally let this leak.
-	static Pool< ObserverPtrBlock >* pool =  new Pool< ObserverPtrBlock >(128, true);
-	return *pool;
+	if (observerPtrBlockPool == nullptr)
+		observerPtrBlockPool = new Pool<ObserverPtrBlock>(128, true);
+	return *observerPtrBlockPool;
 }
 
 
-void DeallocateObserverPtrBlockIfEmpty(ObserverPtrBlock* block) {
+void DeallocateObserverPtrBlockIfEmpty(ObserverPtrBlock* block)
+{
 	RMLUI_ASSERT(block->num_observers >= 0);
 	if (block->num_observers == 0 && block->pointed_to_object == nullptr)
 	{