瀏覽代碼

Resource meta files

Marko Pintera 13 年之前
父節點
當前提交
d0f2212f2a

+ 1 - 0
CamelotRenderer/CamelotRenderer.vcxproj

@@ -143,6 +143,7 @@
     <ClInclude Include="Include\CmResourceRef.h" />
     <ClInclude Include="Include\CmResourceRef.h" />
     <ClInclude Include="Include\CmResourceRefRTTI.h" />
     <ClInclude Include="Include\CmResourceRefRTTI.h" />
     <ClInclude Include="Include\CmResources.h" />
     <ClInclude Include="Include\CmResources.h" />
+    <ClInclude Include="Include\CmResourcesRTTI.h" />
     <ClInclude Include="Include\CmSceneManager.h" />
     <ClInclude Include="Include\CmSceneManager.h" />
     <ClInclude Include="Include\CmSpecificImporter.h" />
     <ClInclude Include="Include\CmSpecificImporter.h" />
     <ClInclude Include="Include\CmTexture.h" />
     <ClInclude Include="Include\CmTexture.h" />

+ 3 - 0
CamelotRenderer/CamelotRenderer.vcxproj.filters

@@ -286,6 +286,9 @@
     <ClInclude Include="Include\CmCgProgramRTTI.h">
     <ClInclude Include="Include\CmCgProgramRTTI.h">
       <Filter>Header Files\RTTI</Filter>
       <Filter>Header Files\RTTI</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\CmResourcesRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CamelotRenderer.cpp">
     <ClCompile Include="Source\CamelotRenderer.cpp">

+ 0 - 2
CamelotRenderer/Include/CmApplication.h

@@ -41,8 +41,6 @@ namespace CamelotEngine
 			TextureRef mDbgTexture;
 			TextureRef mDbgTexture;
 			MeshRef mDbgMesh;
 			MeshRef mDbgMesh;
 			GameObjectPtr mCameraGO;
 			GameObjectPtr mCameraGO;
-			GpuProgramParametersPtr mVertParams;
-			GpuProgramParametersPtr mFragParams;
 
 
 			ShaderPtr mTestShader;
 			ShaderPtr mTestShader;
 			MaterialPtr mTestMaterial;
 			MaterialPtr mTestMaterial;

+ 0 - 1
CamelotRenderer/Include/CmCgProgram.h

@@ -66,7 +66,6 @@ namespace CamelotEngine {
 		void mapTypeAndElementSize(CGtype cgType, bool isRegisterCombiner, GpuConstantDefinition& def) const;
 		void mapTypeAndElementSize(CGtype cgType, bool isRegisterCombiner, GpuConstantDefinition& def) const;
 
 
         vector<String>::type mProfiles;
         vector<String>::type mProfiles;
-        String mEntryPoint;
         String mSelectedProfile;
         String mSelectedProfile;
         CGprofile mSelectedCgProfile;
         CGprofile mSelectedCgProfile;
         String mCompileArgs;
         String mCompileArgs;

+ 9 - 9
CamelotRenderer/Include/CmPass.h

@@ -70,11 +70,11 @@ namespace CamelotEngine
         //-------------------------------------------------------------------------
         //-------------------------------------------------------------------------
 
 
 		// Vertex program
 		// Vertex program
-		GpuProgramPtr mVertexProgram;
+		GpuProgramRef mVertexProgram;
 		// Fragment program
 		// Fragment program
-		GpuProgramPtr mFragmentProgram;
+		GpuProgramRef mFragmentProgram;
 		// Geometry program
 		// Geometry program
-		GpuProgramPtr mGeometryProgram;
+		GpuProgramRef mGeometryProgram;
 
 
         // number of pass iterations to perform
         // number of pass iterations to perform
         size_t mPassIterationCount;
         size_t mPassIterationCount;
@@ -468,23 +468,23 @@ namespace CamelotEngine
 
 
 		/** Sets the details of the vertex program to use.
 		/** Sets the details of the vertex program to use.
 		*/
 		*/
-		void setVertexProgram(GpuProgramPtr gpuProgram);
+		void setVertexProgram(GpuProgramRef gpuProgram);
 
 
 		/** Gets the vertex program used by this pass, only available after _load(). */
 		/** Gets the vertex program used by this pass, only available after _load(). */
-		const GpuProgramPtr& getVertexProgram(void) const;
+		const GpuProgramRef& getVertexProgram(void) const;
 
 
 		/** Sets the details of the fragment program to use.
 		/** Sets the details of the fragment program to use.
 		*/
 		*/
-		void setFragmentProgram(GpuProgramPtr gpuProgram);
+		void setFragmentProgram(GpuProgramRef gpuProgram);
 		
 		
 		/** Gets the fragment program used by this pass, only available after _load(). */
 		/** Gets the fragment program used by this pass, only available after _load(). */
-		const GpuProgramPtr& getFragmentProgram(void) const;
+		const GpuProgramRef& getFragmentProgram(void) const;
 
 
 		/** Sets the details of the geometry program to use.
 		/** Sets the details of the geometry program to use.
 		*/
 		*/
-		void setGeometryProgram(GpuProgramPtr gpuProgram);
+		void setGeometryProgram(GpuProgramRef gpuProgram);
 		
 		
 		/** Gets the geometry program used by this pass, only available after _load(). */
 		/** Gets the geometry program used by this pass, only available after _load(). */
-		const GpuProgramPtr& getGeometryProgram(void) const;
+		const GpuProgramRef& getGeometryProgram(void) const;
     };
     };
 }
 }

