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

Project library:
- Dependency import is no longer delayed a frame
- Proper handling if resource metas don't exist
- Do not force reimport when a meta file is missing
- Internal resources will now be cleaned up if their source resources are missing

BearishSun 10 лет назад
Родитель
Сommit
bae75227c1

+ 3 - 21
BansheeEditor/Include/BsProjectLibrary.h

@@ -71,13 +71,6 @@ namespace BansheeEngine
 		ProjectLibrary();
 		ProjectLibrary();
 		~ProjectLibrary();
 		~ProjectLibrary();
 
 
-		/**
-		 * @brief	To be called once per frame.
-		 *
-		 * @note	Internal methods.
-		 */
-		void update();
-
 		/**
 		/**
 		 * @brief	Checks if any resources at the specified path have been modified, added or deleted,
 		 * @brief	Checks if any resources at the specified path have been modified, added or deleted,
 		 *			and updates the internal hierarchy accordingly. 
 		 *			and updates the internal hierarchy accordingly. 
@@ -253,6 +246,7 @@ namespace BansheeEngine
 
 
 		Event<void(const Path&)> onEntryRemoved; /**< Triggered whenever an entry is removed from the library. Path provided is absolute. */
 		Event<void(const Path&)> onEntryRemoved; /**< Triggered whenever an entry is removed from the library. Path provided is absolute. */
 		Event<void(const Path&)> onEntryAdded; /**< Triggered whenever an entry is added to the library. Path provided is absolute. */
 		Event<void(const Path&)> onEntryAdded; /**< Triggered whenever an entry is added to the library. Path provided is absolute. */
+		Event<void(const Path&)> onEntryImport; /**< Triggered when a resource is being (re)imported. Path provided is absolute. */
 
 
 		static const Path RESOURCES_DIR;
 		static const Path RESOURCES_DIR;
 		static const Path INTERNAL_RESOURCES_DIR;
 		static const Path INTERNAL_RESOURCES_DIR;
@@ -343,16 +337,6 @@ namespace BansheeEngine
 		 */
 		 */
 		bool isMeta(const Path& fullPath) const;
 		bool isMeta(const Path& fullPath) const;
 
 
-		/**
-		 * @brief	Triggered whenever a library entry is removed.
-		 */
-		void doOnEntryRemoved(const LibraryEntry* entry);
-
-		/**
-		 * @brief	Triggered whenever a library entry is added.
-		 */
-		void doOnEntryAdded(const LibraryEntry* entry);
-
 		/**
 		/**
 		 * @brief	Returns a set of resource paths that are dependent on the provided
 		 * @brief	Returns a set of resource paths that are dependent on the provided
 		 *			resource entry. (e.g. a shader file might be dependent on shader include file).
 		 *			resource entry. (e.g. a shader file might be dependent on shader include file).
@@ -370,10 +354,9 @@ namespace BansheeEngine
 		void removeDependencies(const ResourceEntry* entry);
 		void removeDependencies(const ResourceEntry* entry);
 
 
 		/**
 		/**
-		 * @brief	Finds dependants resource for the specified resource entry and queues
-		 *			them for reimport next frame.
+		 * @brief	Finds dependants resource for the specified resource entry and reimports them.
 		 */
 		 */
