浏览代码

Fixed multiple exceptions and deadlocks that were happening when attempting to exit the application

Marko Pintera 13 年之前
父节点
当前提交
fda3ca2150
共有 32 个文件被更改,包括 229 次插入203 次删除
  1. 55 49
      CamelotClient/CamelotClient.cpp
  2. 4 4
      CamelotClient/CamelotClient.vcxproj
  3. 0 1
      CamelotD3D11RenderSystem/Include/CmD3D11HLSLProgramFactory.h
  4. 0 5
      CamelotD3D11RenderSystem/Source/CmD3D11HLSLProgramFactory.cpp
  5. 2 1
      CamelotD3D11RenderSystem/Source/CmD3D11RenderSystem.cpp
  6. 0 2
      CamelotD3D9Renderer/Include/CmD3D9HLSLProgramFactory.h
  7. 6 10
      CamelotD3D9Renderer/Include/CmD3D9ResourceManager.h
  8. 0 2
      CamelotD3D9Renderer/Source/CmD3D9Device.cpp
  9. 3 0
      CamelotD3D9Renderer/Source/CmD3D9GpuProgram.cpp
  10. 0 6
      CamelotD3D9Renderer/Source/CmD3D9HLSLProgramFactory.cpp
  11. 2 0
      CamelotD3D9Renderer/Source/CmD3D9IndexBuffer.cpp
  12. 23 26
      CamelotD3D9Renderer/Source/CmD3D9RenderSystem.cpp
  13. 1 1
      CamelotD3D9Renderer/Source/CmD3D9Resource.cpp
  14. 20 20
      CamelotD3D9Renderer/Source/CmD3D9ResourceManager.cpp
  15. 2 0
      CamelotD3D9Renderer/Source/CmD3D9Texture.cpp
  16. 2 0
      CamelotD3D9Renderer/Source/CmD3D9VertexBuffer.cpp
  17. 3 0
      CamelotD3D9Renderer/Source/CmD3D9VertexDeclaration.cpp
  18. 17 16
      CamelotGLRenderer/Source/CmGLRenderSystem.cpp
  19. 0 1
      CamelotGLRenderer/Source/GLSL/include/CmGLSLProgramFactory.h
  20. 0 7
      CamelotGLRenderer/Source/GLSL/src/CmGLSLProgramFactory.cpp
  21. 23 0
      CamelotRenderer/Include/CmApplication.h
  22. 0 1
      CamelotRenderer/Include/CmCommandQueue.h
  23. 0 3
      CamelotRenderer/Include/CmGpuProgramManager.h
  24. 1 1
      CamelotRenderer/Include/CmHighLevelGpuProgram.h
  25. 0 3
      CamelotRenderer/Include/CmHighLevelGpuProgramManager.h
  26. 1 1
      CamelotRenderer/Include/CmRenderSystem.h
  27. 11 3
      CamelotRenderer/Source/CmApplication.cpp
  28. 1 12
      CamelotRenderer/Source/CmGpuProgramManager.cpp
  29. 3 8
      CamelotRenderer/Source/CmHighLevelGpuProgramManager.cpp
  30. 22 17
      CamelotRenderer/Source/CmRenderSystem.cpp
  31. 4 1
      CamelotRenderer/Source/CmWindowEventUtilities.cpp
  32. 23 2
      CamelotRenderer/TODO.txt

+ 55 - 49
CamelotClient/CamelotClient.cpp

@@ -2,6 +2,7 @@
 //
 //
 
 
 #include "stdafx.h"
 #include "stdafx.h"
+#include <windows.h>
 
 
 #include "CmApplication.h"
 #include "CmApplication.h"
 #include "CmDynLibManager.h"
 #include "CmDynLibManager.h"
@@ -24,10 +25,15 @@
 
 
 using namespace CamelotEngine;
 using namespace CamelotEngine;
 
 
