소스 검색

Loading from DLL works

Marko Pintera 13 년 전
부모
커밋
0e66e5a89f

+ 1 - 0
CamelotD3D9Renderer/CamelotD3D9Renderer.vcxproj

@@ -105,6 +105,7 @@
     <ClInclude Include="Include\CmD3D9VideoModeList.h" />
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="CmD3D9Plugin.cpp" />
     <ClCompile Include="Source\CmD3D9Device.cpp" />
     <ClCompile Include="Source\CmD3D9DeviceManager.cpp" />
     <ClCompile Include="Source\CmD3D9Driver.cpp" />

+ 3 - 0
CamelotD3D9Renderer/CamelotD3D9Renderer.vcxproj.filters

@@ -170,5 +170,8 @@
     <ClCompile Include="Source\CmD3D9VideoModeList.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="CmD3D9Plugin.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 10 - 0
CamelotD3D9Renderer/CmD3D9Plugin.cpp

@@ -0,0 +1,10 @@
+#include "CmD3D9Prerequisites.h"
+#include "CmD3D9RenderSystemFactory.h"
+
+namespace CamelotEngine
+{
+	extern "C" CM_D3D9_EXPORT const String& getPluginName()
+	{
+		return SystemName;
+	}
+}

+ 1 - 0
CamelotGLRenderer/CamelotGLRenderer.vcxproj

@@ -118,6 +118,7 @@
     <ClInclude Include="Source\win32\CmGLUtil.h" />
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="CmGLPlugin.cpp" />
     <ClCompile Include="Source\atifs\src\ATI_FS_GLGpuProgram.cpp" />
     <ClCompile Include="Source\atifs\src\Compiler2Pass.cpp" />
     <ClCompile Include="Source\atifs\src\ps_1_4.cpp" />

+ 3 - 0
CamelotGLRenderer/CamelotGLRenderer.vcxproj.filters

@@ -251,5 +251,8 @@
     <ClCompile Include="Source\glew.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="CmGLPlugin.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 10 - 0
CamelotGLRenderer/CmGLPlugin.cpp

@@ -0,0 +1,10 @@
+#include "CmGLPrerequisites.h"
+#include "CmGLRenderSystemFactory.h"
+
+namespace CamelotEngine
+{
+	extern "C" CM_RSGL_EXPORT const String& getPluginName()
+	{
+		return SystemName;
+	}
+}

+ 9 - 0
CamelotRenderer.sln

@@ -9,10 +9,19 @@ EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CamelotUtility", "CamelotUtility\CamelotUtility.vcxproj", "{CC7F9445-71C9-4559-9976-FF0A64DCB582}"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CamelotD3D9Renderer", "CamelotD3D9Renderer\CamelotD3D9Renderer.vcxproj", "{796B6DFF-BA04-42B7-A43A-2B14D707A33A}"
+	ProjectSection(ProjectDependencies) = postProject
+		{9B21D41C-516B-43BF-9B10-E99B599C7589} = {9B21D41C-516B-43BF-9B10-E99B599C7589}
+	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CamelotClient", "CamelotClient\CamelotClient.vcxproj", "{67137A0D-7A67-4D0C-9FBF-AF904FABEF05}"
+	ProjectSection(ProjectDependencies) = postProject
+		{9B21D41C-516B-43BF-9B10-E99B599C7589} = {9B21D41C-516B-43BF-9B10-E99B599C7589}
+	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CamelotGLRenderer", "CamelotGLRenderer\CamelotGLRenderer.vcxproj", "{F58FF869-2EA6-4FFF-AB84-328C531BA9D9}"
+	ProjectSection(ProjectDependencies) = postProject
+		{9B21D41C-516B-43BF-9B10-E99B599C7589} = {9B21D41C-516B-43BF-9B10-E99B599C7589}
+	EndProjectSection
 EndProject
 Global
 	GlobalSection(SubversionScc) = preSolution

+ 0 - 1
CamelotRenderer/CamelotRenderer.vcxproj

@@ -121,7 +121,6 @@
     <ClInclude Include="Include\CmRenderTarget.h" />
     <ClInclude Include="Include\CmRenderTexture.h" />
     <ClInclude Include="Include\CmRenderWindow.h" />
-    <ClInclude Include="Include\CmSingleton.h" />
     <ClInclude Include="Include\CmTexture.h" />
     <ClInclude Include="Include\CmTextureManager.h" />
     <ClInclude Include="Include\CmTextureState.h" />

+ 6 - 12
CamelotRenderer/CamelotRenderer.vcxproj.filters

