Răsfoiți Sursa

Project library will now clear deleted entries on load
Project library will now properly delete the .meta file when its parent file is detected to be deleted
Resources::loadFromUUID will now properly return in-memory resources without complaining their files don't exist

BearishSun 10 ani în urmă
părinte
comite
eee54de424

+ 1 - 2
BansheeCore/Source/BsPrefab.cpp

@@ -99,8 +99,7 @@ namespace BansheeEngine
 			{
 			{
 				HSceneObject child = current->getChild(i);
 				HSceneObject child = current->getChild(i);
 
 
-				String prefabLinkUUID = child->getPrefabLink();
-				if (!prefabLinkUUID.empty())
+				if (!child->mPrefabLinkUUID.empty())
 					PrefabUtility::updateFromPrefab(child);
 					PrefabUtility::updateFromPrefab(child);
 				else
 				else
 					todo.push(child);
 					todo.push(child);

+ 1 - 1
BansheeCore/Source/BsPrefabDiff.cpp

@@ -29,7 +29,7 @@ namespace BansheeEngine
 
 
 	SPtr<PrefabDiff> PrefabDiff::create(const HSceneObject& prefab, const HSceneObject& instance)
 	SPtr<PrefabDiff> PrefabDiff::create(const HSceneObject& prefab, const HSceneObject& instance)
 	{
 	{
-		if (prefab->getPrefabLink() != instance->getPrefabLink() || prefab->getLinkId() != instance->getLinkId())
+		if (prefab->mPrefabLinkUUID != instance->mPrefabLinkUUID || prefab->getLinkId() != instance->getLinkId())
 			return nullptr;
 			return nullptr;
 
 
 		Vector<RenamedGameObject> renamedObjects;
 		Vector<RenamedGameObject> renamedObjects;

+ 4 - 5
BansheeCore/Source/BsPrefabUtility.cpp

@@ -50,8 +50,7 @@ namespace BansheeEngine
 			HSceneObject current = todo.top();
 			HSceneObject current = todo.top();
 			todo.pop();
 			todo.pop();
 
 
-			String prefabLinkUUID = current->getPrefabLink();
-			if (!prefabLinkUUID.empty())
+			if (!current->mPrefabLinkUUID.empty())
 				prefabInstanceRoots.push_back(current);
 				prefabInstanceRoots.push_back(current);
 
 
 			UINT32 childCount = current->getNumChildren();
 			UINT32 childCount = current->getNumChildren();
@@ -66,7 +65,7 @@ namespace BansheeEngine
 		for (auto iter = prefabInstanceRoots.rbegin(); iter != prefabInstanceRoots.rend(); ++iter)
 		for (auto iter = prefabInstanceRoots.rbegin(); iter != prefabInstanceRoots.rend(); ++iter)
 		{
 		{
 			HSceneObject current = *iter;
 			HSceneObject current = *iter;
-			HPrefab prefabLink = static_resource_cast<Prefab>(gResources().loadFromUUID(current->getPrefabLink(), false, false));
+			HPrefab prefabLink = static_resource_cast<Prefab>(gResources().loadFromUUID(current->mPrefabLinkUUID, false, false));
 
 
 			if (prefabLink != nullptr && prefabLink->getHash() != current->mPrefabHash)
 			if (prefabLink != nullptr && prefabLink->getHash() != current->mPrefabHash)
 			{
 			{
@@ -197,11 +196,11 @@ namespace BansheeEngine
 			HSceneObject current = todo.top();
 			HSceneObject current = todo.top();
 			todo.pop();
 			todo.pop();
 
 
-			if (!current->getPrefabLink().empty())
+			if (!current->mPrefabLinkUUID.empty())
 			{
 			{
 				current->mPrefabDiff = nullptr;
 				current->mPrefabDiff = nullptr;
 
 
-				HPrefab prefabLink = static_resource_cast<Prefab>(gResources().loadFromUUID(current->getPrefabLink(), false, false));
+				HPrefab prefabLink = static_resource_cast<Prefab>(gResources().loadFromUUID(current->mPrefabLinkUUID, false, false));
 				if (prefabLink != nullptr)
 				if (prefabLink != nullptr)
 					current->mPrefabDiff = PrefabDiff::create(prefabLink->_getRoot(), current->getHandle());
 					current->mPrefabDiff = PrefabDiff::create(prefabLink->_getRoot(), current->getHandle());
 			}
 			}

+ 70 - 13
BansheeCore/Source/BsResources.cpp

@@ -45,6 +45,35 @@ namespace BansheeEngine
 
 
 	HResource Resources::loadFromUUID(const String& uuid, bool async, bool loadDependencies)
 	HResource Resources::loadFromUUID(const String& uuid, bool async, bool loadDependencies)
 	{
 	{
+		HResource outputResource;
+		bool alreadyLoading = false;
+		{
+			BS_LOCK_MUTEX(mLoadedResourceMutex);
+			auto iterFind = mLoadedResources.find(uuid);
+			if (iterFind != mLoadedResources.end()) // Resource is already loaded
+			{
+				outputResource = iterFind->second;
+				alreadyLoading = true;
+
+			}
+		}
+
+		if (!alreadyLoading)
+		{
+			BS_LOCK_MUTEX(mInProgressResourcesMutex);
+			auto iterFind2 = mInProgressResources.find(uuid);
+			if (iterFind2 != mInProgressResources.end())
+			{
+				outputResource = iterFind2->second->resource;
+
+				// Previously being loaded as async but now we want it synced, so we wait
+				if (!async)
+					outputResource.blockUntilLoaded();
+
+				alreadyLoading = true;
+			}
+		}
+
 		Path filePath;
 		Path filePath;
 		bool foundPath = false;
 		bool foundPath = false;
 
 
@@ -59,17 +88,37 @@ namespace BansheeEngine
 			}
 			}
 		}
 		}
 
 
-		if(!foundPath)
+		if (!alreadyLoading)
 		{
 		{
-			gDebug().logWarning("Cannot load resource. Resource with UUID '" + uuid + "' doesn't exist.");
+			if (!foundPath)
+			{
+				gDebug().logWarning("Cannot load resource. Resource with UUID '" + uuid + "' doesn't exist.");
 
 
-			HResource outputResource(uuid);
-			loadComplete(outputResource);
+				HResource outputResource(uuid);
+				return outputResource;
+			}
 
 
-			return outputResource;
+			return loadInternal(filePath, !async, loadDependencies);
 		}
 		}
+		else
+		{
+			// Load dependencies
+			if (loadDependencies && foundPath)
+			{
+				// Load saved resource data
+				FileDecoder fs(filePath);
+				SPtr<SavedResourceData> savedResourceData = std::static_pointer_cast<SavedResourceData>(fs.decode());
+
+				{
+					for (auto& dependency : savedResourceData->getDependencies())
+					{
+						loadFromUUID(dependency, async);
+					}
+				}
+			}
 
 
-		return loadInternal(filePath, !async, loadDependencies);
+			return outputResource;
+		}
 	}
 	}
 
 
 	HResource Resources::loadInternal(const Path& filePath, bool synchronous, bool loadDependencies)
 	HResource Resources::loadInternal(const Path& filePath, bool synchronous, bool loadDependencies)
@@ -111,14 +160,24 @@ namespace BansheeEngine
 		// Not loaded and not in progress, start loading of new resource
 		// Not loaded and not in progress, start loading of new resource
 		// (or if already loaded or in progress, load any dependencies)
 		// (or if already loaded or in progress, load any dependencies)
 		if (!alreadyLoading)
 		if (!alreadyLoading)
+		{
 			outputResource = HResource(uuid);
 			outputResource = HResource(uuid);
 
 
-		if(!FileSystem::isFile(filePath))
-		{
-			LOGWRN("Specified file: " + filePath.toString() + " doesn't exist.");
+			if (!FileSystem::isFile(filePath))
+			{
+				LOGWRN("Specified file: " + filePath.toString() + " doesn't exist.");
 
 
-			loadComplete(outputResource);
-			return outputResource;
+				loadComplete(outputResource);
+				return outputResource;
+			}
+		}
+		else
+		{
+			if (!FileSystem::isFile(filePath))
+			{
+				LOGWRN("Specified file: " + filePath.toString() + " doesn't exist.");
+				return outputResource;
+			}
 		}
 		}
 
 
 		// Load saved resource data
 		// Load saved resource data
@@ -177,8 +236,6 @@ namespace BansheeEngine
 				TaskScheduler::instance().addTask(task);
 				TaskScheduler::instance().addTask(task);
 			}
 			}
 		}
 		}