-int _tmain(int argc, _TCHAR* argv[])
+int CALLBACK WinMain(
+	_In_  HINSTANCE hInstance,
+	_In_  HINSTANCE hPrevInstance,
+	_In_  LPSTR lpCmdLine,
+	_In_  int nCmdShow
+	)
 {
 {
-	//gApplication().startUp("CamelotGLRenderSystem", "CamelotForwardRenderer");
-	gApplication().startUp("CamelotD3D9RenderSystem", "CamelotForwardRenderer");
+	gApplication().startUp("CamelotGLRenderSystem", "CamelotForwardRenderer");
+	//gApplication().startUp("CamelotD3D9RenderSystem", "CamelotForwardRenderer");
 	//gApplication().startUp("CamelotD3D11RenderSystem", "CamelotForwardRenderer");
 	//gApplication().startUp("CamelotD3D11RenderSystem", "CamelotForwardRenderer");
 
 
 	RenderSystem* renderSystem = RenderSystem::instancePtr();
 	RenderSystem* renderSystem = RenderSystem::instancePtr();
@@ -51,27 +57,27 @@ int _tmain(int argc, _TCHAR* argv[])
 	HighLevelGpuProgramPtr vertProg;
 	HighLevelGpuProgramPtr vertProg;
 
 
 	/////////////////// HLSL 9 SHADERS //////////////////////////
 	/////////////////// HLSL 9 SHADERS //////////////////////////
-	String fragShaderCode = "sampler2D tex;			\
-							float4 ps_main(float2 uv : TEXCOORD0) : COLOR0		\
-							{														\
-							float4 color = tex2D(tex, uv);				\
-							return color;										\
-							}";
-
-	fragProg =  HighLevelGpuProgram::create(fragShaderCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
-
-	String vertShaderCode = "float4x4 matViewProjection;	\
-							void vs_main(										\
-							float4 inPos : POSITION,							\
-							float2 uv : TEXCOORD0,								\
-							out float4 oPosition : POSITION,					\
-							out float2 oUv : TEXCOORD0)							\
-							{														\
-							oPosition = mul(matViewProjection, inPos);			\
-							oUv = uv;											\
-							}";
-
-	vertProg =  HighLevelGpuProgram::create(vertShaderCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
+	//String fragShaderCode = "sampler2D tex;			\
+	//						float4 ps_main(float2 uv : TEXCOORD0) : COLOR0		\
+	//						{														\
+	//						float4 color = tex2D(tex, uv);				\
+	//						return color;										\
+	//						}";
+
+	//fragProg =  HighLevelGpuProgram::create(fragShaderCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
+
+	//String vertShaderCode = "float4x4 matViewProjection;	\
+	//						void vs_main(										\
+	//						float4 inPos : POSITION,							\
+	//						float2 uv : TEXCOORD0,								\
+	//						out float4 oPosition : POSITION,					\
+	//						out float2 oUv : TEXCOORD0)							\
+	//						{														\
+	//						oPosition = mul(matViewProjection, inPos);			\
+	//						oUv = uv;											\
+	//						}";
+
+	//vertProg =  HighLevelGpuProgram::create(vertShaderCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
 
 
 	/////////////////// HLSL 11 SHADERS //////////////////////////
 	/////////////////// HLSL 11 SHADERS //////////////////////////
 	//String fragShaderCode = "SamplerState samp : register(s0);			\
 	//String fragShaderCode = "SamplerState samp : register(s0);			\
@@ -121,31 +127,31 @@ int _tmain(int argc, _TCHAR* argv[])
 	//vertProg =  HighLevelGpuProgram::create(vertShaderCode, "vs_main", "cg", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
 	//vertProg =  HighLevelGpuProgram::create(vertShaderCode, "vs_main", "cg", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
 
 
 	///////////////// GLSL SHADERS ////////////////////////////
 	///////////////// GLSL SHADERS ////////////////////////////
-	//String fragShaderCode = " #version 400 \n \
-	//						  uniform sampler2D tex; \
-	//						  in vec2 texcoord0; \
-	//						  out vec4 fragColor; \
-	//						  void main() \
-	//						  {\
-	//							  vec4 texColor = texture2D(tex, texcoord0.st);\
-	//							  fragColor = texColor; \
-	//						  }";
-
-	//fragProg = HighLevelGpuProgram::create(fragShaderCode, "main", "glsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
-
-	//// TODO - Make sure to document the strict input parameter naming. (Exact supported names are in GLSLParamParser)
-	//String vertShaderCode = "#version 400 \n \
-	//						 uniform mainFragBlock { mat4 matViewProjection; }; \
-	//						 in vec4 cm_position; \
-	//						 in vec2 cm_texcoord0; \
-	//						 out vec2 texcoord0; \
-	//						 void main() \
-	//						 { \
-	//							texcoord0 = cm_texcoord0; \
-	//							gl_Position = cm_position * matViewProjection; \
-	//						 }";
-
-	//vertProg = HighLevelGpuProgram::create(vertShaderCode, "main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
+	String fragShaderCode = " #version 400 \n \
+							  uniform sampler2D tex; \
+							  in vec2 texcoord0; \
+							  out vec4 fragColor; \
+							  void main() \
+							  {\
+								  vec4 texColor = texture2D(tex, texcoord0.st);\
+								  fragColor = texColor; \
+							  }";
+
+	fragProg = HighLevelGpuProgram::create(fragShaderCode, "main", "glsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
+
+	// TODO - Make sure to document the strict input parameter naming. (Exact supported names are in GLSLParamParser)
+	String vertShaderCode = "#version 400 \n \
+							 uniform mainFragBlock { mat4 matViewProjection; }; \
+							 in vec4 cm_position; \
+							 in vec2 cm_texcoord0; \
+							 out vec2 texcoord0; \
+							 void main() \
+							 { \
+								texcoord0 = cm_texcoord0; \
+								gl_Position = cm_position * matViewProjection; \
+							 }";
+
+	vertProg = HighLevelGpuProgram::create(vertShaderCode, "main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
 
 
 	HighLevelGpuProgramHandle vertProgRef(vertProg);
 	HighLevelGpuProgramHandle vertProgRef(vertProg);
 
 

+ 4 - 4
CamelotClient/CamelotClient.vcxproj

@@ -97,7 +97,7 @@
       <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
       <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
     </ClCompile>
     <Link>
     <Link>
-      <SubSystem>Console</SubSystem>
+      <SubSystem>Windows</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <AdditionalDependencies>CamelotRenderer.lib;CamelotUtility.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalDependencies>CamelotRenderer.lib;CamelotUtility.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>..\lib\$(Configuration);..\Dependencies\lib\Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalLibraryDirectories>..\lib\$(Configuration);..\Dependencies\lib\Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -114,7 +114,7 @@
       <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
       <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
     </ClCompile>
     <Link>
     <Link>
-      <SubSystem>Console</SubSystem>
+      <SubSystem>Windows</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <AdditionalDependencies>CamelotRenderer.lib;CamelotUtility.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalDependencies>CamelotRenderer.lib;CamelotUtility.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>..\lib\$(Platform)\$(Configuration);..\Dependencies\lib\x64\Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalLibraryDirectories>..\lib\$(Platform)\$(Configuration);..\Dependencies\lib\x64\Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -133,7 +133,7 @@
       <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
       <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
     </ClCompile>
     <Link>
     <Link>
-      <SubSystem>Console</SubSystem>
+      <SubSystem>Windows</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
       <OptimizeReferences>true</OptimizeReferences>
@@ -154,7 +154,7 @@
       <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
       <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
     </ClCompile>
     <Link>
     <Link>
-      <SubSystem>Console</SubSystem>
+      <SubSystem>Windows</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
       <OptimizeReferences>true</OptimizeReferences>

+ 0 - 1
CamelotD3D11RenderSystem/Include/CmD3D11HLSLProgramFactory.h

@@ -16,6 +16,5 @@ namespace CamelotEngine
 		const String& getLanguage(void) const;
 		const String& getLanguage(void) const;
 		HighLevelGpuProgram* create(const String& source, const String& entryPoint, GpuProgramType gptype, GpuProgramProfile profile);
 		HighLevelGpuProgram* create(const String& source, const String& entryPoint, GpuProgramType gptype, GpuProgramProfile profile);
 		HighLevelGpuProgram* create();
 		HighLevelGpuProgram* create();
-		void destroy_internal(HighLevelGpuProgram* prog);
 	};
 	};
 }
 }

+ 0 - 5
CamelotD3D11RenderSystem/Source/CmD3D11HLSLProgramFactory.cpp

@@ -31,9 +31,4 @@ namespace CamelotEngine
 
 
 		return prog;
 		return prog;
 	}
 	}
-
-	void D3D11HLSLProgramFactory::destroy_internal(HighLevelGpuProgram* prog)
-    {
-        delete prog;
-    }
 }
 }

+ 2 - 1
CamelotD3D11RenderSystem/Source/CmD3D11RenderSystem.cpp

