浏览代码

Resource metas

Marko Pintera 13 年之前
父节点
当前提交
c4b88fc22f
共有 3 个文件被更改,包括 119 次插入39 次删除
  1. 22 6
      CamelotRenderer/Include/CmResources.h
  2. 8 8
      CamelotRenderer/Source/CmApplication.cpp
  3. 89 25
      CamelotRenderer/Source/CmResources.cpp

+ 22 - 6
CamelotRenderer/Include/CmResources.h

@@ -29,7 +29,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 String& filePath);
+		BaseResourceRef loadFromPath(const String& filePath);
 
 
 		/**
 		/**
 		 * @brief	Loads the resource with the given uuid.
 		 * @brief	Loads the resource with the given uuid.
@@ -41,12 +41,22 @@ namespace CamelotEngine
 		BaseResourceRef loadFromUUID(const String& uuid);
 		BaseResourceRef loadFromUUID(const String& uuid);
 
 
 		/**
 		/**
-		 * @brief	Saves the resource at the specified location.
+		 * @brief	Saves the resource. Resource must be registered using Resources::create beforehand.
 		 *
 		 *
-		 * @param	resource	The resource.
-		 * @param	filePath	Full pathname of the file.
+		 * @param	resource   	The resource.
 		 */
 		 */
-		void save(BaseResourceRef resource, const String& filePath);
+		void save(BaseResourceRef resource);
+
+		/**
+		 * @brief	Creates a new resource at the specified location. Throws an exception if resource already exists.
+		 * 			Automatically calls Resources::save.
+		 *
+		 * @param	resource 	The resource.
+		 * @param	filePath 	Full pathname of the file.
+		 * @param	overwrite	(optional) If true, any existing resource at the specified location
+		 * 						will be overwritten.
+		 */
+		void create(BaseResourceRef resource, const String& filePath, bool overwrite = false);
 
 
 	public:
 	public:
 		struct ResourceMetaData : public IReflectable
 		struct ResourceMetaData : public IReflectable
@@ -70,10 +80,16 @@ namespace CamelotEngine
 		void loadMetaData();
 		void loadMetaData();
 		void saveMetaData(const ResourceMetaDataPtr metaData);
 		void saveMetaData(const ResourceMetaDataPtr metaData);
 
 
+		void createMetaData(const String& uuid, const String& filePath);
 		void addMetaData(const String& uuid, const String& filePath);
 		void addMetaData(const String& uuid, const String& filePath);
 		void updateMetaData(const String& uuid, const String& newFilePath);
 		void updateMetaData(const String& uuid, const String& newFilePath);
+		void removeMetaData(const String& uuid);
+
+		bool metaExists_UUID(const String& uuid) const;
+		bool metaExists_Path(const String& path) const;
 
 
-		bool exists(const String& uuid) const;
+		const String& getPathFromUUID(const String& uuid) const;
+		const String& getUUIDFromPath(const String& path) const;
 
 
 		String mMetaDataFolderPath;
 		String mMetaDataFolderPath;
 	};
 	};

+ 8 - 8
CamelotRenderer/Source/CmApplication.cpp

@@ -120,13 +120,13 @@ namespace CamelotEngine
 
 
 		HighLevelGpuProgramRef vertProgRef(mVertProg);
 		HighLevelGpuProgramRef vertProgRef(mVertProg);
 
 
-		gResources().save(vertProgRef, "C:\\vertProgCg.vprog");
-		vertProgRef = static_resource_cast<HighLevelGpuProgram>(gResources().load("C:\\vertProgCg.vprog"));
+		gResources().create(vertProgRef, "C:\\vertProgCg.vprog", true);
+		vertProgRef = static_resource_cast<HighLevelGpuProgram>(gResources().loadFromPath("C:\\vertProgCg.vprog"));
 
 
 		HighLevelGpuProgramRef fragProgRef(mFragProg);
 		HighLevelGpuProgramRef fragProgRef(mFragProg);
 
 
