Quellcode durchsuchen

Resource handle refactor (part 3)
- Working on managed ResourceRef

BearishSun vor 10 Jahren
Ursprung
Commit
e24c1c9270

+ 3 - 3
BansheeEngine/Include/BsSpriteTextureRTTI.h

@@ -26,18 +26,18 @@ namespace BansheeEngine
 			addPlainField("mUVScale", 2, &SpriteTextureRTTI::getUVScale, &SpriteTextureRTTI::setUVScale);
 		}
 
-		virtual const String& getRTTIName()
+		virtual const String& getRTTIName() override
 		{
 			static String name = "SpriteTexture";
 			return name;
 		}
 
-		virtual UINT32 getRTTIId()
+		virtual UINT32 getRTTIId() override
 		{
 			return TID_SpriteTexture;
 		}
 
-		virtual std::shared_ptr<IReflectable> newRTTIObject()
+		virtual std::shared_ptr<IReflectable> newRTTIObject() override
 		{
 			return SpriteTexture::createEmpty();
 		}

+ 1 - 0
MBansheeEngine/MBansheeEngine.csproj

@@ -121,6 +121,7 @@
     <Compile Include="RenderTexture.cs" />
     <Compile Include="RenderTexture2D.cs" />
     <Compile Include="Resource.cs" />
+    <Compile Include="ResourceRef.cs" />
     <Compile Include="Resources.cs" />
     <Compile Include="RunInEditor.cs" />
     <Compile Include="Scene.cs" />

+ 41 - 0
MBansheeEngine/ResourceRef.cs