@@ -43,7 +43,8 @@ namespace CamelotEngine
 
 
 	D3D11RenderSystem::~D3D11RenderSystem()
 	D3D11RenderSystem::~D3D11RenderSystem()
 	{
 	{
-		destroy_internal();
+		// This needs to be called from the child class, since destroy_internal is virtual
+		queueCommand(boost::bind(&D3D11RenderSystem::destroy_internal, this), true);
 	}
 	}
 
 
 	const String& D3D11RenderSystem::getName() const
 	const String& D3D11RenderSystem::getName() const

+ 0 - 2
CamelotD3D9Renderer/Include/CmD3D9HLSLProgramFactory.h

@@ -45,8 +45,6 @@ namespace CamelotEngine
 		const String& getLanguage(void) const;
 		const String& getLanguage(void) const;
         HighLevelGpuProgram* create(const String& source, const String& entryPoint, GpuProgramType gptype, GpuProgramProfile profile);
         HighLevelGpuProgram* create(const String& source, const String& entryPoint, GpuProgramType gptype, GpuProgramProfile profile);
 		HighLevelGpuProgram* create();
 		HighLevelGpuProgram* create();
-		void destroy_internal(HighLevelGpuProgram* prog);
-
     };
     };
 }
 }
 
 

+ 6 - 10
CamelotD3D9Renderer/Include/CmD3D9ResourceManager.h

@@ -76,6 +76,12 @@ namespace CamelotEngine {
 		// Relevant for multi thread application.
 		// Relevant for multi thread application.
 		void unlockDeviceAccess		();
 		void unlockDeviceAccess		();
 		
 		
+		// Called when new resource created.
+		void _notifyResourceCreated		(D3D9Resource* pResource);
+
+		// Called when resource is about to be destroyed.
+		void _notifyResourceDestroyed	(D3D9Resource* pResource);
+
 		D3D9ResourceManager			();
 		D3D9ResourceManager			();
 		~D3D9ResourceManager		();		
 		~D3D9ResourceManager		();		
 
 
@@ -91,16 +97,6 @@ namespace CamelotEngine {
 		typedef vector<D3D9Resource*>::type		ResourceContainer;
 		typedef vector<D3D9Resource*>::type		ResourceContainer;
 		typedef ResourceContainer::iterator		ResourceContainerIterator;
 		typedef ResourceContainer::iterator		ResourceContainerIterator;
 
 
-	// Protected methods.
-	protected:
-		
-		// Called when new resource created.
-		void _notifyResourceCreated		(D3D9Resource* pResource);
-
-		// Called when resource is about to be destroyed.
-		void _notifyResourceDestroyed	(D3D9Resource* pResource);
-				
-
 	// Attributes.
 	// Attributes.
 	protected:		
 	protected:		
 		CM_MUTEX(mResourcesMutex)
 		CM_MUTEX(mResourcesMutex)

+ 0 - 2
CamelotD3D9Renderer/Source/CmD3D9Device.cpp

@@ -706,8 +706,6 @@ namespace CamelotEngine
 
 
 			mpDeviceManager->setActiveDevice(pCurActiveDevice);
 			mpDeviceManager->setActiveDevice(pCurActiveDevice);
 			
 			
-			clearDeviceStreams();		
-
 			// Release device.
 			// Release device.
 			SAFE_RELEASE(mpDevice);	
 			SAFE_RELEASE(mpDevice);	
 			
 			

+ 3 - 0
CamelotD3D9Renderer/Source/CmD3D9GpuProgram.cpp

@@ -30,6 +30,7 @@ THE SOFTWARE.
 #include "CmException.h"
 #include "CmException.h"
 #include "CmD3D9Mappings.h"
 #include "CmD3D9Mappings.h"
 #include "CmD3D9RenderSystem.h"
 #include "CmD3D9RenderSystem.h"
+#include "CmD3D9ResourceManager.h"
 #include "CmGpuParams.h"
 #include "CmGpuParams.h"
 #include "CmAsyncOp.h"
 #include "CmAsyncOp.h"
 
 
@@ -291,6 +292,8 @@ namespace CamelotEngine {
 		}
 		}
 		mMapDeviceToPixelShader.clear();	
 		mMapDeviceToPixelShader.clear();	
 
 
+		D3D9RenderSystem::getResourceManager()->_notifyResourceDestroyed(static_cast<D3D9Resource*>(this));
+
 		D3D9GpuProgram::destroy_internal();
 		D3D9GpuProgram::destroy_internal();
     }
     }
 	//-----------------------------------------------------------------------------
 	//-----------------------------------------------------------------------------

+ 0 - 6
CamelotD3D9Renderer/Source/CmD3D9HLSLProgramFactory.cpp

@@ -60,10 +60,4 @@ namespace CamelotEngine {
 
 
 		return prog;
 		return prog;
 	}
 	}
-    //-----------------------------------------------------------------------
-	void D3D9HLSLProgramFactory::destroy_internal(HighLevelGpuProgram* prog)
-    {
-        delete prog;
-    }
-    //-----------------------------------------------------------------------
 }
 }

+ 2 - 0
CamelotD3D9Renderer/Source/CmD3D9IndexBuffer.cpp

@@ -341,6 +341,8 @@ namespace CamelotEngine {
 		mMapDeviceToBufferResources.clear();   
 		mMapDeviceToBufferResources.clear();   
 		SAFE_DELETE_ARRAY(mSystemMemoryBuffer);
 		SAFE_DELETE_ARRAY(mSystemMemoryBuffer);
 
 
+		D3D9RenderSystem::getResourceManager()->_notifyResourceDestroyed(static_cast<D3D9Resource*>(this));
+
 		IndexBuffer::destroy_internal();
 		IndexBuffer::destroy_internal();
 	}
 	}
 }
 }

+ 23 - 26
CamelotD3D9Renderer/Source/CmD3D9RenderSystem.cpp

@@ -116,28 +116,9 @@ namespace CamelotEngine
 	}
 	}
 	//---------------------------------------------------------------------
 	//---------------------------------------------------------------------
 	D3D9RenderSystem::~D3D9RenderSystem()
 	D3D9RenderSystem::~D3D9RenderSystem()
