Ver código fonte

Added ManagedResource and improve project library and resource meta data management

Marko Pintera 11 anos atrás
pai
commit
a35f11d8cc

+ 2 - 1
BansheeCore/Include/BsCorePrerequisites.h

@@ -299,7 +299,8 @@ namespace BansheeEngine
 		TID_ResourceManifestEntry = 1068,
 		TID_EmulatedParamBlock = 1069,
 		TID_TextureImportOptions = 1070,
-		TID_ResourceMetaData = 1071
+		TID_ResourceMetaData = 1071,
+		TID_GpuProgramInclude = 1072
 	};
 }
 

+ 1 - 0
BansheeCore/Include/BsResourceRTTI.h

@@ -3,6 +3,7 @@
 #include "BsCorePrerequisites.h"
 #include "BsRTTIType.h"
 #include "BsResource.h"
+#include "BsResourceMetaData.h"
 
 namespace BansheeEngine
 {

+ 1 - 1
BansheeEditor/Include/BsEditorPrerequisites.h

@@ -68,7 +68,7 @@ namespace BansheeEngine
 
 	enum TypeID_BansheeEditor
 	{
-		TID_ResourceMeta = 40000,
+		TID_ProjectResourceMeta = 40000,
 		TID_ProjectLibraryEntries = 40001,
 		TID_ProjectLibraryResEntry = 40002,
 		TID_ProjectLibraryDirEntry = 40003,

+ 1 - 1
BansheeEditor/Include/BsProjectLibrary.h

@@ -6,7 +6,7 @@
 
 namespace BansheeEngine
 {
-	class ProjectLibrary : public Module<ProjectLibrary>
+	class BS_ED_EXPORT ProjectLibrary : public Module<ProjectLibrary>
 	{
 	public:
 		struct LibraryEntry;

+ 4 - 2
BansheeEditor/Include/BsProjectResourceMeta.h

@@ -13,17 +13,19 @@ namespace BansheeEngine
 	public:
 		explicit ProjectResourceMeta(const ConstructPrivately&);
 
-		static ProjectResourceMetaPtr create(const String& uuid, const ResourceMetaDataPtr& resourceMetaData,
+		static ProjectResourceMetaPtr create(const String& uuid, UINT32 typeId, const ResourceMetaDataPtr& resourceMetaData,
 			const ImportOptionsPtr& importOptions);
 
 		const String& getUUID() const { return mUUID; }
 		ResourceMetaDataPtr getResourceMetaData() const { return mResourceMeta; }
 		const ImportOptionsPtr& getImportOptions() const { return mImportOptions; }
+		UINT32 getTypeID() const { return mTypeId; }
 
 	private:
 		String mUUID;
 		ResourceMetaDataPtr mResourceMeta;
 		ImportOptionsPtr mImportOptions;
+		UINT32 mTypeId;
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/
@@ -31,7 +33,7 @@ namespace BansheeEngine
 		static ProjectResourceMetaPtr createEmpty();
 
 	public:
-		friend class ResourceMetaRTTI;
+		friend class ProjectResourceMetaRTTI;
 		static RTTITypeBase* getRTTIStatic();
 		virtual RTTITypeBase* getRTTI() const;	
 	};

+ 11 - 7
BansheeEditor/Include/BsProjectResourceMetaRTTI.h

@@ -8,12 +8,15 @@
 
 namespace BansheeEngine
 {
-	class ResourceMetaRTTI : public RTTIType<ProjectResourceMeta, IReflectable, ResourceMetaRTTI>
+	class ProjectResourceMetaRTTI : public RTTIType<ProjectResourceMeta, IReflectable, ProjectResourceMetaRTTI>
 	{
 	private:
 		String& getUUID(ProjectResourceMeta* obj) { return obj->mUUID; }
 		void setUUID(ProjectResourceMeta* obj, String& val) { obj->mUUID = val; } 
 
+		UINT32& getTypeId(ProjectResourceMeta* obj) { return obj->mTypeId; }
+		void setTypeId(ProjectResourceMeta* obj, UINT32& val) { obj->mTypeId = val; }
+
 		ResourceMetaDataPtr getResourceMeta(ProjectResourceMeta* obj) { return obj->mResourceMeta; }
 		void setResourceMeta(ProjectResourceMeta* obj, ResourceMetaDataPtr val) { obj->mResourceMeta = val; }
 
@@ -21,22 +24,23 @@ namespace BansheeEngine
 		void setImportOptions(ProjectResourceMeta* obj, ImportOptionsPtr val) { obj->mImportOptions = val; }
 
 	public:
-		ResourceMetaRTTI()
+		ProjectResourceMetaRTTI()
 		{
-			addPlainField("mUUID", 0, &ResourceMetaRTTI::getUUID, &ResourceMetaRTTI::setUUID);
-			addReflectablePtrField("mImportOptions", 1, &ResourceMetaRTTI::getImportOptions, &ResourceMetaRTTI::setImportOptions);
-			addReflectablePtrField("mResourceMeta", 2, &ResourceMetaRTTI::getResourceMeta, &ResourceMetaRTTI::setResourceMeta);
+			addPlainField("mUUID", 0, &ProjectResourceMetaRTTI::getUUID, &ProjectResourceMetaRTTI::setUUID);
+			addReflectablePtrField("mImportOptions", 1, &ProjectResourceMetaRTTI::getImportOptions, &ProjectResourceMetaRTTI::setImportOptions);
+			addReflectablePtrField("mResourceMeta", 2, &ProjectResourceMetaRTTI::getResourceMeta, &ProjectResourceMetaRTTI::setResourceMeta);
+			addPlainField("mTypeId", 3, &ProjectResourceMetaRTTI::getTypeId, &ProjectResourceMetaRTTI::setTypeId);
 		}
 
 		virtual const String& getRTTIName()
 		{
-			static String name = "ResourceMeta";
+			static String name = "ProjectResourceMeta";
 			return name;
 		}
 
 		virtual UINT32 getRTTIId()
 		{
-			return TID_ResourceMeta;
+			return TID_ProjectResourceMeta;
 		}
 
 		virtual std::shared_ptr<IReflectable> newRTTIObject()

+ 2 - 1
BansheeEditor/Source/BsProjectLibrary.cpp

@@ -379,8 +379,9 @@ namespace BansheeEngine
 				importedResource = Importer::instance().import(resource->path, importOptions);
 
 				ResourceMetaDataPtr subMeta = importedResource->getMetaData();
+				UINT32 typeId = importedResource->getTypeId();
 
-				resource->meta = ProjectResourceMeta::create(importedResource.getUUID(), subMeta, importOptions);
+				resource->meta = ProjectResourceMeta::create(importedResource.getUUID(), typeId, subMeta, importOptions);
 				FileSerializer fs;
 				fs.encode(resource->meta.get(), metaPath);
 			}

+ 3 - 2
BansheeEditor/Source/BsProjectResourceMeta.cpp

@@ -8,11 +8,12 @@ namespace BansheeEngine
 
 	}
 
-	ProjectResourceMetaPtr ProjectResourceMeta::create(const String& uuid, const ResourceMetaDataPtr& resourceMetaData, 
+	ProjectResourceMetaPtr ProjectResourceMeta::create(const String& uuid, UINT32 typeId, const ResourceMetaDataPtr& resourceMetaData,
 		const ImportOptionsPtr& importOptions)
 	{
 		ProjectResourceMetaPtr meta = bs_shared_ptr<ProjectResourceMeta>(ConstructPrivately());
 		meta->mUUID = uuid;
+		meta->mTypeId = typeId;
 		meta->mResourceMeta = resourceMetaData;
 		meta->mImportOptions = importOptions;
 
@@ -30,7 +31,7 @@ namespace BansheeEngine
 
 	RTTITypeBase* ProjectResourceMeta::getRTTIStatic()
 	{
-		return ResourceMetaRTTI::instance();
+		return ProjectResourceMetaRTTI::instance();
 	}
 
 	RTTITypeBase* ProjectResourceMeta::getRTTI() const

+ 8 - 3
Inspector.txt

@@ -1,9 +1,14 @@
 Update C# GUIElementStyle
 Update GUIFoldout with sub styles
 
-GUIResourceField needs to be able to check resource type without loading it
- - I need this for ProjectLibrary too (so I can display valid icons in TreeView)
- - But I need a more exact version since resources could be custom C# classes (This will likely need to be supported in some special way)
+ManagedResource class is unfinished. Need to clean up managed instance after resource is released.
+Its getMetaData should return managed type of the stored resource
+Update GUIResourceField so it uses meta data for detecting valid type
+
+How will I create ManagedResource from C#?
+ - BansheeEditor::ProjectLibrary::create(obj, path)
+ - This call C++ with the managed instance. Object is checked if it is Serializable
+ - If so it is serialized using ManagedSerializableObjectPtr
 
 TODO:
  - Hook up int field set/get callbacks

+ 1 - 0
MBansheeEditor/MBansheeEditor.csproj

@@ -66,6 +66,7 @@
     <Compile Include="Inspector\Inspector.cs" />
     <Compile Include="Inspector\InspectorWindow.cs" />
     <Compile Include="Program.cs" />
+    <Compile Include="ProjectLibrary.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
   <ItemGroup>

+ 31 - 0
MBansheeEditor/ProjectLibrary.cs

@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    public sealed class ProjectLibrary
+    {
+        public static void Create(Resource resource, string path)
+        {
+            Internal_Create(resource, path);
+        }
+
+        // TODO - Will also need (at least):
+        // - GetPath
+        // - Reimport
+        // - Load
+        // - Move
+        // - Rename
+        // - Delete
+        // - Copy
+        // - CreateFolder
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_Create(Resource resource, string path);
+    }
+}

+ 19 - 0
SBansheeEditor/Include/BsScriptProjectLibrary.h

@@ -0,0 +1,19 @@
+#pragma once
+
+#include "BsScriptEditorPrerequisites.h"
+#include "BsScriptObject.h"
+#include "BsStringTable.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BED_EXPORT ScriptProjectLibrary : public ScriptObject<ScriptProjectLibrary>
+	{
+	public:
+		SCRIPT_OBJ(BansheeEditorAssemblyName, "BansheeEditor", "ProjectLibrary")
+
+	private:
+		static void internal_Create(MonoObject* resource, MonoString* path);
+
+		ScriptProjectLibrary(MonoObject* instance);
+	};
+}

+ 2 - 0
SBansheeEditor/SBansheeEditor.vcxproj

@@ -243,6 +243,7 @@
     <ClInclude Include="Include\BsScriptGUIVector2Field.h" />
     <ClInclude Include="Include\BsScriptGUIVector3Field.h" />
     <ClInclude Include="Include\BsScriptGUIVector4Field.h" />
+    <ClInclude Include="Include\BsScriptProjectLibrary.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsGUIGameObjectField.cpp" />
@@ -262,6 +263,7 @@
     <ClCompile Include="Source\BsScriptGUIVector2Field.cpp" />
     <ClCompile Include="Source\BsScriptGUIVector3Field.cpp" />
     <ClCompile Include="Source\BsScriptGUIVector4Field.cpp" />
+    <ClCompile Include="Source\BsScriptProjectLibrary.cpp" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">

+ 6 - 0
SBansheeEditor/SBansheeEditor.vcxproj.filters

@@ -66,6 +66,9 @@
     <ClInclude Include="Include\BsScriptGUIResourceField.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsScriptProjectLibrary.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsScriptEditorPlugin.cpp">
@@ -119,5 +122,8 @@
     <ClCompile Include="Source\BsScriptGUIResourceField.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsScriptProjectLibrary.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 50 - 1
SBansheeEditor/Source/BsGUIResourceField.cpp

@@ -14,6 +14,8 @@
 #include "BsMonoClass.h"
 #include "BsResources.h"
 #include "BsProjectLibrary.h"
+#include "BsProjectResourceMeta.h"
+#include "BsManagedResourceMetaData.h"
 #include "BsEditorGUI.h"
 
 using namespace std::placeholders;
@@ -205,7 +207,54 @@ namespace BansheeEngine
 
 		for (UINT32 i = 0; i < numResources; i++)
 		{
-			// TODO - I need to be able to check resource type without loading it
+			String uuid = draggedResources->resourceUUIDs[i];
+
+			ProjectResourceMetaPtr meta = ProjectLibrary::instance().findResourceMeta(uuid);
+			if (meta == nullptr)
+				continue;
+
+			bool found = false;
+			UINT32 typeId = meta->getTypeID();
+			switch (typeId)
+			{
+			case TID_Texture:
+			{
+				const String& texTypeName = RuntimeScriptObjects::instance().getTextureClass()->getFullName();
+				if (texTypeName == mType)
+				{
+					setUUID(uuid);
+					found = true;
+				}
+			}
+				break;
+			case TID_SpriteTexture:
+			{
+				const String& spriteTexTypeName = RuntimeScriptObjects::instance().getSpriteTextureClass()->getFullName();
+				if (spriteTexTypeName == mType)
+				{
+					setUUID(uuid);
+					found = true;
+				}
+			}
+				break;
+			case TID_ManagedResource:
+			{
+				ManagedResourceMetaDataPtr managedResMetaData = std::static_pointer_cast<ManagedResourceMetaData>(meta->getResourceMetaData());
+				String fullTypeName = managedResMetaData->typeNamespace + "." + managedResMetaData->typeName;
+
+				if (fullTypeName == mType)
+				{
+					setUUID(uuid);
+					found = true;
+				}
+			}
+				break;
+			default:
+				BS_EXCEPT(NotImplementedException, "Unsupported resource type added to resource field.");
+			}
+
+			if (found)
+				break;
 		}
 	}
 

+ 28 - 0
SBansheeEditor/Source/BsScriptProjectLibrary.cpp

@@ -0,0 +1,28 @@
+#include "BsScriptProjectLibrary.h"
+#include "BsScriptMeta.h"
+#include "BsMonoField.h"
+#include "BsMonoClass.h"
+#include "BsMonoManager.h"
+#include "BsMonoUtil.h"
+#include "BsProjectLibrary.h"
+#include "BsScriptResource.h"
+
+namespace BansheeEngine
+{
+	ScriptProjectLibrary::ScriptProjectLibrary(MonoObject* instance)
+		:ScriptObject(instance)
+	{ }
+
+	void ScriptProjectLibrary::initRuntimeData()
+	{
+		metaData.scriptClass->addInternalCall("Internal_Create", &ScriptProjectLibrary::internal_Create);
+	}
+
+	void ScriptProjectLibrary::internal_Create(MonoObject* resource, MonoString* path)
+	{
+		ScriptResource* scrResource = ScriptResource::toNative(resource);
+		Path resourcePath = MonoUtil::monoToWString(path);
+
+		//ProjectLibrary::instance().create(scrResource->getNativeHandle(), resourcePath);
+	}
+}

+ 39 - 0
SBansheeEngine/Include/BsManagedResource.h

@@ -0,0 +1,39 @@
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+#include "BsResource.h"
+#include <mono/jit/jit.h>
+#include <mono/metadata/object.h>
+
+namespace BansheeEngine
+{
+	class BS_SCR_BE_EXPORT ManagedResource : public Resource
+	{
+	public:
+		ManagedResource(MonoReflectionType* runtimeType);
+		void construct(MonoObject* object, MonoReflectionType* runtimeType);
+
+		MonoObject* getManagedInstance() const { return mManagedInstance; }
+		MonoReflectionType* getRuntimeType() const { return mRuntimeType; }
+
+		static ManagedResourcePtr createEmpty();
+
+	private:
+		void destroy_internal();
+
+		MonoObject* mManagedInstance;
+		MonoReflectionType* mRuntimeType;
+		uint32_t mManagedHandle;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+	public:
+		friend class ManagedResourceRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const;
+
+	protected:
+		ManagedResource() {} // Serialization only
+	};
+}

+ 22 - 0
SBansheeEngine/Include/BsManagedResourceMetaData.h

@@ -0,0 +1,22 @@
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+#include "BsResourceMetaData.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BE_EXPORT ManagedResourceMetaData : public ResourceMetaData
+	{
+	public:
+		String typeNamespace;
+		String typeName;
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	public:
+		friend class ManagedResourceMetaDataRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const;
+	};
+}

+ 55 - 0
SBansheeEngine/Include/BsManagedResourceMetaDataRTTI.h

@@ -0,0 +1,55 @@
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsManagedResourceMetaData.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BE_EXPORT ManagedResourceMetaDataRTTI : public RTTIType<ManagedResourceMetaData, ResourceMetaData, ManagedResourceMetaDataRTTI>
+	{
+	private:
+		String& getNamespace(ManagedResourceMetaData* obj)
+		{
+			return obj->typeNamespace;
+		}
+
+		void setNamespace(ManagedResourceMetaData* obj, String& val)
+		{
+			obj->typeNamespace = val;
+		}
+
+		String& getTypename(ManagedResourceMetaData* obj)
+		{
+			return obj->typeName;
+		}
+
+		void setTypename(ManagedResourceMetaData* obj, String& val)
+		{
+			obj->typeName = val;
+		}
+
+	public:
+		ManagedResourceMetaDataRTTI()
+		{
+			addPlainField("mTypeNamespace", 0, &ManagedResourceMetaDataRTTI::getNamespace, &ManagedResourceMetaDataRTTI::setNamespace);
+			addPlainField("mTypeName", 1, &ManagedResourceMetaDataRTTI::getTypename, &ManagedResourceMetaDataRTTI::setTypename);
+		}
+
+		virtual const String& getRTTIName()
+		{
+			static String name = "ManagedResourceMetaData";
+			return name;
+		}
+
+		virtual UINT32 getRTTIId()
+		{
+			return TID_ManagedResourceMetaData;
+		}
+
+		virtual std::shared_ptr<IReflectable> newRTTIObject()
+		{
+			return bs_shared_ptr<ManagedResourceMetaData>();
+		}
+	};
+}

+ 66 - 0
SBansheeEngine/Include/BsManagedResourceRTTI.h

@@ -0,0 +1,66 @@
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsResourceRTTI.h"
+#include "BsManagedResource.h"
+#include "BsMonoManager.h"
+#include "BsManagedSerializableObject.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BE_EXPORT ManagedResourceRTTI : public RTTIType<ManagedResource, Resource, ManagedResourceRTTI>
+	{
+	private:
+		ManagedSerializableObjectPtr getObjectData(ManagedResource* obj)
+		{
+			return any_cast<ManagedSerializableObjectPtr>(obj->mRTTIData);
+		}
+
+		void setObjectData(ManagedResource* obj, ManagedSerializableObjectPtr val)
+		{
+			obj->mRTTIData = val;
+		}
+
+	public:
+		ManagedResourceRTTI()
+		{
+			addReflectablePtrField("mObjectData", 0, &ManagedResourceRTTI::getObjectData, &ManagedResourceRTTI::setObjectData);
+		}
+
+		void onSerializationStarted(IReflectable* obj)
+		{
+			ManagedResource* mc = static_cast<ManagedResource*>(obj);
+
+			mc->mRTTIData = ManagedSerializableObject::create(mc->getManagedInstance());
+		}
+
+		virtual void onDeserializationStarted(IReflectable* obj)
+		{
+			ManagedResource* mc = static_cast<ManagedResource*>(obj);
+			ManagedSerializableObjectPtr serializableObject = any_cast<ManagedSerializableObjectPtr>(mc->mRTTIData);
+
+			::MonoClass* monoClass = mono_object_get_class(serializableObject->getManagedInstance());
+			MonoType* monoType = mono_class_get_type(monoClass);
+			MonoReflectionType* runtimeType = mono_type_get_object(MonoManager::instance().getDomain(), monoType);
+
+			mc->construct(serializableObject->getManagedInstance(), runtimeType);
+		}
+
+		virtual const String& getRTTIName()
+		{
+			static String name = "ManagedResource";
+			return name;
+		}
+
+		virtual UINT32 getRTTIId()
+		{
+			return TID_ManagedResource;
+		}
+
+		virtual std::shared_ptr<IReflectable> newRTTIObject()
+		{
+			return ManagedResource::createEmpty();
+		}
+	};
+}