+ 4 - 1
CamelotRenderer/Include/CmPrerequisites.h

@@ -158,7 +158,8 @@ namespace CamelotEngine
 		TID_ResourceRef = 1009,
 		TID_ResourceRef = 1009,
 		TID_GpuProgram = 1010,
 		TID_GpuProgram = 1010,
 		TID_ResourceRefData = 1011,
 		TID_ResourceRefData = 1011,
-		TID_CgProgram = 1012
+		TID_CgProgram = 1012,
+		TID_ResourceMetaData = 1013
 	};
 	};
 }
 }
 
 
@@ -173,6 +174,8 @@ namespace CamelotEngine
 	typedef ResourceRef<Resource> BaseResourceRef;
 	typedef ResourceRef<Resource> BaseResourceRef;
 	typedef ResourceRef<Texture> TextureRef;
 	typedef ResourceRef<Texture> TextureRef;
 	typedef ResourceRef<Mesh> MeshRef;
 	typedef ResourceRef<Mesh> MeshRef;
+	typedef ResourceRef<GpuProgram> GpuProgramRef;
+	typedef ResourceRef<HighLevelGpuProgram> HighLevelGpuProgramRef;
 }
 }
 
 
 #endif // __OgrePrerequisites_H__
 #endif // __OgrePrerequisites_H__

+ 1 - 4
CamelotRenderer/Include/CmResource.h

@@ -2,7 +2,6 @@
 
 
 #include "CmPrerequisites.h"
 #include "CmPrerequisites.h"
 #include "CmIReflectable.h"
 #include "CmIReflectable.h"
-#include "CmUUID.h"
 
 
 namespace CamelotEngine
 namespace CamelotEngine
 {
 {
@@ -18,9 +17,7 @@ namespace CamelotEngine
 	class CM_EXPORT Resource : public IReflectable
 	class CM_EXPORT Resource : public IReflectable
 	{
 	{
 	public:
 	public:
-		Resource(/*UUID& _UUID*/) // TODO - Temporarily don't initialize UUID, because I want texture to inherit from resource and UUIDs arent set up yet
-			:mSize(0), mLoadState(RS_Unloaded) /*mUUID(_UUID),*/
-		{}
+		Resource();
 		virtual ~Resource() {};
 		virtual ~Resource() {};
 
 
 		void load();
 		void load();

+ 28 - 7
CamelotRenderer/Include/CmResourceRef.h

@@ -2,6 +2,12 @@
 
 
 #include "CmIReflectable.h"
 #include "CmIReflectable.h"
 
 
+template<class _Ty>
+struct CM_Bool_struct
+{
+	int _Member;
+};
+
 namespace CamelotEngine
 namespace CamelotEngine
 {
 {
 	template <typename T>
 	template <typename T>
@@ -79,15 +85,18 @@ namespace CamelotEngine
 			return ResourceRef<Resource>(mData->mPtr); 
 			return ResourceRef<Resource>(mData->mPtr); 
 		}
 		}
 
 
-		const T* get() const { return static_cast<T*>(mData->mPtr.get()); }
-		const T* operator-> () const { return get(); }
-		const T& operator* () const { return *get(); }
-
-		T* get() { return static_cast<T*>(mData->mPtr.get()); }
-		T* operator-> () { return get(); }
-		T& operator* () { return *get(); }
+		T* get() const { return static_cast<T*>(mData->mPtr.get()); }
+		T* operator->() const { return get(); }
+		T& operator*() const { return *get(); }
 
 
 		std::shared_ptr<T> getInternalPtr() { return std::static_pointer_cast<T>(mData->mPtr); }
 		std::shared_ptr<T> getInternalPtr() { return std::static_pointer_cast<T>(mData->mPtr); }
+
+		// Conversion to bool
+		// (Why not just directly convert to bool? Because then we can assign pointer to bool and that's weird)
+		operator int CM_Bool_struct<T>::*() const
+		{
+			return (mData->mPtr.get() != 0 ? &CM_Bool_struct<T>::_Member : 0);
+		}
 	};
 	};
 
 
 	template<class _Ty1, class _Ty2>
 	template<class _Ty1, class _Ty2>
@@ -95,4 +104,16 @@ namespace CamelotEngine
 	{	
 	{	
 		return ResourceRef<_Ty1>(other);
 		return ResourceRef<_Ty1>(other);
 	}
 	}
+
+	template<class _Ty1, class _Ty2>
+	bool operator==(const ResourceRef<_Ty1>& _Left, const ResourceRef<_Ty2>& _Right)
+	{	
+		return (_Left.get() == _Right.get());
+	}
+
+	template<class _Ty1, class _Ty2>
+	bool operator!=(const ResourceRef<_Ty1>& _Left, const ResourceRef<_Ty2>& _Right)
+	{	
+		return (!(_Left == _Right));
+	}
 }
 }

