Просмотр исходного кода

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 лет назад
Родитель
Сommit
eee54de424

+ 1 - 2
BansheeCore/Source/BsPrefab.cpp

@@ -99,8 +99,7 @@ namespace BansheeEngine
 			{
 				HSceneObject child = current->getChild(i);
 
-				String prefabLinkUUID = child->getPrefabLink();
-				if (!prefabLinkUUID.empty())
+				if (!child->mPrefabLinkUUID.empty())
 					PrefabUtility::updateFromPrefab(child);
 				else
 					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)
 	{
-		if (prefab->getPrefabLink() != instance->getPrefabLink() || prefab->getLinkId() != instance->getLinkId())
+		if (prefab->mPrefabLinkUUID != instance->mPrefabLinkUUID || prefab->getLinkId() != instance->getLinkId())
 			return nullptr;
 
 		Vector<RenamedGameObject> renamedObjects;

+ 4 - 5
BansheeCore/Source/BsPrefabUtility.cpp

@@ -50,8 +50,7 @@ namespace BansheeEngine
 			HSceneObject current = todo.top();
 			todo.pop();
 
-			String prefabLinkUUID = current->getPrefabLink();
-			if (!prefabLinkUUID.empty())
+			if (!current->mPrefabLinkUUID.empty())
 				prefabInstanceRoots.push_back(current);
 
 			UINT32 childCount = current->getNumChildren();
@@ -66,7 +65,7 @@ namespace BansheeEngine
 		for (auto iter = prefabInstanceRoots.rbegin(); iter != prefabInstanceRoots.rend(); ++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)
 			{
@@ -197,11 +196,11 @@ namespace BansheeEngine
 			HSceneObject current = todo.top();
 			todo.pop();
 
-			if (!current->getPrefabLink().empty())
+			if (!current->mPrefabLinkUUID.empty())
 			{
 				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)
 					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 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;
 		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)
@@ -111,14 +160,24 @@ namespace BansheeEngine
 		// Not loaded and not in progress, start loading of new resource
 		// (or if already loaded or in progress, load any dependencies)
 		if (!alreadyLoading)
+		{
 			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
@@ -177,8 +236,6 @@ namespace BansheeEngine
 				TaskScheduler::instance().addTask(task);
 			}
 		}
-		else
-			loadComplete(outputResource);
 
 		return outputResource;
 	}

+ 34 - 19
BansheeEditor/Source/BsProjectLibrary.cpp

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