@@ -16,9 +16,6 @@
     <Filter Include="Header Files\ForRemoval">
       <UniqueIdentifier>{f916bd59-03a7-42a7-9b9c-60abe94020bc}</UniqueIdentifier>
     </Filter>
-    <Filter Include="Source Files\ForRemoval">
-      <UniqueIdentifier>{004ec8e4-409f-4bc2-b697-f24c707a2429}</UniqueIdentifier>
-    </Filter>
     <Filter Include="Header Files\Utility">
       <UniqueIdentifier>{2c09857e-4a4a-480f-8ebb-1661a9ce78dd}</UniqueIdentifier>
     </Filter>
@@ -35,15 +32,6 @@
     <ClInclude Include="Include\CmConfigOptionMap.h">
       <Filter>Header Files\ForRemoval</Filter>
     </ClInclude>
-    <ClInclude Include="Include\CmPrerequisites.h">
-      <Filter>Header Files\ForRemoval</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\CmRenderOperation.h">
-      <Filter>Header Files\ForRemoval</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\CmSingleton.h">
-      <Filter>Header Files\ForRemoval</Filter>
-    </ClInclude>
     <ClInclude Include="Include\CmCommon.h">
       <Filter>Header Files\Utility</Filter>
     </ClInclude>
@@ -137,6 +125,12 @@
     <ClInclude Include="Include\targetver.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\CmRenderOperation.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmPrerequisites.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CamelotRenderer.cpp">

+ 3 - 1
CamelotRenderer/Include/CmApplication.h

@@ -1,6 +1,6 @@
 #pragma once
 
-#include <memory>
+#include "CmPrerequisites.h"
 #include "CmHighLevelGpuProgram.h"
 
 namespace CamelotEngine
@@ -31,6 +31,8 @@ namespace CamelotEngine
 			Camera* mCamera;
 			HighLevelGpuProgramPtr mFragProg;
 			HighLevelGpuProgramPtr mVertProg;
+
+			DynLibManager* mDynLibManager; // TODO - Handle singletons differently
 	};
 
 	CM_EXPORT Application& gApplication();

+ 1 - 1
CamelotRenderer/Include/CmRenderSystemManager.h