-		gResources().save(fragProgRef, "C:\\fragProgCg.vprog");
-		fragProgRef = static_resource_cast<HighLevelGpuProgram>(gResources().load("C:\\fragProgCg.vprog"));
+		gResources().create(fragProgRef, "C:\\fragProgCg.vprog", true);
+		fragProgRef = static_resource_cast<HighLevelGpuProgram>(gResources().loadFromPath("C:\\fragProgCg.vprog"));
 
 
 		///////////////// GLSL SHADERS ////////////////////////////
 		///////////////// GLSL SHADERS ////////////////////////////
 		//String fragShaderCode = "uniform sampler2D tex; \
 		//String fragShaderCode = "uniform sampler2D tex; \
@@ -170,11 +170,11 @@ 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"));
 
 
-		gResources().save(testTex, "C:\\ExportTest.tex");
-		gResources().save(mDbgMesh, "C:\\ExportMesh.mesh");
+		gResources().create(testTex, "C:\\ExportTest.tex", true);
+		gResources().create(mDbgMesh, "C:\\ExportMesh.mesh", true);
 
 
-		mDbgTexture = static_resource_cast<Texture>(gResources().load("C:\\ExportTest.tex"));
-		mDbgMesh = static_resource_cast<Mesh>(gResources().load("C:\\ExportMesh.mesh"));
+		mDbgTexture = static_resource_cast<Texture>(gResources().loadFromPath("C:\\ExportTest.tex"));
+		mDbgMesh = static_resource_cast<Mesh>(gResources().loadFromPath("C:\\ExportMesh.mesh"));
 
 
 		mDbgTexture = testTex;
 		mDbgTexture = testTex;
 
 

+ 89 - 25
CamelotRenderer/Source/CmResources.cpp

@@ -27,7 +27,7 @@ namespace CamelotEngine
 
 
 	}
 	}
 
 