@@ -0,0 +1,41 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace BansheeEngine
+{
+    /// <summary>
+    /// Allows you to store a reference to a resource without needing to have that resource loaded.
+    /// </summary>
+    public class ResourceRef<T> : ScriptObject where T : Resource
+    {
+        /// <summary>
+        /// Constructor for internal use only.
+        /// </summary>
+        private ResourceRef()
+        { }
+
+        /// <summary>
+        /// Checks is the referenced resource loaded
+        /// </summary>
+        public bool IsLoaded
+        {
+            get { return Internal_IsLoaded(mCachedPtr); }
+        }
+
+        /// <summary>
+        /// Retrieves the referenced resource. This will load the resources if it is not already loaded.
+        /// </summary>
+        /// <typeparam name="T">Type of the resource to load.</typeparam>
+        /// <returns>Loaded resource object.</returns>
+        public T Get()
+        {
+            return (T)Internal_GetResource(mCachedPtr);
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_IsLoaded(IntPtr thisPtr);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern Resource Internal_GetResource(IntPtr thisPtr);
+    }
+}

+ 6 - 123
SBansheeEditor/Source/BsGUIResourceField.cpp

@@ -17,20 +17,6 @@
 #include "BsProjectResourceMeta.h"
 #include "BsManagedResourceMetaData.h"
 #include "BsBuiltinEditorResources.h"
-#include "BsScriptTexture2D.h"
-#include "BsScriptTexture3D.h"
-#include "BsScriptTextureCube.h"
-#include "BsScriptSpriteTexture.h"
-#include "BsScriptMaterial.h"
-#include "BsScriptMesh.h"
-#include "BsScriptFont.h"
-#include "BsScriptShader.h"
-#include "BsScriptShaderInclude.h"
-#include "BsScriptPlainText.h"
-#include "BsScriptScriptCode.h"
-#include "BsScriptStringTable.h"
-#include "BsScriptGUISkin.h"
-#include "BsScriptPrefab.h"
 #include "BsScriptManagedResource.h"
 #include "BsSelection.h"
 
@@ -286,119 +272,16 @@ namespace BansheeEngine
 			String uuid = meta->getUUID();
 
 			bool found = false;
-			switch (typeId)
+			MonoClass* scriptClass = ScriptResource::getClassFromTypeId(typeId);
+			if (scriptClass != nullptr)
 			{
-			case TID_Texture:
-			{
-				// TODO - Need to distinguish from 2D/3D/Cube
-				if (ScriptTexture2D::getMetaData()->scriptClass->isSubClassOf(acceptedClass) ||
-					ScriptTexture3D::getMetaData()->scriptClass->isSubClassOf(acceptedClass) ||
-					ScriptTextureCube::getMetaData()->scriptClass->isSubClassOf(acceptedClass))
-				{
-					setUUID(uuid);
-					found = true;
-				}
-			}
-				break;
-			case TID_SpriteTexture:
-			{
-				if (ScriptSpriteTexture::getMetaData()->scriptClass->isSubClassOf(acceptedClass))
-				{
-					setUUID(uuid);
-					found = true;
-				}
-			}
-				break;
-			case TID_Font:
-			{
-				if (ScriptFont::getMetaData()->scriptClass->isSubClassOf(acceptedClass))
-				{
-					setUUID(uuid);
-					found = true;
-				}
-			}
-				break;
-			case TID_PlainText:
-			{
-				if (ScriptPlainText::getMetaData()->scriptClass->isSubClassOf(acceptedClass))
-				{
-					setUUID(uuid);
-					found = true;
-				}
-			}
-				break;
-			case TID_ScriptCode:
-			{
-				if (ScriptScriptCode::getMetaData()->scriptClass->isSubClassOf(acceptedClass))
-				{
-					setUUID(uuid);
-					found = true;
-				}
-			}
-				break;
-			case TID_Shader:
-			{
-				if (ScriptShader::getMetaData()->scriptClass->isSubClassOf(acceptedClass))
+				if (scriptClass->isSubClassOf(acceptedClass))
 				{
 					setUUID(uuid);
 					found = true;
 				}
 			}
-				break;
-			case TID_ShaderInclude:
-			{
-				if (ScriptShaderInclude::getMetaData()->scriptClass->isSubClassOf(acceptedClass))
-				{
-					setUUID(uuid);
-					found = true;
-				}
-			}
-			break;
-			case TID_Material:
-			{
-				if (ScriptMaterial::getMetaData()->scriptClass->isSubClassOf(acceptedClass))
-				{
-					setUUID(uuid);
-					found = true;
-				}
-			}
-				break;
-			case TID_Mesh:
-			{
-				if (ScriptMesh::getMetaData()->scriptClass->isSubClassOf(acceptedClass))
-				{
-					setUUID(uuid);
-					found = true;
-				}
-			}
-				break;
-			case TID_Prefab:
-			{
-				if (ScriptPrefab::getMetaData()->scriptClass->isSubClassOf(acceptedClass))
-				{
-					setUUID(uuid);
-					found = true;
-				}
-			}
-			case TID_StringTable:
-			{
-				if (ScriptStringTable::getMetaData()->scriptClass->isSubClassOf(acceptedClass))
-				{
-					setUUID(uuid);
-					found = true;
-				}
-			}
-				break;
-			case TID_GUISkin:
-			{
-				if (ScriptGUISkin::getMetaData()->scriptClass->isSubClassOf(acceptedClass))
-				{
-					setUUID(uuid);
-					found = true;
-				}
-			}
-				break;
-			case TID_ManagedResource:
+			else if (typeId == TID_ManagedResource)
 			{
 				ManagedResourceMetaDataPtr managedResMetaData = std::static_pointer_cast<ManagedResourceMetaData>(meta->getResourceMetaData());
 				MonoClass* providedClass = MonoManager::instance().findClass(managedResMetaData->typeNamespace, managedResMetaData->typeName);
@@ -409,8 +292,8 @@ namespace BansheeEngine
 					found = true;
 				}
 			}
-				break;
-			default:
+			else
+			{
 				BS_EXCEPT(NotImplementedException, "Unsupported resource type added to resource field.");
 			}
 

+ 1 - 0
SBansheeEngine/Include/BsScriptEnginePrerequisites.h

@@ -25,6 +25,7 @@ namespace BansheeEngine
 	class ScriptResourceBase;
 	class ScriptFont;
 	class ScriptSpriteTexture;
+	class ScriptShaderInclude;
 	class ScriptTexture2D;
 	class ScriptTexture3D;
 	class ScriptTextureCube;

+ 5 - 0
SBansheeEngine/Include/BsScriptResource.h

@@ -149,6 +149,11 @@ namespace BansheeEngine
 		 * @brief	Converts a ScriptResourceType into a RTTI id belonging to that resource type.
 		 */
 		static UINT32 getTypeIdFromType(ScriptResourceType type);
+
+		/**
+		 * @brief	Converts a RTTI id belonging to a resource type into a managed class representing that type.
+		 */
+		static MonoClass* ScriptResource::getClassFromTypeId(UINT32 typeId);
 	private:
 		ScriptResource(MonoObject* instance)
 			:ScriptObject(instance)

+ 34 - 0
SBansheeEngine/Include/BsScriptResourceRef.h

@@ -0,0 +1,34 @@
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+#include "BsScriptObject.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * @brief	Interop class between C++ & CLR for ResourceRef.
+	 */
+	class BS_SCR_BE_EXPORT ScriptResourceRef : public ScriptObject<ScriptResourceRef>
+	{
+	public:
+		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "ResourceRef`1")
+
+		/**
+		 * @brief	Creates a new managed ResourceRef for the provided resource type.
+		 *
+		 * @param	typeId	RTTI type ID of the resource to reference.
+		 */
+		static MonoObject* create(UINT32 typeId);
+
+	private:
+		ScriptResourceRef(MonoObject* instance, const WeakResourceHandle<Resource>& resource);
+
+		WeakResourceHandle<Resource> mResource;
+
+		/************************************************************************/
+		/* 								CLR HOOKS						   		*/
+		/************************************************************************/
+		static bool internal_IsLoaded(ScriptResourceRef* nativeInstance);
+		static MonoObject* internal_GetResource(ScriptResourceRef* nativeInstance);
+	};
+}