-	{		
-		destroy_internal();
-
-		// Deleting the HLSL program factory
-		if (mHLSLProgramFactory)
-		{
-			HighLevelGpuProgramManager::instance().removeFactory(mHLSLProgramFactory);
-			delete mHLSLProgramFactory;
-			mHLSLProgramFactory = 0;
-		}
-
-		if(mCgProgramFactory)
-		{
-			HighLevelGpuProgramManager::instance().removeFactory(mCgProgramFactory);
-			delete mCgProgramFactory;
-			mCgProgramFactory = 0;
-		}
-
-		SAFE_RELEASE( mpD3D );
-		SAFE_DELETE ( mResourceManager );
-
-		msD3D9RenderSystem = NULL;
+	{
+		// This needs to be called from the child class, since destroy_internal is virtual
+		queueCommand(boost::bind(&D3D9RenderSystem::destroy_internal, this), true);
 	}
 	}
 
 
 	const String& D3D9RenderSystem::getName() const
 	const String& D3D9RenderSystem::getName() const
@@ -225,6 +206,26 @@ namespace CamelotEngine
 		GpuProgramManager::shutDown();	
 		GpuProgramManager::shutDown();	
 		RenderWindowManager::shutDown();
 		RenderWindowManager::shutDown();
 		RenderStateManager::shutDown();
 		RenderStateManager::shutDown();
+
+		// Deleting the HLSL program factory
+		if (mHLSLProgramFactory)
+		{
+			HighLevelGpuProgramManager::instance().removeFactory(mHLSLProgramFactory);
+			delete mHLSLProgramFactory;
+			mHLSLProgramFactory = 0;
+		}
+
+		if(mCgProgramFactory)
+		{
+			HighLevelGpuProgramManager::instance().removeFactory(mCgProgramFactory);
+			delete mCgProgramFactory;
+			mCgProgramFactory = 0;
+		}
+
+		SAFE_RELEASE( mpD3D );
+		SAFE_DELETE ( mResourceManager );
+
+		msD3D9RenderSystem = NULL;
 	}
 	}
 	//--------------------------------------------------------------------
 	//--------------------------------------------------------------------
 	void D3D9RenderSystem::registerRenderWindow(D3D9RenderWindowPtr renderWindow)
 	void D3D9RenderSystem::registerRenderWindow(D3D9RenderWindowPtr renderWindow)
@@ -1171,10 +1172,6 @@ namespace CamelotEngine
 			CM_EXCEPT(RenderingAPIException, "Error beginning frame :" + msg);
 			CM_EXCEPT(RenderingAPIException, "Error beginning frame :" + msg);
 		}
 		}
 
 
-		// Clear left overs of previous viewport.
-		// I.E: Viewport A can use 3 different textures and light states
-		// When trying to render viewport B these settings should be cleared, otherwise 
-		// graphical artifacts might occur.
  		mDeviceManager->getActiveDevice()->clearDeviceStreams();
  		mDeviceManager->getActiveDevice()->clearDeviceStreams();
 	}
 	}
 	//---------------------------------------------------------------------
 	//---------------------------------------------------------------------

+ 1 - 1
CamelotD3D9Renderer/Source/CmD3D9Resource.cpp

@@ -40,7 +40,7 @@ namespace CamelotEngine
 
 
 	D3D9Resource::~D3D9Resource()
 	D3D9Resource::~D3D9Resource()
 	{		
 	{		
-		D3D9RenderSystem::getResourceManager()->_notifyResourceDestroyed(static_cast<D3D9Resource*>(this));
+		
 	}
 	}
 	
 	
 	void D3D9Resource::lockDeviceAccess()
 	void D3D9Resource::lockDeviceAccess()

+ 20 - 20
CamelotD3D9Renderer/Source/CmD3D9ResourceManager.cpp

@@ -60,53 +60,53 @@ namespace CamelotEngine
 	 //-----------------------------------------------------------------------
 	 //-----------------------------------------------------------------------
 	void D3D9ResourceManager::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device)
 	void D3D9ResourceManager::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device)
 	{				
 	{				
-		CM_LOCK_MUTEX(mResourcesMutex)
+/*		CM_LOCK_MUTEX(mResourcesMutex)
 
 
 		ResourceContainerIterator it = mResources.begin();
 		ResourceContainerIterator it = mResources.begin();
 		while (it != mResources.end())
 		while (it != mResources.end())
 		{
 		{
 			(*it)->notifyOnDeviceCreate(d3d9Device);
 			(*it)->notifyOnDeviceCreate(d3d9Device);
 			++it;
 			++it;
-		}				
+		}		*/		
 	}
 	}
 
 
 	 //-----------------------------------------------------------------------
 	 //-----------------------------------------------------------------------
 	void D3D9ResourceManager::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device)
 	void D3D9ResourceManager::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device)
 	{
 	{
-		CM_LOCK_MUTEX(mResourcesMutex)
-
-		ResourceContainerIterator it = mResources.begin();
-		while (it != mResources.end())
-		{
-			(*it)->notifyOnDeviceDestroy(d3d9Device);
-			++it;
-		}	
+		//CM_LOCK_MUTEX(mResourcesMutex)
+
+		//ResourceContainerIterator it = mResources.begin();
+		//while (it != mResources.end())
+		//{
+		//	(*it)->notifyOnDeviceDestroy(d3d9Device);
+		//	++it;
+		//}	
 	}
 	}
 
 
 	 //-----------------------------------------------------------------------
 	 //-----------------------------------------------------------------------
 	void D3D9ResourceManager::notifyOnDeviceLost(IDirect3DDevice9* d3d9Device)
 	void D3D9ResourceManager::notifyOnDeviceLost(IDirect3DDevice9* d3d9Device)
 	{
 	{
-		CM_LOCK_MUTEX(mResourcesMutex)
-
-		ResourceContainerIterator it = mResources.begin();
-		while (it != mResources.end())
-		{
-			(*it)->notifyOnDeviceLost(d3d9Device);
-			++it;
-		}	
+		//CM_LOCK_MUTEX(mResourcesMutex)
+
+		//ResourceContainerIterator it = mResources.begin();
+		//while (it != mResources.end())
+		//{
+		//	(*it)->notifyOnDeviceLost(d3d9Device);
+		//	++it;
+		//}	
 	}
 	}
 
 
 	 //-----------------------------------------------------------------------
 	 //-----------------------------------------------------------------------
 	void D3D9ResourceManager::notifyOnDeviceReset(IDirect3DDevice9* d3d9Device)
 	void D3D9ResourceManager::notifyOnDeviceReset(IDirect3DDevice9* d3d9Device)
 	{		
 	{		
-		CM_LOCK_MUTEX(mResourcesMutex)
+/*		CM_LOCK_MUTEX(mResourcesMutex)
 
 
 		ResourceContainerIterator it = mResources.begin();
 		ResourceContainerIterator it = mResources.begin();
 		while (it != mResources.end())
 		while (it != mResources.end())
 		{
 		{
 			(*it)->notifyOnDeviceReset(d3d9Device);
 			(*it)->notifyOnDeviceReset(d3d9Device);
 			++it;			
 			++it;			
-		}		
+		}	*/	
 	}
 	}
 
 
 	//-----------------------------------------------------------------------
 	//-----------------------------------------------------------------------

