Explorar o código

Refactored resource loading so it will load dependencies even if the parent resource is already loaded (This probably broke async resource loading in some way)

BearishSun %!s(int64=10) %!d(string=hai) anos
pai
achega
00b3967714
Modificáronse 2 ficheiros con 91 adicións e 23 borrados
  1. 91 22
      BansheeCore/Source/BsResources.cpp
  2. 0 1
      MBansheeEditor/EditorApplication.cs

+ 91 - 22
BansheeCore/Source/BsResources.cpp

@@ -180,6 +180,64 @@ namespace BansheeEngine
 				}
 			}
 		}
+		else if (loadDependencies && savedResourceData != nullptr) // Queue dependencies in case they aren't already loaded
+		{
+			const Vector<String>& dependencies = savedResourceData->getDependencies();
+			if (!dependencies.empty())
+			{
+				{
+					BS_LOCK_MUTEX(mInProgressResourcesMutex);
+
+					ResourceLoadData* loadData = nullptr;
+
+					auto iterFind = mInProgressResources.find(UUID);
+					if (iterFind == mInProgressResources.end()) // Fully loaded
+					{
+						loadData = bs_new<ResourceLoadData>(outputResource, 0);
+						loadData->resource = outputResource;
+						loadData->remainingDependencies = 0;
+						loadData->notifyImmediately = synchronous; // Make resource listener trigger before exit if loading synchronously
+
+						mInProgressResources[UUID] = loadData;
+					}
+					else
+					{
+						loadData = iterFind->second;
+					}
+
+					// Register dependencies and count them so we know when the resource is fully loaded
+					for (auto& dependency : dependencies)
+					{
+						if (dependency != UUID)
+						{
+							bool registerDependency = true;
+
+							auto iterFind2 = mDependantLoads.find(dependency);
+							if (iterFind2 != mDependantLoads.end())
+							{
+								Vector<ResourceLoadData*>& dependantData = iterFind2->second;
+								auto iterFind3 = std::find_if(dependantData.begin(), dependantData.end(),
+									[&](ResourceLoadData* x)
+								{
+									return x->resource.getUUID() == outputResource.getUUID();
+								});
+
+								registerDependency = iterFind3 == dependantData.end();
+							}
+
+							if (registerDependency)
+							{
+								mDependantLoads[dependency].push_back(loadData);
+								loadData->remainingDependencies++;
+							}
+						}
+					}
+				}
+
+				for (auto& dependency : dependencies)
+					loadFromUUID(dependency, !synchronous);
+			}
+		}
 
 		// Actually start the file read operation if not already loaded or in progress
 		if (!alreadyLoading && !filePath.isEmpty())
@@ -439,42 +497,57 @@ namespace BansheeEngine
 		String uuid = resource.getUUID();
 
 		ResourceLoadData* myLoadData = nullptr;
+		bool finishLoad = true;
 		Vector<ResourceLoadData*> dependantLoads;
 		{
 			BS_LOCK_MUTEX(mInProgressResourcesMutex);
+
 			auto iterFind = mInProgressResources.find(uuid);
 			if (iterFind != mInProgressResources.end())
 			{
 				myLoadData = iterFind->second;
-				mInProgressResources.erase(iterFind);
+				finishLoad = myLoadData->remainingDependencies == 0;
+				
+				if (finishLoad)
+					mInProgressResources.erase(iterFind);
 			}
 
-			dependantLoads = mDependantLoads[uuid];
-			mDependantLoads.erase(uuid);
-		}
+			auto iterFind2 = mDependantLoads.find(uuid);
 
-		if (myLoadData != nullptr)
-		{
+			if (iterFind2 != mDependantLoads.end())
+				dependantLoads = iterFind2->second;
+
+			if (finishLoad)
 			{
-				BS_LOCK_MUTEX(mLoadedResourceMutex);
-				mLoadedResources[uuid] = resource;
-			}
+				mDependantLoads.erase(uuid);
 
-			resource._setHandleData(myLoadData->loadedData, uuid);
-			onResourceLoaded(resource);
+				// If loadedData is null then we're probably completing load on an already loaded resource, triggered
+				// by its dependencies.
+				if (myLoadData != nullptr && myLoadData->loadedData != nullptr)
+				{
+					BS_LOCK_MUTEX(mLoadedResourceMutex);
 
-			if (myLoadData->notifyImmediately)
-				ResourceListenerManager::instance().notifyListeners(uuid);
+					mLoadedResources[uuid] = resource;
+					resource._setHandleData(myLoadData->loadedData, uuid);
+				}
 
-			bs_delete(myLoadData);
+				for (auto& dependantLoad : dependantLoads)
+					dependantLoad->remainingDependencies--;
+			}
 		}
 
 		for (auto& dependantLoad : dependantLoads)
+			loadComplete(dependantLoad->resource);
+
+		if (finishLoad && myLoadData != nullptr)
 		{
-			dependantLoad->remainingDependencies--;
+			onResourceLoaded(resource);
 
-			if (dependantLoad->remainingDependencies == 0)
-				loadComplete(dependantLoad->resource);
+			// This should only ever be true on the main thread
+			if (myLoadData->notifyImmediately)
+				ResourceListenerManager::instance().notifyListeners(uuid);
+
+			bs_delete(myLoadData);
 		}
 	}
 
@@ -482,7 +555,6 @@ namespace BansheeEngine
 	{
 		ResourcePtr rawResource = loadFromDiskAndDeserialize(filePath);
 
-		bool finishLoad = false;
 		{
 			BS_LOCK_MUTEX(mInProgressResourcesMutex);
 
@@ -490,12 +562,9 @@ namespace BansheeEngine
 			ResourceLoadData* myLoadData = mInProgressResources[resource.getUUID()];
 			myLoadData->loadedData = rawResource;
 			myLoadData->remainingDependencies--;
-
-			finishLoad = myLoadData->remainingDependencies == 0;
 		}
 
-		if (finishLoad)
-			loadComplete(resource);
+		loadComplete(resource);
 	}
 
 	BS_CORE_EXPORT Resources& gResources()

+ 0 - 1
MBansheeEditor/EditorApplication.cs

@@ -248,7 +248,6 @@ namespace BansheeEditor
                     scenePath += ".prefab";
 
                     SaveScene(scenePath);
-                    LoadScene(scenePath);
                 }
             }
         }