소스 검색

Changing built-in shaders will not only trigger reimport for those modified shaders, instead of importing all of them

BearishSun 8 년 전
부모
커밋
f89621a614

+ 1 - 1
Source/BansheeEditor/Include/BsBuiltinEditorResources.h

@@ -182,7 +182,7 @@ namespace bs
 		 * @note	
 		 * Normally you only want to use this during development phase and then ship with engine-ready format only.
 		 */
-		void preprocess();
+		void preprocess(bool forceImport);
 
 		/**	Generates the default editor skin and all GUI element styles. */
 		SPtr<GUISkin> generateGUISkin();

+ 13 - 7
Source/BansheeEditor/Source/BsBuiltinEditorResources.cpp

@@ -327,7 +327,9 @@ namespace bs
 
 		// Update from raw assets if needed
 #if BS_DEBUG_MODE
-		if (BuiltinResourcesHelper::checkForModifications(BuiltinRawDataFolder, BuiltinDataFolder + L"Timestamp.asset"))
+		UINT32 modifications =
+			BuiltinResourcesHelper::checkForModifications(BuiltinRawDataFolder, BuiltinDataFolder + L"Timestamp.asset");
+		if (modifications > 0)
 		{
 			SPtr<ResourceManifest> oldResourceManifest;
 			if (FileSystem::exists(ResourceManifestPath))
@@ -340,7 +342,7 @@ namespace bs
 			mResourceManifest = ResourceManifest::create("BuiltinResources");
 			gResources().registerResourceManifest(mResourceManifest);
 
-			preprocess();
+			preprocess(modifications == 2);
 			BuiltinResourcesHelper::writeTimestamp(BuiltinDataFolder + L"Timestamp.asset");
 
 			ResourceManifest::save(mResourceManifest, ResourceManifestPath, BuiltinDataFolder);
@@ -391,7 +393,7 @@ namespace bs
 	BuiltinEditorResources::~BuiltinEditorResources()
 	{ }
 
-	void BuiltinEditorResources::preprocess()
+	void BuiltinEditorResources::preprocess(bool forceImport)
 	{
 		Resources::instance().unloadAllUnused();
 
@@ -429,10 +431,14 @@ namespace bs
 			dataListStream->close();
 		}
 
-		BuiltinResourcesHelper::importAssets(iconsJSON, EditorRawIconsFolder, EditorIconFolder, mResourceManifest, BuiltinResourcesHelper::AssetType::Sprite);
-		BuiltinResourcesHelper::importAssets(includesJSON, EditorRawShaderIncludeFolder, EditorShaderIncludeFolder, mResourceManifest); // Hidden dependency: Includes must be imported before shaders
-		BuiltinResourcesHelper::importAssets(shadersJSON, EditorRawShaderFolder, EditorShaderFolder, mResourceManifest);
-		BuiltinResourcesHelper::importAssets(skinJSON, EditorRawSkinFolder, EditorSkinFolder, mResourceManifest, BuiltinResourcesHelper::AssetType::Sprite);
+		BuiltinResourcesHelper::importAssets(iconsJSON, EditorRawIconsFolder, EditorIconFolder, mResourceManifest, 
+			BuiltinResourcesHelper::AssetType::Sprite, forceImport);
+		BuiltinResourcesHelper::importAssets(includesJSON, EditorRawShaderIncludeFolder, EditorShaderIncludeFolder, 
+			mResourceManifest, BuiltinResourcesHelper::AssetType::Normal, forceImport); // Hidden dependency: Includes must be imported before shaders
+		BuiltinResourcesHelper::importAssets(shadersJSON, EditorRawShaderFolder, EditorShaderFolder, mResourceManifest,
+			BuiltinResourcesHelper::AssetType::Normal, forceImport);
+		BuiltinResourcesHelper::importAssets(skinJSON, EditorRawSkinFolder, EditorSkinFolder, mResourceManifest, 
+			BuiltinResourcesHelper::AssetType::Sprite, forceImport);
 
 		// Import fonts
 		BuiltinResourcesHelper::importFont(BuiltinRawDataFolder + DefaultFontFilename, DefaultFontFilename, 

+ 1 - 1
Source/BansheeEngine/Include/BsBuiltinResources.h

@@ -137,7 +137,7 @@ namespace bs
 		 * @note	
 		 * Normally you only want to use this during development phase and then ship with engine-ready format only.
 		 */
-		void preprocess();
+		void preprocess(bool forceImport);
 
 		/**	Generates the default engine skin and all GUI element styles. */
 		SPtr<GUISkin> generateGUISkin();

+ 6 - 3
Source/BansheeEngine/Include/BsBuiltinResourcesHelper.h

@@ -37,10 +37,12 @@ namespace bs
 		 * @param[in]	outputFolder	Folder in which to store the imported resources.
 		 * @param[in]	manifest		Manifest in which to register the imported resources in.
 		 * @param[in]	mode			Mode that controls how are files imported.
+		 * @param[in]	forceImport		If true, all assets will be imported regardless if they have been modified or not.
+		 *								If false, assets will be imported only if the source is newer than the imported file.
 		 * @return						True if the process was sucessful.
 		 */
 		static bool importAssets(const nlohmann::json& entries, const Path& inputFolder, const Path& outputFolder, 
-			const SPtr<ResourceManifest>& manifest, AssetType mode = AssetType::Normal);
+			const SPtr<ResourceManifest>& manifest, AssetType mode = AssetType::Normal, bool forceImport = false);
 
 		/**
 		 * Imports a font from the specified file. Imported font assets are saved in the output folder. All saved resources
@@ -64,9 +66,10 @@ namespace bs
 
 		/**
 		 * Checks all files in the specified folder for modifications compared to the time stored in the timestamp file. 
-		 * Timestamp file must have been saved using writeTimestamp().
+		 * Timestamp file must have been saved using writeTimestamp(). Returns 0 if no changes, 1 if timestamp is out date,
+		 * or 2 if timestamp doesn't exist.
 		 */
-		static bool checkForModifications(const Path& folder, const Path& timeStampFile);
+		static UINT32 checkForModifications(const Path& folder, const Path& timeStampFile);
 
 		/** Checks if the shader compiled properly and reports the problem if it hasn't. Returns true if shader is valid. */
 		static bool verifyAndReportShader(const HShader& shader);

+ 15 - 8
Source/BansheeEngine/Source/BsBuiltinResources.cpp

@@ -238,7 +238,9 @@ namespace bs
 #if BS_DEBUG_MODE
 		if (FileSystem::exists(mBuiltinRawDataFolder))
 		{
-			if (BuiltinResourcesHelper::checkForModifications(mBuiltinRawDataFolder, mBuiltinDataFolder + L"Timestamp.asset"))
+			UINT32 modifications = 
+				BuiltinResourcesHelper::checkForModifications(mBuiltinRawDataFolder, mBuiltinDataFolder + L"Timestamp.asset");
+			if (modifications > 0)
 			{
 				SPtr<ResourceManifest> oldResourceManifest;
 				if (FileSystem::exists(ResourceManifestPath))
@@ -251,7 +253,7 @@ namespace bs
 				mResourceManifest = ResourceManifest::create("BuiltinResources");
 				gResources().registerResourceManifest(mResourceManifest);
 
-				preprocess();
+				preprocess(modifications == 2);
 				BuiltinResourcesHelper::writeTimestamp(mBuiltinDataFolder + L"Timestamp.asset");
 
 				ResourceManifest::save(mResourceManifest, ResourceManifestPath, mBuiltinDataFolder);
@@ -358,7 +360,7 @@ namespace bs
 		gCoreThread().submit(true);
 	}
 
-	void BuiltinResources::preprocess()
+	void BuiltinResources::preprocess(bool forceImport)
 	{
 		// Hidden dependency: Textures need to be generated before shaders as they may use the default textures
 		generateTextures();
@@ -409,11 +411,16 @@ namespace bs
 		Path iconFolder = mBuiltinDataFolder + IconFolder;
 		Path shaderIncludeFolder = mBuiltinDataFolder + ShaderIncludeFolder;
 
-		BuiltinResourcesHelper::importAssets(cursorsJSON, rawCursorFolder, mEngineCursorFolder, mResourceManifest);
-		BuiltinResourcesHelper::importAssets(iconsJSON, rawIconFolder, iconFolder, mResourceManifest);
-		BuiltinResourcesHelper::importAssets(includesJSON, rawShaderIncludeFolder, shaderIncludeFolder, mResourceManifest); // Hidden dependency: Includes must be imported before shaders
-		BuiltinResourcesHelper::importAssets(shadersJSON, rawShaderFolder, mEngineShaderFolder, mResourceManifest);
-		BuiltinResourcesHelper::importAssets(skinJSON, rawSkinFolder, skinFolder, mResourceManifest, BuiltinResourcesHelper::AssetType::Sprite);
+		BuiltinResourcesHelper::importAssets(cursorsJSON, rawCursorFolder, mEngineCursorFolder, mResourceManifest, 
+			BuiltinResourcesHelper::AssetType::Normal, forceImport);
+		BuiltinResourcesHelper::importAssets(iconsJSON, rawIconFolder, iconFolder, mResourceManifest, 
+			BuiltinResourcesHelper::AssetType::Normal, forceImport);
+		BuiltinResourcesHelper::importAssets(includesJSON, rawShaderIncludeFolder, shaderIncludeFolder, mResourceManifest,
+			BuiltinResourcesHelper::AssetType::Normal, forceImport); // Hidden dependency: Includes must be imported before shaders
+		BuiltinResourcesHelper::importAssets(shadersJSON, rawShaderFolder, mEngineShaderFolder, mResourceManifest,
+			BuiltinResourcesHelper::AssetType::Normal, forceImport);
+		BuiltinResourcesHelper::importAssets(skinJSON, rawSkinFolder, skinFolder, mResourceManifest, 
+			BuiltinResourcesHelper::AssetType::Sprite);
 
 		// Import font
 		BuiltinResourcesHelper::importFont(mBuiltinRawDataFolder + DefaultFontFilename, DefaultFontFilename, 

+ 46 - 20
Source/BansheeEngine/Source/BsBuiltinResourcesHelper.cpp

@@ -26,15 +26,17 @@ using json = nlohmann::json;
 namespace bs
 {
 	bool BuiltinResourcesHelper::importAssets(const nlohmann::json& entries, const Path& inputFolder, 
-		const Path& outputFolder, const SPtr<ResourceManifest>& manifest, AssetType mode)
+		const Path& outputFolder, const SPtr<ResourceManifest>& manifest, AssetType mode, bool forceImport)
 	{
 		if (!FileSystem::exists(inputFolder))
 			return true;
 
-		if (FileSystem::exists(outputFolder))
+		bool outputExists = FileSystem::exists(outputFolder);
+		if (forceImport && outputExists)
 			FileSystem::remove(outputFolder);
 		
-		FileSystem::createDir(outputFolder);
+		if(!outputExists || forceImport)
+			FileSystem::createDir(outputFolder);
 
 		Path spriteOutputFolder = outputFolder + "/Sprites/";
 		if(mode == AssetType::Sprite)
@@ -99,33 +101,54 @@ namespace bs
 					resourcesToSave.push_back(std::make_pair(relativeAssetPath, nullptr));
 			}
 
-			// Use the provided UUID if just one resource, otherwise we ignore the UUID. The current assumption is that
-			// such resources don't require persistent UUIDs. If that changes then this method needs to be updated.
-			if(resourcesToSave.size() == 1)
+			// Check if this resource actually changed
+			bool import = true;
+			if(!forceImport)
 			{
-				Path outputPath = outputFolder + resourcesToSave[0].first;
+				import = false;
 
-				HResource resource = Importer::instance().import(filePath, resourcesToSave[0].second, UUID);
-				if (resource != nullptr)
+				time_t lastModifiedSrc = FileSystem::getLastModifiedTime(filePath);
+				for(auto& entry : resourcesToSave)
 				{
-					Resources::instance().save(resource, outputPath, true);
-					manifest->registerResource(resource.getUUID(), outputPath);
+					Path outputPath = outputFolder + entry.first;
+					if(lastModifiedSrc > FileSystem::getLastModifiedTime(outputPath))
+					{
+						import = true;
+						break;
+					}
 				}
-
-				return resource;
 			}
-			else
+
+			if (import)
 			{
-				for (auto& entry : resourcesToSave)
+				// Use the provided UUID if just one resource, otherwise we ignore the UUID. The current assumption is that
+				// such resources don't require persistent UUIDs. If that changes then this method needs to be updated.
+				if (resourcesToSave.size() == 1)
 				{
-					Path outputPath = outputFolder + entry.first;;
+					Path outputPath = outputFolder + resourcesToSave[0].first;
 
-					HResource resource = Importer::instance().import(filePath, entry.second);
+					HResource resource = Importer::instance().import(filePath, resourcesToSave[0].second, UUID);
 					if (resource != nullptr)
 					{
 						Resources::instance().save(resource, outputPath, true);
 						manifest->registerResource(resource.getUUID(), outputPath);
 					}
+
+					return resource;
+				}
+				else
+				{
+					for (auto& entry : resourcesToSave)
+					{
+						Path outputPath = outputFolder + entry.first;;
+
+						HResource resource = Importer::instance().import(filePath, entry.second);
+						if (resource != nullptr)
+						{
+							Resources::instance().save(resource, outputPath, true);
+							manifest->registerResource(resource.getUUID(), outputPath);
+						}
+					}
 				}
 			}
 
@@ -396,10 +419,10 @@ namespace bs
 		fileStream->close();
 	}
 
-	bool BuiltinResourcesHelper::checkForModifications(const Path& folder, const Path& timeStampFile)
+	UINT32 BuiltinResourcesHelper::checkForModifications(const Path& folder, const Path& timeStampFile)
 	{
 		if (!FileSystem::exists(timeStampFile))
-			return true;
+			return 2;
 
 		SPtr<DataStream> fileStream = FileSystem::openFile(timeStampFile);
 		time_t lastUpdateTime = 0;
@@ -421,8 +444,11 @@ namespace bs
 		};
 
 		FileSystem::iterate(folder, checkUpToDate, checkUpToDate);
+		
+		if (!upToDate)
+			return 1;
 
-		return !upToDate;
+		return 0;
 	}
 
 	bool BuiltinResourcesHelper::verifyAndReportShader(const HShader& shader)