Explorar o código

More resource ref changes

Marko Pintera %!s(int64=13) %!d(string=hai) anos
pai
achega
5c1037f02c

+ 7 - 9
CamelotRenderer/Include/CmResourceRef.h

@@ -1,7 +1,6 @@
 #pragma once
 #pragma once
 
 
 #include "CmIReflectable.h"
 #include "CmIReflectable.h"
-#include <atomic>
 
 
 template<class _Ty>
 template<class _Ty>
 struct CM_Bool_struct
 struct CM_Bool_struct
@@ -17,13 +16,12 @@ namespace CamelotEngine
 	struct CM_EXPORT ResourceRefData : public IReflectable
 	struct CM_EXPORT ResourceRefData : public IReflectable
 	{
 	{
 		ResourceRefData()
 		ResourceRefData()
-		{
-			mIsResolved.store(false);
-		}
+			:mIsResolved(false)
+		{ }
 
 
 		std::shared_ptr<Resource> mPtr;
 		std::shared_ptr<Resource> mPtr;
 		String mUUID;
 		String mUUID;
-		std::atomic_bool mIsResolved; // TODO Low priority. I might not need an atomic here. Volatile bool should do.
+		bool mIsResolved;
 
 
 		/************************************************************************/
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/* 								RTTI		                     		*/
@@ -40,7 +38,7 @@ namespace CamelotEngine
 		/**
 		/**
 		 * @brief	Checks if the resource is loaded
 		 * @brief	Checks if the resource is loaded
 		 */
 		 */
-		bool isResolved() { return mData->mIsResolved.load(); }
+		bool isResolved() const { return mData->mIsResolved; }
 
 
 	protected:
 	protected:
 		ResourceRefBase();
 		ResourceRefBase();
@@ -105,17 +103,17 @@ namespace CamelotEngine
 		}
 		}
 
 
 		// TODO Low priority - User can currently try to access these even if resource ptr is not resolved
 		// TODO Low priority - User can currently try to access these even if resource ptr is not resolved
-		T* get() const { return static_cast<T*>(mData->mPtr.get()); }
+		T* get() const { if(!isResolved()) return nullptr; return static_cast<T*>(mData->mPtr.get()); }
 		T* operator->() const { return get(); }
 		T* operator->() const { return get(); }
 		T& operator*() const { return *get(); }
 		T& operator*() const { return *get(); }
 
 
-		std::shared_ptr<T> getInternalPtr() { return std::static_pointer_cast<T>(mData->mPtr); }
+		std::shared_ptr<T> getInternalPtr() { if(!isResolved()) return nullptr; return std::static_pointer_cast<T>(mData->mPtr); }
 
 
 		// Conversion to bool
 		// Conversion to bool
 		// (Why not just directly convert to bool? Because then we can assign pointer to bool and that's weird)
 		// (Why not just directly convert to bool? Because then we can assign pointer to bool and that's weird)
 		operator int CM_Bool_struct<T>::*() const
 		operator int CM_Bool_struct<T>::*() const
 		{
 		{
-			return (mData->mPtr.get() != 0 ? &CM_Bool_struct<T>::_Member : 0);
+			return ((isResolved() && (mData->mPtr.get() != 0)) ? &CM_Bool_struct<T>::_Member : 0);
 		}
 		}
 	};
 	};
 
 

+ 18 - 0
CamelotRenderer/Include/CmResources.h

@@ -64,6 +64,14 @@ namespace CamelotEngine
 		 */
 		 */
 		BaseResourceRef load(const String& filePath);
 		BaseResourceRef load(const String& filePath);
 
 
+		/**
+		 * @brief	Loads the resource asynchronously. Initially returned resource should not be used
+		 * 			until BaseResourceRef.isResolved gets set to true. (Set only at the end of each frame)
+		 *
+		 * @param	filePath	Full pathname of the file.
+		 * 						
+		 * @return	Resource where the data will eventually be loaded, or null if the file cannot be found.
+		 */
 		BaseResourceRef loadAsync(const String& filePath);
 		BaseResourceRef loadAsync(const String& filePath);
 
 
 		/**
 		/**
@@ -75,6 +83,16 @@ namespace CamelotEngine
 		 */
 		 */
 		BaseResourceRef loadFromUUID(const String& uuid);
 		BaseResourceRef loadFromUUID(const String& uuid);
 
 