+ 2 - 0
SBansheeEngine/SBansheeEngine.vcxproj

@@ -330,6 +330,7 @@
     <ClInclude Include="Include\BsScriptRenderTexture2D.h" />
     <ClInclude Include="Include\BsScriptResource.h" />
     <ClInclude Include="Include\BsScriptResourceManager.h" />
+    <ClInclude Include="Include\BsScriptResourceRef.h" />
     <ClInclude Include="Include\BsScriptResources.h" />
     <ClInclude Include="Include\BsScriptScene.h" />
     <ClInclude Include="Include\BsScriptSceneObject.h" />
@@ -428,6 +429,7 @@
     <ClCompile Include="Source\BsScriptRenderTexture2D.cpp" />
     <ClCompile Include="Source\BsScriptResource.cpp" />
     <ClCompile Include="Source\BsScriptResourceManager.cpp" />
+    <ClCompile Include="Source\BsScriptResourceRef.cpp" />
     <ClCompile Include="Source\BsScriptResources.cpp" />
     <ClCompile Include="Source\BsScriptScene.cpp" />
     <ClCompile Include="Source\BsScriptSceneObject.cpp" />

+ 6 - 0
SBansheeEngine/SBansheeEngine.vcxproj.filters

@@ -360,6 +360,9 @@
     <ClInclude Include="Include\BsPlayInEditorManager.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsScriptResourceRef.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsScriptTexture2D.cpp">
@@ -659,5 +662,8 @@
     <ClCompile Include="Source\BsPlayInEditorManager.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsScriptResourceRef.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 48 - 0
SBansheeEngine/Source/BsScriptResource.cpp

@@ -2,6 +2,20 @@
 #include "BsScriptResourceManager.h"
 #include "BsResource.h"
 #include "BsMonoUtil.h"
+#include "BsScriptTexture2D.h"
+#include "BsScriptTexture3D.h"
+#include "BsScriptTextureCube.h"
+#include "BsScriptSpriteTexture.h"
+#include "BsScriptMaterial.h"
+#include "BsScriptMesh.h"
+#include "BsScriptFont.h"
+#include "BsScriptShader.h"
+#include "BsScriptShaderInclude.h"
+#include "BsScriptPlainText.h"
+#include "BsScriptScriptCode.h"
+#include "BsScriptStringTable.h"
+#include "BsScriptGUISkin.h"
+#include "BsScriptPrefab.h"
 
 namespace BansheeEngine
 {
@@ -37,6 +51,40 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_GetUUID", &ScriptResource::internal_getUUID);
 	}
 