+ 2 - 0
CamelotD3D9Renderer/Source/CmD3D9Texture.cpp

@@ -240,6 +240,8 @@ namespace CamelotEngine
 		
 		
 		clearBufferViews();
 		clearBufferViews();
 
 
+		D3D9RenderSystem::getResourceManager()->_notifyResourceDestroyed(static_cast<D3D9Resource*>(this));
+
 		IDestroyable::destroy();
 		IDestroyable::destroy();
 	}
 	}
 	/****************************************************************************************/
 	/****************************************************************************************/

+ 2 - 0
CamelotD3D9Renderer/Source/CmD3D9VertexBuffer.cpp

@@ -340,6 +340,8 @@ namespace CamelotEngine {
 		mMapDeviceToBufferResources.clear();   
 		mMapDeviceToBufferResources.clear();   
 		SAFE_DELETE_ARRAY(mSystemMemoryBuffer);
 		SAFE_DELETE_ARRAY(mSystemMemoryBuffer);
 
 
+		D3D9RenderSystem::getResourceManager()->_notifyResourceDestroyed(static_cast<D3D9Resource*>(this));
+
 		VertexBuffer::destroy_internal();
 		VertexBuffer::destroy_internal();
 	}
 	}
 }
 }

+ 3 - 0
CamelotD3D9Renderer/Source/CmD3D9VertexDeclaration.cpp

@@ -29,6 +29,7 @@ THE SOFTWARE.
 #include "CmD3D9Mappings.h"
 #include "CmD3D9Mappings.h"
 #include "CmException.h"
 #include "CmException.h"
 #include "CmD3D9RenderSystem.h"
 #include "CmD3D9RenderSystem.h"
+#include "CmD3D9ResourceManager.h"
 
 
 namespace CamelotEngine {
 namespace CamelotEngine {
 
 
@@ -188,6 +189,8 @@ namespace CamelotEngine {
 	{
 	{
 		releaseDeclaration();
 		releaseDeclaration();
 
 
+		D3D9RenderSystem::getResourceManager()->_notifyResourceDestroyed(static_cast<D3D9Resource*>(this));
+
 		VertexDeclaration::destroy_internal();
 		VertexDeclaration::destroy_internal();
 	}
 	}
 }
 }

+ 17 - 16
CamelotGLRenderer/Source/CmGLRenderSystem.cpp

@@ -124,21 +124,8 @@ namespace CamelotEngine
 
 
 	GLRenderSystem::~GLRenderSystem()
 	GLRenderSystem::~GLRenderSystem()
 	{
 	{
-		destroy_internal();
-
-		if(mProgramPipelineManager != nullptr)
-			delete mProgramPipelineManager;
-
-		// Destroy render windows
-		for (auto i = mRenderTargets.begin(); i != mRenderTargets.end(); ++i)
-		{
-			delete *i;
-		}
-
-		mRenderTargets.clear();
-
-        if(mGLSupport)
-            delete mGLSupport;
+		// This needs to be called from the child class, since destroy_internal is virtual
+		queueCommand(boost::bind(&GLRenderSystem::destroy_internal, this), true);
 	}
 	}
 
 
 	const String& GLRenderSystem::getName(void) const
 	const String& GLRenderSystem::getName(void) const
@@ -166,7 +153,7 @@ namespace CamelotEngine
 		RenderSystem::initialize_internal();
 		RenderSystem::initialize_internal();
 	}
 	}
 
 
-	void GLRenderSystem::destroy_internal(void)
+	void GLRenderSystem::destroy_internal()
 	{
 	{
 		RenderSystem::destroy_internal();
 		RenderSystem::destroy_internal();
 
 
@@ -220,6 +207,20 @@ namespace CamelotEngine
 		//  some params will access an invalid pointer, so it is best to reset
 		//  some params will access an invalid pointer, so it is best to reset
 		//  the whole state.
 		//  the whole state.
 		mGLInitialised = 0;
 		mGLInitialised = 0;
+
+		if(mProgramPipelineManager != nullptr)
+			delete mProgramPipelineManager;
+
+		// Destroy render windows
+		for (auto i = mRenderTargets.begin(); i != mRenderTargets.end(); ++i)
+		{
+			delete *i;
+		}
+
+		mRenderTargets.clear();
+
+		if(mGLSupport)
+			delete mGLSupport;
 	}
 	}
 
 
 	//---------------------------------------------------------------------
 	//---------------------------------------------------------------------

+ 0 - 1
CamelotGLRenderer/Source/GLSL/include/CmGLSLProgramFactory.h

@@ -46,7 +46,6 @@ namespace CamelotEngine
 		/// create an instance of GLSLProgram
 		/// create an instance of GLSLProgram
         HighLevelGpuProgram* create(const String& source, const String& entryPoint, GpuProgramType gptype, GpuProgramProfile profile);
         HighLevelGpuProgram* create(const String& source, const String& entryPoint, GpuProgramType gptype, GpuProgramProfile profile);
 		HighLevelGpuProgram* create();
 		HighLevelGpuProgram* create();
-		void destroy_internal(HighLevelGpuProgram* prog);
     };
     };
 }
 }
 
 

+ 0 - 7
CamelotGLRenderer/Source/GLSL/src/CmGLSLProgramFactory.cpp

@@ -51,11 +51,4 @@ namespace CamelotEngine {
 
 
 		return prog;
 		return prog;
 	}
 	}
-    //-----------------------------------------------------------------------
-	void GLSLProgramFactory::destroy_internal(HighLevelGpuProgram* prog)
-    {
-        delete prog;
-    }
-    //-----------------------------------------------------------------------
-
 }
 }

+ 23 - 0
CamelotRenderer/Include/CmApplication.h

@@ -18,8 +18,29 @@ namespace CamelotEngine
 		public:
 		public:
 			Application();
 			Application();
 
 
+			/**
+			 * @brief	Starts the application using the specified options. 
+			 * 			This is how you start the engine.
+			 */
 			void startUp(const String& renderSystemDll, const String& rendererDll);
 			void startUp(const String& renderSystemDll, const String& rendererDll);