+ 7 - 0
SBansheeEngine/Include/BsScriptEnginePrerequisites.h

@@ -51,8 +51,11 @@ namespace BansheeEngine
 	class ManagedSerializableAssemblyInfo;
 	class ManagedSerializableObjectInfo;
 	class ManagedSerializableFieldInfo;
+	class ManagedResource;
+	class ManagedResourceMetaData;
 
 	typedef GameObjectHandle<ManagedComponent> HManagedComponent;
+	typedef ResourceHandle<ManagedResource> HManagedResource;
 
 	enum TypeID_BansheeScript
 	{
@@ -92,6 +95,8 @@ namespace BansheeEngine
 		TID_SerializableTypeInfoDictionary = 50034,
 		TID_ScriptSerializableList = 50035,
 		TID_ScriptSerializableDictionary = 50036,
+		TID_ManagedResource = 50037,
+		TID_ManagedResourceMetaData = 50038
 	};
 
 	static const char* BansheeEngineAssemblyName = "MBansheeEngine";
@@ -111,4 +116,6 @@ namespace BansheeEngine
 	typedef std::shared_ptr<ManagedSerializableTypeInfoArray> ManagedSerializableTypeInfoArrayPtr;
 	typedef std::shared_ptr<ManagedSerializableTypeInfoList> ManagedSerializableTypeInfoListPtr;
 	typedef std::shared_ptr<ManagedSerializableTypeInfoDictionary> ManagedSerializableTypeInfoDictionaryPtr;