+	MonoClass* ScriptResource::getClassFromTypeId(UINT32 typeId)
+	{
+		switch (typeId)
+		{
+		case TID_Texture:
+			// TODO - Need to distinguish from 2D/3D/Cube
+			return ScriptTexture2D::getMetaData()->scriptClass;
+		case TID_SpriteTexture:
+			return ScriptSpriteTexture::getMetaData()->scriptClass;
+		case TID_Font:
+			return ScriptFont::getMetaData()->scriptClass;
+		case TID_PlainText:
+			return ScriptPlainText::getMetaData()->scriptClass;
+		case TID_ScriptCode:
+			return ScriptScriptCode::getMetaData()->scriptClass;
+		case TID_Shader:
+			return ScriptShader::getMetaData()->scriptClass;
+		case TID_ShaderInclude:
+			return ScriptShaderInclude::getMetaData()->scriptClass;
+		case TID_Material:
+			return ScriptMaterial::getMetaData()->scriptClass;
+		case TID_Mesh:
+			return ScriptMesh::getMetaData()->scriptClass;
+		case TID_Prefab:
+			return ScriptPrefab::getMetaData()->scriptClass;
+		case TID_StringTable:
+			return ScriptStringTable::getMetaData()->scriptClass;
+		case TID_GUISkin:
+			return ScriptGUISkin::getMetaData()->scriptClass;
+		}
+
+		return nullptr;
+	}
+
 	ScriptResourceType ScriptResource::getTypeFromTypeId(UINT32 typeId)
 	{
 		switch (typeId)

+ 56 - 0
SBansheeEngine/Source/BsScriptResourceRef.cpp

@@ -0,0 +1,56 @@
+#include "BsScriptResourceRef.h"
+#include "BsScriptMeta.h"
+#include "BsMonoField.h"
+#include "BsMonoClass.h"
+#include "BsMonoManager.h"
+#include "BsMonoUtil.h"
+#include "BsResources.h"
+#include "BsScriptResource.h"
+#include "BsScriptResourceManager.h"
+
+namespace BansheeEngine
+{
+	ScriptResourceRef::ScriptResourceRef(MonoObject* instance, const WeakResourceHandle<Resource>& resource)
+		:ScriptObject(instance), mResource(resource)
+	{ }
+
+	void ScriptResourceRef::initRuntimeData()
+	{
+		metaData.scriptClass->addInternalCall("Internal_IsLoaded", &ScriptResourceRef::internal_IsLoaded);
+		metaData.scriptClass->addInternalCall("Internal_GetResource", &ScriptResourceRef::internal_GetResource);
+	}
+
+	MonoObject* ScriptResourceRef::create(UINT32 typeId)
+	{
+		MonoClass* resourceClass = ScriptResource::getClassFromTypeId(typeId);
+		if (resourceClass == nullptr)
+			return nullptr;
+
+		MonoType* genParams[1] = { mono_class_get_type(resourceClass->_getInternalClass()) };
+
+		::MonoClass* resourceRefClass = mono_class_bind_generic_parameters(metaData.scriptClass->_getInternalClass(), 1, genParams, false);
+		MonoObject* obj = mono_object_new(MonoManager::instance().getDomain(), resourceRefClass);
+		mono_runtime_object_init(obj);
+
+		WeakResourceHandle<Resource> emptyHandle;
+		ScriptResourceRef* scriptResourceRef = new (bs_alloc<ScriptResourceRef>()) ScriptResourceRef(obj, emptyHandle);
+
+		return obj;
+	}
+
+	bool ScriptResourceRef::internal_IsLoaded(ScriptResourceRef* nativeInstance)
+	{
+		return nativeInstance->mResource.isLoaded(false);
+	}
+
+	MonoObject* ScriptResourceRef::internal_GetResource(ScriptResourceRef* nativeInstance)
+	{
+		HResource resource = gResources().load(nativeInstance->mResource);
+		ScriptResourceBase* scriptResource;
+
+		ScriptResourceManager::instance().getScriptResource(resource, &scriptResource, true);
+
+		return scriptResource->getManagedInstance();
+	}
+}
+