+ 33 - 6
CamelotRenderer/Include/CmResources.h

@@ -2,7 +2,6 @@
 
 
 #include "CmPrerequisites.h"
 #include "CmPrerequisites.h"
 #include "CmModule.h"
 #include "CmModule.h"
-#include "CmUUID.h"
 
 
 namespace CamelotEngine
 namespace CamelotEngine
 {
 {
@@ -12,11 +11,10 @@ namespace CamelotEngine
 		/**
 		/**
 		 * @brief	Constructor.
 		 * @brief	Constructor.
 		 *
 		 *
-		 * @param	assetDatabasePath	Pathname of the asset database file. Path should not include file extension.
-		 * 								If the database file doesn't exist it will be created in that location.
-		 * 								Meta data for resources is stored in the asset database.
+		 * @param	resMetaPath		Folder where the resource meta-data will be stored. If the folder doesn't exist
+		 * 							it will be created.
 		 */
 		 */
-		Resources();
+		Resources(const String& metaDataFolder);
 		~Resources();
 		~Resources();
 
 
 		/**
 		/**
@@ -40,7 +38,7 @@ namespace CamelotEngine
 		 *
 		 *
 		 * @return	Loaded resource, or null if it cannot be found.
 		 * @return	Loaded resource, or null if it cannot be found.
 		 */
 		 */
-		BaseResourceRef load(const UUID& uuid);
+		BaseResourceRef loadFromUUID(const String& uuid);
 
 
 		/**
 		/**
 		 * @brief	Saves the resource at the specified location.
 		 * @brief	Saves the resource at the specified location.
@@ -49,6 +47,35 @@ namespace CamelotEngine
 		 * @param	filePath	Full pathname of the file.
 		 * @param	filePath	Full pathname of the file.
 		 */
 		 */
 		void save(BaseResourceRef resource, const String& filePath);
 		void save(BaseResourceRef resource, const String& filePath);
+
+	public:
+		struct ResourceMetaData : public IReflectable
+		{
+			String mUUID;
+			String mPath;
+
+			/************************************************************************/
+			/* 								SERIALIZATION                      		*/
+			/************************************************************************/
+		public:
+			friend class ResourceMetaDataRTTI;
+			static RTTITypeBase* getRTTIStatic();
+			virtual RTTITypeBase* getRTTI() const;
+		};
+
+	private:
+		typedef std::shared_ptr<ResourceMetaData> ResourceMetaDataPtr;
+		map<String, ResourceMetaDataPtr>::type mResourceMetaData;
+
+		void loadMetaData();
+		void saveMetaData(const ResourceMetaDataPtr metaData);
+
+		void addMetaData(const String& uuid, const String& filePath);
+		void updateMetaData(const String& uuid, const String& newFilePath);
+
+		bool exists(const String& uuid) const;
+
+		String mMetaDataFolderPath;
 	};
 	};
 
 
 	CM_EXPORT Resources& gResources();
 	CM_EXPORT Resources& gResources();

+ 40 - 0
CamelotRenderer/Include/CmResourcesRTTI.h

@@ -0,0 +1,40 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+#include "CmRTTIType.h"
+#include "CmResources.h"
+
+namespace CamelotEngine
+{
+	class ResourceMetaDataRTTI : public RTTIType<Resources::ResourceMetaData, IReflectable, ResourceMetaDataRTTI>
+	{
+		String& getUUID(Resources::ResourceMetaData* obj) { return obj->mUUID; }
+		void setUUID(Resources::ResourceMetaData* obj, String& val) { obj->mUUID = val; }
+
+		String& getPath(Resources::ResourceMetaData* obj) { return obj->mPath; }
+		void setPath(Resources::ResourceMetaData* obj, String& val) { obj->mPath = val; }
+
+	public:
+		ResourceMetaDataRTTI()
+		{
+			addPlainField("mUUID", 0, &ResourceMetaDataRTTI::getUUID, &ResourceMetaDataRTTI::setUUID);
+			addPlainField("mPath", 1, &ResourceMetaDataRTTI::getPath, &ResourceMetaDataRTTI::setPath);
+		}
+
+		virtual std::shared_ptr<IReflectable> newRTTIObject() 
+		{
+			return std::shared_ptr<Resources::ResourceMetaData>(new Resources::ResourceMetaData());
+		}
+
+		virtual const String& getRTTIName() 
+		{
+			static String name = "ResourceMetaData";
+			throw name;
+		}
+
+		virtual UINT32 getRTTIId() 
+		{
+			return TID_ResourceMetaData;
+		}
+	};
+}