+	typedef std::shared_ptr<ManagedResource> ManagedResourcePtr;
+	typedef std::shared_ptr<ManagedResourceMetaData> ManagedResourceMetaDataPtr;
 }

+ 6 - 0
SBansheeEngine/SBansheeEngine.vcxproj

@@ -228,6 +228,10 @@
   <ItemGroup>
     <ClInclude Include="Include\BsManagedComponent.h" />
     <ClInclude Include="Include\BsManagedComponentRTTI.h" />
+    <ClInclude Include="Include\BsManagedResource.h" />
+    <ClInclude Include="Include\BsManagedResourceMetaData.h" />
+    <ClInclude Include="Include\BsManagedResourceMetaDataRTTI.h" />
+    <ClInclude Include="Include\BsManagedResourceRTTI.h" />
     <ClInclude Include="Include\BsManagedSerializableArray.h" />
     <ClInclude Include="Include\BsManagedSerializableArrayRTTI.h" />
     <ClInclude Include="Include\BsManagedSerializableDictionary.h" />
@@ -282,6 +286,8 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsManagedComponent.cpp" />
+    <ClCompile Include="Source\BsManagedResource.cpp" />
+    <ClCompile Include="Source\BsManagedResourceMetaData.cpp" />
     <ClCompile Include="Source\BsRuntimeScriptObjects.cpp" />
     <ClCompile Include="Source\BsScriptComponent.cpp" />
     <ClCompile Include="Source\BsScriptDebug.cpp" />