@@ -10,7 +10,7 @@ namespace CamelotEngine
 	class CM_EXPORT RenderSystemManager
 	{
 	public:
-		static void initialize(const std::string& name);
+		static void initialize(const String& name);
 		static RenderSystem* getActive() { return mActiveRenderSystem.get(); }
 
 		static void registerRenderSystemFactory(RenderSystemFactoryPtr factory);

+ 4 - 2
CamelotRenderer/Source/CmApplication.cpp

@@ -10,6 +10,7 @@
 #include "CmViewport.h"
 #include "CmHighLevelGpuProgram.h"
 #include "CmHighLevelGpuProgramManager.h"
+#include "CmDynLibManager.h"
 
 namespace CamelotEngine
 {
@@ -20,9 +21,10 @@ namespace CamelotEngine
 	void Application::startUp(String renderSystemDll)
 	{
 		mGpuProgramManager = new HighLevelGpuProgramManager(); // TODO - Use Camelot::Module for instantiating this
+		mDynLibManager = new DynLibManager(); // TODO - Same as above, use Module
 
-		//RenderSystemManager::initialize("D3D9RenderSystem");
-		RenderSystemManager::initialize("GLRenderSystem");
+		//RenderSystemManager::initialize("CamelotD3D9Renderer.dll");
+		RenderSystemManager::initialize("CamelotGLRenderer.dll");
 
 		RenderSystem* renderSystem = RenderSystemManager::getActive();
 		renderSystem->_initialise(false, "Camelot Renderer");

+ 13 - 2
CamelotRenderer/Source/CmRenderSystemManager.cpp

@@ -1,14 +1,25 @@
 #include "CmRenderSystemManager.h"
 #include "CmException.h"
 #include "CmRenderSystem.h"
+#include "CmDynLib.h"
+#include "CmDynLibManager.h"
 
 namespace CamelotEngine
 {
 	RenderSystemPtr RenderSystemManager::mActiveRenderSystem;
 
-	void RenderSystemManager::initialize(const std::string& name)
+	void RenderSystemManager::initialize(const String& pluginFilename)
 	{
-		assert(mActiveRenderSystem == nullptr); // Once loaded the render system is set for life
+		DynLib* loadedLibrary = DynLibManager::getSingleton().load(pluginFilename);
+		String name = "";
+
+		if(loadedLibrary != nullptr)
+		{
+			typedef const String& (*GetPluginNameFunc)();
+
+			GetPluginNameFunc getPluginNameFunc = (GetPluginNameFunc)loadedLibrary->getSymbol("getPluginName");
+			name = getPluginNameFunc();
+		}
 
 		for(auto iter = getAvailableFactories().begin(); iter != getAvailableFactories().end(); ++iter)
 		{

+ 3 - 0
CamelotUtility/CamelotUtility.vcxproj

@@ -74,9 +74,11 @@
     <ClInclude Include="Include\CmBitwise.h" />
     <ClInclude Include="Include\CmBox.h" />
     <ClInclude Include="Include\CmColor.h" />
+    <ClInclude Include="Include\CmDynLibManager.h" />
     <ClInclude Include="Include\CmException.h" />
     <ClInclude Include="Include\CmMathAsm.h" />
     <ClInclude Include="Include\CmPixelUtil.h" />
+    <ClInclude Include="Include\CmSingleton.h" />
     <ClInclude Include="Include\CmString.h" />
     <ClInclude Include="Include\CmThreadDefines.h" />
     <ClInclude Include="Include\CmTypes.h" />
@@ -100,6 +102,7 @@
   <ItemGroup>
     <ClCompile Include="Include\CmAxisAlignedBox.cpp" />
     <ClCompile Include="Source\CmColor.cpp" />
+    <ClCompile Include="Source\CmDynLibManager.cpp" />
     <ClCompile Include="Source\CmException.cpp" />
     <ClCompile Include="Source\CmMath.cpp" />
     <ClCompile Include="Source\CmMatrix3.cpp" />

+ 9 - 0
CamelotUtility/CamelotUtility.vcxproj.filters

@@ -102,6 +102,12 @@
     <ClInclude Include="Include\CmBox.h">
       <Filter>Header Files\Math</Filter>
     </ClInclude>
+    <ClInclude Include="Include\CmDynLibManager.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmSingleton.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Include\CmAxisAlignedBox.cpp">
@@ -146,5 +152,8 @@
     <ClCompile Include="Source\CmPixelUtil.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\CmDynLibManager.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 114 - 0
CamelotUtility/Include/CmDynLibManager.h

@@ -0,0 +1,114 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+    (Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org/
+
+Copyright (c) 2000-2011 Torus Knot Software Ltd
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+-----------------------------------------------------------------------------
+*/
+#pragma once
+
+#include "CmPrerequisitesUtil.h"
+#include "CmSingleton.h"
+
+namespace CamelotEngine {
+	/** \addtogroup Core
+	*  @{
+	*/
+	/** \addtogroup General
+	*  @{
+	*/
+	/** Manager for Dynamic-loading Libraries.
+        @remarks
+            This manager keeps a track of all the open dynamic-loading
+            libraries, opens them and returns references to already-open
+            libraries.
+    */
+    class CM_EXPORT DynLibManager: public Singleton<DynLibManager>
+    {
+	protected:
+		typedef map<String, DynLib*>::type DynLibList;
+		DynLibList mLibList;
+    public:
+        /** Default constructor.
+            @note
+                <br>Should never be called as the singleton is automatically
+                created during the creation of the Root object.
+            @see
+                Root::Root
+        */
+        DynLibManager();
+
+        /** Default destructor.
+            @see
+                Root::~Root
+        */
+        virtual ~DynLibManager();
+
+        /** Loads the passed library.
+            @param
+                filename The name of the library. The extension can be omitted
+        */
+        DynLib* load(const String& filename);
+
+		/** Unloads the passed library.
+		@param
+		filename The name of the library. The extension can be omitted
+		*/
+		void unload(DynLib* lib);
+
+		/** Override standard Singleton retrieval.
+        @remarks
+        Why do we do this? Well, it's because the Singleton
+        implementation is in a .h file, which means it gets compiled
+        into anybody who includes it. This is needed for the
+        Singleton template to work, but we actually only want it
+        compiled into the implementation of the class based on the
+        Singleton, not all of them. If we don't change this, we get
+        link errors when trying to use the Singleton-based class from
+        an outside dll.
+        @par
+        This method just delegates to the template version anyway,
+        but the implementation stays in this single compilation unit,
+        preventing link errors.
+        */
+        static DynLibManager& getSingleton(void);
+        /** Override standard Singleton retrieval.
+        @remarks
+        Why do we do this? Well, it's because the Singleton
+        implementation is in a .h file, which means it gets compiled
+        into anybody who includes it. This is needed for the
+        Singleton template to work, but we actually only want it
+        compiled into the implementation of the class based on the
+        Singleton, not all of them. If we don't change this, we get
+        link errors when trying to use the Singleton-based class from
+        an outside dll.
+        @par
+        This method just delegates to the template version anyway,
+        but the implementation stays in this single compilation unit,
+        preventing link errors.
+        */
+        static DynLibManager* getSingletonPtr(void);
+    };
+	/** @} */
+	/** @} */
+}

+ 2 - 0
CamelotUtility/Include/CmFwdDeclUtil.h

@@ -19,4 +19,6 @@ namespace CamelotEngine {
 	class Vector3;
 	class Vector4;
 	class Color;
+	class DynLib;
+	class DynLibManager;
 }

+ 1 - 1
CamelotRenderer/Include/CmSingleton.h → CamelotUtility/Include/CmSingleton.h

@@ -38,7 +38,7 @@ THE SOFTWARE.
 #define _SINGLETON_H__
 
 // Added by Steve Streeting for Ogre
-#include "CmPrerequisites.h"
+#include "CmPrerequisitesUtil.h"
 
 #if CM_COMPILER == CM_COMPILER_MSVC
 // Turn off warnings generated by this singleton implementation

+ 4 - 4
CamelotUtility/Source/CmDynLib.cpp

@@ -37,7 +37,7 @@ THE SOFTWARE.
 #  include <windows.h>
 #endif
 
-#if CM_PLATFORM == CM_PLATFORM_APPLE || CM_PLATFORM == CM_PLATFORM_IPHONE
+#if CM_PLATFORM == CM_PLATFORM_APPLE
 #   include "macUtils.h"
 #   include <dlfcn.h>
 #endif
@@ -61,15 +61,15 @@ namespace CamelotEngine {
     void DynLib::load()
     {
 		String name = mName;
-#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
+#if CM_PLATFORM == CM_PLATFORM_LINUX
         // dlopen() does not add .so to the filename, like windows does for .dll
         if (name.substr(name.length() - 3, 3) != ".so")
            name += ".so";
-#elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE
+#elif CM_PLATFORM == CM_PLATFORM_APPLE
         // dlopen() does not add .dylib to the filename, like windows does for .dll
         if (name.substr(name.length() - 6, 6) != ".dylib")
 			name += ".dylib";
-#elif OGRE_PLATFORM == OGRE_PLATFORM_WIN32
+#elif CM_PLATFORM == CM_PLATFORM_WIN32
 		// Although LoadLibraryEx will add .dll itself when you only specify the library name,
 		// if you include a relative path then it does not. So, add it to be sure.
 		if (name.substr(name.length() - 4, 4) != ".dll")

+ 88 - 0
CamelotUtility/Source/CmDynLibManager.cpp

@@ -0,0 +1,88 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+    (Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org/
+
+Copyright (c) 2000-2011 Torus Knot Software Ltd
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+-----------------------------------------------------------------------------
+*/
+#include "CmDynLibManager.h"
+#include "CmDynLib.h"
+
+namespace CamelotEngine
+{
+    //-----------------------------------------------------------------------
+    template<> DynLibManager* Singleton<DynLibManager>::ms_Singleton = 0;
+    DynLibManager* DynLibManager::getSingletonPtr(void)
+    {
+        return ms_Singleton;
+    }
+	//-----------------------------------------------------------------------
+    DynLibManager& DynLibManager::getSingleton(void)
+    {  
+        assert( ms_Singleton );  return ( *ms_Singleton );  
+    }
+    //-----------------------------------------------------------------------
+	DynLibManager::DynLibManager()
+	{
+	}
+	//-----------------------------------------------------------------------
+    DynLib* DynLibManager::load( const String& filename)
+    {
+		DynLibList::iterator i = mLibList.find(filename);
+		if (i != mLibList.end())
+		{
+			return i->second;
+		}
+		else
+		{
+	        DynLib* pLib = new DynLib(filename);
+			pLib->load();        
+        	mLibList[filename] = pLib;
+	        return pLib;
+		}
+    }
+	//-----------------------------------------------------------------------
+	void DynLibManager::unload(DynLib* lib)
+	{
+		DynLibList::iterator i = mLibList.find(lib->getName());
+		if (i != mLibList.end())
+		{
+			mLibList.erase(i);
+		}
+		lib->unload();
+		delete lib;
+	}
+	//-----------------------------------------------------------------------
+    DynLibManager::~DynLibManager()
+    {
+        // Unload & delete resources in turn
+        for( DynLibList::iterator it = mLibList.begin(); it != mLibList.end(); ++it )
+        {
+            it->second->unload();
+            delete it->second;
+        }
+
+        // Empty the list
+        mLibList.clear();
+    }
+}