+ 12 - 8
CamelotRenderer/Source/CmApplication.cpp

@@ -50,6 +50,7 @@ namespace CamelotEngine
 		renderSystem->_initialise(false, "Camelot Renderer");
 		renderSystem->_initialise(false, "Camelot Renderer");
 
 
 		SceneManager::startUp(new SceneManager());
 		SceneManager::startUp(new SceneManager());
+		Resources::startUp(new Resources("D:\\CamelotResourceMetas"));
 
 
 		mRenderWindow = renderSystem->_createRenderWindow("Camelot Renderer", 800, 600, false);
 		mRenderWindow = renderSystem->_createRenderWindow("Camelot Renderer", 800, 600, false);
 
 
@@ -116,8 +117,16 @@ namespace CamelotEngine
 
 
 		mVertProg =  HighLevelGpuProgramManager::instance().createProgram(vertShaderCode, "vs_main", "cg", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
 		mVertProg =  HighLevelGpuProgramManager::instance().createProgram(vertShaderCode, "vs_main", "cg", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
 		mVertProg->load();
 		mVertProg->load();
-		
 
 
+		HighLevelGpuProgramRef vertProgRef(mVertProg);
+
+		gResources().save(vertProgRef, "C:\\vertProgCg.vprog");
+		vertProgRef = static_resource_cast<HighLevelGpuProgram>(gResources().load("C:\\vertProgCg.vprog"));
+
+		HighLevelGpuProgramRef fragProgRef(mFragProg);
+
+		gResources().save(fragProgRef, "C:\\fragProgCg.vprog");
+		fragProgRef = static_resource_cast<HighLevelGpuProgram>(gResources().load("C:\\fragProgCg.vprog"));
 
 
 		///////////////// GLSL SHADERS ////////////////////////////
 		///////////////// GLSL SHADERS ////////////////////////////
 		//String fragShaderCode = "uniform sampler2D tex; \
 		//String fragShaderCode = "uniform sampler2D tex; \
@@ -141,15 +150,12 @@ namespace CamelotEngine
 
 
 		//mVertProg = HighLevelGpuProgramManager::instance().createProgram(vertShaderCode, "main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
 		//mVertProg = HighLevelGpuProgramManager::instance().createProgram(vertShaderCode, "main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
 		//mVertProg->load();
 		//mVertProg->load();
-		
-		mVertParams = mVertProg->createParameters();
-		mFragParams = mFragProg->createParameters();
 
 
 		mTestShader = ShaderPtr(new Shader("TestShader"));
 		mTestShader = ShaderPtr(new Shader("TestShader"));
 		TechniquePtr newTechnique = mTestShader->addTechnique("GLRenderSystem", "ForwardRenderer");
 		TechniquePtr newTechnique = mTestShader->addTechnique("GLRenderSystem", "ForwardRenderer");
 		PassPtr newPass = newTechnique->addPass();
 		PassPtr newPass = newTechnique->addPass();
-		newPass->setVertexProgram(mVertProg);
-		newPass->setFragmentProgram(mFragProg);
+		newPass->setVertexProgram(vertProgRef);
+		newPass->setFragmentProgram(fragProgRef);
 
 
 		mTestMaterial = MaterialPtr(new Material());
 		mTestMaterial = MaterialPtr(new Material());
 		mTestMaterial->setShader(mTestShader);
 		mTestMaterial->setShader(mTestShader);
@@ -164,8 +170,6 @@ namespace CamelotEngine
 		mDbgMesh = static_resource_cast<Mesh>(Importer::instance().import("C:\\X_Arena_Tower.FBX"));
 		mDbgMesh = static_resource_cast<Mesh>(Importer::instance().import("C:\\X_Arena_Tower.FBX"));
 		//mDbgMesh = std::static_pointer_cast<Mesh>(Importer::instance().import("C:\\BarrelMesh.fbx"));
 		//mDbgMesh = std::static_pointer_cast<Mesh>(Importer::instance().import("C:\\BarrelMesh.fbx"));
 
 
-		Resources::startUp(new Resources());
-
 		gResources().save(testTex, "C:\\ExportTest.tex");
 		gResources().save(testTex, "C:\\ExportTest.tex");
 		gResources().save(mDbgMesh, "C:\\ExportMesh.mesh");
 		gResources().save(mDbgMesh, "C:\\ExportMesh.mesh");
 
 

+ 1 - 1
CamelotRenderer/Source/CmImporter.cpp

@@ -47,7 +47,7 @@ namespace CamelotEngine
 
 
 	BaseResourceRef Importer::import(const String& inputFilePath)
 	BaseResourceRef Importer::import(const String& inputFilePath)
 	{
 	{
-		if(!Path::exists(inputFilePath))
+		if(!FileSystem::fileExists(inputFilePath))
 		{
 		{
 			LOGWRN("Trying to import asset that doesn't exists. Asset path: " + inputFilePath);
 			LOGWRN("Trying to import asset that doesn't exists. Asset path: " + inputFilePath);
 			return nullptr;
 			return nullptr;

+ 6 - 6
CamelotRenderer/Source/CmMaterial.cpp

@@ -29,15 +29,15 @@ namespace CamelotEngine
 
 
 					ParamsPerPass params;
 					ParamsPerPass params;
 
 
-					GpuProgramPtr vertProgram = curPass->getVertexProgram();
+					GpuProgramRef vertProgram = curPass->getVertexProgram();
 					if(vertProgram)
 					if(vertProgram)
 						params.mVertParams = vertProgram->createParameters();
 						params.mVertParams = vertProgram->createParameters();
 
 
-					GpuProgramPtr fragProgram = curPass->getFragmentProgram();
+					GpuProgramRef fragProgram = curPass->getFragmentProgram();
 					if(fragProgram)
 					if(fragProgram)
 						params.mFragParams = fragProgram->createParameters();
 						params.mFragParams = fragProgram->createParameters();
 
 
-					GpuProgramPtr geomProgram = curPass->getGeometryProgram();
+					GpuProgramRef geomProgram = curPass->getGeometryProgram();
 					if(geomProgram)
 					if(geomProgram)
 						params.mGeomParams = geomProgram->createParameters();	
 						params.mGeomParams = geomProgram->createParameters();	
 
 
@@ -125,21 +125,21 @@ namespace CamelotEngine
 		PassPtr curPass = mBestTechnique->getPass(passIdx);
 		PassPtr curPass = mBestTechnique->getPass(passIdx);
 		ParamsPerPass params = mParameters[passIdx];
 		ParamsPerPass params = mParameters[passIdx];
 
 
-		GpuProgramPtr vertProgram = curPass->getVertexProgram();
+		GpuProgramRef vertProgram = curPass->getVertexProgram();
 		if(vertProgram)
 		if(vertProgram)
 		{
 		{
 			renderSystem->bindGpuProgram(vertProgram->_getBindingDelegate());
 			renderSystem->bindGpuProgram(vertProgram->_getBindingDelegate());
 			renderSystem->bindGpuProgramParameters(GPT_VERTEX_PROGRAM, params.mVertParams, GPV_ALL);
 			renderSystem->bindGpuProgramParameters(GPT_VERTEX_PROGRAM, params.mVertParams, GPV_ALL);
 		}
 		}
 
 
-		GpuProgramPtr fragProgram = curPass->getFragmentProgram();
+		GpuProgramRef fragProgram = curPass->getFragmentProgram();
 		if(fragProgram)
 		if(fragProgram)
 		{
 		{
 			renderSystem->bindGpuProgram(fragProgram->_getBindingDelegate());
 			renderSystem->bindGpuProgram(fragProgram->_getBindingDelegate());
 			renderSystem->bindGpuProgramParameters(GPT_FRAGMENT_PROGRAM, params.mFragParams, GPV_ALL);
 			renderSystem->bindGpuProgramParameters(GPT_FRAGMENT_PROGRAM, params.mFragParams, GPV_ALL);
 		}
 		}
 
 
-		GpuProgramPtr geomProgram = curPass->getGeometryProgram();
+		GpuProgramRef geomProgram = curPass->getGeometryProgram();
 		if(geomProgram)
 		if(geomProgram)
 		{
 		{
 			renderSystem->bindGpuProgram(geomProgram->_getBindingDelegate());
 			renderSystem->bindGpuProgram(geomProgram->_getBindingDelegate());

+ 6 - 6
CamelotRenderer/Source/CmPass.cpp

@@ -344,37 +344,37 @@ namespace CamelotEngine
 		return mDepthBiasPerIteration;
 		return mDepthBiasPerIteration;
 	}
 	}
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
-	void Pass::setVertexProgram(GpuProgramPtr gpuProgram)
+	void Pass::setVertexProgram(GpuProgramRef gpuProgram)
 	{
 	{
 		CM_LOCK_MUTEX(mGpuProgramChangeMutex)
 		CM_LOCK_MUTEX(mGpuProgramChangeMutex)
 		mVertexProgram = gpuProgram;
 		mVertexProgram = gpuProgram;
 	}
 	}
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
-	void Pass::setFragmentProgram(GpuProgramPtr gpuProgram)
+	void Pass::setFragmentProgram(GpuProgramRef gpuProgram)
 	{
 	{
 		CM_LOCK_MUTEX(mGpuProgramChangeMutex)
 		CM_LOCK_MUTEX(mGpuProgramChangeMutex)
 		mFragmentProgram = gpuProgram;
 		mFragmentProgram = gpuProgram;
 	}
 	}
 	//-----------------------------------------------------------------------
 	//-----------------------------------------------------------------------
-	void Pass::setGeometryProgram(GpuProgramPtr gpuProgram)
+	void Pass::setGeometryProgram(GpuProgramRef gpuProgram)
 	{
 	{
 		CM_LOCK_MUTEX(mGpuProgramChangeMutex)
 		CM_LOCK_MUTEX(mGpuProgramChangeMutex)
 		mGeometryProgram = gpuProgram;
 		mGeometryProgram = gpuProgram;
 	}
 	}
 	//-----------------------------------------------------------------------
 	//-----------------------------------------------------------------------
-	const GpuProgramPtr& Pass::getVertexProgram(void) const
+	const GpuProgramRef& Pass::getVertexProgram(void) const
 	{
 	{
 		CM_LOCK_MUTEX(mGpuProgramChangeMutex)
 		CM_LOCK_MUTEX(mGpuProgramChangeMutex)
 		return mVertexProgram;
 		return mVertexProgram;
 	}
 	}
 	//-----------------------------------------------------------------------
 	//-----------------------------------------------------------------------
-	const GpuProgramPtr& Pass::getFragmentProgram(void) const
+	const GpuProgramRef& Pass::getFragmentProgram(void) const
 	{
 	{
 		CM_LOCK_MUTEX(mGpuProgramChangeMutex)
 		CM_LOCK_MUTEX(mGpuProgramChangeMutex)
 		return mFragmentProgram;
 		return mFragmentProgram;
 	}
 	}
 	//-----------------------------------------------------------------------
 	//-----------------------------------------------------------------------
-	const GpuProgramPtr& Pass::getGeometryProgram(void) const
+	const GpuProgramRef& Pass::getGeometryProgram(void) const
 	{
 	{
 		CM_LOCK_MUTEX(mGpuProgramChangeMutex)
 		CM_LOCK_MUTEX(mGpuProgramChangeMutex)
 		return mGeometryProgram;
 		return mGeometryProgram;

+ 9 - 0
CamelotRenderer/Source/CmResource.cpp

@@ -1,8 +1,17 @@
 #include "CmResource.h"
 #include "CmResource.h"
 #include "CmResourceRTTI.h"
 #include "CmResourceRTTI.h"
+#include "CmUUID.h"
 
 
 namespace CamelotEngine
 namespace CamelotEngine
 {
 {
+	Resource::Resource()
+		:mSize(0), mLoadState(RS_Unloaded)
+	{
+		// We always generate a random UUID, and then overwrite it with the actual one 
+		// during loading if one was previously generated and saved.
+		mUUID = UUIDGenerator::generateRandom();
+	}
+
 	void Resource::load()
 	void Resource::load()
 	{
 	{
 		if(mLoadState != RS_Loaded)
 		if(mLoadState != RS_Loaded)

+ 114 - 3
CamelotRenderer/Source/CmResources.cpp

@@ -2,12 +2,24 @@
 #include "CmResource.h"
 #include "CmResource.h"
 #include "CmException.h"
 #include "CmException.h"
 #include "CmFileSerializer.h"
 #include "CmFileSerializer.h"
+#include "CmFileSystem.h"
+#include "CmUUID.h"
+#include "CmPath.h"
+#include "CmDebug.h"
+#include "CmResourcesRTTI.h"
 
 
 namespace CamelotEngine
 namespace CamelotEngine
 {
 {
-	Resources::Resources()
+	Resources::Resources(const String& metaDataFolder)
 	{
 	{
+		mMetaDataFolderPath = metaDataFolder;
 
 
+		if(!FileSystem::dirExists(mMetaDataFolderPath))
+		{
+			FileSystem::createDir(mMetaDataFolderPath);
+		}
+
+		loadMetaData();
 	}
 	}
 
 
 	Resources::~Resources()
 	Resources::~Resources()
@@ -34,9 +46,17 @@ namespace CamelotEngine
 		return BaseResourceRef(resource);
 		return BaseResourceRef(resource);
 	}
 	}
 
 
-	BaseResourceRef Resources::load(const UUID& uuid)
+	BaseResourceRef Resources::loadFromUUID(const String& uuid)
 	{
 	{
-		CM_EXCEPT(NotImplementedException, "Not implemented");
+		if(!exists(uuid))
+		{
+			gDebug().logWarning("Cannot load resource. Resource with UUID '" + uuid + "' doesn't exist.");
+			return nullptr;
+		}
+
+		ResourceMetaDataPtr metaEntry = mResourceMetaData[uuid];
+
+		return load(metaEntry->mPath);
 	}
 	}
 
 
 	void Resources::save(BaseResourceRef resource, const String& filePath)
 	void Resources::save(BaseResourceRef resource, const String& filePath)
@@ -45,12 +65,103 @@ namespace CamelotEngine
 
 
 		// TODO - Low priority. Check is file path valid?
 		// TODO - Low priority. Check is file path valid?
 		
 		
+		// TODO - When saving we just overwrite any existing resource and generate new meta file
+		//         - What if we just want to update existing resource, ie. reimport it?
+		
 		FileSerializer fs;
 		FileSerializer fs;
 		fs.encode(resource.get(), filePath);
 		fs.encode(resource.get(), filePath);
+
+		if(exists(resource->getUUID()))
+			updateMetaData(resource->getUUID(), filePath);
+		else
+			addMetaData(resource->getUUID(), filePath);
+	}
+
+	void Resources::loadMetaData()
+	{
+		vector<String>::type allFiles = FileSystem::getFiles(mMetaDataFolderPath);
+
+		for(auto iter = allFiles.begin(); iter != allFiles.end(); ++iter)
+		{
+			String& path = *iter;
+			if(Path::hasExtension(path, "resmeta"))
+			{
+				FileSerializer fs;
+				std::shared_ptr<IReflectable> loadedData = fs.decode(path);
+
+				ResourceMetaDataPtr metaData = std::static_pointer_cast<ResourceMetaData>(loadedData);
+				mResourceMetaData[metaData->mUUID] = metaData;
+			}
+		}
+	}
+
+	void Resources::saveMetaData(const ResourceMetaDataPtr metaData)
+	{
+		String fullPath = Path::combine(mMetaDataFolderPath, metaData->mUUID + ".resmeta");
+
+		FileSerializer fs;
+		fs.encode(metaData.get(), fullPath);
+	}
+
+	void Resources::addMetaData(const String& uuid, const String& filePath)
+	{
+		for(auto iter = mResourceMetaData.begin(); iter != mResourceMetaData.end(); ++iter)
+		{
+			if(iter->second->mPath == filePath)
+			{
+				CM_EXCEPT(InvalidParametersException, "Resource with the path '" + filePath + "' already exists.");
+			}
+		}
+
+		if(exists(uuid))
+		{
+			CM_EXCEPT(InternalErrorException, "Resource with the same UUID already exists. UUID: " + uuid);
+		}
+
+		ResourceMetaDataPtr dbEntry(new ResourceMetaData());
+		dbEntry->mPath = filePath;
+		dbEntry->mUUID = uuid;
+
+		mResourceMetaData[uuid] = dbEntry;
+
+		saveMetaData(dbEntry);
+	}
+
+	void Resources::updateMetaData(const String& uuid, const String& newFilePath)
+	{
+		if(!exists(uuid))
+		{
+			CM_EXCEPT(InvalidParametersException, "Cannot update a resource that doesn't exist. UUID: " + uuid + ". File path: " + newFilePath);
+		}
+
+		ResourceMetaDataPtr dbEntry = mResourceMetaData[uuid];
+		dbEntry->mPath = newFilePath;
+
+		saveMetaData(dbEntry);
+	}
+
+	bool Resources::exists(const String& uuid) const
+	{
+		auto findIter = mResourceMetaData.find(uuid);
+
+		return findIter != mResourceMetaData.end();
 	}
 	}
 
 
 	CM_EXPORT Resources& gResources()
 	CM_EXPORT Resources& gResources()
 	{
 	{
 		return Resources::instance();
 		return Resources::instance();
 	}
 	}
+
+	/************************************************************************/
+	/* 								SERIALIZATION                      		*/
+	/************************************************************************/
+	RTTITypeBase* Resources::ResourceMetaData::getRTTIStatic()
+	{
+		return ResourceMetaDataRTTI::instance();
+	}
+
+	RTTITypeBase* Resources::ResourceMetaData::getRTTI() const
+	{
+		return Resources::ResourceMetaData::getRTTIStatic();
+	}
 }
 }

+ 1 - 0
CamelotUtility/CamelotUtility.vcxproj

@@ -82,6 +82,7 @@
     </Link>
     </Link>
   </ItemDefinitionGroup>
   </ItemDefinitionGroup>
   <ItemGroup>
   <ItemGroup>
+    <ClCompile Include="Source\CmUUID.cpp" />
     <ClCompile Include="Source\Win32\CmTimer.cpp" />
     <ClCompile Include="Source\Win32\CmTimer.cpp" />
     <ClInclude Include="Include\CmBinarySerializer.h" />
     <ClInclude Include="Include\CmBinarySerializer.h" />
     <ClInclude Include="Include\CmBitwise.h" />
     <ClInclude Include="Include\CmBitwise.h" />

+ 3 - 0
CamelotUtility/CamelotUtility.vcxproj.filters

@@ -272,5 +272,8 @@
     <ClCompile Include="Source\Win32\CmTimer.cpp">
     <ClCompile Include="Source\Win32\CmTimer.cpp">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="Source\CmUUID.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 7 - 0
CamelotUtility/Include/CmFileSystem.h

@@ -12,5 +12,12 @@ namespace CamelotEngine
 		static DataStreamPtr create(const String& fullPath);
 		static DataStreamPtr create(const String& fullPath);
 
 
 		static void remove(const String& fullPath);
 		static void remove(const String& fullPath);
+
+		static bool fileExists(const String& fullPath);
+		static bool dirExists(const String& fullPath);
+
+		static void createDir(const String& fullPath);
+
+		static vector<String>::type getFiles(const String& dirPath);
 	};
 	};
 }
 }

+ 4 - 14
CamelotUtility/Include/CmPath.h

@@ -11,29 +11,19 @@ namespace CamelotEngine
 	class Path
 	class Path
 	{
 	{
 	public:
 	public:
-		static bool exists(const String& path)
-		{
-			return boost::filesystem::exists(path);
-		}
-
 		static String getExtension(const String& path)
 		static String getExtension(const String& path)
 		{
 		{
 			return boost::filesystem::extension(path);
 			return boost::filesystem::extension(path);
 		}
 		}
 
 
-
-		static bool isAbsolute(const String& path)
+		static bool hasExtension(const String& path, const String& extension)
 		{
 		{
-#if CM_PLATFORM == CM_PLATFORM_WIN32
-			if (isalpha(UINT8(path[0])) && path[1] == ':')
-				return true;
-#endif
-			return path[0] == '/' || path[0] == '\\';
+			return getExtension(path) == extension;
 		}
 		}
 
 
-		static String concatenatePath(const String& base, const String& name)
+		static String combine(const String& base, const String& name)
 		{
 		{
-			if (base.empty() || isAbsolute(name.c_str()))
+			if (base.empty())
 				return name;
 				return name;
 			else
 			else
 				return base + '/' + name;
 				return base + '/' + name;

+ 1 - 1
CamelotUtility/Include/CmRTTIField.h

@@ -97,7 +97,7 @@ namespace CamelotEngine
 
 
 		static UINT32 getDynamicSize(String& data)	
 		static UINT32 getDynamicSize(String& data)	
 		{ 
 		{ 
-			return data.size() + sizeof(UINT32);
+			return data.size() * sizeof(String::value_type) + sizeof(UINT32);
 		}	
 		}	
 	}; 
 	}; 
 
 

+ 5 - 2
CamelotUtility/Include/CmUUID.h

@@ -1,9 +1,12 @@
 #pragma once
 #pragma once
 
 
 #include "CmPrerequisitesUtil.h"
 #include "CmPrerequisitesUtil.h"
-#include <boost/uuid/uuid.hpp>
 
 
 namespace CamelotEngine
 namespace CamelotEngine
 {
 {
-	typedef boost::uuids::uuid UUID;
+	class CM_UTILITY_EXPORT UUIDGenerator
+	{
+	public:
+		static String generateRandom();
+	};
 }
 }

+ 40 - 0
CamelotUtility/Source/CmFileSystem.cpp

@@ -3,6 +3,8 @@
 #include "CmPath.h"
 #include "CmPath.h"
 #include "CmException.h"
 #include "CmException.h"
 
 
+#include <boost/filesystem.hpp>
+
 #include <sys/types.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/stat.h>
 
 
@@ -107,4 +109,42 @@ namespace CamelotEngine
 	{
 	{
 		::remove(fullPath.c_str());
 		::remove(fullPath.c_str());
 	}
 	}
+
+	bool FileSystem::fileExists(const String& fullPath)
+	{
+		if(boost::filesystem::exists(fullPath) && !boost::filesystem::is_directory(fullPath))
+			return true;
+
+		return false;
+	}
+
+	bool FileSystem::dirExists(const String& fullPath)
+	{
+		if(boost::filesystem::exists(fullPath) && boost::filesystem::is_directory(fullPath))
+			return true;
+
+		return false;
+	}
+
+	void FileSystem::createDir(const String& fullPath)
+	{
+		boost::filesystem::create_directory(fullPath);
+	}
+
+	vector<String>::type FileSystem::getFiles(const String& dirPath)
+	{
+		boost::filesystem::directory_iterator dirIter(dirPath);
+
+		vector<String>::type foundFiles;
+		
+		while(dirIter != boost::filesystem::directory_iterator())
+		{
+			if(boost::filesystem::is_regular_file(dirIter->path()))
+				foundFiles.push_back(dirIter->path().string());
+
+			dirIter++;
+		}
+
+		return foundFiles;
+	}
 }
 }

+ 18 - 0
CamelotUtility/Source/CmUUID.cpp

@@ -0,0 +1,18 @@
+#include "CmUUID.h"
+#include <boost/uuid/uuid.hpp>
+#include <boost/uuid/uuid_generators.hpp>
+#include <boost/uuid/uuid_io.hpp>
+
+using namespace boost::uuids;
+
+namespace CamelotEngine
+{
+	String UUIDGenerator::generateRandom()
+	{
+		static random_generator gen;
+
+		uuid newUUID = gen();
+
+		return to_string(newUUID);
+	}
+};