+ 24 - 3
SBansheeEngine/SBansheeEngine.vcxproj.filters

@@ -28,6 +28,9 @@
     <Filter Include="Header Files\Serialization\RTTI">
       <UniqueIdentifier>{3225801f-fe74-4e07-aa59-37ad5d5ac1da}</UniqueIdentifier>
     </Filter>
+    <Filter Include="Header Files\RTTI">
+      <UniqueIdentifier>{cff4d9c9-b006-4675-a58e-6a0e449ff8d5}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Include\BsScriptFont.h">
@@ -60,9 +63,6 @@
     <ClInclude Include="Include\BsScriptComponent.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="Include\BsManagedComponentRTTI.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="Include\BsScriptResource.h">
       <Filter>Header Files</Filter>
     </ClInclude>
@@ -189,6 +189,21 @@
     <ClInclude Include="Include\BsScriptGUILayoutUtility.h">
       <Filter>Header Files\GUI</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsManagedResource.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsManagedResourceMetaData.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsManagedComponentRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsManagedResourceRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsManagedResourceMetaDataRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsScriptTexture2D.cpp">
@@ -320,5 +335,11 @@
     <ClCompile Include="Source\BsScriptGUILayoutUtility.cpp">
       <Filter>Source Files\GUI</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsManagedResource.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsManagedResourceMetaData.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 68 - 0