-	BaseResourceRef Resources::load(const String& filePath)
+	BaseResourceRef Resources::loadFromPath(const String& filePath)
 	{
 	{
 		FileSerializer fs;
 		FileSerializer fs;
 		std::shared_ptr<IReflectable> loadedData = fs.decode(filePath);
 		std::shared_ptr<IReflectable> loadedData = fs.decode(filePath);
@@ -43,12 +43,18 @@ namespace CamelotEngine
 		ResourcePtr resource = std::static_pointer_cast<Resource>(loadedData);
 		ResourcePtr resource = std::static_pointer_cast<Resource>(loadedData);
 		resource->load();
 		resource->load();
 
 
+		if(!metaExists_UUID(resource->getUUID()))
+		{
+			gDebug().logWarning("Loading a resource that doesn't have meta-data. Creating meta-data automatically. Resource path: " + filePath);
+			addMetaData(resource->getUUID(), filePath);
+		}
+
 		return BaseResourceRef(resource);
 		return BaseResourceRef(resource);
 	}
 	}
 
 
 	BaseResourceRef Resources::loadFromUUID(const String& uuid)
 	BaseResourceRef Resources::loadFromUUID(const String& uuid)
 	{
 	{
-		if(!exists(uuid))
+		if(!metaExists_UUID(uuid))
 		{
 		{
 			gDebug().logWarning("Cannot load resource. Resource with UUID '" + uuid + "' doesn't exist.");
 			gDebug().logWarning("Cannot load resource. Resource with UUID '" + uuid + "' doesn't exist.");
 			return nullptr;
 			return nullptr;
@@ -56,25 +62,46 @@ namespace CamelotEngine
 
 
 		ResourceMetaDataPtr metaEntry = mResourceMetaData[uuid];
 		ResourceMetaDataPtr metaEntry = mResourceMetaData[uuid];
 
 
-		return load(metaEntry->mPath);
+		return loadFromPath(metaEntry->mPath);
 	}
 	}
 
 
-	void Resources::save(BaseResourceRef resource, const String& filePath)
+	void Resources::create(BaseResourceRef resource, const String& filePath, bool overwrite)
 	{
 	{
 		assert(resource.get() != nullptr);
 		assert(resource.get() != nullptr);
 
 
-		// 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?
+		if(metaExists_UUID(resource->getUUID()))
+			CM_EXCEPT(InvalidParametersException, "Specified resource already exists.");
 		
 		
+		bool fileExists = FileSystem::fileExists(filePath);
+		const String& existingUUID = getUUIDFromPath(filePath);
+		bool metaExists = metaExists_UUID(existingUUID);
+
+		if(fileExists)
+		{
+			if(overwrite)
+				FileSystem::remove(filePath);
+			else
+				CM_EXCEPT(InvalidParametersException, "Another file exists at the specified location.");
+		}
+
+		if(metaExists)
+			removeMetaData(existingUUID);
+
+		addMetaData(resource->getUUID(), filePath);
+		save(resource);
+	}
+
+	void Resources::save(BaseResourceRef resource)
+	{
+		assert(resource.get() != nullptr);
+
+		if(!metaExists_UUID(resource->getUUID()))
+			CM_EXCEPT(InvalidParametersException, "Cannot find resource meta-data. Please call Resources::create before trying to save the resource.");
+
+		const String& filePath = getPathFromUUID(resource->getUUID());
+
 		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()
 	void Resources::loadMetaData()
@@ -103,20 +130,21 @@ namespace CamelotEngine
 		fs.encode(metaData.get(), fullPath);
 		fs.encode(metaData.get(), fullPath);
 	}
 	}
 
 
+	void Resources::removeMetaData(const String& uuid)
+	{
+		String fullPath = Path::combine(mMetaDataFolderPath, uuid + ".resmeta");
+		FileSystem::remove(fullPath);
+
+		mResourceMetaData.erase(uuid);
+	}
+
 	void Resources::addMetaData(const String& uuid, const String& filePath)
 	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(metaExists_Path(filePath))
+			CM_EXCEPT(InvalidParametersException, "Resource with the path '" + filePath + "' already exists.");
 
 
-		if(exists(uuid))
-		{
+		if(metaExists_UUID(uuid))
 			CM_EXCEPT(InternalErrorException, "Resource with the same UUID already exists. UUID: " + uuid);
 			CM_EXCEPT(InternalErrorException, "Resource with the same UUID already exists. UUID: " + uuid);
-		}
 
 
 		ResourceMetaDataPtr dbEntry(new ResourceMetaData());
 		ResourceMetaDataPtr dbEntry(new ResourceMetaData());
 		dbEntry->mPath = filePath;
 		dbEntry->mPath = filePath;
@@ -129,7 +157,7 @@ namespace CamelotEngine
 
 
 	void Resources::updateMetaData(const String& uuid, const String& newFilePath)
 	void Resources::updateMetaData(const String& uuid, const String& newFilePath)
 	{
 	{
-		if(!exists(uuid))
+		if(!metaExists_UUID(uuid))
 		{
 		{
 			CM_EXCEPT(InvalidParametersException, "Cannot update a resource that doesn't exist. UUID: " + uuid + ". File path: " + newFilePath);
 			CM_EXCEPT(InvalidParametersException, "Cannot update a resource that doesn't exist. UUID: " + uuid + ". File path: " + newFilePath);
 		}
 		}
@@ -140,13 +168,49 @@ namespace CamelotEngine
 		saveMetaData(dbEntry);
 		saveMetaData(dbEntry);
 	}
 	}
 
 
-	bool Resources::exists(const String& uuid) const
+	const String& Resources::getPathFromUUID(const String& uuid) const
+	{
+		auto findIter = mResourceMetaData.find(uuid);
+
+		if(findIter != mResourceMetaData.end())
+			return findIter->second->mPath;
+		else
+			return "";
+	}
+
+	const String& Resources::getUUIDFromPath(const String& path) const
+	{
+		for(auto iter = mResourceMetaData.begin(); iter != mResourceMetaData.end(); ++iter)
+		{
+			if(iter->second->mPath == path)
+			{
+				return iter->second->mUUID;
+			}
+		}
+
+		return StringUtil::BLANK;
+	}
+
+	bool Resources::metaExists_UUID(const String& uuid) const
 	{
 	{
 		auto findIter = mResourceMetaData.find(uuid);
 		auto findIter = mResourceMetaData.find(uuid);
 
 
 		return findIter != mResourceMetaData.end();
 		return findIter != mResourceMetaData.end();
 	}
 	}
 
 
+	bool Resources::metaExists_Path(const String& path) const
+	{
+		for(auto iter = mResourceMetaData.begin(); iter != mResourceMetaData.end(); ++iter)
+		{
+			if(iter->second->mPath == path)
+			{
+				return true;
+			}
+		}
+
+		return false;
+	}
+
 	CM_EXPORT Resources& gResources()
 	CM_EXPORT Resources& gResources()
 	{
 	{
 		return Resources::instance();
 		return Resources::instance();