+
+			/**
+			 * @brief	Executes the main loop. This will cause actually rendering to be performed
+			 * 			and simulation to be run. Usually called immediately after startUp().
+			 * 			
+			 *			This will run infinitely until stopMainLoop is called (usually from another thread or internally).
+			 */
 			void runMainLoop();
 			void runMainLoop();
+
+			/**
+			 * @brief	Stops a (infinite) main loop from running. The loop will complete its current cycle before stopping.
+			 * 			You may call this from other threads.
+			 */
+			void stopMainLoop();
+
+			/**
+			 * @brief	Frees up all resources allocated during startUp, and while the application was running.
+			 */
 			void shutDown();
 			void shutDown();
 
 
 			UINT64 getAppWindowId();
 			UINT64 getAppWindowId();
@@ -43,6 +64,8 @@ namespace CamelotEngine
 		bool mIsFrameRenderingFinished;
 		bool mIsFrameRenderingFinished;
 		CM_MUTEX(mFrameRenderingFinishedMutex);
 		CM_MUTEX(mFrameRenderingFinishedMutex);
 
 
+		volatile bool mRunMainLoop;
+
 		/**
 		/**
 		 * @brief	Callback called from the render thread in order to initialize resources.
 		 * @brief	Callback called from the render thread in order to initialize resources.
 		 */
 		 */

+ 0 - 1
CamelotRenderer/Include/CmCommandQueue.h

@@ -112,7 +112,6 @@ namespace CamelotEngine
 	private:
 	private:
 		vector<Command>::type* mCommands;
 		vector<Command>::type* mCommands;
 
 
-		bool mIsShutdown;
 		bool mAllowAllThreads;
 		bool mAllowAllThreads;
 
 
 		CM_THREAD_ID_TYPE mMyThreadId;
 		CM_THREAD_ID_TYPE mMyThreadId;

+ 0 - 3
CamelotRenderer/Include/CmGpuProgramManager.h