-		else
-			loadComplete(outputResource);
 
 
 		return outputResource;
 		return outputResource;
 	}
 	}

+ 34 - 19
BansheeEditor/Source/BsProjectLibrary.cpp

@@ -331,6 +331,10 @@ namespace BansheeEngine
 			mUUIDToPath.erase(uuid);
 			mUUIDToPath.erase(uuid);
 		}
 		}
 
 
+		Path metaPath = getMetaPath(resource->path);
+		if (FileSystem::isFile(metaPath))
+			FileSystem::remove(metaPath);
+
 		DirectoryEntry* parent = resource->parent;
 		DirectoryEntry* parent = resource->parent;
 		auto findIter = std::find_if(parent->mChildren.begin(), parent->mChildren.end(), 
 		auto findIter = std::find_if(parent->mChildren.begin(), parent->mChildren.end(), 
 			[&] (const LibraryEntry* entry) { return entry == resource; });
 			[&] (const LibraryEntry* entry) { return entry == resource; });
@@ -688,12 +692,7 @@ namespace BansheeEngine
 			if (!mResourcesFolder.includes(newFullPath))
 			if (!mResourcesFolder.includes(newFullPath))
 			{
 			{
 				if(oldEntry->type == LibraryEntryType::File)
 				if(oldEntry->type == LibraryEntryType::File)
-				{
 					deleteResourceInternal(static_cast<ResourceEntry*>(oldEntry));
 					deleteResourceInternal(static_cast<ResourceEntry*>(oldEntry));
-
-					if(FileSystem::isFile(oldMetaPath))
-						FileSystem::remove(oldMetaPath);
-				}
 				else if(oldEntry->type == LibraryEntryType::Directory)
 				else if(oldEntry->type == LibraryEntryType::Directory)
 					deleteDirectoryInternal(static_cast<DirectoryEntry*>(oldEntry));
 					deleteDirectoryInternal(static_cast<DirectoryEntry*>(oldEntry));
 			}
 			}