SBansheeEngine/Source/BsManagedResource.cpp

@@ -0,0 +1,68 @@
+#include "BsManagedResource.h"
+#include "BsManagedResourceRTTI.h"
+#include "BsManagedResourceMetaData.h"
+#include "BsMonoManager.h"
+#include "BsMonoClass.h"
+#include "BsDebug.h"
+
+namespace BansheeEngine
+{
+	ManagedResource::ManagedResource(MonoReflectionType* runtimeType)
+		:mManagedInstance(nullptr), mRuntimeType(runtimeType)
+	{
+		ManagedResourceMetaDataPtr metaData = bs_shared_ptr<ManagedResourceMetaData>();
+		mMetaData = metaData;
+
+		MonoType* monoType = mono_reflection_type_get_type(mRuntimeType);
+		::MonoClass* monoClass = mono_type_get_class(monoType);
+
+		metaData->typeNamespace = mono_class_get_namespace(monoClass);
+		metaData->typeName = mono_class_get_name(monoClass);
+
+		MonoClass* managedClass = MonoManager::instance().findClass(metaData->typeNamespace, metaData->typeName);
+		if (managedClass == nullptr)
+		{
+			LOGWRN("Cannot create managed component: " + metaData->typeNamespace + "." + metaData->typeName + " because that type doesn't exist.");
+			return;
+		}
+
+		construct(managedClass->createInstance(), runtimeType);
+	}
+
+	ManagedResourcePtr ManagedResource::createEmpty()
+	{
+		ManagedResourcePtr newRes = bs_core_ptr<ManagedResource, GenAlloc>(new (bs_alloc<ManagedResource>()) ManagedResource());
+		newRes->_setThisPtr(newRes);
+		newRes->initialize();
+
+		return newRes;
+	}
+
+	void ManagedResource::construct(MonoObject* object, MonoReflectionType* runtimeType)
+	{
+		mManagedInstance = object;
+		mRuntimeType = runtimeType;
+		mManagedHandle = mono_gchandle_new(mManagedInstance, false);
+	}
+
+	void ManagedResource::destroy_internal()
+	{
+		Resource::destroy_internal();
+
+		if (mManagedInstance != nullptr)
+		{
+			mManagedInstance = nullptr;
+			mono_gchandle_free(mManagedHandle);
+		}
+	}
+
+	RTTITypeBase* ManagedResource::getRTTIStatic()
+	{
+		return ManagedResourceRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedResource::getRTTI() const
+	{
+		return ManagedResource::getRTTIStatic();
+	}
+}

+ 15 - 0
SBansheeEngine/Source/BsManagedResourceMetaData.cpp

@@ -0,0 +1,15 @@
+#include "BsManagedResourceMetaData.h"
+#include "BsManagedResourceMetaDataRTTI.h"
+
+namespace BansheeEngine
+{
+	RTTITypeBase* ManagedResourceMetaData::getRTTIStatic()
+	{
+		return ManagedResourceMetaDataRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedResourceMetaData::getRTTI() const
+	{
+		return ManagedResourceMetaData::getRTTIStatic();
+	}
+}