@@ -53,9 +53,6 @@ namespace CamelotEngine {
         */
         */
         virtual GpuProgram* create(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype, GpuProgramProfile profile) = 0;
         virtual GpuProgram* create(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype, GpuProgramProfile profile) = 0;
 
 
-		void destroy(GpuProgram* program);
-		virtual void destroy_internal(GpuProgram* program);
-
 	public:
 	public:
 		GpuProgramManager();
 		GpuProgramManager();
 		virtual ~GpuProgramManager();
 		virtual ~GpuProgramManager();

+ 1 - 1
CamelotRenderer/Include/CmHighLevelGpuProgram.h

@@ -63,7 +63,7 @@ namespace CamelotEngine {
     class CM_EXPORT HighLevelGpuProgram : public GpuProgram
     class CM_EXPORT HighLevelGpuProgram : public GpuProgram
     {
     {
     public:
     public:
-        ~HighLevelGpuProgram();
+        virtual ~HighLevelGpuProgram();
 
 
 		/** @copydoc GpuProgram::initialize_internal(). */
 		/** @copydoc GpuProgram::initialize_internal(). */
 		virtual void initialize_internal();
 		virtual void initialize_internal();

+ 0 - 3
CamelotRenderer/Include/CmHighLevelGpuProgramManager.h

@@ -51,9 +51,6 @@ namespace CamelotEngine {
 		virtual const String& getLanguage(void) const = 0;
 		virtual const String& getLanguage(void) const = 0;
         virtual HighLevelGpuProgram* create(const String& source, const String& entryPoint, GpuProgramType gptype, GpuProgramProfile profile) = 0;
         virtual HighLevelGpuProgram* create(const String& source, const String& entryPoint, GpuProgramType gptype, GpuProgramProfile profile) = 0;
 		virtual HighLevelGpuProgram* create() = 0;
 		virtual HighLevelGpuProgram* create() = 0;
-
-		void destroy(HighLevelGpuProgram* prog);
-		virtual void destroy_internal(HighLevelGpuProgram* prog) = 0;
 	};
 	};
 	/** This ResourceManager manages high-level vertex and fragment programs. 
 	/** This ResourceManager manages high-level vertex and fragment programs. 
 	@remarks
 	@remarks

+ 1 - 1
CamelotRenderer/Include/CmRenderSystem.h

@@ -449,7 +449,7 @@ namespace CamelotEngine
 		};
 		};
 
 
 		RenderWorkerFunc* mRenderThreadFunc;
 		RenderWorkerFunc* mRenderThreadFunc;
-		bool mRenderThreadShutdown;
+		volatile bool mRenderThreadShutdown;
 
 
 		CM_THREAD_ID_TYPE mRenderThreadId;
 		CM_THREAD_ID_TYPE mRenderThreadId;
 		CM_THREAD_SYNCHRONISER(mRenderThreadStartCondition)
 		CM_THREAD_SYNCHRONISER(mRenderThreadStartCondition)

+ 11 - 3
CamelotRenderer/Source/CmApplication.cpp

@@ -34,7 +34,7 @@
 namespace CamelotEngine
 namespace CamelotEngine
 {
 {
 	Application::Application()
 	Application::Application()
-		:mPrimaryRenderWindow(nullptr), mIsFrameRenderingFinished(true)
+		:mPrimaryRenderWindow(nullptr), mIsFrameRenderingFinished(true), mRunMainLoop(false)
 	{ }
 	{ }
 
 
 	void Application::startUp(const String& renderSystemName, const String& rendererName)
 	void Application::startUp(const String& renderSystemName, const String& rendererName)
@@ -72,7 +72,9 @@ namespace CamelotEngine
 
 
 	void Application::runMainLoop()
 	void Application::runMainLoop()
 	{
 	{
-		while(true)
+		mRunMainLoop = true;
+
+		while(mRunMainLoop)
 		{
 		{
 			gSceneManager().update();
 			gSceneManager().update();
 
 
@@ -108,6 +110,12 @@ namespace CamelotEngine
 		}
 		}
 	}
 	}
 
 
+	void Application::stopMainLoop()
+	{
+		mRunMainLoop = false; // No sync primitives needed, in that rare case of 
+		// a race condition we might run the loop one extra iteration which is acceptable
+	}
+
 	void Application::updateMessagePump()
 	void Application::updateMessagePump()
 	{
 	{
 		WindowEventUtilities::messagePump();
 		WindowEventUtilities::messagePump();
@@ -131,7 +139,7 @@ namespace CamelotEngine
 		RenderSystem::shutDown();
 		RenderSystem::shutDown();
 
 
 		HighLevelGpuProgramManager::shutDown();
 		HighLevelGpuProgramManager::shutDown();
-		DynLibManager::shutDown();
+		//DynLibManager::shutDown();
 		Resources::shutDown();
 		Resources::shutDown();
 		Input::shutDown();
 		Input::shutDown();
 		Time::shutDown();
 		Time::shutDown();

+ 1 - 12
CamelotRenderer/Source/CmGpuProgramManager.cpp

@@ -41,21 +41,10 @@ namespace CamelotEngine {
 	{
 	{
 		// subclasses should unregister with resource group manager
 		// subclasses should unregister with resource group manager
 	}
 	}
-	//-------------------------------------------------------------------------
-	void GpuProgramManager::destroy(GpuProgram* program)
-	{
-		RenderSystem::instancePtr()->queueCommand(boost::bind(&GpuProgramManager::destroy_internal, this, program));
-	}
-	//-------------------------------------------------------------------------
-	void GpuProgramManager::destroy_internal(GpuProgram* program)
-	{
-		if(program != nullptr)
-			delete program;
-	}
     //---------------------------------------------------------------------------
     //---------------------------------------------------------------------------
 	GpuProgramPtr GpuProgramManager::createProgram(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype, GpuProgramProfile profile)
 	GpuProgramPtr GpuProgramManager::createProgram(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype, GpuProgramProfile profile)
     {
     {
-		GpuProgramPtr prg = GpuProgramPtr(create(source, entryPoint, language, gptype, profile), boost::bind(&GpuProgramManager::destroy, this, _1));
+		GpuProgramPtr prg = GpuProgramPtr(create(source, entryPoint, language, gptype, profile));
 
 
         return prg;
         return prg;
     }
     }

+ 3 - 8
CamelotRenderer/Source/CmHighLevelGpuProgramManager.cpp

@@ -132,11 +132,6 @@ namespace CamelotEngine {
 		}
 		}
 		return i->second;
 		return i->second;
 	}
 	}
-	//---------------------------------------------------------------------------
-	void HighLevelGpuProgramFactory::destroy(HighLevelGpuProgram* prog)
-	{
-		RenderSystem::instancePtr()->queueCommand(boost::bind(&HighLevelGpuProgramFactory::destroy_internal, this, prog));
-	}
 	//---------------------------------------------------------------------
 	//---------------------------------------------------------------------
 	bool HighLevelGpuProgramManager::isLanguageSupported(const String& lang)
 	bool HighLevelGpuProgramManager::isLanguageSupported(const String& lang)
 	{
 	{
@@ -150,7 +145,7 @@ namespace CamelotEngine {
 		GpuProgramType gptype, GpuProgramProfile profile)
 		GpuProgramType gptype, GpuProgramProfile profile)
     {
     {
 		HighLevelGpuProgramFactory* factory = getFactory(language);
 		HighLevelGpuProgramFactory* factory = getFactory(language);
-        HighLevelGpuProgramPtr ret = HighLevelGpuProgramPtr(factory->create(source, entryPoint, gptype, profile), boost::bind(&HighLevelGpuProgramFactory::destroy, factory, _1));
+        HighLevelGpuProgramPtr ret = HighLevelGpuProgramPtr(factory->create(source, entryPoint, gptype, profile));
 		ret->initialize();
 		ret->initialize();
 
 
         return ret;
         return ret;
@@ -159,7 +154,7 @@ namespace CamelotEngine {
 	HighLevelGpuProgramPtr HighLevelGpuProgramManager::create(const String& language)
 	HighLevelGpuProgramPtr HighLevelGpuProgramManager::create(const String& language)
 	{
 	{
 		HighLevelGpuProgramFactory* factory = getFactory(language);
 		HighLevelGpuProgramFactory* factory = getFactory(language);
-		HighLevelGpuProgramPtr ret = HighLevelGpuProgramPtr(factory->create(), boost::bind(&HighLevelGpuProgramFactory::destroy, factory, _1));
+		HighLevelGpuProgramPtr ret = HighLevelGpuProgramPtr(factory->create());
 		ret->initialize();
 		ret->initialize();
 
 
 		return ret;
 		return ret;
@@ -168,7 +163,7 @@ namespace CamelotEngine {
 	HighLevelGpuProgramPtr HighLevelGpuProgramManager::createEmpty(const String& language)
 	HighLevelGpuProgramPtr HighLevelGpuProgramManager::createEmpty(const String& language)
 	{
 	{
 		HighLevelGpuProgramFactory* factory = getFactory(language);
 		HighLevelGpuProgramFactory* factory = getFactory(language);
-		HighLevelGpuProgramPtr ret = HighLevelGpuProgramPtr(factory->create(), boost::bind(&HighLevelGpuProgramFactory::destroy, factory, _1));
+		HighLevelGpuProgramPtr ret = HighLevelGpuProgramPtr(factory->create());
 
 
 		return ret;
 		return ret;
 	}
 	}

+ 22 - 17
CamelotRenderer/Source/CmRenderSystem.cpp

@@ -76,10 +76,17 @@ namespace CamelotEngine {
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     RenderSystem::~RenderSystem()
     RenderSystem::~RenderSystem()
     {
     {
-		queueCommand(boost::bind(&RenderSystem::destroy_internal, this), true);
-		// TODO - What if something gets queued between these two calls?
+		// Base classes need to call virtual destroy_internal method (queue it on render thread)
+
+		// TODO - What if something gets queued between the queued call to destroy_internal and this!?
 		shutdownRenderThread();
 		shutdownRenderThread();
 
 
+		if(mCommandQueue != nullptr)
+		{
+			delete mCommandQueue;
+			mCommandQueue = nullptr;
+		}
+
 		delete mCurrentCapabilities;
 		delete mCurrentCapabilities;
 		mCurrentCapabilities = 0;
 		mCurrentCapabilities = 0;
     }
     }
@@ -103,10 +110,8 @@ namespace CamelotEngine {
 		mFragmentProgramBound = false;
 		mFragmentProgramBound = false;
 	}
 	}
 	//-----------------------------------------------------------------------
 	//-----------------------------------------------------------------------
-	void RenderSystem::destroy_internal(void)
+	void RenderSystem::destroy_internal()
 	{
 	{
-		// TODO - I should probably sync this up to make sure no other threads are doing anything while shutdown is in progress
-
 		// Remove all the render targets.
 		// Remove all the render targets.
 		// (destroy primary target last since others may depend on it)
 		// (destroy primary target last since others may depend on it)
 		RenderTarget* primary = 0;
 		RenderTarget* primary = 0;
@@ -121,12 +126,6 @@ namespace CamelotEngine {
 		mRenderTargets.clear();
 		mRenderTargets.clear();
 
 
 		mPrioritisedRenderTargets.clear();
 		mPrioritisedRenderTargets.clear();
-
-		if(mCommandQueue != nullptr)
-		{
-			delete mCommandQueue;
-			mCommandQueue = nullptr;
-		}
 	}
 	}
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     void RenderSystem::swapAllRenderTargetBuffers(bool waitForVSync)
     void RenderSystem::swapAllRenderTargetBuffers(bool waitForVSync)
@@ -405,16 +404,18 @@ namespace CamelotEngine {
 
 
 		while(true)
 		while(true)
 		{
 		{
-			if(mRenderThreadShutdown)
-				return;
-
 			// Wait until we get some ready commands
 			// Wait until we get some ready commands
 			vector<CommandQueue::Command>::type* commands = nullptr;
 			vector<CommandQueue::Command>::type* commands = nullptr;
 			{
 			{
 				CM_LOCK_MUTEX_NAMED(mCommandQueueMutex, lock)
 				CM_LOCK_MUTEX_NAMED(mCommandQueueMutex, lock)
 
 
 				while(mCommandQueue->isEmpty())
 				while(mCommandQueue->isEmpty())
-					CM_THREAD_WAIT(mCommandReadyCondition, mCommandQueueMutex, lock)
+				{
+					if(mRenderThreadShutdown)
+						return;
+
+					CM_THREAD_WAIT(mCommandReadyCondition, mCommandQueueMutex, lock);
+				}
 
 
 				commands = mCommandQueue->flush();
 				commands = mCommandQueue->flush();
 			}
 			}
@@ -428,10 +429,14 @@ namespace CamelotEngine {
 	void RenderSystem::shutdownRenderThread()
 	void RenderSystem::shutdownRenderThread()
 	{
 	{
 #if !CM_FORCE_SINGLETHREADED_RENDERING
 #if !CM_FORCE_SINGLETHREADED_RENDERING
-		mRenderThreadShutdown = true;
+
+		{
+			CM_LOCK_MUTEX(mCommandQueueMutex);
+			mRenderThreadShutdown = true;
+		}
 
 
 		// Wake all threads. They will quit after they see the shutdown flag
 		// Wake all threads. They will quit after they see the shutdown flag
-		CM_THREAD_NOTIFY_ALL(mCommandReadyCondition)
+		CM_THREAD_NOTIFY_ALL(mCommandReadyCondition);
 
 
 		mRenderThread->join();
 		mRenderThread->join();
 		CM_THREAD_DESTROY(mRenderThread);
 		CM_THREAD_DESTROY(mRenderThread);

+ 4 - 1
CamelotRenderer/Source/CmWindowEventUtilities.cpp

@@ -27,6 +27,7 @@ THE SOFTWARE.
 */
 */
 #include "CmWindowEventUtilities.h"
 #include "CmWindowEventUtilities.h"
 #include "CmRenderWindow.h"
 #include "CmRenderWindow.h"
+#include "CmApplication.h"
 #include "CmException.h"
 #include "CmException.h"
 #if CM_PLATFORM == CM_PLATFORM_LINUX
 #if CM_PLATFORM == CM_PLATFORM_LINUX
 #include <X11/Xlib.h>
 #include <X11/Xlib.h>
@@ -241,7 +242,9 @@ LRESULT CALLBACK WindowEventUtilities::_WndProc(HWND hWnd, UINT uMsg, WPARAM wPa
 
 
 		for(index = _msListeners.lower_bound(win); index != end; ++index)
 		for(index = _msListeners.lower_bound(win); index != end; ++index)
 			(index->second)->windowClosed(win);
 			(index->second)->windowClosed(win);
-		win->destroy();
+
+		gApplication().stopMainLoop();
+
 		return 0;
 		return 0;
 	}
 	}
 	}
 	}