@@ -860,13 +859,7 @@ namespace BansheeEngine
 		if(entry != nullptr)
 		if(entry != nullptr)
 		{
 		{
 			if(entry->type == LibraryEntryType::File)
 			if(entry->type == LibraryEntryType::File)
-			{
 				deleteResourceInternal(static_cast<ResourceEntry*>(entry));
 				deleteResourceInternal(static_cast<ResourceEntry*>(entry));
-
-				Path metaPath = getMetaPath(fullPath);
-				if(FileSystem::isFile(metaPath))
-					FileSystem::remove(metaPath);
-			}
 			else if(entry->type == LibraryEntryType::Directory)
 			else if(entry->type == LibraryEntryType::Directory)
 				deleteDirectoryInternal(static_cast<DirectoryEntry*>(entry));
 				deleteDirectoryInternal(static_cast<DirectoryEntry*>(entry));
 		}
 		}
@@ -1131,6 +1124,8 @@ namespace BansheeEngine
 		Stack<DirectoryEntry*> todo;
 		Stack<DirectoryEntry*> todo;
 		todo.push(mRootEntry);
 		todo.push(mRootEntry);
 
 
+		Vector<LibraryEntry*> deletedEntries;
+
 		while(!todo.empty())
 		while(!todo.empty())
 		{
 		{
 			DirectoryEntry* curDir = todo.top();
 			DirectoryEntry* curDir = todo.top();
@@ -1141,10 +1136,10 @@ namespace BansheeEngine
 				if(child->type == LibraryEntryType::File)
 				if(child->type == LibraryEntryType::File)
 				{
 				{
 					ResourceEntry* resEntry = static_cast<ResourceEntry*>(child);
 					ResourceEntry* resEntry = static_cast<ResourceEntry*>(child);
-					bool doAddDependencies = true;
-
+					
 					if (FileSystem::isFile(resEntry->path))
 					if (FileSystem::isFile(resEntry->path))
 					{
 					{
+						bool doAddDependencies = true;
 						if (resEntry->meta == nullptr)
 						if (resEntry->meta == nullptr)
 						{
 						{
 							Path metaPath = resEntry->path;
 							Path metaPath = resEntry->path;
@@ -1168,21 +1163,41 @@ namespace BansheeEngine
 								doAddDependencies = false;
 								doAddDependencies = false;
 							}
 							}
 						}
 						}
-					}
 
 
-					if (resEntry->meta != nullptr)
-						mUUIDToPath[resEntry->meta->getUUID()] = resEntry->path;
+						if (resEntry->meta != nullptr)
+							mUUIDToPath[resEntry->meta->getUUID()] = resEntry->path;
 
 
-					if (doAddDependencies)
-						addDependencies(resEntry);
+						if (doAddDependencies)
+							addDependencies(resEntry);
+					}
+					else
+						deletedEntries.push_back(resEntry);
 				}
 				}
 				else if(child->type == LibraryEntryType::Directory)
 				else if(child->type == LibraryEntryType::Directory)
 				{
 				{
-					todo.push(static_cast<DirectoryEntry*>(child));
+					if (FileSystem::isDirectory(child->path))
+						todo.push(static_cast<DirectoryEntry*>(child));
+					else
+						deletedEntries.push_back(child);
 				}
 				}
 			}
 			}
 		}
 		}
 
 
+		// Remove entries that no longer have corresponding files
+		for (auto& deletedEntry : deletedEntries)
+		{
+			if (deletedEntry->type == LibraryEntryType::File)
+			{
+				ResourceEntry* resEntry = static_cast<ResourceEntry*>(deletedEntry);
+				deleteResourceInternal(resEntry);
+			}
+			else
+			{
+				DirectoryEntry* dirEntry = static_cast<DirectoryEntry*>(deletedEntry);
+				deleteDirectoryInternal(dirEntry);
+			}
+		}
+
 		mIsLoaded = true;
 		mIsLoaded = true;
 	}
 	}