-		void queueDependantForReimport(const ResourceEntry* entry);
+		void reimportDependants(const Path& entryPath);
 
 
 		/**
 		/**
 		 * @brief	Makes all library entry paths relative to the current resources folder.
 		 * @brief	Makes all library entry paths relative to the current resources folder.
@@ -401,7 +384,6 @@ namespace BansheeEngine
 		bool mIsLoaded;
 		bool mIsLoaded;
 
 
 		UnorderedMap<Path, Vector<Path>> mDependencies;
 		UnorderedMap<Path, Vector<Path>> mDependencies;
-		UnorderedSet<Path> mReimportQueue;
 		UnorderedMap<String, Path> mUUIDToPath;
 		UnorderedMap<String, Path> mUUIDToPath;
 	};
 	};
 
 

+ 0 - 2
BansheeEditor/Source/BsEditorApplication.cpp

@@ -153,9 +153,7 @@ namespace BansheeEngine
 	{
 	{
 		Application::postUpdate();
 		Application::postUpdate();
 
 
-		gProjectLibrary().update();
 		EditorWindowManager::instance().update();
 		EditorWindowManager::instance().update();
-
 		SplashScreen::hide();
 		SplashScreen::hide();
 	}
 	}
 
 

+ 1 - 1
BansheeEditor/Source/BsGUISceneTreeView.cpp

@@ -333,7 +333,7 @@ namespace BansheeEngine
 				if (entry != nullptr && entry->type == ProjectLibrary::LibraryEntryType::File)
 				if (entry != nullptr && entry->type == ProjectLibrary::LibraryEntryType::File)
 				{
 				{
 					ProjectLibrary::ResourceEntry* resEntry = static_cast<ProjectLibrary::ResourceEntry*>(entry);
 					ProjectLibrary::ResourceEntry* resEntry = static_cast<ProjectLibrary::ResourceEntry*>(entry);
-					if (resEntry->meta->getTypeID() == TID_Prefab)
+					if (resEntry->meta != nullptr && resEntry->meta->getTypeID() == TID_Prefab)
 					{
 					{
 						HPrefab prefab = static_resource_cast<Prefab>(gResources().loadFromUUID(resEntry->meta->getUUID()));
 						HPrefab prefab = static_resource_cast<Prefab>(gResources().loadFromUUID(resEntry->meta->getUUID()));
 
 

+ 78 - 73
BansheeEditor/Source/BsProjectLibrary.cpp

@@ -59,23 +59,6 @@ namespace BansheeEngine
 		clearEntries();
 		clearEntries();
 	}
 	}
 
 
-	void ProjectLibrary::update()
-	{
-		while (!mReimportQueue.empty())
-		{
-			Path toReimport = *mReimportQueue.begin();
-			LibraryEntry* entry = findEntry(toReimport);
-			if (entry != nullptr && entry->type == LibraryEntryType::File)
-			{
-				ResourceEntry* resEntry = static_cast<ResourceEntry*>(entry);
-				reimportResourceInternal(resEntry, resEntry->meta->getImportOptions(), true);
-				queueDependantForReimport(resEntry);
-			}
-
-			mReimportQueue.erase(mReimportQueue.begin());
-		}
-	}
-
 	void ProjectLibrary::checkForModifications(const Path& fullPath)
 	void ProjectLibrary::checkForModifications(const Path& fullPath)
 	{
 	{
 		Vector<Path> dirtyResources;
 		Vector<Path> dirtyResources;
@@ -134,7 +117,7 @@ namespace BansheeEngine
 					{
 					{
 						addDirectoryInternal(entryParent, pathToSearch);
 						addDirectoryInternal(entryParent, pathToSearch);
 
 
-						checkForModifications(pathToSearch);
+						checkForModifications(pathToSearch, import, dirtyResources);
 					}
 					}
 				}
 				}
 			}
 			}
@@ -146,10 +129,7 @@ namespace BansheeEngine
 				ResourceEntry* resEntry = static_cast<ResourceEntry*>(entry);
 				ResourceEntry* resEntry = static_cast<ResourceEntry*>(entry);
 
 
 				if (import)
 				if (import)
-				{
 					reimportResourceInternal(resEntry);
 					reimportResourceInternal(resEntry);
-					queueDependantForReimport(resEntry);
-				}
 
 
 				if (!isUpToDate(resEntry))
 				if (!isUpToDate(resEntry))
 					dirtyResources.push_back(entry->path);
 					dirtyResources.push_back(entry->path);
@@ -223,10 +203,7 @@ namespace BansheeEngine
 							if(existingEntry != nullptr)
 							if(existingEntry != nullptr)
 							{
 							{
 								if (import)
 								if (import)
-								{
 									reimportResourceInternal(existingEntry);
 									reimportResourceInternal(existingEntry);
-									queueDependantForReimport(existingEntry);
-								}
 
 
 								if (!isUpToDate(existingEntry))
 								if (!isUpToDate(existingEntry))
 									dirtyResources.push_back(existingEntry->path);
 									dirtyResources.push_back(existingEntry->path);
@@ -298,7 +275,7 @@ namespace BansheeEngine
 		parent->mChildren.push_back(newResource);
 		parent->mChildren.push_back(newResource);
 
 
 		reimportResourceInternal(newResource, importOptions, forceReimport);
 		reimportResourceInternal(newResource, importOptions, forceReimport);
-		doOnEntryAdded(newResource);
+		onEntryAdded(newResource->path);
 
 
 		return newResource;
 		return newResource;
 	}
 	}
@@ -308,7 +285,7 @@ namespace BansheeEngine
 		DirectoryEntry* newEntry = bs_new<DirectoryEntry>(dirPath, dirPath.getWTail(), parent);
 		DirectoryEntry* newEntry = bs_new<DirectoryEntry>(dirPath, dirPath.getWTail(), parent);
 		parent->mChildren.push_back(newEntry);
 		parent->mChildren.push_back(newEntry);
 
 
-		doOnEntryAdded(newEntry);
+		onEntryAdded(newEntry->path);
 		return newEntry;
 		return newEntry;
 	}
 	}
 
 
@@ -340,8 +317,13 @@ namespace BansheeEngine
 
 
 		parent->mChildren.erase(findIter);
 		parent->mChildren.erase(findIter);
 
 
-		doOnEntryRemoved(resource);
+		Path originalPath = resource->path;
+		onEntryRemoved(originalPath);
+
+		removeDependencies(resource);
 		bs_delete(resource);
 		bs_delete(resource);
+
+		reimportDependants(originalPath);
 	}
 	}
 
 
 	void ProjectLibrary::deleteDirectoryInternal(DirectoryEntry* directory)
 	void ProjectLibrary::deleteDirectoryInternal(DirectoryEntry* directory)
@@ -367,7 +349,7 @@ namespace BansheeEngine
 			parent->mChildren.erase(findIter);
 			parent->mChildren.erase(findIter);
 		}
 		}
 
 
-		doOnEntryRemoved(directory);
+		onEntryRemoved(directory->path);
 		bs_delete(directory);
 		bs_delete(directory);
 	}
 	}
 
 
@@ -466,6 +448,9 @@ namespace BansheeEngine
 			}
 			}
 
 
 			resource->lastUpdateTime = std::time(nullptr);
 			resource->lastUpdateTime = std::time(nullptr);
+
+			onEntryImport(resource->path);
+			reimportDependants(resource->path);
 		}
 		}
 	}
 	}
 
 
@@ -524,7 +509,7 @@ namespace BansheeEngine
 							ResourceEntry* childResEntry = static_cast<ResourceEntry*>(child);
 							ResourceEntry* childResEntry = static_cast<ResourceEntry*>(child);
 							for (auto& typeId : typeIds)
 							for (auto& typeId : typeIds)
 							{
 							{
-								if (childResEntry->meta->getTypeID() == typeId)
+								if (childResEntry->meta != nullptr && childResEntry->meta->getTypeID() == typeId)
 								{
 								{
 									foundEntries.push_back(child);
 									foundEntries.push_back(child);
 									break;
 									break;
@@ -709,7 +694,14 @@ namespace BansheeEngine
 			}
 			}
 			else // Just moving internally
 			else // Just moving internally
 			{
 			{
-				doOnEntryRemoved(oldEntry);
+				onEntryRemoved(oldEntry->path);
+
+				ResourceEntry* resEntry = nullptr;
+				if (oldEntry->type == LibraryEntryType::File)
+				{
+					resEntry = static_cast<ResourceEntry*>(oldEntry);
+					removeDependencies(resEntry);
+				}
 
 
 				if(FileSystem::isFile(oldMetaPath))
 				if(FileSystem::isFile(oldMetaPath))
 					FileSystem::move(oldMetaPath, newMetaPath);
 					FileSystem::move(oldMetaPath, newMetaPath);
@@ -760,7 +752,13 @@ namespace BansheeEngine
 					}
 					}
 				}
 				}
 
 
-				doOnEntryAdded(oldEntry);
+				onEntryAdded(oldEntry->path);
+
+				if (resEntry != nullptr)
+				{
+					reimportDependants(oldFullPath);
+					reimportDependants(newFullPath);
+				}
 			}
 			}
 		}
 		}
 		else // Moving from outside of the Resources folder (likely adding a new resource)
 		else // Moving from outside of the Resources folder (likely adding a new resource)
@@ -813,7 +811,11 @@ namespace BansheeEngine
 			assert(oldEntry->type == LibraryEntryType::File);
 			assert(oldEntry->type == LibraryEntryType::File);
 			ResourceEntry* oldResEntry = static_cast<ResourceEntry*>(oldEntry);
 			ResourceEntry* oldResEntry = static_cast<ResourceEntry*>(oldEntry);
 
 
-			newEntry = addResourceInternal(newEntryParent, newFullPath, oldResEntry->meta->getImportOptions(), true);
+			ImportOptionsPtr importOptions;
+			if (oldResEntry->meta != nullptr)
+				importOptions = oldResEntry->meta->getImportOptions();
+
+			newEntry = addResourceInternal(newEntryParent, newFullPath, importOptions, true);
 		}
 		}
 		else
 		else
 		{
 		{
@@ -843,7 +845,11 @@ namespace BansheeEngine
 					{
 					{
 						ResourceEntry* childResEntry = static_cast<ResourceEntry*>(child);
 						ResourceEntry* childResEntry = static_cast<ResourceEntry*>(child);
 
 
-						addResourceInternal(destDir, childDestPath, childResEntry->meta->getImportOptions(), true);
+						ImportOptionsPtr importOptions;
+						if (childResEntry->meta != nullptr)
+							importOptions = childResEntry->meta->getImportOptions();
+
+						addResourceInternal(destDir, childDestPath, importOptions, true);
 					}
 					}
 					else // Directory
 					else // Directory
 					{
 					{
@@ -885,7 +891,6 @@ namespace BansheeEngine
 			{
 			{
 				ResourceEntry* resEntry = static_cast<ResourceEntry*>(entry);
 				ResourceEntry* resEntry = static_cast<ResourceEntry*>(entry);
 				reimportResourceInternal(resEntry, importOptions, forceReimport);
 				reimportResourceInternal(resEntry, importOptions, forceReimport);
-				queueDependantForReimport(resEntry);
 			}
 			}
 		}
 		}
 	}
 	}
@@ -948,6 +953,9 @@ namespace BansheeEngine
 			return HResource();
 			return HResource();
 
 
 		ResourceEntry* resEntry = static_cast<ResourceEntry*>(entry);
 		ResourceEntry* resEntry = static_cast<ResourceEntry*>(entry);
+		if (resEntry->meta == nullptr)
+			return;
+
 		String resUUID = resEntry->meta->getUUID();
 		String resUUID = resEntry->meta->getUUID();
 
 
 		return gResources().loadFromUUID(resUUID);
 		return gResources().loadFromUUID(resUUID);
@@ -1028,7 +1036,6 @@ namespace BansheeEngine
 		clearEntries();
 		clearEntries();
 		mRootEntry = bs_new<DirectoryEntry>(mResourcesFolder, mResourcesFolder.getWTail(), nullptr);
 		mRootEntry = bs_new<DirectoryEntry>(mResourcesFolder, mResourcesFolder.getWTail(), nullptr);
 
 
-		mReimportQueue.clear();
 		mDependencies.clear();
 		mDependencies.clear();
 		gResources().unregisterResourceManifest(mResourceManifest);
 		gResources().unregisterResourceManifest(mResourceManifest);
 		mResourceManifest = nullptr;
 		mResourceManifest = nullptr;
@@ -1160,7 +1167,6 @@ namespace BansheeEngine
 					
 					
 					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;
@@ -1177,19 +1183,12 @@ namespace BansheeEngine
 									resEntry->meta = resourceMeta;
 									resEntry->meta = resourceMeta;
 								}
 								}
 							}
 							}
-							else
-							{
-								LOGWRN("Missing meta file: " + metaPath.toString() + ". Triggering reimport.");
-								reimportResourceInternal(resEntry);
-								doAddDependencies = false;
-							}
 						}
 						}
 
 
 						if (resEntry->meta != nullptr)
 						if (resEntry->meta != nullptr)
 							mUUIDToPath[resEntry->meta->getUUID()] = resEntry->path;
 							mUUIDToPath[resEntry->meta->getUUID()] = resEntry->path;
 
 
-						if (doAddDependencies)
-							addDependencies(resEntry);
+						addDependencies(resEntry);
 					}
 					}
 					else
 					else
 						deletedEntries.push_back(resEntry);
 						deletedEntries.push_back(resEntry);
@@ -1219,6 +1218,23 @@ namespace BansheeEngine
 			}
 			}
 		}
 		}
 
 
+		// Clean up internal library folder from obsolete files
+		Path internalResourcesFolder = mProjectFolder;
+		internalResourcesFolder.append(INTERNAL_RESOURCES_DIR);
+
+		Vector<Path> toDelete;
+		auto processFile = [&](const Path& file)
+		{
+			String uuid = file.getFilename(false);
+			if (mUUIDToPath.find(uuid) == mUUIDToPath.end())
+				toDelete.push_back(file);
+		};
+
+		FileSystem::iterate(internalResourcesFolder, &processFile);
+
+		for (auto& entry : toDelete)
+			FileSystem::remove(entry);
+
 		mIsLoaded = true;
 		mIsLoaded = true;
 	}
 	}
 
 
@@ -1245,31 +1261,6 @@ namespace BansheeEngine
 		mRootEntry = nullptr;
 		mRootEntry = nullptr;
 	}
 	}
 
 
-	void ProjectLibrary::doOnEntryRemoved(const LibraryEntry* entry)
-	{
-		if (!onEntryRemoved.empty())
-			onEntryRemoved(entry->path);
-
-		if (entry->type == LibraryEntryType::File)
-		{
-			const ResourceEntry* resEntry = static_cast<const ResourceEntry*>(entry);
-			queueDependantForReimport(resEntry);
-			removeDependencies(resEntry);
-		}
-	}
-
-	void ProjectLibrary::doOnEntryAdded(const LibraryEntry* entry)
-	{
-		if (!onEntryAdded.empty())
-			onEntryAdded(entry->path);
-
-		if (entry->type == LibraryEntryType::File)
-		{
-			const ResourceEntry* resEntry = static_cast<const ResourceEntry*>(entry);
-			queueDependantForReimport(resEntry);
-		}
-	}
-
 	Vector<Path> ProjectLibrary::getImportDependencies(const ResourceEntry* entry)
 	Vector<Path> ProjectLibrary::getImportDependencies(const ResourceEntry* entry)
 	{
 	{
 		Vector<Path> output;
 		Vector<Path> output;
@@ -1311,14 +1302,28 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void ProjectLibrary::queueDependantForReimport(const ResourceEntry* entry)
+	void ProjectLibrary::reimportDependants(const Path& entryPath)
 	{
 	{
-		auto iterFind = mDependencies.find(entry->path);
+		auto iterFind = mDependencies.find(entryPath);
 		if (iterFind == mDependencies.end())
 		if (iterFind == mDependencies.end())
 			return;
 			return;
 
 
-		for (auto& dependency : iterFind->second)
-			mReimportQueue.insert(dependency);
+		// Make a copy since we might modify this list during reimport
+		Vector<Path> dependencies = iterFind->second;
+		for (auto& dependency : dependencies)
+		{
+			LibraryEntry* entry = findEntry(dependency);
+			if (entry != nullptr && entry->type == LibraryEntryType::File)
+			{
+				ResourceEntry* resEntry = static_cast<ResourceEntry*>(entry);
+
+				ImportOptionsPtr importOptions;
+				if (resEntry->meta != nullptr)
+					importOptions = resEntry->meta->getImportOptions();
+
+				reimportResourceInternal(resEntry, importOptions, true);
+			}
+		}
 	}
 	}
 
 
 	BS_ED_EXPORT ProjectLibrary& gProjectLibrary()
 	BS_ED_EXPORT ProjectLibrary& gProjectLibrary()

+ 3 - 1
BansheeEditor/Source/BsSelection.cpp

@@ -61,7 +61,9 @@ namespace BansheeEngine
 			if (entry != nullptr && entry->type == ProjectLibrary::LibraryEntryType::File)
 			if (entry != nullptr && entry->type == ProjectLibrary::LibraryEntryType::File)
 			{
 			{
 				ProjectLibrary::ResourceEntry* resEntry = static_cast<ProjectLibrary::ResourceEntry*>(entry);
 				ProjectLibrary::ResourceEntry* resEntry = static_cast<ProjectLibrary::ResourceEntry*>(entry);
-				UUIDs.push_back(resEntry->meta->getUUID());
+
+				if (resEntry->meta != nullptr)
+					UUIDs.push_back(resEntry->meta->getUUID());
 			}
 			}
 		}
 		}
 
 

+ 3 - 1
BansheeEditor/Source/BsShaderIncludeHandler.cpp

@@ -24,7 +24,9 @@ namespace BansheeEngine
 		if (entry != nullptr && entry->type == ProjectLibrary::LibraryEntryType::File)
 		if (entry != nullptr && entry->type == ProjectLibrary::LibraryEntryType::File)
 		{
 		{
 			ProjectLibrary::ResourceEntry* resEntry = static_cast<ProjectLibrary::ResourceEntry*>(entry);
 			ProjectLibrary::ResourceEntry* resEntry = static_cast<ProjectLibrary::ResourceEntry*>(entry);
-			return static_resource_cast<ShaderInclude>(Resources::instance().loadFromUUID(resEntry->meta->getUUID()));
+
+			if (resEntry->meta != nullptr)
+				return static_resource_cast<ShaderInclude>(Resources::instance().loadFromUUID(resEntry->meta->getUUID()));
 		}
 		}
 
 
 		return HShaderInclude();
 		return HShaderInclude();

+ 6 - 0
SBansheeEditor/Source/BsEditorResourceLoader.cpp

@@ -14,6 +14,12 @@ namespace BansheeEngine
 			return HResource();
 			return HResource();
 
 
 		ProjectLibrary::ResourceEntry* resEntry = static_cast<ProjectLibrary::ResourceEntry*>(entry);
 		ProjectLibrary::ResourceEntry* resEntry = static_cast<ProjectLibrary::ResourceEntry*>(entry);
+		if (resEntry->meta == nullptr)
+		{
+			LOGWRN("Missing .meta file for resource at path: \"" + path.toString() + "\".");
+			return HResource();
+		}
+
 		String resUUID = resEntry->meta->getUUID();
 		String resUUID = resEntry->meta->getUUID();
 
 
 		if (resEntry->meta->getIncludeInBuild())
 		if (resEntry->meta->getIncludeInBuild())

+ 3 - 0
SBansheeEditor/Source/BsGUIResourceField.cpp

@@ -278,6 +278,9 @@ namespace BansheeEngine
 			ProjectLibrary::ResourceEntry* resEntry = static_cast<ProjectLibrary::ResourceEntry*>(libEntry);
 			ProjectLibrary::ResourceEntry* resEntry = static_cast<ProjectLibrary::ResourceEntry*>(libEntry);
 
 
 			ProjectResourceMetaPtr meta = resEntry->meta;
 			ProjectResourceMetaPtr meta = resEntry->meta;
+			if (meta == nullptr)
+				continue;
+
 			UINT32 typeId = meta->getTypeID();
 			UINT32 typeId = meta->getTypeID();
 			String uuid = meta->getUUID();
 			String uuid = meta->getUUID();
 
 

+ 1 - 1
SBansheeEditor/Source/BsScriptEditorApplication.cpp

@@ -173,7 +173,7 @@ namespace BansheeEngine
 				return nullptr;
 				return nullptr;
 
 
 			ProjectLibrary::ResourceEntry* resEntry = static_cast<ProjectLibrary::ResourceEntry*>(entry);
 			ProjectLibrary::ResourceEntry* resEntry = static_cast<ProjectLibrary::ResourceEntry*>(entry);
-			if (resEntry->meta->getTypeID() != TID_Prefab)
+			if (resEntry->meta == nullptr || resEntry->meta->getTypeID() != TID_Prefab)
 				return nullptr;
 				return nullptr;
 
 
 			scene = static_resource_cast<Prefab>(gProjectLibrary().load(nativePath));
 			scene = static_resource_cast<Prefab>(gProjectLibrary().load(nativePath));

+ 3 - 1
SBansheeEditor/Source/BsScriptProjectLibrary.cpp

@@ -91,7 +91,9 @@ namespace BansheeEngine
 		if (entry != nullptr && entry->type == ProjectLibrary::LibraryEntryType::File)
 		if (entry != nullptr && entry->type == ProjectLibrary::LibraryEntryType::File)
 		{
 		{
 			ProjectLibrary::ResourceEntry* resEntry = static_cast <ProjectLibrary::ResourceEntry*>(entry);
 			ProjectLibrary::ResourceEntry* resEntry = static_cast <ProjectLibrary::ResourceEntry*>(entry);
-			resource = gResources().loadFromUUID(resEntry->meta->getUUID());
+
+			if (resEntry->meta != nullptr)
+				resource = gResources().loadFromUUID(resEntry->meta->getUUID());
 		}
 		}
 		
 		
 		if (!resource)
 		if (!resource)

+ 1 - 7
TODOExperimentation.txt

@@ -13,13 +13,7 @@ Assign ViewOrigin, PreViewTranslation, TransViewProj
  - Perhaps do all these modifcations outside of shader (i.e. have the world matrix be pre-transformed)
  - Perhaps do all these modifcations outside of shader (i.e. have the world matrix be pre-transformed)
  - Do this after I have basic rendering working, to avoid additional issues when I'm initially trying to get it to work
  - Do this after I have basic rendering working, to avoid additional issues when I'm initially trying to get it to work
  
  
- - Finish RenderAPI::generateParamBlockDesc
-   - DX11 and OpenGL have different packing rules:
-   - https://msdn.microsoft.com/en-us/library/windows/desktop/bb509632(v=vs.85).aspx
-   - https://www.safaribooksonline.com/library/view/opengl-programming-guide/9780132748445/app09lev1sec3.html
- - Replace param buffer generation by using a dummy shader with manual generation
-   - Test if this works on all rendder APIs (initially dont delete the old code so I can compare offsets)
-    - Problem with DX9, parameters seem to be in different order, plus block buffer size is 4 instead of 52 (for perCamera buffer)
+Replace param buffer generation by using a dummy shader with manual generation
 
 
 Next week:
 Next week:
  - Deferred base and light passes use different PerCamera buffers, unify them (both in shader and in code)
  - Deferred base and light passes use different PerCamera buffers, unify them (both in shader and in code)