فهرست منبع

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 10 سال پیش
والد
کامیت
00b3967714
2فایلهای تغییر یافته به همراه91 افزوده شده و 23 حذف شده
  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);
                 }
             }
         }