+		/**
+		* @brief	Loads the resource with the given UUID asynchronously. Initially returned resource should not be used
+		* 			until BaseResourceRef.isResolved gets set to true. (Set only at the end of each frame)
+		 *
+		 * @param	uuid	UUID of the resource to load. 
+		 *
+		 * @return	Resource where the data will eventually be loaded, or null if the file cannot be found.
+		 */
+		BaseResourceRef loadFromUUIDAsync(const String& uuid);
+
 		/**
 		/**
 		 * @brief	Saves the resource. Resource must be registered using Resources::create beforehand.
 		 * @brief	Saves the resource. Resource must be registered using Resources::create beforehand.
 		 *
 		 *

+ 1 - 1
CamelotRenderer/Source/CmResourceRef.cpp

@@ -38,7 +38,7 @@ namespace CamelotEngine
 		if(mData->mPtr)
 		if(mData->mPtr)
 		{
 		{
 			mData->mUUID = mData->mPtr->getUUID();
 			mData->mUUID = mData->mPtr->getUUID();
-			mData->mIsResolved.store(true); 
+			mData->mIsResolved = true; 
 		}
 		}
 	}
 	}
 
 

+ 33 - 10
CamelotRenderer/Source/CmResources.cpp

@@ -107,18 +107,28 @@ namespace CamelotEngine
 
 
 		// TODO - Low priority. Check is file path valid?
 		// TODO - Low priority. Check is file path valid?
 
 
-		BaseResourceRef resource = loadInternal(filePath);
-		resource->init();
+		//BaseResourceRef resource = loadInternal(filePath);
+		//resource->init();
+
+		//// TODO - This should probably be called in loadInternal, but it isn't thread safe
+		////        - loadAsync never calls this code and it should
+		//if(!metaExists_UUID(resource->getUUID()))
+		//{
+		//	gDebug().logWarning("Loading a resource that doesn't have meta-data. Creating meta-data automatically. Resource path: " + filePath);
+		//	addMetaData(resource->getUUID(), filePath);
+		//}
+
+		//return resource;
+		
+		BaseResourceRef newResource;
 
 
-		// TODO - This should probably be called in loadInternal, but it isn't thread safe
-		//        - loadAsync never calls this code and it should
-		if(!metaExists_UUID(resource->getUUID()))
-		{
-			gDebug().logWarning("Loading a resource that doesn't have meta-data. Creating meta-data automatically. Resource path: " + filePath);
-			addMetaData(resource->getUUID(), filePath);
-		}
+		ResourceLoadRequestPtr resRequest = ResourceLoadRequestPtr(new Resources::ResourceLoadRequest());
+		resRequest->filePath = filePath;
+		resRequest->resource = newResource;
 
 
-		return resource;
+		mWorkQueue->addRequest(mWorkQueueChannel, resRequest, 0, true);
+
+		return newResource;
 	}
 	}
 
 
 	BaseResourceRef Resources::loadAsync(const String& filePath)
 	BaseResourceRef Resources::loadAsync(const String& filePath)
@@ -149,6 +159,19 @@ namespace CamelotEngine
 		return load(metaEntry->mPath);
 		return load(metaEntry->mPath);
 	}
 	}
 
 
+	BaseResourceRef Resources::loadFromUUIDAsync(const String& uuid)
+	{
+		if(!metaExists_UUID(uuid))
+		{
+			gDebug().logWarning("Cannot load resource. Resource with UUID '" + uuid + "' doesn't exist.");
+			return nullptr;
+		}
+
+		ResourceMetaDataPtr metaEntry = mResourceMetaData[uuid];
+
+		return loadAsync(metaEntry->mPath);
+	}
+
 	ResourcePtr Resources::loadInternal(const String& filePath)
 	ResourcePtr Resources::loadInternal(const String& filePath)
 	{
 	{
 		FileSerializer fs;
 		FileSerializer fs;