+ 23 - 2
CamelotRenderer/TODO.txt

@@ -50,9 +50,25 @@ Stuff that needs destroy():
   - Shader
   - Shader
   - Technique
   - Technique
 
 
-Calling destroy() and then immediately releasing last reference to an object will delete the object before it is destroyed. (Since destroy()) gets queued.
+I am currently completely ignoring D3D9ResourceManager. It is not notified when a resource is destroyed (actually destructed), 
+so it's mResources array contains many invalid pointers. Normally resource was removed from that list whenever it was 
+destructed but with my current approach, that might be AFTER the render system is shut down, which doesn't work. I need to 
+figure out a better way of releasing all resources when the application shuts down so that this doesn't happen.
+
+Plan today & saturday:
+ Add destroy() for remaining classes
+ Handle the issue with destroy() and immediately releasing object reference before destroy gets executed()
+
+ - Support loading of compound objects:
+   - Loading Material also loads attached Shader and Textures/Samplers
+  - Make Resources::destroy() private
+  - Have Resources::unload which calls destroy() internally
+  - Have Resources::unloadUnused() which unloads all with reference count of 1
+
 
 
-Upon calling destroy() I should keep a temporary reference to the object until it actually is destroyed.
+
+Calling destroy() and then immediately releasing last reference to an object will delete the object before it is destroyed. (Since destroy()) gets queued.
+ - Upon calling destroy() I should keep a temporary reference to the object until it actually is destroyed.
 
 
 Material RTTI should also serialize shared buffers (they need to be made into a resource)
 Material RTTI should also serialize shared buffers (they need to be made into a resource)
  - BE CAREFUL on how this will be implemented. Likely it will have much of the same interface as a material and/or GpuParams
  - BE CAREFUL on how this will be implemented. Likely it will have much of the same interface as a material and/or GpuParams
@@ -148,6 +164,11 @@ Command buffer TODO:
     that call.
     that call.
  - In general I need to rethink how to handle modifying resources with multithreading
  - In general I need to rethink how to handle modifying resources with multithreading
 
 
+Editor IMPORTANT:
+ - When displaying inspector data for a component, take into consideration that it will need to be able
+    to display that data for user created C# classes as well. AND I will most certainly have C# versions of all my
+	components. Therefore is there any purpose of having C++ only inspector parsing code?
+
 -----------------------BACKLOG TODO---------------------------------------------------------------
 -----------------------BACKLOG TODO---------------------------------------------------------------
 
 
 HIGH PRIORITY TODO:
 HIGH PRIORITY TODO: