Forráskód Böngészése

Refactored managed serialization so that reference types (resources and game objects) store their exact type even for non-built-in types

BearishSun 9 éve
szülő
commit
208a2c3402

+ 51 - 19
Source/SBansheeEngine/Include/BsManagedSerializableObjectInfo.h

@@ -28,25 +28,31 @@ namespace BansheeEngine
 		Float,
 		Double,
 		String,
-		Texture2DRef,
-		Texture3DRef,
-		TextureCubeRef,
-		SpriteTextureRef,
-		ManagedResourceRef,
-		PlainTextRef,
-		ScriptCodeRef,
-		ShaderRef,
-		ShaderIncludeRef,
-		MaterialRef,
-		MeshRef,
-		PrefabRef,
-		FontRef,
-		StringTableRef,
-		GUISkinRef,
-		SceneObjectRef,
-		ComponentRef,
-		PhysicsMaterialRef,
-		PhysicsMeshRef,
+		Count // Keep at end
+	};
+
+	/** Valid reference script types. */
+	enum class ScriptReferenceType
+	{
+		Texture2D,
+		Texture3D,
+		TextureCube,
+		SpriteTexture,
+		ManagedResource,
+		PlainText,
+		ScriptCode,
+		Shader,
+		ShaderInclude,
+		Material,
+		Mesh,
+		Prefab,
+		Font,
+		StringTable,
+		GUISkin,
+		SceneObject,
+		Component,
+		PhysicsMaterial,
+		PhysicsMesh,
 		Count // Keep at end
 	};
 
@@ -111,6 +117,32 @@ namespace BansheeEngine
 		virtual RTTITypeBase* getRTTI() const override;
 	};
 
+	/**	Contains information about a type of a managed serializable game object or resource reference. */
+	class BS_SCR_BE_EXPORT ManagedSerializableTypeInfoRef : public ManagedSerializableTypeInfo
+	{
+	public:
+		/** @copydoc ManagedSerializableTypeInfo::matches */
+		bool matches(const ManagedSerializableTypeInfoPtr& typeInfo) const override;
+
+		/** @copydoc ManagedSerializableTypeInfo::isTypeLoaded */
+		bool isTypeLoaded() const override;
+
+		/** @copydoc ManagedSerializableTypeInfo::getMonoClass */
+		::MonoClass* getMonoClass() const override;
+
+		ScriptReferenceType mType;
+		String mTypeNamespace;
+		String mTypeName;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+	public:
+		friend class ManagedSerializableTypeInfoRefRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;
+	};
+
 	/**	Contains information about a type of a managed serializable complex object (for example struct or class). */
 	class BS_SCR_BE_EXPORT ManagedSerializableTypeInfoObject : public ManagedSerializableTypeInfo
 	{

+ 58 - 0
Source/SBansheeEngine/Include/BsManagedSerializableObjectInfoRTTI.h

@@ -283,6 +283,64 @@ namespace BansheeEngine
 		}
 	};
 
+	class BS_SCR_BE_EXPORT ManagedSerializableTypeInfoRefRTTI : public RTTIType<ManagedSerializableTypeInfoRef, ManagedSerializableTypeInfo, ManagedSerializableTypeInfoRefRTTI>
+	{
+	private:
+		ScriptReferenceType& getType(ManagedSerializableTypeInfoRef* obj)
+		{
+			return obj->mType;
+		}
+
+		void setType(ManagedSerializableTypeInfoRef* obj, ScriptReferenceType& val)
+		{
+			obj->mType = val;
+		}
+
+		String& getTypeNamespace(ManagedSerializableTypeInfoRef* obj)
+		{
+			return obj->mTypeNamespace;
+		}
+
+		void setTypeNamespace(ManagedSerializableTypeInfoRef* obj, String& val)
+		{
+			obj->mTypeNamespace = val;
+		}
+
+		String& getTypeName(ManagedSerializableTypeInfoRef* obj)
+		{
+			return obj->mTypeName;
+		}
+
+		void setTypeName(ManagedSerializableTypeInfoRef* obj, String& val)
+		{
+			obj->mTypeName = val;
+		}
+
+	public:
+		ManagedSerializableTypeInfoRefRTTI()
+		{
+			addPlainField("mType", 0, &ManagedSerializableTypeInfoRefRTTI::getType, &ManagedSerializableTypeInfoRefRTTI::setType);
+			addPlainField("mTypeName", 1, &ManagedSerializableTypeInfoRefRTTI::getTypeName, &ManagedSerializableTypeInfoRefRTTI::setTypeName);
+			addPlainField("mTypeNamespace", 2, &ManagedSerializableTypeInfoRefRTTI::getTypeNamespace, &ManagedSerializableTypeInfoRefRTTI::setTypeNamespace);
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "ScriptSerializableTypeInfoRef";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_SerializableTypeInfoRef;
+		}
+
+		std::shared_ptr<IReflectable> newRTTIObject() override
+		{
+			return bs_shared_ptr_new<ManagedSerializableTypeInfoRef>();
+		}
+	};
+
 	class BS_SCR_BE_EXPORT ManagedSerializableTypeInfoObjectRTTI : public RTTIType<ManagedSerializableTypeInfoObject, ManagedSerializableTypeInfo, ManagedSerializableTypeInfoObjectRTTI>
 	{
 	private:

+ 2 - 1
Source/SBansheeEngine/Include/BsScriptEnginePrerequisites.h

@@ -156,7 +156,8 @@ namespace BansheeEngine
 		TID_ScriptModifiedField = 50046,
 		TID_ScriptModifiedArrayEntry = 50047,
 		TID_ScriptModifiedDictionaryEntry = 50048,
-		TID_ScriptSerializableDictionaryKeyValue = 50049
+		TID_ScriptSerializableDictionaryKeyValue = 50049,
+		TID_SerializableTypeInfoRef = 50050
 	};
 
 	typedef std::shared_ptr<ManagedSerializableFieldData> ManagedSerializableFieldDataPtr;

+ 1362 - 1355
Source/SBansheeEngine/Source/BsManagedSerializableField.cpp

@@ -1,1356 +1,1363 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#include "BsManagedSerializableField.h"
-#include "BsManagedSerializableObjectInfo.h"
-#include "BsManagedSerializableFieldRTTI.h"
-#include "BsMonoUtil.h"
-#include "BsMonoManager.h"
-#include "BsScriptResourceManager.h"
-#include "BsScriptGameObjectManager.h"
-#include "BsScriptTexture2D.h"
-#include "BsScriptTexture3D.h"
-#include "BsScriptTextureCube.h"
-#include "BsScriptSpriteTexture.h"
-#include "BsScriptManagedResource.h"
-#include "BsScriptPlainText.h"
-#include "BsScriptScriptCode.h"
-#include "BsScriptShader.h"
-#include "BsScriptShaderInclude.h"
-#include "BsScriptMaterial.h"
-#include "BsScriptMesh.h"
-#include "BsScriptPrefab.h"
-#include "BsScriptFont.h"
-#include "BsScriptStringTable.h"
-#include "BsScriptGUISkin.h"
-#include "BsScriptPhysicsMaterial.h"
-#include "BsScriptPhysicsMesh.h"
-#include "BsScriptSceneObject.h"
-#include "BsScriptComponent.h"
-#include "BsManagedSerializableObject.h"
-#include "BsManagedSerializableArray.h"
-#include "BsManagedSerializableList.h"
-#include "BsManagedSerializableDictionary.h"
-
-namespace BansheeEngine
-{
-	template<class T>
-	bool compareFieldData(const T* a, const ManagedSerializableFieldDataPtr& b)
-	{
-		if (rtti_is_of_type<T>(b))
-		{
-			auto castObj = std::static_pointer_cast<T>(b);
-			return a->value == castObj->value;
-		}
-
-		return false;
-	}
-
-	ManagedSerializableFieldKey::ManagedSerializableFieldKey()
-		:mTypeId(0), mFieldId(0)
-	{ }
-
-	ManagedSerializableFieldKey::ManagedSerializableFieldKey(UINT16 typeId, UINT16 fieldId)
-		:mTypeId(typeId), mFieldId(fieldId)
-	{ }
-
-	ManagedSerializableFieldKeyPtr ManagedSerializableFieldKey::create(UINT16 typeId, UINT16 fieldId)
-	{
-		ManagedSerializableFieldKeyPtr fieldKey = bs_shared_ptr_new<ManagedSerializableFieldKey>(typeId, fieldId);
-		return fieldKey;
-	}
-
-	ManagedSerializableFieldDataEntryPtr ManagedSerializableFieldDataEntry::create(const ManagedSerializableFieldKeyPtr& key, const ManagedSerializableFieldDataPtr& value)
-	{
-		ManagedSerializableFieldDataEntryPtr fieldDataEntry = bs_shared_ptr_new<ManagedSerializableFieldDataEntry>();
-		fieldDataEntry->mKey = key;
-		fieldDataEntry->mValue = value;
-
-		return fieldDataEntry;
-	}
-
-	ManagedSerializableFieldDataPtr ManagedSerializableFieldData::create(const ManagedSerializableTypeInfoPtr& typeInfo, MonoObject* value)
-	{
-		return create(typeInfo, value, true);
-	}
-
-	ManagedSerializableFieldDataPtr ManagedSerializableFieldData::createDefault(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		return create(typeInfo, nullptr, false);
-	}
-
-	template<class ResType, class ScriptType>
-	MonoObject* getScriptResource(const HResource& value)
-	{
-		ResourceHandle<ResType> castValue = static_resource_cast<ResType>(value);
-		if (castValue.isLoaded())
-		{
-			ScriptType* scriptResource;
-			ScriptResourceManager::instance().getScriptResource(castValue, &scriptResource, true);
-
-			return scriptResource->getManagedInstance();
-		}
-		else
-			return nullptr;
-	}
-
-	template<class ScriptType>
-	ManagedSerializableFieldDataPtr setScriptResource(MonoObject* value)
-	{
-		auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataResourceRef>();
-
-		if (value != nullptr)
-		{
-			ScriptType* scriptResource = ScriptType::toNative(value);
-			fieldData->value = scriptResource->getHandle();
-		}
-
-		return fieldData;
-	}
-
-	struct ResourceFieldDataAccessors
-	{
-		std::function<MonoObject*(const HResource&)> getter;
-		std::function<ManagedSerializableFieldDataPtr(MonoObject*)> setter;
-	};
-
-	ResourceFieldDataAccessors* getResourceFieldLookup()
-	{
-		static ResourceFieldDataAccessors lookup[(int)ScriptPrimitiveType::Count];
-		static bool initialized = false;
-
-		if(!initialized)
-		{
-			lookup[(int)ScriptPrimitiveType::Texture2DRef] =
-				{ &getScriptResource<Texture, ScriptTexture2D>, &setScriptResource<ScriptTexture2D> };
-
-			lookup[(int)ScriptPrimitiveType::Texture3DRef] =
-				{ &getScriptResource<Texture, ScriptTexture3D>, &setScriptResource<ScriptTexture3D> };
-
-			lookup[(int)ScriptPrimitiveType::TextureCubeRef] =
-				{ &getScriptResource<Texture, ScriptTextureCube>, &setScriptResource<ScriptTextureCube> };
-
-			lookup[(int)ScriptPrimitiveType::SpriteTextureRef] =
-				{ &getScriptResource<SpriteTexture, ScriptSpriteTexture>, &setScriptResource<ScriptSpriteTexture> };
-
-			lookup[(int)ScriptPrimitiveType::ShaderRef] =
-				{ &getScriptResource<Shader, ScriptShader>, &setScriptResource<ScriptShader> };
-
-			lookup[(int)ScriptPrimitiveType::ShaderIncludeRef] =
-				{ &getScriptResource<ShaderInclude, ScriptShaderInclude>, &setScriptResource<ScriptShaderInclude> };
-
-			lookup[(int)ScriptPrimitiveType::MaterialRef] =
-				{ &getScriptResource<Material, ScriptMaterial>, &setScriptResource<ScriptMaterial> };
-
-			lookup[(int)ScriptPrimitiveType::MeshRef] =
-				{ &getScriptResource<Mesh, ScriptMesh>, &setScriptResource<ScriptMesh> };
-
-			lookup[(int)ScriptPrimitiveType::PrefabRef] =
-				{ &getScriptResource<Prefab, ScriptPrefab>, &setScriptResource<ScriptPrefab> };
-
-			lookup[(int)ScriptPrimitiveType::FontRef] =
-				{ &getScriptResource<Font, ScriptFont>, &setScriptResource<ScriptFont> };
-
-			lookup[(int)ScriptPrimitiveType::StringTableRef] =
-				{ &getScriptResource<StringTable, ScriptStringTable>, &setScriptResource<ScriptStringTable> };
-
-			lookup[(int)ScriptPrimitiveType::GUISkinRef] =
-				{ &getScriptResource<GUISkin, ScriptGUISkin>, &setScriptResource<ScriptGUISkin> };
-
-			lookup[(int)ScriptPrimitiveType::PhysicsMaterialRef] =
-				{ &getScriptResource<PhysicsMaterial, ScriptPhysicsMaterial>, &setScriptResource<ScriptPhysicsMaterial> };
-
-			lookup[(int)ScriptPrimitiveType::PhysicsMeshRef] =
-				{ &getScriptResource<PhysicsMesh, ScriptPhysicsMesh>, &setScriptResource<ScriptPhysicsMesh> };
-
-			lookup[(int)ScriptPrimitiveType::ManagedResourceRef] =
-				{ &getScriptResource<ManagedResource, ScriptManagedResource>, &setScriptResource<ScriptManagedResource> };
-
-			lookup[(int)ScriptPrimitiveType::PlainTextRef] =
-				{ &getScriptResource<PlainText, ScriptPlainText>, &setScriptResource<ScriptPlainText> };
-
-			lookup[(int)ScriptPrimitiveType::ScriptCodeRef] =
-				{ &getScriptResource<ScriptCode, ScriptScriptCode>, &setScriptResource<ScriptScriptCode> };
-		}
-
-		return lookup;
-	}
-
-	ManagedSerializableFieldDataPtr ManagedSerializableFieldData::create(const ManagedSerializableTypeInfoPtr& typeInfo, MonoObject* value, bool allowNull)
-	{
-		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			switch (primitiveTypeInfo->mType)
-			{
-			case ScriptPrimitiveType::Bool:
-				{
-					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataBool>();
-					if(value != nullptr)
-						memcpy(&fieldData->value, mono_object_unbox(value), sizeof(fieldData->value));
-
-					return fieldData;
-				}
-			case ScriptPrimitiveType::Char:
-				{
-					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataChar>();
-					if(value != nullptr)
-						memcpy(&fieldData->value, mono_object_unbox(value), sizeof(fieldData->value));
-
-					return fieldData;
-				}
-			case ScriptPrimitiveType::I8:
-				{
-					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataI8>();
-					if(value != nullptr)
-						memcpy(&fieldData->value, mono_object_unbox(value), sizeof(fieldData->value));
-
-					return fieldData;
-				}
-			case ScriptPrimitiveType::U8:
-				{
-					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataU8>();
-					if(value != nullptr)
-						memcpy(&fieldData->value, mono_object_unbox(value), sizeof(fieldData->value));
-
-					return fieldData;
-				}
-			case ScriptPrimitiveType::I16:
-				{
-					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataI16>();
-					if(value != nullptr)
-						memcpy(&fieldData->value, mono_object_unbox(value), sizeof(fieldData->value));
-
-					return fieldData;
-				}
-			case ScriptPrimitiveType::U16:
-				{
-					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataU16>();
-					if(value != nullptr)
-						memcpy(&fieldData->value, mono_object_unbox(value), sizeof(fieldData->value));
-
-					return fieldData;
-				}
-			case ScriptPrimitiveType::I32:
-				{
-					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataI32>();
-					if(value != nullptr)
-						memcpy(&fieldData->value, mono_object_unbox(value), sizeof(fieldData->value));
-
-					return fieldData;
-				}
-			case ScriptPrimitiveType::U32:
-				{
-					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataU32>();
-					if(value != nullptr)
-						memcpy(&fieldData->value, mono_object_unbox(value), sizeof(fieldData->value));
-
-					return fieldData;
-				}
-			case ScriptPrimitiveType::I64:
-				{
-					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataI64>();
-					if(value != nullptr)
-						memcpy(&fieldData->value, mono_object_unbox(value), sizeof(fieldData->value));
-
-					return fieldData;
-				}
-			case ScriptPrimitiveType::U64:
-				{
-					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataU64>();
-					if(value != nullptr)
-						memcpy(&fieldData->value, mono_object_unbox(value), sizeof(fieldData->value));
-
-					return fieldData;
-				}
-			case ScriptPrimitiveType::Float:
-				{
-					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataFloat>();
-					if(value != nullptr)
-						memcpy(&fieldData->value, mono_object_unbox(value), sizeof(fieldData->value));
-
-					return fieldData;
-				}
-			case ScriptPrimitiveType::Double:
-				{
-					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataDouble>();
-					if(value != nullptr)
-						memcpy(&fieldData->value, mono_object_unbox(value), sizeof(fieldData->value));
-
-					return fieldData;
-				}
-			case ScriptPrimitiveType::String:
-				{
-					MonoString* strVal = (MonoString*)(value);
-
-					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataString>();
-					if (strVal != nullptr)
-						fieldData->value = MonoUtil::monoToWString(strVal);
-					else
-						fieldData->isNull = allowNull;
-
-					return fieldData;
-				}
-			case ScriptPrimitiveType::SceneObjectRef:
-				{
-					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataGameObjectRef>();
-
-					if(value != nullptr)
-					{
-						ScriptSceneObject* scriptSceneObject = ScriptSceneObject::toNative(value);
-						fieldData->value = static_object_cast<SceneObject>(scriptSceneObject->getNativeHandle());
-					}
-
-					return fieldData;
-				}
-			case ScriptPrimitiveType::ComponentRef:
-				{
-					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataGameObjectRef>();
-
-					if(value != nullptr)
-					{
-						ScriptComponent* scriptComponent = ScriptComponent::toNative(value);
-						fieldData->value = static_object_cast<Component>(scriptComponent->getNativeHandle());
-					}
-
-					return fieldData;
-				}
-			default:
-				// Must be a resource
-				return getResourceFieldLookup()[(int)primitiveTypeInfo->mType].setter(value);
-			}
-		}
-		else if(typeInfo->getTypeId() == TID_SerializableTypeInfoObject)
-		{
-			auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataObject>();
-			if (value != nullptr)
-				fieldData->value = ManagedSerializableObject::createFromExisting(value);
-			else if (!allowNull)
-				fieldData->value = ManagedSerializableObject::createNew(std::static_pointer_cast<ManagedSerializableTypeInfoObject>(typeInfo));
-
-			return fieldData;
-		}
-		else if(typeInfo->getTypeId() == TID_SerializableTypeInfoArray)
-		{
-			ManagedSerializableTypeInfoArrayPtr arrayTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoArray>(typeInfo);
-
-			auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataArray>();
-			if(value != nullptr)
-				fieldData->value = ManagedSerializableArray::createFromExisting(value, arrayTypeInfo);
-			else if (!allowNull)
-			{
-				Vector<UINT32> sizes(arrayTypeInfo->mRank, 0);
-				fieldData->value = ManagedSerializableArray::createNew(arrayTypeInfo, sizes);
-			}
-
-			return fieldData;
-		}
-		else if(typeInfo->getTypeId() == TID_SerializableTypeInfoList)
-		{
-			ManagedSerializableTypeInfoListPtr listTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoList>(typeInfo);
-
-			auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataList>();
-			if(value != nullptr)
-				fieldData->value = ManagedSerializableList::createFromExisting(value, listTypeInfo);
-			else if (!allowNull)
-				fieldData->value = ManagedSerializableList::createNew(listTypeInfo, 0);
-
-			return fieldData;
-		}
-		else if(typeInfo->getTypeId() == TID_SerializableTypeInfoDictionary)
-		{
-			ManagedSerializableTypeInfoDictionaryPtr dictTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoDictionary>(typeInfo);
-
-			auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataDictionary>();
-			if(value != nullptr)
-				fieldData->value = ManagedSerializableDictionary::createFromExisting(value, dictTypeInfo);
-			else if (!allowNull)
-				fieldData->value = ManagedSerializableDictionary::createNew(dictTypeInfo);
-
-			return fieldData;
-		}
-
-		return nullptr;
-	}
-
-	void* ManagedSerializableFieldDataBool::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if(primitiveTypeInfo->mType == ScriptPrimitiveType::Bool)
-				return &value;
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	void* ManagedSerializableFieldDataChar::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if(primitiveTypeInfo->mType == ScriptPrimitiveType::Char)
-				return &value;
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	void* ManagedSerializableFieldDataI8::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if(primitiveTypeInfo->mType == ScriptPrimitiveType::I8)
-				return &value;
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	void* ManagedSerializableFieldDataU8::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if(primitiveTypeInfo->mType == ScriptPrimitiveType::U8)
-				return &value;
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	void* ManagedSerializableFieldDataI16::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if(primitiveTypeInfo->mType == ScriptPrimitiveType::I16)
-				return &value;
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	void* ManagedSerializableFieldDataU16::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if(primitiveTypeInfo->mType == ScriptPrimitiveType::U16)
-				return &value;
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	void* ManagedSerializableFieldDataI32::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if(primitiveTypeInfo->mType == ScriptPrimitiveType::I32)
-				return &value;
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	void* ManagedSerializableFieldDataU32::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if(primitiveTypeInfo->mType == ScriptPrimitiveType::U32)
-				return &value;
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	void* ManagedSerializableFieldDataI64::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if(primitiveTypeInfo->mType == ScriptPrimitiveType::I64)
-				return &value;
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	void* ManagedSerializableFieldDataU64::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if(primitiveTypeInfo->mType == ScriptPrimitiveType::U64)
-				return &value;
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	void* ManagedSerializableFieldDataFloat::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if(primitiveTypeInfo->mType == ScriptPrimitiveType::Float)
-				return &value;
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	void* ManagedSerializableFieldDataDouble::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if(primitiveTypeInfo->mType == ScriptPrimitiveType::Double)
-				return &value;
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	void* ManagedSerializableFieldDataString::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if(primitiveTypeInfo->mType == ScriptPrimitiveType::String)
-			{
-				if (!isNull)
-					return MonoUtil::wstringToMono(value);
-				else
-					return nullptr;
-			}
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	void* ManagedSerializableFieldDataResourceRef::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		static std::function<MonoObject*(const HResource&)> lookup[(int)ScriptPrimitiveType::Count];
-
-		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-
-			return getResourceFieldLookup()[(int)primitiveTypeInfo->mType].getter(value);
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	void* ManagedSerializableFieldDataGameObjectRef::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-
-			if(primitiveTypeInfo->mType == ScriptPrimitiveType::SceneObjectRef)
-			{
-				if(value)
-				{
-					ScriptSceneObject* scriptSceneObject = ScriptGameObjectManager::instance().getOrCreateScriptSceneObject(value);
-					return scriptSceneObject->getManagedInstance();
-				}
-				else
-					return nullptr;
-			}
-			else if(primitiveTypeInfo->mType == ScriptPrimitiveType::ComponentRef)
-			{
-				if (value)
-				{
-					ScriptComponent* scriptComponent = ScriptGameObjectManager::instance().getScriptComponent(value);
-					assert(scriptComponent != nullptr);
-
-					return scriptComponent->getManagedInstance();
-				}
-				else
-					return nullptr;
-			}
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	void* ManagedSerializableFieldDataObject::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if(typeInfo->getTypeId() == TID_SerializableTypeInfoObject)
-		{
-			auto objectTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoObject>(typeInfo);
-
-			if(value != nullptr)
-			{
-				if(objectTypeInfo->mValueType)
-				{
-					MonoObject* managedInstance = value->getManagedInstance();
-					
-					if(managedInstance != nullptr)
-						return mono_object_unbox(managedInstance); // Structs are passed as raw types because mono expects them as such
-				}
-				else
-					return value->getManagedInstance();
-			}
-
-			return nullptr;
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	void* ManagedSerializableFieldDataArray::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if(typeInfo->getTypeId() == TID_SerializableTypeInfoArray)
-		{
-			auto objectTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoArray>(typeInfo);
-
-			if(value != nullptr)
-				return value->getManagedInstance();
-
-			return nullptr;
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	void* ManagedSerializableFieldDataList::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if(typeInfo->getTypeId() == TID_SerializableTypeInfoList)
-		{
-			auto listTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoList>(typeInfo);
-
-			if(value != nullptr)
-				return value->getManagedInstance();
-
-			return nullptr;
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	void* ManagedSerializableFieldDataDictionary::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if(typeInfo->getTypeId() == TID_SerializableTypeInfoDictionary)
-		{
-			auto dictionaryTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoDictionary>(typeInfo);
-
-			if(value != nullptr)
-				return value->getManagedInstance();
-
-			return nullptr;
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	MonoObject* ManagedSerializableFieldDataBool::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if (typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if (primitiveTypeInfo->mType == ScriptPrimitiveType::Bool)
-				return mono_value_box(MonoManager::instance().getDomain(), mono_get_boolean_class(), &value);
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	MonoObject* ManagedSerializableFieldDataChar::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if (typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if (primitiveTypeInfo->mType == ScriptPrimitiveType::Char)
-				return mono_value_box(MonoManager::instance().getDomain(), mono_get_char_class(), &value);
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	MonoObject* ManagedSerializableFieldDataI8::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if (typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if (primitiveTypeInfo->mType == ScriptPrimitiveType::I8)
-				return mono_value_box(MonoManager::instance().getDomain(), mono_get_sbyte_class(), &value);
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	MonoObject* ManagedSerializableFieldDataU8::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if (typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if (primitiveTypeInfo->mType == ScriptPrimitiveType::U8)
-				return mono_value_box(MonoManager::instance().getDomain(), mono_get_byte_class(), &value);
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	MonoObject* ManagedSerializableFieldDataI16::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if (typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if (primitiveTypeInfo->mType == ScriptPrimitiveType::I16)
-				return mono_value_box(MonoManager::instance().getDomain(), mono_get_int16_class(), &value);
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	MonoObject* ManagedSerializableFieldDataU16::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if (typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if (primitiveTypeInfo->mType == ScriptPrimitiveType::U16)
-				return mono_value_box(MonoManager::instance().getDomain(), mono_get_uint16_class(), &value);
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	MonoObject* ManagedSerializableFieldDataI32::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if (typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if (primitiveTypeInfo->mType == ScriptPrimitiveType::I32)
-				return mono_value_box(MonoManager::instance().getDomain(), mono_get_int32_class(), &value);
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	MonoObject* ManagedSerializableFieldDataU32::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if (typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if (primitiveTypeInfo->mType == ScriptPrimitiveType::U32)
-				return mono_value_box(MonoManager::instance().getDomain(), mono_get_uint32_class(), &value);
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	MonoObject* ManagedSerializableFieldDataI64::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if (typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if (primitiveTypeInfo->mType == ScriptPrimitiveType::I64)
-				return mono_value_box(MonoManager::instance().getDomain(), mono_get_int64_class(), &value);
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	MonoObject* ManagedSerializableFieldDataU64::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if (typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if (primitiveTypeInfo->mType == ScriptPrimitiveType::U64)
-				return mono_value_box(MonoManager::instance().getDomain(), mono_get_uint64_class(), &value);
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	MonoObject* ManagedSerializableFieldDataFloat::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if (typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if (primitiveTypeInfo->mType == ScriptPrimitiveType::Float)
-				return mono_value_box(MonoManager::instance().getDomain(), mono_get_single_class(), &value);
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	MonoObject* ManagedSerializableFieldDataDouble::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if (typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
-		{
-			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-			if (primitiveTypeInfo->mType == ScriptPrimitiveType::Double)
-				return mono_value_box(MonoManager::instance().getDomain(), mono_get_double_class(), &value);
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	MonoObject* ManagedSerializableFieldDataString::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		return (MonoObject*)getValue(typeInfo);
-	}
-
-	MonoObject* ManagedSerializableFieldDataResourceRef::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		return (MonoObject*)getValue(typeInfo);
-	}
-
-	MonoObject* ManagedSerializableFieldDataGameObjectRef::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		return (MonoObject*)getValue(typeInfo);
-	}
-
-	MonoObject* ManagedSerializableFieldDataObject::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		if (typeInfo->getTypeId() == TID_SerializableTypeInfoObject)
-		{
-			auto objectTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoObject>(typeInfo);
-
-			if (value != nullptr)
-				return value->getManagedInstance();
-
-			return nullptr;
-		}
-
-		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
-		return nullptr;
-	}
-
-	MonoObject* ManagedSerializableFieldDataArray::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		return (MonoObject*)getValue(typeInfo);
-	}
-
-	MonoObject* ManagedSerializableFieldDataList::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		return (MonoObject*)getValue(typeInfo);
-	}
-
-	MonoObject* ManagedSerializableFieldDataDictionary::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
-	{
-		return (MonoObject*)getValue(typeInfo);
-	}
-
-	bool ManagedSerializableFieldDataBool::equals(const ManagedSerializableFieldDataPtr& other)
-	{
-		return compareFieldData(this, other);
-	}
-
-	bool ManagedSerializableFieldDataChar::equals(const ManagedSerializableFieldDataPtr& other)
-	{
-		return compareFieldData(this, other);
-	}
-
-	bool ManagedSerializableFieldDataI8::equals(const ManagedSerializableFieldDataPtr& other)
-	{
-		return compareFieldData(this, other);
-	}
-
-	bool ManagedSerializableFieldDataU8::equals(const ManagedSerializableFieldDataPtr& other)
-	{
-		return compareFieldData(this, other);
-	}
-
-	bool ManagedSerializableFieldDataI16::equals(const ManagedSerializableFieldDataPtr& other)
-	{
-		return compareFieldData(this, other);
-	}
-
-	bool ManagedSerializableFieldDataU16::equals(const ManagedSerializableFieldDataPtr& other)
-	{
-		return compareFieldData(this, other);
-	}
-
-	bool ManagedSerializableFieldDataI32::equals(const ManagedSerializableFieldDataPtr& other)
-	{
-		return compareFieldData(this, other);
-	}
-
-	bool ManagedSerializableFieldDataU32::equals(const ManagedSerializableFieldDataPtr& other)
-	{
-		return compareFieldData(this, other);
-	}
-
-	bool ManagedSerializableFieldDataI64::equals(const ManagedSerializableFieldDataPtr& other)
-	{
-		return compareFieldData(this, other);
-	}
-
-	bool ManagedSerializableFieldDataU64::equals(const ManagedSerializableFieldDataPtr& other)
-	{
-		return compareFieldData(this, other);
-	}
-
-	bool ManagedSerializableFieldDataFloat::equals(const ManagedSerializableFieldDataPtr& other)
-	{
-		return compareFieldData(this, other);
-	}
-
-	bool ManagedSerializableFieldDataDouble::equals(const ManagedSerializableFieldDataPtr& other)
-	{
-		return compareFieldData(this, other);
-	}
-
-	bool ManagedSerializableFieldDataString::equals(const ManagedSerializableFieldDataPtr& other)
-	{
-		if (rtti_is_of_type<ManagedSerializableFieldDataString>(other))
-		{
-			auto castObj = std::static_pointer_cast<ManagedSerializableFieldDataString>(other);
-			return (isNull == true && isNull == castObj->isNull) || value == castObj->value;
-		}
-
-		return false;
-	}
-
-	bool ManagedSerializableFieldDataResourceRef::equals(const ManagedSerializableFieldDataPtr& other)
-	{
-		return compareFieldData(this, other);
-	}
-
-	bool ManagedSerializableFieldDataGameObjectRef::equals(const ManagedSerializableFieldDataPtr& other)
-	{
-		return compareFieldData(this, other);
-	}
-
-	bool ManagedSerializableFieldDataObject::equals(const ManagedSerializableFieldDataPtr& other)
-	{
-		return compareFieldData(this, other);
-	}
-
-	bool ManagedSerializableFieldDataArray::equals(const ManagedSerializableFieldDataPtr& other)
-	{
-		return compareFieldData(this, other);
-	}
-
-	bool ManagedSerializableFieldDataList::equals(const ManagedSerializableFieldDataPtr& other)
-	{
-		return compareFieldData(this, other);
-	}
-
-	bool ManagedSerializableFieldDataDictionary::equals(const ManagedSerializableFieldDataPtr& other)
-	{
-		return compareFieldData(this, other);
-	}
-
-	size_t ManagedSerializableFieldDataBool::getHash()
-	{
-		std::hash<bool> hasher;
-		return hasher(value);
-	}
-
-	size_t ManagedSerializableFieldDataChar::getHash()
-	{
-		std::hash<wchar_t> hasher;
-		return hasher(value);
-	}
-
-	size_t ManagedSerializableFieldDataI8::getHash()
-	{
-		std::hash<INT8> hasher;
-		return hasher(value);
-	}
-
-	size_t ManagedSerializableFieldDataU8::getHash()
-	{
-		std::hash<UINT8> hasher;
-		return hasher(value);
-	}
-
-	size_t ManagedSerializableFieldDataI16::getHash()
-	{
-		std::hash<INT16> hasher;
-		return hasher(value);
-	}
-
-	size_t ManagedSerializableFieldDataU16::getHash()
-	{
-		std::hash<UINT16> hasher;
-		return hasher(value);
-	}
-
-	size_t ManagedSerializableFieldDataI32::getHash()
-	{
-		std::hash<INT32> hasher;
-		return hasher(value);
-	}
-
-	size_t ManagedSerializableFieldDataU32::getHash()
-	{
-		std::hash<UINT32> hasher;
-		return hasher(value);
-	}
-
-	size_t ManagedSerializableFieldDataI64::getHash()
-	{
-		std::hash<INT64> hasher;
-		return hasher(value);
-	}
-
-	size_t ManagedSerializableFieldDataU64::getHash()
-	{
-		std::hash<UINT64> hasher;
-		return hasher(value);
-	}
-
-	size_t ManagedSerializableFieldDataFloat::getHash()
-	{
-		std::hash<float> hasher;
-		return hasher(value);
-	}
-
-	size_t ManagedSerializableFieldDataDouble::getHash()
-	{
-		std::hash<double> hasher;
-		return hasher(value);
-	}
-
-	size_t ManagedSerializableFieldDataString::getHash()
-	{
-		std::hash<WString> hasher;
-		return hasher(value);
-	}
-
-	size_t ManagedSerializableFieldDataResourceRef::getHash()
-	{
-		std::hash<String> hasher;
-		return hasher(value.getUUID());
-	}
-
-	size_t ManagedSerializableFieldDataGameObjectRef::getHash()
-	{
-		std::hash<UINT64> hasher;
-		return hasher(value.getInstanceId());
-	}
-
-	size_t ManagedSerializableFieldDataObject::getHash()
-	{
-		std::hash<std::shared_ptr<ManagedSerializableObject>> hasher;
-		return hasher(value);
-	}
-
-	size_t ManagedSerializableFieldDataArray::getHash()
-	{
-		std::hash<std::shared_ptr<ManagedSerializableArray>> hasher;
-		return hasher(value);
-	}
-
-	size_t ManagedSerializableFieldDataList::getHash()
-	{
-		std::hash<std::shared_ptr<ManagedSerializableList>> hasher;
-		return hasher(value);
-	}
-
-	size_t ManagedSerializableFieldDataDictionary::getHash()
-	{
-		std::hash<std::shared_ptr<ManagedSerializableDictionary>> hasher;
-		return hasher(value);
-	}
-
-	void ManagedSerializableFieldDataObject::serialize()
-	{
-		if (value != nullptr)
-			value->serialize();
-	}
-
-	void ManagedSerializableFieldDataObject::deserialize()
-	{
-		if (value != nullptr)
-			value->deserialize();
-	}
-
-	void ManagedSerializableFieldDataArray::serialize()
-	{
-		if (value != nullptr)
-			value->serialize();
-	}
-
-	void ManagedSerializableFieldDataArray::deserialize()
-	{
-		if (value != nullptr)
-			value->deserialize();
-	}
-
-	void ManagedSerializableFieldDataList::serialize()
-	{
-		if (value != nullptr)
-			value->serialize();
-	}
-
-	void ManagedSerializableFieldDataList::deserialize()
-	{
-		if (value != nullptr)
-			value->deserialize();
-	}
-
-	void ManagedSerializableFieldDataDictionary::serialize()
-	{
-		if (value != nullptr)
-			value->serialize();
-	}
-
-	void ManagedSerializableFieldDataDictionary::deserialize()
-	{
-		if (value != nullptr)
-			value->deserialize();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldKey::getRTTIStatic()
-	{
-		return ManagedSerializableFieldKeyRTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldKey::getRTTI() const
-	{
-		return ManagedSerializableFieldKey::getRTTIStatic();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldData::getRTTIStatic()
-	{
-		return ManagedSerializableFieldDataRTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldData::getRTTI() const
-	{
-		return ManagedSerializableFieldData::getRTTIStatic();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataEntry::getRTTIStatic()
-	{
-		return ManagedSerializableFieldDataEntryRTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataEntry::getRTTI() const
-	{
-		return ManagedSerializableFieldDataEntry::getRTTIStatic();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataBool::getRTTIStatic()
-	{
-		return ManagedSerializableFieldDataBoolRTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataBool::getRTTI() const
-	{
-		return ManagedSerializableFieldDataBool::getRTTIStatic();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataChar::getRTTIStatic()
-	{
-		return ManagedSerializableFieldDataCharRTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataChar::getRTTI() const
-	{
-		return ManagedSerializableFieldDataChar::getRTTIStatic();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataI8::getRTTIStatic()
-	{
-		return ManagedSerializableFieldDataI8RTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataI8::getRTTI() const
-	{
-		return ManagedSerializableFieldDataI8::getRTTIStatic();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataU8::getRTTIStatic()
-	{
-		return ManagedSerializableFieldDataU8RTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataU8::getRTTI() const
-	{
-		return ManagedSerializableFieldDataU8::getRTTIStatic();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataI16::getRTTIStatic()
-	{
-		return ManagedSerializableFieldDataI16RTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataI16::getRTTI() const
-	{
-		return ManagedSerializableFieldDataI16::getRTTIStatic();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataU16::getRTTIStatic()
-	{
-		return ManagedSerializableFieldDataU16RTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataU16::getRTTI() const
-	{
-		return ManagedSerializableFieldDataU16::getRTTIStatic();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataI32::getRTTIStatic()
-	{
-		return ManagedSerializableFieldDataI32RTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataI32::getRTTI() const
-	{
-		return ManagedSerializableFieldDataI32::getRTTIStatic();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataU32::getRTTIStatic()
-	{
-		return ManagedSerializableFieldDataU32RTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataU32::getRTTI() const
-	{
-		return ManagedSerializableFieldDataU32::getRTTIStatic();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataI64::getRTTIStatic()
-	{
-		return ManagedSerializableFieldDataI64RTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataI64::getRTTI() const
-	{
-		return ManagedSerializableFieldDataI64::getRTTIStatic();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataU64::getRTTIStatic()
-	{
-		return ManagedSerializableFieldDataU64RTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataU64::getRTTI() const
-	{
-		return ManagedSerializableFieldDataU64::getRTTIStatic();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataFloat::getRTTIStatic()
-	{
-		return ManagedSerializableFieldDataFloatRTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataFloat::getRTTI() const
-	{
-		return ManagedSerializableFieldDataFloat::getRTTIStatic();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataDouble::getRTTIStatic()
-	{
-		return ManagedSerializableFieldDataDoubleRTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataDouble::getRTTI() const
-	{
-		return ManagedSerializableFieldDataDouble::getRTTIStatic();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataString::getRTTIStatic()
-	{
-		return ManagedSerializableFieldDataStringRTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataString::getRTTI() const
-	{
-		return ManagedSerializableFieldDataString::getRTTIStatic();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataResourceRef::getRTTIStatic()
-	{
-		return ManagedSerializableFieldDataResourceRefRTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataResourceRef::getRTTI() const
-	{
-		return ManagedSerializableFieldDataResourceRef::getRTTIStatic();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataGameObjectRef::getRTTIStatic()
-	{
-		return ManagedSerializableFieldDataGameObjectRefRTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataGameObjectRef::getRTTI() const
-	{
-		return ManagedSerializableFieldDataGameObjectRef::getRTTIStatic();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataObject::getRTTIStatic()
-	{
-		return ManagedSerializableFieldDataObjectRTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataObject::getRTTI() const
-	{
-		return ManagedSerializableFieldDataObject::getRTTIStatic();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataArray::getRTTIStatic()
-	{
-		return ManagedSerializableFieldDataArrayRTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataArray::getRTTI() const
-	{
-		return ManagedSerializableFieldDataArray::getRTTIStatic();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataList::getRTTIStatic()
-	{
-		return ManagedSerializableFieldDataListRTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataList::getRTTI() const
-	{
-		return ManagedSerializableFieldDataList::getRTTIStatic();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataDictionary::getRTTIStatic()
-	{
-		return ManagedSerializableFieldDataDictionaryRTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldDataDictionary::getRTTI() const
-	{
-		return ManagedSerializableFieldDataDictionary::getRTTIStatic();
-	}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsManagedSerializableField.h"
+#include "BsManagedSerializableObjectInfo.h"
+#include "BsManagedSerializableFieldRTTI.h"
+#include "BsMonoUtil.h"
+#include "BsMonoManager.h"
+#include "BsScriptResourceManager.h"
+#include "BsScriptGameObjectManager.h"
+#include "BsScriptTexture2D.h"
+#include "BsScriptTexture3D.h"
+#include "BsScriptTextureCube.h"
+#include "BsScriptSpriteTexture.h"
+#include "BsScriptManagedResource.h"
+#include "BsScriptPlainText.h"
+#include "BsScriptScriptCode.h"
+#include "BsScriptShader.h"
+#include "BsScriptShaderInclude.h"
+#include "BsScriptMaterial.h"
+#include "BsScriptMesh.h"
+#include "BsScriptPrefab.h"
+#include "BsScriptFont.h"
+#include "BsScriptStringTable.h"
+#include "BsScriptGUISkin.h"
+#include "BsScriptPhysicsMaterial.h"
+#include "BsScriptPhysicsMesh.h"
+#include "BsScriptSceneObject.h"
+#include "BsScriptComponent.h"
+#include "BsManagedSerializableObject.h"
+#include "BsManagedSerializableArray.h"
+#include "BsManagedSerializableList.h"
+#include "BsManagedSerializableDictionary.h"
+
+namespace BansheeEngine
+{
+	template<class T>
+	bool compareFieldData(const T* a, const ManagedSerializableFieldDataPtr& b)
+	{
+		if (rtti_is_of_type<T>(b))
+		{
+			auto castObj = std::static_pointer_cast<T>(b);
+			return a->value == castObj->value;
+		}
+
+		return false;
+	}
+
+	ManagedSerializableFieldKey::ManagedSerializableFieldKey()
+		:mTypeId(0), mFieldId(0)
+	{ }
+
+	ManagedSerializableFieldKey::ManagedSerializableFieldKey(UINT16 typeId, UINT16 fieldId)
+		:mTypeId(typeId), mFieldId(fieldId)
+	{ }
+
+	ManagedSerializableFieldKeyPtr ManagedSerializableFieldKey::create(UINT16 typeId, UINT16 fieldId)
+	{
+		ManagedSerializableFieldKeyPtr fieldKey = bs_shared_ptr_new<ManagedSerializableFieldKey>(typeId, fieldId);
+		return fieldKey;
+	}
+
+	ManagedSerializableFieldDataEntryPtr ManagedSerializableFieldDataEntry::create(const ManagedSerializableFieldKeyPtr& key, const ManagedSerializableFieldDataPtr& value)
+	{
+		ManagedSerializableFieldDataEntryPtr fieldDataEntry = bs_shared_ptr_new<ManagedSerializableFieldDataEntry>();
+		fieldDataEntry->mKey = key;
+		fieldDataEntry->mValue = value;
+
+		return fieldDataEntry;
+	}
+
+	ManagedSerializableFieldDataPtr ManagedSerializableFieldData::create(const ManagedSerializableTypeInfoPtr& typeInfo, MonoObject* value)
+	{
+		return create(typeInfo, value, true);
+	}
+
+	ManagedSerializableFieldDataPtr ManagedSerializableFieldData::createDefault(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		return create(typeInfo, nullptr, false);
+	}
+
+	template<class ResType, class ScriptType>
+	MonoObject* getScriptResource(const HResource& value)
+	{
+		ResourceHandle<ResType> castValue = static_resource_cast<ResType>(value);
+		if (castValue.isLoaded())
+		{
+			ScriptType* scriptResource;
+			ScriptResourceManager::instance().getScriptResource(castValue, &scriptResource, true);
+
+			return scriptResource->getManagedInstance();
+		}
+		else
+			return nullptr;
+	}
+
+	template<class ScriptType>
+	ManagedSerializableFieldDataPtr setScriptResource(MonoObject* value)
+	{
+		auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataResourceRef>();
+
+		if (value != nullptr)
+		{
+			ScriptType* scriptResource = ScriptType::toNative(value);
+			fieldData->value = scriptResource->getHandle();
+		}
+
+		return fieldData;
+	}
+
+	struct ResourceFieldDataAccessors
+	{
+		std::function<MonoObject*(const HResource&)> getter;
+		std::function<ManagedSerializableFieldDataPtr(MonoObject*)> setter;
+	};
+
+	ResourceFieldDataAccessors* getResourceFieldLookup()
+	{
+		static ResourceFieldDataAccessors lookup[(int)ScriptReferenceType::Count];
+		static bool initialized = false;
+
+		if(!initialized)
+		{
+			lookup[(int)ScriptReferenceType::Texture2D] =
+				{ &getScriptResource<Texture, ScriptTexture2D>, &setScriptResource<ScriptTexture2D> };
+
+			lookup[(int)ScriptReferenceType::Texture3D] =
+				{ &getScriptResource<Texture, ScriptTexture3D>, &setScriptResource<ScriptTexture3D> };
+
+			lookup[(int)ScriptReferenceType::TextureCube] =
+				{ &getScriptResource<Texture, ScriptTextureCube>, &setScriptResource<ScriptTextureCube> };
+
+			lookup[(int)ScriptReferenceType::SpriteTexture] =
+				{ &getScriptResource<SpriteTexture, ScriptSpriteTexture>, &setScriptResource<ScriptSpriteTexture> };
+
+			lookup[(int)ScriptReferenceType::Shader] =
+				{ &getScriptResource<Shader, ScriptShader>, &setScriptResource<ScriptShader> };
+
+			lookup[(int)ScriptReferenceType::ShaderInclude] =
+				{ &getScriptResource<ShaderInclude, ScriptShaderInclude>, &setScriptResource<ScriptShaderInclude> };
+
+			lookup[(int)ScriptReferenceType::Material] =
+				{ &getScriptResource<Material, ScriptMaterial>, &setScriptResource<ScriptMaterial> };
+
+			lookup[(int)ScriptReferenceType::Mesh] =
+				{ &getScriptResource<Mesh, ScriptMesh>, &setScriptResource<ScriptMesh> };
+
+			lookup[(int)ScriptReferenceType::Prefab] =
+				{ &getScriptResource<Prefab, ScriptPrefab>, &setScriptResource<ScriptPrefab> };
+
+			lookup[(int)ScriptReferenceType::Font] =
+				{ &getScriptResource<Font, ScriptFont>, &setScriptResource<ScriptFont> };
+
+			lookup[(int)ScriptReferenceType::StringTable] =
+				{ &getScriptResource<StringTable, ScriptStringTable>, &setScriptResource<ScriptStringTable> };
+
+			lookup[(int)ScriptReferenceType::GUISkin] =
+				{ &getScriptResource<GUISkin, ScriptGUISkin>, &setScriptResource<ScriptGUISkin> };
+
+			lookup[(int)ScriptReferenceType::PhysicsMaterial] =
+				{ &getScriptResource<PhysicsMaterial, ScriptPhysicsMaterial>, &setScriptResource<ScriptPhysicsMaterial> };
+
+			lookup[(int)ScriptReferenceType::PhysicsMesh] =
+				{ &getScriptResource<PhysicsMesh, ScriptPhysicsMesh>, &setScriptResource<ScriptPhysicsMesh> };
+
+			lookup[(int)ScriptReferenceType::ManagedResource] =
+				{ &getScriptResource<ManagedResource, ScriptManagedResource>, &setScriptResource<ScriptManagedResource> };
+
+			lookup[(int)ScriptReferenceType::PlainText] =
+				{ &getScriptResource<PlainText, ScriptPlainText>, &setScriptResource<ScriptPlainText> };
+
+			lookup[(int)ScriptReferenceType::ScriptCode] =
+				{ &getScriptResource<ScriptCode, ScriptScriptCode>, &setScriptResource<ScriptScriptCode> };
+		}
+
+		return lookup;
+	}
+
+	ManagedSerializableFieldDataPtr ManagedSerializableFieldData::create(const ManagedSerializableTypeInfoPtr& typeInfo, MonoObject* value, bool allowNull)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			switch (primitiveTypeInfo->mType)
+			{
+			case ScriptPrimitiveType::Bool:
+				{
+					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataBool>();
+					if(value != nullptr)
+						memcpy(&fieldData->value, mono_object_unbox(value), sizeof(fieldData->value));
+
+					return fieldData;
+				}
+			case ScriptPrimitiveType::Char:
+				{
+					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataChar>();
+					if(value != nullptr)
+						memcpy(&fieldData->value, mono_object_unbox(value), sizeof(fieldData->value));
+
+					return fieldData;
+				}
+			case ScriptPrimitiveType::I8:
+				{
+					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataI8>();
+					if(value != nullptr)
+						memcpy(&fieldData->value, mono_object_unbox(value), sizeof(fieldData->value));
+
+					return fieldData;
+				}
+			case ScriptPrimitiveType::U8:
+				{
+					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataU8>();
+					if(value != nullptr)
+						memcpy(&fieldData->value, mono_object_unbox(value), sizeof(fieldData->value));
+
+					return fieldData;
+				}
+			case ScriptPrimitiveType::I16:
+				{
+					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataI16>();
+					if(value != nullptr)
+						memcpy(&fieldData->value, mono_object_unbox(value), sizeof(fieldData->value));
+
+					return fieldData;
+				}
+			case ScriptPrimitiveType::U16:
+				{
+					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataU16>();
+					if(value != nullptr)
+						memcpy(&fieldData->value, mono_object_unbox(value), sizeof(fieldData->value));
+
+					return fieldData;
+				}
+			case ScriptPrimitiveType::I32:
+				{
+					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataI32>();
+					if(value != nullptr)
+						memcpy(&fieldData->value, mono_object_unbox(value), sizeof(fieldData->value));
+
+					return fieldData;
+				}
+			case ScriptPrimitiveType::U32:
+				{
+					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataU32>();
+					if(value != nullptr)
+						memcpy(&fieldData->value, mono_object_unbox(value), sizeof(fieldData->value));
+
+					return fieldData;
+				}
+			case ScriptPrimitiveType::I64:
+				{
+					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataI64>();
+					if(value != nullptr)
+						memcpy(&fieldData->value, mono_object_unbox(value), sizeof(fieldData->value));
+
+					return fieldData;
+				}
+			case ScriptPrimitiveType::U64:
+				{
+					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataU64>();
+					if(value != nullptr)
+						memcpy(&fieldData->value, mono_object_unbox(value), sizeof(fieldData->value));
+
+					return fieldData;
+				}
+			case ScriptPrimitiveType::Float:
+				{
+					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataFloat>();
+					if(value != nullptr)
+						memcpy(&fieldData->value, mono_object_unbox(value), sizeof(fieldData->value));
+
+					return fieldData;
+				}
+			case ScriptPrimitiveType::Double:
+				{
+					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataDouble>();
+					if(value != nullptr)
+						memcpy(&fieldData->value, mono_object_unbox(value), sizeof(fieldData->value));
+
+					return fieldData;
+				}
+			case ScriptPrimitiveType::String:
+				{
+					MonoString* strVal = (MonoString*)(value);
+
+					auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataString>();
+					if (strVal != nullptr)
+						fieldData->value = MonoUtil::monoToWString(strVal);
+					else
+						fieldData->isNull = allowNull;
+
+					return fieldData;
+				}
+			}
+		}
+		else if (typeInfo->getTypeId() == TID_SerializableTypeInfoRef)
+		{
+			auto refTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoRef>(typeInfo);
+			switch (refTypeInfo->mType)
+			{
+			case ScriptReferenceType::SceneObject:
+			{
+				auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataGameObjectRef>();
+
+				if (value != nullptr)
+				{
+					ScriptSceneObject* scriptSceneObject = ScriptSceneObject::toNative(value);
+					fieldData->value = static_object_cast<SceneObject>(scriptSceneObject->getNativeHandle());
+				}
+
+				return fieldData;
+			}
+			case ScriptReferenceType::Component:
+			{
+				auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataGameObjectRef>();
+
+				if (value != nullptr)
+				{
+					ScriptComponent* scriptComponent = ScriptComponent::toNative(value);
+					fieldData->value = static_object_cast<Component>(scriptComponent->getNativeHandle());
+				}
+
+				return fieldData;
+			}
+			default:
+				// Must be a resource
+				return getResourceFieldLookup()[(int)refTypeInfo->mType].setter(value);
+			}
+		}
+		else if(typeInfo->getTypeId() == TID_SerializableTypeInfoObject)
+		{
+			auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataObject>();
+			if (value != nullptr)
+				fieldData->value = ManagedSerializableObject::createFromExisting(value);
+			else if (!allowNull)
+				fieldData->value = ManagedSerializableObject::createNew(std::static_pointer_cast<ManagedSerializableTypeInfoObject>(typeInfo));
+
+			return fieldData;
+		}
+		else if(typeInfo->getTypeId() == TID_SerializableTypeInfoArray)
+		{
+			ManagedSerializableTypeInfoArrayPtr arrayTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoArray>(typeInfo);
+
+			auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataArray>();
+			if(value != nullptr)
+				fieldData->value = ManagedSerializableArray::createFromExisting(value, arrayTypeInfo);
+			else if (!allowNull)
+			{
+				Vector<UINT32> sizes(arrayTypeInfo->mRank, 0);
+				fieldData->value = ManagedSerializableArray::createNew(arrayTypeInfo, sizes);
+			}
+
+			return fieldData;
+		}
+		else if(typeInfo->getTypeId() == TID_SerializableTypeInfoList)
+		{
+			ManagedSerializableTypeInfoListPtr listTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoList>(typeInfo);
+
+			auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataList>();
+			if(value != nullptr)
+				fieldData->value = ManagedSerializableList::createFromExisting(value, listTypeInfo);
+			else if (!allowNull)
+				fieldData->value = ManagedSerializableList::createNew(listTypeInfo, 0);
+
+			return fieldData;
+		}
+		else if(typeInfo->getTypeId() == TID_SerializableTypeInfoDictionary)
+		{
+			ManagedSerializableTypeInfoDictionaryPtr dictTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoDictionary>(typeInfo);
+
+			auto fieldData = bs_shared_ptr_new<ManagedSerializableFieldDataDictionary>();
+			if(value != nullptr)
+				fieldData->value = ManagedSerializableDictionary::createFromExisting(value, dictTypeInfo);
+			else if (!allowNull)
+				fieldData->value = ManagedSerializableDictionary::createNew(dictTypeInfo);
+
+			return fieldData;
+		}
+
+		return nullptr;
+	}
+
+	void* ManagedSerializableFieldDataBool::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::Bool)
+				return &value;
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	void* ManagedSerializableFieldDataChar::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::Char)
+				return &value;
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	void* ManagedSerializableFieldDataI8::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::I8)
+				return &value;
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	void* ManagedSerializableFieldDataU8::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::U8)
+				return &value;
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	void* ManagedSerializableFieldDataI16::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::I16)
+				return &value;
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	void* ManagedSerializableFieldDataU16::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::U16)
+				return &value;
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	void* ManagedSerializableFieldDataI32::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::I32)
+				return &value;
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	void* ManagedSerializableFieldDataU32::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::U32)
+				return &value;
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	void* ManagedSerializableFieldDataI64::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::I64)
+				return &value;
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	void* ManagedSerializableFieldDataU64::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::U64)
+				return &value;
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	void* ManagedSerializableFieldDataFloat::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::Float)
+				return &value;
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	void* ManagedSerializableFieldDataDouble::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::Double)
+				return &value;
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	void* ManagedSerializableFieldDataString::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::String)
+			{
+				if (!isNull)
+					return MonoUtil::wstringToMono(value);
+				else
+					return nullptr;
+			}
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	void* ManagedSerializableFieldDataResourceRef::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		static std::function<MonoObject*(const HResource&)> lookup[(int)ScriptReferenceType::Count];
+
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoRef)
+		{
+			auto refTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoRef>(typeInfo);
+
+			return getResourceFieldLookup()[(int)refTypeInfo->mType].getter(value);
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	void* ManagedSerializableFieldDataGameObjectRef::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoRef)
+		{
+			auto refTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoRef>(typeInfo);
+
+			if(refTypeInfo->mType == ScriptReferenceType::SceneObject)
+			{
+				if(value)
+				{
+					ScriptSceneObject* scriptSceneObject = ScriptGameObjectManager::instance().getOrCreateScriptSceneObject(value);
+					return scriptSceneObject->getManagedInstance();
+				}
+				else
+					return nullptr;
+			}
+			else if(refTypeInfo->mType == ScriptReferenceType::Component)
+			{
+				if (value)
+				{
+					ScriptComponent* scriptComponent = ScriptGameObjectManager::instance().getScriptComponent(value);
+					assert(scriptComponent != nullptr);
+
+					return scriptComponent->getManagedInstance();
+				}
+				else
+					return nullptr;
+			}
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	void* ManagedSerializableFieldDataObject::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoObject)
+		{
+			auto objectTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoObject>(typeInfo);
+
+			if(value != nullptr)
+			{
+				if(objectTypeInfo->mValueType)
+				{
+					MonoObject* managedInstance = value->getManagedInstance();
+					
+					if(managedInstance != nullptr)
+						return mono_object_unbox(managedInstance); // Structs are passed as raw types because mono expects them as such
+				}
+				else
+					return value->getManagedInstance();
+			}
+
+			return nullptr;
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	void* ManagedSerializableFieldDataArray::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoArray)
+		{
+			auto objectTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoArray>(typeInfo);
+
+			if(value != nullptr)
+				return value->getManagedInstance();
+
+			return nullptr;
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	void* ManagedSerializableFieldDataList::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoList)
+		{
+			auto listTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoList>(typeInfo);
+
+			if(value != nullptr)
+				return value->getManagedInstance();
+
+			return nullptr;
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	void* ManagedSerializableFieldDataDictionary::getValue(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoDictionary)
+		{
+			auto dictionaryTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoDictionary>(typeInfo);
+
+			if(value != nullptr)
+				return value->getManagedInstance();
+
+			return nullptr;
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	MonoObject* ManagedSerializableFieldDataBool::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if (typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if (primitiveTypeInfo->mType == ScriptPrimitiveType::Bool)
+				return mono_value_box(MonoManager::instance().getDomain(), mono_get_boolean_class(), &value);
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	MonoObject* ManagedSerializableFieldDataChar::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if (typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if (primitiveTypeInfo->mType == ScriptPrimitiveType::Char)
+				return mono_value_box(MonoManager::instance().getDomain(), mono_get_char_class(), &value);
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	MonoObject* ManagedSerializableFieldDataI8::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if (typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if (primitiveTypeInfo->mType == ScriptPrimitiveType::I8)
+				return mono_value_box(MonoManager::instance().getDomain(), mono_get_sbyte_class(), &value);
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	MonoObject* ManagedSerializableFieldDataU8::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if (typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if (primitiveTypeInfo->mType == ScriptPrimitiveType::U8)
+				return mono_value_box(MonoManager::instance().getDomain(), mono_get_byte_class(), &value);
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	MonoObject* ManagedSerializableFieldDataI16::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if (typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if (primitiveTypeInfo->mType == ScriptPrimitiveType::I16)
+				return mono_value_box(MonoManager::instance().getDomain(), mono_get_int16_class(), &value);
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	MonoObject* ManagedSerializableFieldDataU16::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if (typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if (primitiveTypeInfo->mType == ScriptPrimitiveType::U16)
+				return mono_value_box(MonoManager::instance().getDomain(), mono_get_uint16_class(), &value);
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	MonoObject* ManagedSerializableFieldDataI32::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if (typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if (primitiveTypeInfo->mType == ScriptPrimitiveType::I32)
+				return mono_value_box(MonoManager::instance().getDomain(), mono_get_int32_class(), &value);
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	MonoObject* ManagedSerializableFieldDataU32::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if (typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if (primitiveTypeInfo->mType == ScriptPrimitiveType::U32)
+				return mono_value_box(MonoManager::instance().getDomain(), mono_get_uint32_class(), &value);
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	MonoObject* ManagedSerializableFieldDataI64::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if (typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if (primitiveTypeInfo->mType == ScriptPrimitiveType::I64)
+				return mono_value_box(MonoManager::instance().getDomain(), mono_get_int64_class(), &value);
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	MonoObject* ManagedSerializableFieldDataU64::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if (typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if (primitiveTypeInfo->mType == ScriptPrimitiveType::U64)
+				return mono_value_box(MonoManager::instance().getDomain(), mono_get_uint64_class(), &value);
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	MonoObject* ManagedSerializableFieldDataFloat::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if (typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if (primitiveTypeInfo->mType == ScriptPrimitiveType::Float)
+				return mono_value_box(MonoManager::instance().getDomain(), mono_get_single_class(), &value);
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	MonoObject* ManagedSerializableFieldDataDouble::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if (typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+			if (primitiveTypeInfo->mType == ScriptPrimitiveType::Double)
+				return mono_value_box(MonoManager::instance().getDomain(), mono_get_double_class(), &value);
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	MonoObject* ManagedSerializableFieldDataString::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		return (MonoObject*)getValue(typeInfo);
+	}
+
+	MonoObject* ManagedSerializableFieldDataResourceRef::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		return (MonoObject*)getValue(typeInfo);
+	}
+
+	MonoObject* ManagedSerializableFieldDataGameObjectRef::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		return (MonoObject*)getValue(typeInfo);
+	}
+
+	MonoObject* ManagedSerializableFieldDataObject::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		if (typeInfo->getTypeId() == TID_SerializableTypeInfoObject)
+		{
+			auto objectTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoObject>(typeInfo);
+
+			if (value != nullptr)
+				return value->getManagedInstance();
+
+			return nullptr;
+		}
+
+		BS_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+		return nullptr;
+	}
+
+	MonoObject* ManagedSerializableFieldDataArray::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		return (MonoObject*)getValue(typeInfo);
+	}
+
+	MonoObject* ManagedSerializableFieldDataList::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		return (MonoObject*)getValue(typeInfo);
+	}
+
+	MonoObject* ManagedSerializableFieldDataDictionary::getValueBoxed(const ManagedSerializableTypeInfoPtr& typeInfo)
+	{
+		return (MonoObject*)getValue(typeInfo);
+	}
+
+	bool ManagedSerializableFieldDataBool::equals(const ManagedSerializableFieldDataPtr& other)
+	{
+		return compareFieldData(this, other);
+	}
+
+	bool ManagedSerializableFieldDataChar::equals(const ManagedSerializableFieldDataPtr& other)
+	{
+		return compareFieldData(this, other);
+	}
+
+	bool ManagedSerializableFieldDataI8::equals(const ManagedSerializableFieldDataPtr& other)
+	{
+		return compareFieldData(this, other);
+	}
+
+	bool ManagedSerializableFieldDataU8::equals(const ManagedSerializableFieldDataPtr& other)
+	{
+		return compareFieldData(this, other);
+	}
+
+	bool ManagedSerializableFieldDataI16::equals(const ManagedSerializableFieldDataPtr& other)
+	{
+		return compareFieldData(this, other);
+	}
+
+	bool ManagedSerializableFieldDataU16::equals(const ManagedSerializableFieldDataPtr& other)
+	{
+		return compareFieldData(this, other);
+	}
+
+	bool ManagedSerializableFieldDataI32::equals(const ManagedSerializableFieldDataPtr& other)
+	{
+		return compareFieldData(this, other);
+	}
+
+	bool ManagedSerializableFieldDataU32::equals(const ManagedSerializableFieldDataPtr& other)
+	{
+		return compareFieldData(this, other);
+	}
+
+	bool ManagedSerializableFieldDataI64::equals(const ManagedSerializableFieldDataPtr& other)
+	{
+		return compareFieldData(this, other);
+	}
+
+	bool ManagedSerializableFieldDataU64::equals(const ManagedSerializableFieldDataPtr& other)
+	{
+		return compareFieldData(this, other);
+	}
+
+	bool ManagedSerializableFieldDataFloat::equals(const ManagedSerializableFieldDataPtr& other)
+	{
+		return compareFieldData(this, other);
+	}
+
+	bool ManagedSerializableFieldDataDouble::equals(const ManagedSerializableFieldDataPtr& other)
+	{
+		return compareFieldData(this, other);
+	}
+
+	bool ManagedSerializableFieldDataString::equals(const ManagedSerializableFieldDataPtr& other)
+	{
+		if (rtti_is_of_type<ManagedSerializableFieldDataString>(other))
+		{
+			auto castObj = std::static_pointer_cast<ManagedSerializableFieldDataString>(other);
+			return (isNull == true && isNull == castObj->isNull) || value == castObj->value;
+		}
+
+		return false;
+	}
+
+	bool ManagedSerializableFieldDataResourceRef::equals(const ManagedSerializableFieldDataPtr& other)
+	{
+		return compareFieldData(this, other);
+	}
+
+	bool ManagedSerializableFieldDataGameObjectRef::equals(const ManagedSerializableFieldDataPtr& other)
+	{
+		return compareFieldData(this, other);
+	}
+
+	bool ManagedSerializableFieldDataObject::equals(const ManagedSerializableFieldDataPtr& other)
+	{
+		return compareFieldData(this, other);
+	}
+
+	bool ManagedSerializableFieldDataArray::equals(const ManagedSerializableFieldDataPtr& other)
+	{
+		return compareFieldData(this, other);
+	}
+
+	bool ManagedSerializableFieldDataList::equals(const ManagedSerializableFieldDataPtr& other)
+	{
+		return compareFieldData(this, other);
+	}
+
+	bool ManagedSerializableFieldDataDictionary::equals(const ManagedSerializableFieldDataPtr& other)
+	{
+		return compareFieldData(this, other);
+	}
+
+	size_t ManagedSerializableFieldDataBool::getHash()
+	{
+		std::hash<bool> hasher;
+		return hasher(value);
+	}
+
+	size_t ManagedSerializableFieldDataChar::getHash()
+	{
+		std::hash<wchar_t> hasher;
+		return hasher(value);
+	}
+
+	size_t ManagedSerializableFieldDataI8::getHash()
+	{
+		std::hash<INT8> hasher;
+		return hasher(value);
+	}
+
+	size_t ManagedSerializableFieldDataU8::getHash()
+	{
+		std::hash<UINT8> hasher;
+		return hasher(value);
+	}
+
+	size_t ManagedSerializableFieldDataI16::getHash()
+	{
+		std::hash<INT16> hasher;
+		return hasher(value);
+	}
+
+	size_t ManagedSerializableFieldDataU16::getHash()
+	{
+		std::hash<UINT16> hasher;
+		return hasher(value);
+	}
+
+	size_t ManagedSerializableFieldDataI32::getHash()
+	{
+		std::hash<INT32> hasher;
+		return hasher(value);
+	}
+
+	size_t ManagedSerializableFieldDataU32::getHash()
+	{
+		std::hash<UINT32> hasher;
+		return hasher(value);
+	}
+
+	size_t ManagedSerializableFieldDataI64::getHash()
+	{
+		std::hash<INT64> hasher;
+		return hasher(value);
+	}
+
+	size_t ManagedSerializableFieldDataU64::getHash()
+	{
+		std::hash<UINT64> hasher;
+		return hasher(value);
+	}
+
+	size_t ManagedSerializableFieldDataFloat::getHash()
+	{
+		std::hash<float> hasher;
+		return hasher(value);
+	}
+
+	size_t ManagedSerializableFieldDataDouble::getHash()
+	{
+		std::hash<double> hasher;
+		return hasher(value);
+	}
+
+	size_t ManagedSerializableFieldDataString::getHash()
+	{
+		std::hash<WString> hasher;
+		return hasher(value);
+	}
+
+	size_t ManagedSerializableFieldDataResourceRef::getHash()
+	{
+		std::hash<String> hasher;
+		return hasher(value.getUUID());
+	}
+
+	size_t ManagedSerializableFieldDataGameObjectRef::getHash()
+	{
+		std::hash<UINT64> hasher;
+		return hasher(value.getInstanceId());
+	}
+
+	size_t ManagedSerializableFieldDataObject::getHash()
+	{
+		std::hash<std::shared_ptr<ManagedSerializableObject>> hasher;
+		return hasher(value);
+	}
+
+	size_t ManagedSerializableFieldDataArray::getHash()
+	{
+		std::hash<std::shared_ptr<ManagedSerializableArray>> hasher;
+		return hasher(value);
+	}
+
+	size_t ManagedSerializableFieldDataList::getHash()
+	{
+		std::hash<std::shared_ptr<ManagedSerializableList>> hasher;
+		return hasher(value);
+	}
+
+	size_t ManagedSerializableFieldDataDictionary::getHash()
+	{
+		std::hash<std::shared_ptr<ManagedSerializableDictionary>> hasher;
+		return hasher(value);
+	}
+
+	void ManagedSerializableFieldDataObject::serialize()
+	{
+		if (value != nullptr)
+			value->serialize();
+	}
+
+	void ManagedSerializableFieldDataObject::deserialize()
+	{
+		if (value != nullptr)
+			value->deserialize();
+	}
+
+	void ManagedSerializableFieldDataArray::serialize()
+	{
+		if (value != nullptr)
+			value->serialize();
+	}
+
+	void ManagedSerializableFieldDataArray::deserialize()
+	{
+		if (value != nullptr)
+			value->deserialize();
+	}
+
+	void ManagedSerializableFieldDataList::serialize()
+	{
+		if (value != nullptr)
+			value->serialize();
+	}
+
+	void ManagedSerializableFieldDataList::deserialize()
+	{
+		if (value != nullptr)
+			value->deserialize();
+	}
+
+	void ManagedSerializableFieldDataDictionary::serialize()
+	{
+		if (value != nullptr)
+			value->serialize();
+	}
+
+	void ManagedSerializableFieldDataDictionary::deserialize()
+	{
+		if (value != nullptr)
+			value->deserialize();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldKey::getRTTIStatic()
+	{
+		return ManagedSerializableFieldKeyRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldKey::getRTTI() const
+	{
+		return ManagedSerializableFieldKey::getRTTIStatic();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldData::getRTTIStatic()
+	{
+		return ManagedSerializableFieldDataRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldData::getRTTI() const
+	{
+		return ManagedSerializableFieldData::getRTTIStatic();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataEntry::getRTTIStatic()
+	{
+		return ManagedSerializableFieldDataEntryRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataEntry::getRTTI() const
+	{
+		return ManagedSerializableFieldDataEntry::getRTTIStatic();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataBool::getRTTIStatic()
+	{
+		return ManagedSerializableFieldDataBoolRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataBool::getRTTI() const
+	{
+		return ManagedSerializableFieldDataBool::getRTTIStatic();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataChar::getRTTIStatic()
+	{
+		return ManagedSerializableFieldDataCharRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataChar::getRTTI() const
+	{
+		return ManagedSerializableFieldDataChar::getRTTIStatic();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataI8::getRTTIStatic()
+	{
+		return ManagedSerializableFieldDataI8RTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataI8::getRTTI() const
+	{
+		return ManagedSerializableFieldDataI8::getRTTIStatic();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataU8::getRTTIStatic()
+	{
+		return ManagedSerializableFieldDataU8RTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataU8::getRTTI() const
+	{
+		return ManagedSerializableFieldDataU8::getRTTIStatic();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataI16::getRTTIStatic()
+	{
+		return ManagedSerializableFieldDataI16RTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataI16::getRTTI() const
+	{
+		return ManagedSerializableFieldDataI16::getRTTIStatic();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataU16::getRTTIStatic()
+	{
+		return ManagedSerializableFieldDataU16RTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataU16::getRTTI() const
+	{
+		return ManagedSerializableFieldDataU16::getRTTIStatic();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataI32::getRTTIStatic()
+	{
+		return ManagedSerializableFieldDataI32RTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataI32::getRTTI() const
+	{
+		return ManagedSerializableFieldDataI32::getRTTIStatic();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataU32::getRTTIStatic()
+	{
+		return ManagedSerializableFieldDataU32RTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataU32::getRTTI() const
+	{
+		return ManagedSerializableFieldDataU32::getRTTIStatic();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataI64::getRTTIStatic()
+	{
+		return ManagedSerializableFieldDataI64RTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataI64::getRTTI() const
+	{
+		return ManagedSerializableFieldDataI64::getRTTIStatic();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataU64::getRTTIStatic()
+	{
+		return ManagedSerializableFieldDataU64RTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataU64::getRTTI() const
+	{
+		return ManagedSerializableFieldDataU64::getRTTIStatic();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataFloat::getRTTIStatic()
+	{
+		return ManagedSerializableFieldDataFloatRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataFloat::getRTTI() const
+	{
+		return ManagedSerializableFieldDataFloat::getRTTIStatic();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataDouble::getRTTIStatic()
+	{
+		return ManagedSerializableFieldDataDoubleRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataDouble::getRTTI() const
+	{
+		return ManagedSerializableFieldDataDouble::getRTTIStatic();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataString::getRTTIStatic()
+	{
+		return ManagedSerializableFieldDataStringRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataString::getRTTI() const
+	{
+		return ManagedSerializableFieldDataString::getRTTIStatic();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataResourceRef::getRTTIStatic()
+	{
+		return ManagedSerializableFieldDataResourceRefRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataResourceRef::getRTTI() const
+	{
+		return ManagedSerializableFieldDataResourceRef::getRTTIStatic();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataGameObjectRef::getRTTIStatic()
+	{
+		return ManagedSerializableFieldDataGameObjectRefRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataGameObjectRef::getRTTI() const
+	{
+		return ManagedSerializableFieldDataGameObjectRef::getRTTIStatic();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataObject::getRTTIStatic()
+	{
+		return ManagedSerializableFieldDataObjectRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataObject::getRTTI() const
+	{
+		return ManagedSerializableFieldDataObject::getRTTIStatic();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataArray::getRTTIStatic()
+	{
+		return ManagedSerializableFieldDataArrayRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataArray::getRTTI() const
+	{
+		return ManagedSerializableFieldDataArray::getRTTIStatic();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataList::getRTTIStatic()
+	{
+		return ManagedSerializableFieldDataListRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataList::getRTTI() const
+	{
+		return ManagedSerializableFieldDataList::getRTTIStatic();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataDictionary::getRTTIStatic()
+	{
+		return ManagedSerializableFieldDataDictionaryRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldDataDictionary::getRTTI() const
+	{
+		return ManagedSerializableFieldDataDictionary::getRTTIStatic();
+	}
 }

+ 375 - 346
Source/SBansheeEngine/Source/BsManagedSerializableObjectInfo.cpp

@@ -1,364 +1,393 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#include "BsManagedSerializableObjectInfo.h"
-#include "BsManagedSerializableObjectInfoRTTI.h"
-#include "BsMonoUtil.h"
-#include "BsMonoField.h"
-#include "BsMonoClass.h"
-#include "BsMonoManager.h"
-#include "BsScriptResourceManager.h"
-#include "BsScriptGameObjectManager.h"
-#include "BsScriptTexture2D.h"
-#include "BsScriptSpriteTexture.h"
-#include "BsScriptComponent.h"
-#include "BsScriptSceneObject.h"
-#include "BsManagedSerializableObjectInfo.h"
-#include "BsScriptAssemblyManager.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 "BsScriptPhysicsMaterial.h"
-#include "BsScriptPhysicsMesh.h"
-#include "BsScriptPrefab.h"
-#include "BsScriptManagedResource.h"
-
-namespace BansheeEngine
-{
-	RTTITypeBase* ManagedSerializableAssemblyInfo::getRTTIStatic()
-	{
-		return ManagedSerializableAssemblyInfoRTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableAssemblyInfo::getRTTI() const
-	{
-		return ManagedSerializableAssemblyInfo::getRTTIStatic();
-	}
-
-	ManagedSerializableObjectInfo::ManagedSerializableObjectInfo()
-		:mMonoClass(nullptr)
-	{
-
-	}
-
-	ManagedSerializableFieldInfoPtr ManagedSerializableObjectInfo::findMatchingField(const ManagedSerializableFieldInfoPtr& fieldInfo,
-		const ManagedSerializableTypeInfoPtr& fieldTypeInfo) const
-	{
-		const ManagedSerializableObjectInfo* objInfo = this;
-		while (objInfo != nullptr)
-		{
-			if (objInfo->mTypeInfo->matches(fieldTypeInfo))
-			{
-				auto iterFind = objInfo->mFieldNameToId.find(fieldInfo->mName);
-				if (iterFind != objInfo->mFieldNameToId.end())
-				{
-					auto iterFind2 = objInfo->mFields.find(iterFind->second);
-					if (iterFind2 != objInfo->mFields.end())
-					{
-						ManagedSerializableFieldInfoPtr foundField = iterFind2->second;
-						if (foundField->isSerializable())
-						{
-							if (fieldInfo->mTypeInfo->matches(foundField->mTypeInfo))
-								return foundField;
-						}
-					}
-				}
-
-				return nullptr;
-			}
-
-			if (objInfo->mBaseClass != nullptr)
-				objInfo = objInfo->mBaseClass.get();
-			else
-				objInfo = nullptr;
-		}
-
-		return nullptr;
-	}
-
-	RTTITypeBase* ManagedSerializableObjectInfo::getRTTIStatic()
-	{
-		return ManagedSerializableObjectInfoRTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableObjectInfo::getRTTI() const
-	{
-		return ManagedSerializableObjectInfo::getRTTIStatic();
-	}
-
-	ManagedSerializableFieldInfo::ManagedSerializableFieldInfo()
-		:mMonoField(nullptr), mFlags((ScriptFieldFlags)0), mFieldId(0)
-	{
-
-	}
-
-	RTTITypeBase* ManagedSerializableFieldInfo::getRTTIStatic()
-	{
-		return ManagedSerializableFieldInfoRTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableFieldInfo::getRTTI() const
-	{
-		return ManagedSerializableFieldInfo::getRTTIStatic();
-	}
-
-	RTTITypeBase* ManagedSerializableTypeInfo::getRTTIStatic()
-	{
-		return ManagedSerializableTypeInfoRTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableTypeInfo::getRTTI() const
-	{
-		return ManagedSerializableTypeInfo::getRTTIStatic();
-	}
-
-	bool ManagedSerializableTypeInfoPrimitive::matches(const ManagedSerializableTypeInfoPtr& typeInfo) const
-	{
-		if(!rtti_is_of_type<ManagedSerializableTypeInfoPrimitive>(typeInfo))
-			return false;
-
-		auto primTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
-
-		return primTypeInfo->mType == mType;
-	}
-
-	bool ManagedSerializableTypeInfoPrimitive::isTypeLoaded() const
-	{
-		return true;
-	}
-
-	::MonoClass* ManagedSerializableTypeInfoPrimitive::getMonoClass() const
-	{
-		switch(mType)
-		{
-		case ScriptPrimitiveType::Bool:
-			return mono_get_boolean_class();
-		case ScriptPrimitiveType::Char:
-			return mono_get_char_class();
-		case ScriptPrimitiveType::I8:
-			return mono_get_sbyte_class();
-		case ScriptPrimitiveType::U8:
-			return mono_get_byte_class();
-		case ScriptPrimitiveType::I16:
-			return mono_get_int16_class();
-		case ScriptPrimitiveType::U16:
-			return mono_get_uint16_class();
-		case ScriptPrimitiveType::I32:
-			return mono_get_int32_class();
-		case ScriptPrimitiveType::U32:
-			return mono_get_uint32_class();
-		case ScriptPrimitiveType::I64:
-			return mono_get_int64_class();
-		case ScriptPrimitiveType::U64:
-			return mono_get_uint64_class();
-		case ScriptPrimitiveType::Float:
-			return mono_get_single_class();
-		case ScriptPrimitiveType::Double:
-			return mono_get_double_class();
-		case ScriptPrimitiveType::String:
-			return mono_get_string_class();
-		case ScriptPrimitiveType::Texture2DRef:
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsManagedSerializableObjectInfo.h"
+#include "BsManagedSerializableObjectInfoRTTI.h"
+#include "BsMonoUtil.h"
+#include "BsMonoClass.h"
+#include "BsMonoManager.h"
+#include "BsScriptTexture2D.h"
+#include "BsScriptSpriteTexture.h"
+#include "BsScriptAssemblyManager.h"
+#include "BsScriptTexture3D.h"
+#include "BsScriptTextureCube.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 "BsScriptPhysicsMaterial.h"
+#include "BsScriptPhysicsMesh.h"
+#include "BsScriptPrefab.h"
+#include "BsScriptManagedResource.h"
+
+namespace BansheeEngine
+{
+	RTTITypeBase* ManagedSerializableAssemblyInfo::getRTTIStatic()
+	{
+		return ManagedSerializableAssemblyInfoRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableAssemblyInfo::getRTTI() const
+	{
+		return ManagedSerializableAssemblyInfo::getRTTIStatic();
+	}
+
+	ManagedSerializableObjectInfo::ManagedSerializableObjectInfo()
+		:mMonoClass(nullptr)
+	{
+
+	}
+
+	ManagedSerializableFieldInfoPtr ManagedSerializableObjectInfo::findMatchingField(const ManagedSerializableFieldInfoPtr& fieldInfo,
+		const ManagedSerializableTypeInfoPtr& fieldTypeInfo) const
+	{
+		const ManagedSerializableObjectInfo* objInfo = this;
+		while (objInfo != nullptr)
+		{
+			if (objInfo->mTypeInfo->matches(fieldTypeInfo))
+			{
+				auto iterFind = objInfo->mFieldNameToId.find(fieldInfo->mName);
+				if (iterFind != objInfo->mFieldNameToId.end())
+				{
+					auto iterFind2 = objInfo->mFields.find(iterFind->second);
+					if (iterFind2 != objInfo->mFields.end())
+					{
+						ManagedSerializableFieldInfoPtr foundField = iterFind2->second;
+						if (foundField->isSerializable())
+						{
+							if (fieldInfo->mTypeInfo->matches(foundField->mTypeInfo))
+								return foundField;
+						}
+					}
+				}
+
+				return nullptr;
+			}
+
+			if (objInfo->mBaseClass != nullptr)
+				objInfo = objInfo->mBaseClass.get();
+			else
+				objInfo = nullptr;
+		}
+
+		return nullptr;
+	}
+
+	RTTITypeBase* ManagedSerializableObjectInfo::getRTTIStatic()
+	{
+		return ManagedSerializableObjectInfoRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableObjectInfo::getRTTI() const
+	{
+		return ManagedSerializableObjectInfo::getRTTIStatic();
+	}
+
+	ManagedSerializableFieldInfo::ManagedSerializableFieldInfo()
+		:mMonoField(nullptr), mFlags((ScriptFieldFlags)0), mFieldId(0)
+	{
+
+	}
+
+	RTTITypeBase* ManagedSerializableFieldInfo::getRTTIStatic()
+	{
+		return ManagedSerializableFieldInfoRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableFieldInfo::getRTTI() const
+	{
+		return ManagedSerializableFieldInfo::getRTTIStatic();
+	}
+
+	RTTITypeBase* ManagedSerializableTypeInfo::getRTTIStatic()
+	{
+		return ManagedSerializableTypeInfoRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableTypeInfo::getRTTI() const
+	{
+		return ManagedSerializableTypeInfo::getRTTIStatic();
+	}
+
+	bool ManagedSerializableTypeInfoPrimitive::matches(const ManagedSerializableTypeInfoPtr& typeInfo) const
+	{
+		if(!rtti_is_of_type<ManagedSerializableTypeInfoPrimitive>(typeInfo))
+			return false;
+
+		auto primTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoPrimitive>(typeInfo);
+
+		return primTypeInfo->mType == mType;
+	}
+
+	bool ManagedSerializableTypeInfoPrimitive::isTypeLoaded() const
+	{
+		return mType < ScriptPrimitiveType::Count; // Ignoring some removed types
+	}
+
+	::MonoClass* ManagedSerializableTypeInfoPrimitive::getMonoClass() const
+	{
+		switch(mType)
+		{
+		case ScriptPrimitiveType::Bool:
+			return mono_get_boolean_class();
+		case ScriptPrimitiveType::Char:
+			return mono_get_char_class();
+		case ScriptPrimitiveType::I8:
+			return mono_get_sbyte_class();
+		case ScriptPrimitiveType::U8:
+			return mono_get_byte_class();
+		case ScriptPrimitiveType::I16:
+			return mono_get_int16_class();
+		case ScriptPrimitiveType::U16:
+			return mono_get_uint16_class();
+		case ScriptPrimitiveType::I32:
+			return mono_get_int32_class();
+		case ScriptPrimitiveType::U32:
+			return mono_get_uint32_class();
+		case ScriptPrimitiveType::I64:
+			return mono_get_int64_class();
+		case ScriptPrimitiveType::U64:
+			return mono_get_uint64_class();
+		case ScriptPrimitiveType::Float:
+			return mono_get_single_class();
+		case ScriptPrimitiveType::Double:
+			return mono_get_double_class();
+		case ScriptPrimitiveType::String:
+			return mono_get_string_class();
+		}
+
+		return nullptr;
+	}
+
+	RTTITypeBase* ManagedSerializableTypeInfoPrimitive::getRTTIStatic()
+	{
+		return ManagedSerializableTypeInfoPrimitiveRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableTypeInfoPrimitive::getRTTI() const
+	{
+		return ManagedSerializableTypeInfoPrimitive::getRTTIStatic();
+	}
+
+	bool ManagedSerializableTypeInfoRef::matches(const ManagedSerializableTypeInfoPtr& typeInfo) const
+	{
+		if (!rtti_is_of_type<ManagedSerializableTypeInfoRef>(typeInfo))
+			return false;
+
+		auto objTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoRef>(typeInfo);
+
+		return objTypeInfo->mTypeNamespace == mTypeNamespace && objTypeInfo->mTypeName == mTypeName;
+	}
+
+	bool ManagedSerializableTypeInfoRef::isTypeLoaded() const
+	{
+		return ScriptAssemblyManager::instance().hasSerializableObjectInfo(mTypeNamespace, mTypeName);
+	}
+
+	::MonoClass* ManagedSerializableTypeInfoRef::getMonoClass() const
+	{
+		switch (mType)
+		{
+		case ScriptReferenceType::Texture2D:
 			return ScriptTexture2D::getMetaData()->scriptClass->_getInternalClass();
-		case ScriptPrimitiveType::Texture3DRef:
+		case ScriptReferenceType::Texture3D:
 			return ScriptTexture3D::getMetaData()->scriptClass->_getInternalClass();
-		case ScriptPrimitiveType::TextureCubeRef:
+		case ScriptReferenceType::TextureCube:
 			return ScriptTextureCube::getMetaData()->scriptClass->_getInternalClass();
-		case ScriptPrimitiveType::SpriteTextureRef:
+		case ScriptReferenceType::SpriteTexture:
 			return ScriptSpriteTexture::getMetaData()->scriptClass->_getInternalClass();
-		case ScriptPrimitiveType::ShaderRef:
+		case ScriptReferenceType::Shader:
 			return ScriptShader::getMetaData()->scriptClass->_getInternalClass();
-		case ScriptPrimitiveType::ShaderIncludeRef:
+		case ScriptReferenceType::ShaderInclude:
 			return ScriptShaderInclude::getMetaData()->scriptClass->_getInternalClass();
-		case ScriptPrimitiveType::MaterialRef:
+		case ScriptReferenceType::Material:
 			return ScriptMaterial::getMetaData()->scriptClass->_getInternalClass();
-		case ScriptPrimitiveType::MeshRef:
+		case ScriptReferenceType::Mesh:
 			return ScriptMesh::getMetaData()->scriptClass->_getInternalClass();
-		case ScriptPrimitiveType::ManagedResourceRef:
-			return ScriptManagedResource::getMetaData()->scriptClass->_getInternalClass();
-		case ScriptPrimitiveType::PlainTextRef:
+		case ScriptReferenceType::PlainText:
 			return ScriptPlainText::getMetaData()->scriptClass->_getInternalClass();
-		case ScriptPrimitiveType::ScriptCodeRef:
+		case ScriptReferenceType::ScriptCode:
 			return ScriptScriptCode::getMetaData()->scriptClass->_getInternalClass();
-		case ScriptPrimitiveType::PrefabRef:
+		case ScriptReferenceType::Prefab:
 			return ScriptPrefab::getMetaData()->scriptClass->_getInternalClass();
-		case ScriptPrimitiveType::FontRef:
+		case ScriptReferenceType::Font:
 			return ScriptFont::getMetaData()->scriptClass->_getInternalClass();
-		case ScriptPrimitiveType::StringTableRef:
+		case ScriptReferenceType::StringTable:
 			return ScriptStringTable::getMetaData()->scriptClass->_getInternalClass();
-		case ScriptPrimitiveType::GUISkinRef:
+		case ScriptReferenceType::GUISkin:
 			return ScriptGUISkin::getMetaData()->scriptClass->_getInternalClass();
-		case ScriptPrimitiveType::PhysicsMaterialRef:
+		case ScriptReferenceType::PhysicsMaterial:
 			return ScriptPhysicsMaterial::getMetaData()->scriptClass->_getInternalClass();
-		case ScriptPrimitiveType::PhysicsMeshRef:
+		case ScriptReferenceType::PhysicsMesh:
 			return ScriptPhysicsMesh::getMetaData()->scriptClass->_getInternalClass();
-		case ScriptPrimitiveType::SceneObjectRef:
+		case ScriptReferenceType::SceneObject:
 			return ScriptAssemblyManager::instance().getSceneObjectClass()->_getInternalClass();
-		case ScriptPrimitiveType::ComponentRef:
-			return ScriptAssemblyManager::instance().getComponentClass()->_getInternalClass();
-		}
-
-		return nullptr;
-	}
-
-	RTTITypeBase* ManagedSerializableTypeInfoPrimitive::getRTTIStatic()
-	{
-		return ManagedSerializableTypeInfoPrimitiveRTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableTypeInfoPrimitive::getRTTI() const
-	{
-		return ManagedSerializableTypeInfoPrimitive::getRTTIStatic();
-	}
-
-	bool ManagedSerializableTypeInfoObject::matches(const ManagedSerializableTypeInfoPtr& typeInfo) const
-	{
-		if(!rtti_is_of_type<ManagedSerializableTypeInfoObject>(typeInfo))
-			return false;
-
-		auto objTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoObject>(typeInfo);
-
-		return objTypeInfo->mTypeNamespace == mTypeNamespace && objTypeInfo->mTypeName == mTypeName && objTypeInfo->mValueType == mValueType;
-	}
-
-	bool ManagedSerializableTypeInfoObject::isTypeLoaded() const
-	{
-		return ScriptAssemblyManager::instance().hasSerializableObjectInfo(mTypeNamespace, mTypeName);
-	}
-
-	::MonoClass* ManagedSerializableTypeInfoObject::getMonoClass() const
-	{
-		ManagedSerializableObjectInfoPtr objInfo;
-		if(!ScriptAssemblyManager::instance().getSerializableObjectInfo(mTypeNamespace, mTypeName, objInfo))
-			return nullptr;
-
-		return objInfo->mMonoClass->_getInternalClass();
-	}
-
-	RTTITypeBase* ManagedSerializableTypeInfoObject::getRTTIStatic()
-	{
-		return ManagedSerializableTypeInfoObjectRTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableTypeInfoObject::getRTTI() const
-	{
-		return ManagedSerializableTypeInfoObject::getRTTIStatic();
-	}
-
-	bool ManagedSerializableTypeInfoArray::matches(const ManagedSerializableTypeInfoPtr& typeInfo) const
-	{
-		if(!rtti_is_of_type<ManagedSerializableTypeInfoArray>(typeInfo))
-			return false;
-
-		auto arrayTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoArray>(typeInfo);
-
-		return arrayTypeInfo->mRank == mRank && arrayTypeInfo->mElementType->matches(mElementType);
-	}
-
-	bool ManagedSerializableTypeInfoArray::isTypeLoaded() const
-	{
-		return mElementType->isTypeLoaded();
-	}
-
-	::MonoClass* ManagedSerializableTypeInfoArray::getMonoClass() const
-	{
-		::MonoClass* elementClass = mElementType->getMonoClass();
-		if(elementClass == nullptr)
-			return nullptr;
-
-		return mono_array_class_get(mElementType->getMonoClass(), mRank);
-	}
-
-	RTTITypeBase* ManagedSerializableTypeInfoArray::getRTTIStatic()
-	{
-		return ManagedSerializableTypeInfoArrayRTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableTypeInfoArray::getRTTI() const
-	{
-		return ManagedSerializableTypeInfoArray::getRTTIStatic();
-	}
-
-	bool ManagedSerializableTypeInfoList::matches(const ManagedSerializableTypeInfoPtr& typeInfo) const
-	{
-		if(!rtti_is_of_type<ManagedSerializableTypeInfoList>(typeInfo))
-			return false;
-
-		auto listTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoList>(typeInfo);
-
-		return listTypeInfo->mElementType->matches(mElementType);
-	}
-
-	bool ManagedSerializableTypeInfoList::isTypeLoaded() const
-	{
-		return mElementType->isTypeLoaded();
-	}
-
-	::MonoClass* ManagedSerializableTypeInfoList::getMonoClass() const
-	{
-		::MonoClass* elementClass = mElementType->getMonoClass();
-		if(elementClass == nullptr)
-			return nullptr;
-
-		MonoClass* genericListClass = ScriptAssemblyManager::instance().getSystemGenericListClass();
-		MonoType* genParams[1] = { mono_class_get_type(elementClass) };
-
-		return mono_class_bind_generic_parameters(genericListClass->_getInternalClass(), 1, genParams, false);
-	}
-
-	RTTITypeBase* ManagedSerializableTypeInfoList::getRTTIStatic()
-	{
-		return ManagedSerializableTypeInfoListRTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableTypeInfoList::getRTTI() const
-	{
-		return ManagedSerializableTypeInfoList::getRTTIStatic();
-	}
-
-	bool ManagedSerializableTypeInfoDictionary::matches(const ManagedSerializableTypeInfoPtr& typeInfo) const
-	{
-		if(!rtti_is_of_type<ManagedSerializableTypeInfoDictionary>(typeInfo))
-			return false;
-
-		auto dictTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoDictionary>(typeInfo);
-
-		return dictTypeInfo->mKeyType->matches(mKeyType) && dictTypeInfo->mValueType->matches(mValueType);
-	}
-
-	bool ManagedSerializableTypeInfoDictionary::isTypeLoaded() const
-	{
-		return mKeyType->isTypeLoaded() && mValueType->isTypeLoaded();
-	}
-
-	::MonoClass* ManagedSerializableTypeInfoDictionary::getMonoClass() const
-	{
-		::MonoClass* keyClass = mKeyType->getMonoClass();
-		::MonoClass* valueClass = mValueType->getMonoClass();
-		if(keyClass == nullptr || valueClass == nullptr)
-			return nullptr;
-
-		MonoClass* genericDictionaryClass = ScriptAssemblyManager::instance().getSystemGenericDictionaryClass();
-		MonoType* genParams[2] = { mono_class_get_type(keyClass), mono_class_get_type(valueClass) };
-
-		return mono_class_bind_generic_parameters(genericDictionaryClass->_getInternalClass(), 2, genParams, false);
-	}
-
-	RTTITypeBase* ManagedSerializableTypeInfoDictionary::getRTTIStatic()
-	{
-		return ManagedSerializableTypeInfoDictionaryRTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializableTypeInfoDictionary::getRTTI() const
-	{
-		return ManagedSerializableTypeInfoDictionary::getRTTIStatic();
-	}
+		default:
+			break;
+		}
+
+		// Custom component or resource
+		ManagedSerializableObjectInfoPtr objInfo;
+		if (!ScriptAssemblyManager::instance().getSerializableObjectInfo(mTypeNamespace, mTypeName, objInfo))
+			return nullptr;
+
+		return objInfo->mMonoClass->_getInternalClass();
+	}
+
+	RTTITypeBase* ManagedSerializableTypeInfoRef::getRTTIStatic()
+	{
+		return ManagedSerializableTypeInfoRefRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableTypeInfoRef::getRTTI() const
+	{
+		return ManagedSerializableTypeInfoRef::getRTTIStatic();
+	}
+
+	bool ManagedSerializableTypeInfoObject::matches(const ManagedSerializableTypeInfoPtr& typeInfo) const
+	{
+		if(!rtti_is_of_type<ManagedSerializableTypeInfoObject>(typeInfo))
+			return false;
+
+		auto objTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoObject>(typeInfo);
+
+		return objTypeInfo->mTypeNamespace == mTypeNamespace && objTypeInfo->mTypeName == mTypeName && objTypeInfo->mValueType == mValueType;
+	}
+
+	bool ManagedSerializableTypeInfoObject::isTypeLoaded() const
+	{
+		return ScriptAssemblyManager::instance().hasSerializableObjectInfo(mTypeNamespace, mTypeName);
+	}
+
+	::MonoClass* ManagedSerializableTypeInfoObject::getMonoClass() const
+	{
+		ManagedSerializableObjectInfoPtr objInfo;
+		if(!ScriptAssemblyManager::instance().getSerializableObjectInfo(mTypeNamespace, mTypeName, objInfo))
+			return nullptr;
+
+		return objInfo->mMonoClass->_getInternalClass();
+	}
+
+	RTTITypeBase* ManagedSerializableTypeInfoObject::getRTTIStatic()
+	{
+		return ManagedSerializableTypeInfoObjectRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableTypeInfoObject::getRTTI() const
+	{
+		return ManagedSerializableTypeInfoObject::getRTTIStatic();
+	}
+
+	bool ManagedSerializableTypeInfoArray::matches(const ManagedSerializableTypeInfoPtr& typeInfo) const
+	{
+		if(!rtti_is_of_type<ManagedSerializableTypeInfoArray>(typeInfo))
+			return false;
+
+		auto arrayTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoArray>(typeInfo);
+
+		return arrayTypeInfo->mRank == mRank && arrayTypeInfo->mElementType->matches(mElementType);
+	}
+
+	bool ManagedSerializableTypeInfoArray::isTypeLoaded() const
+	{
+		return mElementType->isTypeLoaded();
+	}
+
+	::MonoClass* ManagedSerializableTypeInfoArray::getMonoClass() const
+	{
+		::MonoClass* elementClass = mElementType->getMonoClass();
+		if(elementClass == nullptr)
+			return nullptr;
+
+		return mono_array_class_get(mElementType->getMonoClass(), mRank);
+	}
+
+	RTTITypeBase* ManagedSerializableTypeInfoArray::getRTTIStatic()
+	{
+		return ManagedSerializableTypeInfoArrayRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableTypeInfoArray::getRTTI() const
+	{
+		return ManagedSerializableTypeInfoArray::getRTTIStatic();
+	}
+
+	bool ManagedSerializableTypeInfoList::matches(const ManagedSerializableTypeInfoPtr& typeInfo) const
+	{
+		if(!rtti_is_of_type<ManagedSerializableTypeInfoList>(typeInfo))
+			return false;
+
+		auto listTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoList>(typeInfo);
+
+		return listTypeInfo->mElementType->matches(mElementType);
+	}
+
+	bool ManagedSerializableTypeInfoList::isTypeLoaded() const
+	{
+		return mElementType->isTypeLoaded();
+	}
+
+	::MonoClass* ManagedSerializableTypeInfoList::getMonoClass() const
+	{
+		::MonoClass* elementClass = mElementType->getMonoClass();
+		if(elementClass == nullptr)
+			return nullptr;
+
+		MonoClass* genericListClass = ScriptAssemblyManager::instance().getSystemGenericListClass();
+		MonoType* genParams[1] = { mono_class_get_type(elementClass) };
+
+		return mono_class_bind_generic_parameters(genericListClass->_getInternalClass(), 1, genParams, false);
+	}
+
+	RTTITypeBase* ManagedSerializableTypeInfoList::getRTTIStatic()
+	{
+		return ManagedSerializableTypeInfoListRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableTypeInfoList::getRTTI() const
+	{
+		return ManagedSerializableTypeInfoList::getRTTIStatic();
+	}
+
+	bool ManagedSerializableTypeInfoDictionary::matches(const ManagedSerializableTypeInfoPtr& typeInfo) const
+	{
+		if(!rtti_is_of_type<ManagedSerializableTypeInfoDictionary>(typeInfo))
+			return false;
+
+		auto dictTypeInfo = std::static_pointer_cast<ManagedSerializableTypeInfoDictionary>(typeInfo);
+
+		return dictTypeInfo->mKeyType->matches(mKeyType) && dictTypeInfo->mValueType->matches(mValueType);
+	}
+
+	bool ManagedSerializableTypeInfoDictionary::isTypeLoaded() const
+	{
+		return mKeyType->isTypeLoaded() && mValueType->isTypeLoaded();
+	}
+
+	::MonoClass* ManagedSerializableTypeInfoDictionary::getMonoClass() const
+	{
+		::MonoClass* keyClass = mKeyType->getMonoClass();
+		::MonoClass* valueClass = mValueType->getMonoClass();
+		if(keyClass == nullptr || valueClass == nullptr)
+			return nullptr;
+
+		MonoClass* genericDictionaryClass = ScriptAssemblyManager::instance().getSystemGenericDictionaryClass();
+		MonoType* genParams[2] = { mono_class_get_type(keyClass), mono_class_get_type(valueClass) };
+
+		return mono_class_bind_generic_parameters(genericDictionaryClass->_getInternalClass(), 2, genParams, false);
+	}
+
+	RTTITypeBase* ManagedSerializableTypeInfoDictionary::getRTTIStatic()
+	{
+		return ManagedSerializableTypeInfoDictionaryRTTI::instance();
+	}
+
+	RTTITypeBase* ManagedSerializableTypeInfoDictionary::getRTTI() const
+	{
+		return ManagedSerializableTypeInfoDictionary::getRTTIStatic();
+	}
 }

+ 511 - 578
Source/SBansheeEngine/Source/BsScriptAssemblyManager.cpp

@@ -1,579 +1,512 @@
-//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
-//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#include "BsScriptAssemblyManager.h"
-#include "BsManagedSerializableObjectInfo.h"
-#include "BsMonoManager.h"
-#include "BsMonoAssembly.h"
-#include "BsMonoClass.h"
-#include "BsMonoField.h"
-#include "BsMonoMethod.h"
-#include "BsMonoProperty.h"
-#include "BsScriptManagedResource.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 "BsScriptPhysicsMaterial.h"
-#include "BsScriptPhysicsMesh.h"
-#include "BsScriptPrefab.h"
-
-namespace BansheeEngine
-{
-	ScriptAssemblyManager::ScriptAssemblyManager()
-		:mBaseTypesInitialized(false), mSerializeObjectAttribute(nullptr), mDontSerializeFieldAttribute(nullptr), 
-		mComponentClass(nullptr), mSceneObjectClass(nullptr), mSerializeFieldAttribute(nullptr), mHideInInspectorAttribute(nullptr), 
-		mSystemArrayClass(nullptr), mSystemGenericListClass(nullptr), mSystemGenericDictionaryClass(nullptr), mMissingComponentClass(nullptr),
-		mSystemTypeClass(nullptr)
-	{
-
-	}
-
-	ScriptAssemblyManager::~ScriptAssemblyManager()
-	{
-
-	}
-
-	Vector<String> ScriptAssemblyManager::getScriptAssemblies() const
-	{
-		Vector<String> initializedAssemblies;
-		for (auto& assemblyPair : mAssemblyInfos)
-			initializedAssemblies.push_back(assemblyPair.first);
-
-		return initializedAssemblies;
-	}
-
-	void ScriptAssemblyManager::loadAssemblyInfo(const String& assemblyName)
-	{
-		if(!mBaseTypesInitialized)
-			initializeBaseTypes();
-
-		// Process all classes and fields
-		UINT32 mUniqueTypeId = 1;
-
-		MonoAssembly* curAssembly = MonoManager::instance().getAssembly(assemblyName);
-		if(curAssembly == nullptr)
-			return;
-
-		std::shared_ptr<ManagedSerializableAssemblyInfo> assemblyInfo = bs_shared_ptr_new<ManagedSerializableAssemblyInfo>();
-		assemblyInfo->mName = assemblyName;
-
-		mAssemblyInfos[assemblyName] = assemblyInfo;
-
-		MonoClass* managedResourceClass = ScriptManagedResource::getMetaData()->scriptClass;
-
-		// Populate class data
-		const Vector<MonoClass*>& allClasses = curAssembly->getAllClasses();
-		for(auto& curClass : allClasses)
-		{
-			if ((curClass->isSubClassOf(mComponentClass) || curClass->isSubClassOf(managedResourceClass) ||
-				curClass->hasAttribute(mSerializeObjectAttribute)) && curClass != mComponentClass && curClass != managedResourceClass)
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoObject> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoObject>();
-				typeInfo->mTypeNamespace = curClass->getNamespace();
-				typeInfo->mTypeName = curClass->getTypeName();
-				typeInfo->mTypeId = mUniqueTypeId++;
-
-				MonoType* monoType = mono_class_get_type(curClass->_getInternalClass());
-				int monoPrimitiveType = mono_type_get_type(monoType);
-
-				if(monoPrimitiveType == MONO_TYPE_VALUETYPE)
-					typeInfo->mValueType = true;
-				else
-					typeInfo->mValueType = false;
-
-				std::shared_ptr<ManagedSerializableObjectInfo> objInfo = bs_shared_ptr_new<ManagedSerializableObjectInfo>();
-
-				objInfo->mTypeInfo = typeInfo;
-				objInfo->mMonoClass = curClass;
-
-				assemblyInfo->mTypeNameToId[objInfo->getFullTypeName()] = typeInfo->mTypeId;
-				assemblyInfo->mObjectInfos[typeInfo->mTypeId] = objInfo;
-			}
-		}
-
-		// Populate field data
-		for(auto& curClassInfo : assemblyInfo->mObjectInfos)
-		{
-			std::shared_ptr<ManagedSerializableObjectInfo> objInfo = curClassInfo.second;
-
-			UINT32 mUniqueFieldId = 1;
-			const Vector<MonoField*>& fields = objInfo->mMonoClass->getAllFields();
-
-			for(auto& field : fields)
-			{
-				if(field->isStatic())
-					continue;
-
-				ManagedSerializableTypeInfoPtr typeInfo = getTypeInfo(field->getType());
-				if (typeInfo == nullptr)
-					continue;
-
-				std::shared_ptr<ManagedSerializableFieldInfo> fieldInfo = bs_shared_ptr_new<ManagedSerializableFieldInfo>();
-				fieldInfo->mFieldId = mUniqueFieldId++;
-				fieldInfo->mName = field->getName();
-				fieldInfo->mMonoField = field;
-				fieldInfo->mTypeInfo = typeInfo;
-				fieldInfo->mParentTypeId = objInfo->mTypeInfo->mTypeId;
-				
-				MonoFieldVisibility visibility = field->getVisibility();
-				if (visibility == MonoFieldVisibility::Public)
-				{
-					if (!field->hasAttribute(mDontSerializeFieldAttribute))
-						fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Serializable);
-
-					if (!field->hasAttribute(mHideInInspectorAttribute))
-						fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Inspectable);
-				}
-				else
-				{
-					if (field->hasAttribute(mSerializeFieldAttribute))
-						fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Serializable);
-				}
-
-				objInfo->mFieldNameToId[fieldInfo->mName] = fieldInfo->mFieldId;
-				objInfo->mFields[fieldInfo->mFieldId] = fieldInfo;
-			}
-		}
-
-		// Form parent/child connections
-		for(auto& curClass : assemblyInfo->mObjectInfos)
-		{
-			MonoClass* base = curClass.second->mMonoClass->getBaseClass();
-			while(base != nullptr)
-			{
-				std::shared_ptr<ManagedSerializableObjectInfo> baseObjInfo;
-				if(getSerializableObjectInfo(base->getNamespace(), base->getTypeName(), baseObjInfo))
-				{
-					curClass.second->mBaseClass = baseObjInfo;
-					baseObjInfo->mDerivedClasses.push_back(curClass.second);
-
-					break;
-				}
-
-				base = base->getBaseClass();
-			}
-		}
-	}
-
-	void ScriptAssemblyManager::clearAssemblyInfo()
-	{
-		clearScriptObjects();
-		mAssemblyInfos.clear();
-	}
-
-	ManagedSerializableTypeInfoPtr ScriptAssemblyManager::getTypeInfo(MonoClass* monoClass)
-	{
-		if(!mBaseTypesInitialized)
-			BS_EXCEPT(InvalidStateException, "Calling determineType without previously initializing base types.");
-
-		MonoType* monoType = mono_class_get_type(monoClass->_getInternalClass());
-		int monoPrimitiveType = mono_type_get_type(monoType);
-		
-		// If enum get the enum base data type
-		bool isEnum = mono_class_is_enum(monoClass->_getInternalClass()) == 1;
-		if (isEnum)
-		{
-			MonoType* underlyingType = mono_type_get_underlying_type(monoType);
-			monoPrimitiveType = mono_type_get_type(underlyingType);
-		}
-
-		//  Determine field type
-		switch(monoPrimitiveType)
-		{
-		case MONO_TYPE_BOOLEAN:
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::Bool;
-				return typeInfo;
-			}
-		case MONO_TYPE_CHAR:
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::Char;
-				return typeInfo;
-			}
-		case MONO_TYPE_I1:
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::I8;
-				return typeInfo;
-			}
-		case MONO_TYPE_U1:
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::U8;
-				return typeInfo;
-			}
-		case MONO_TYPE_I2:
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::I16;
-				return typeInfo;
-			}
-		case MONO_TYPE_U2:
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::U16;
-				return typeInfo;
-			}
-		case MONO_TYPE_I4:
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::I32;
-				return typeInfo;
-			}
-		case MONO_TYPE_U4:
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::U32;
-				return typeInfo;
-			}
-		case MONO_TYPE_I8:
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::I64;
-				return typeInfo;
-			}
-		case MONO_TYPE_U8:
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::U64;
-				return typeInfo;
-			}
-		case MONO_TYPE_STRING:
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::String;
-				return typeInfo;
-			}
-		case MONO_TYPE_R4:
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::Float;
-				return typeInfo;
-			}
-		case MONO_TYPE_R8:
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::Double;
-				return typeInfo;
-			}
-		case MONO_TYPE_CLASS:
-			if(monoClass->isSubClassOf(ScriptTexture2D::getMetaData()->scriptClass))
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::Texture2DRef;
-				return typeInfo;
-			}
-			if (monoClass->isSubClassOf(ScriptTexture3D::getMetaData()->scriptClass))
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::Texture3DRef;
-				return typeInfo;
-			}
-			if (monoClass->isSubClassOf(ScriptTextureCube::getMetaData()->scriptClass))
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::TextureCubeRef;
-				return typeInfo;
-			}
-			else if (monoClass->isSubClassOf(ScriptSpriteTexture::getMetaData()->scriptClass))
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::SpriteTextureRef;
-				return typeInfo;
-			}
-			else if (monoClass->isSubClassOf(ScriptManagedResource::getMetaData()->scriptClass))
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::ManagedResourceRef;
-				return typeInfo;
-			}
-			else if (monoClass->isSubClassOf(ScriptShader::getMetaData()->scriptClass))
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::ShaderRef;
-				return typeInfo;
-			}
-			else if (monoClass->isSubClassOf(ScriptShaderInclude::getMetaData()->scriptClass))
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::ShaderIncludeRef;
-				return typeInfo;
-			}
-			else if (monoClass->isSubClassOf(ScriptMaterial::getMetaData()->scriptClass))
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::MaterialRef;
-				return typeInfo;
-			}
-			else if (monoClass->isSubClassOf(ScriptMesh::getMetaData()->scriptClass))
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::MeshRef;
-				return typeInfo;
-			}
-			else if (monoClass->isSubClassOf(ScriptPlainText::getMetaData()->scriptClass))
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::PlainTextRef;
-				return typeInfo;
-			}
-			else if (monoClass->isSubClassOf(ScriptScriptCode::getMetaData()->scriptClass))
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::ScriptCodeRef;
-				return typeInfo;
-			}
-			else if (monoClass->isSubClassOf(ScriptPrefab::getMetaData()->scriptClass))
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::PrefabRef;
-				return typeInfo;
-			}
-			else if (monoClass->isSubClassOf(ScriptFont::getMetaData()->scriptClass))
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::FontRef;
-				return typeInfo;
-			}
-			else if (monoClass->isSubClassOf(ScriptStringTable::getMetaData()->scriptClass))
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::StringTableRef;
-				return typeInfo;
-			}
-			else if (monoClass->isSubClassOf(ScriptGUISkin::getMetaData()->scriptClass))
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::GUISkinRef;
-				return typeInfo;
-			}
-			else if (monoClass->isSubClassOf(ScriptPhysicsMaterial::getMetaData()->scriptClass))
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::PhysicsMaterialRef;
-				return typeInfo;
-			}
-			else if (monoClass->isSubClassOf(ScriptPhysicsMesh::getMetaData()->scriptClass))
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::PhysicsMeshRef;
-				return typeInfo;
-			}
-			else if(monoClass->isSubClassOf(mSceneObjectClass))
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::SceneObjectRef;
-				return typeInfo;
-			}
-			else if(monoClass->isSubClassOf(mComponentClass))
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
-				typeInfo->mType = ScriptPrimitiveType::ComponentRef;
-				return typeInfo;
-			}
-			else
-			{
-				std::shared_ptr<ManagedSerializableObjectInfo> objInfo;
-				if (getSerializableObjectInfo(monoClass->getNamespace(), monoClass->getTypeName(), objInfo))
-					return objInfo->mTypeInfo;
-			}
-
-			break;
-		case MONO_TYPE_VALUETYPE:
-			{
-				std::shared_ptr<ManagedSerializableObjectInfo> objInfo;
-				if (getSerializableObjectInfo(monoClass->getNamespace(), monoClass->getTypeName(), objInfo))
-					return objInfo->mTypeInfo;
-			}
-
-			break;
-		case MONO_TYPE_GENERICINST:
-			if(monoClass->getFullName() == mSystemGenericListClass->getFullName()) // Full name is part of CIL spec, so it is just fine to compare like this
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoList> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoList>();
-
-				MonoProperty& itemProperty = monoClass->getProperty("Item");
-				MonoClass* itemClass = itemProperty.getReturnType();
-
-				if (itemClass != nullptr)
-					typeInfo->mElementType = getTypeInfo(itemClass);
-				
-				if (typeInfo->mElementType == nullptr)
-					return nullptr;
-
-				return typeInfo;
-			}
-			else if(monoClass->getFullName() == mSystemGenericDictionaryClass->getFullName())
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoDictionary> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoDictionary>();
-
-				MonoMethod* getEnumerator = monoClass->getMethod("GetEnumerator");
-				MonoClass* enumClass = getEnumerator->getReturnType();
-
-				MonoProperty& currentProp = enumClass->getProperty("Current");
-				MonoClass* keyValuePair = currentProp.getReturnType();
-
-				MonoProperty& keyProperty = keyValuePair->getProperty("Key");
-				MonoProperty& valueProperty = keyValuePair->getProperty("Value");
-
-				MonoClass* keyClass = keyProperty.getReturnType();
-				if(keyClass != nullptr)
-					typeInfo->mKeyType = getTypeInfo(keyClass);
-
-				MonoClass* valueClass = valueProperty.getReturnType();
-				if(valueClass != nullptr)
-					typeInfo->mValueType = getTypeInfo(valueClass);
-
-				if (typeInfo->mKeyType == nullptr || typeInfo->mValueType == nullptr)
-					return nullptr;
-
-				return typeInfo;
-			}
-			break;
-		case MONO_TYPE_SZARRAY:
-		case MONO_TYPE_ARRAY:
-			{
-				std::shared_ptr<ManagedSerializableTypeInfoArray> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoArray>();
-
-				::MonoClass* elementClass = mono_class_get_element_class(monoClass->_getInternalClass());
-				if(elementClass != nullptr)
-				{
-					MonoClass* monoElementClass = MonoManager::instance().findClass(elementClass);
-					if(monoElementClass != nullptr)
-						typeInfo->mElementType = getTypeInfo(monoElementClass);
-				}
-
-				if (typeInfo->mElementType == nullptr)
-					return nullptr;
-
-				typeInfo->mRank = (UINT32)mono_class_get_rank(monoClass->_getInternalClass());
-
-				return typeInfo;
-			}
-		}
-
-		return nullptr;
-	}
-
-	void ScriptAssemblyManager::clearScriptObjects()
-	{
-		mBaseTypesInitialized = false;
-
-		mSystemArrayClass = nullptr;
-		mSystemGenericListClass = nullptr;
-		mSystemGenericDictionaryClass = nullptr;
-		mSystemTypeClass = nullptr;
-
-		mSerializeObjectAttribute = nullptr;
-		mDontSerializeFieldAttribute = nullptr;
-
-		mComponentClass = nullptr;
-		mSceneObjectClass = nullptr;
-		mMissingComponentClass = nullptr;
-
-		mSerializeFieldAttribute = nullptr;
-		mHideInInspectorAttribute = nullptr;
-	}
-
-	void ScriptAssemblyManager::initializeBaseTypes()
-	{
-		// Get necessary classes for detecting needed class & field information
-		MonoAssembly* corlib = MonoManager::instance().getAssembly("corlib");
-		if(corlib == nullptr)
-			BS_EXCEPT(InvalidStateException, "corlib assembly is not loaded.");
-
-		MonoAssembly* bansheeEngineAssembly = MonoManager::instance().getAssembly(ENGINE_ASSEMBLY);
-		if(bansheeEngineAssembly == nullptr)
-			BS_EXCEPT(InvalidStateException, String(ENGINE_ASSEMBLY) +  " assembly is not loaded.");
-
-		mSystemArrayClass = corlib->getClass("System", "Array");
-		if(mSystemArrayClass == nullptr)
-			BS_EXCEPT(InvalidStateException, "Cannot find System.Array managed class.");
-
-		mSystemGenericListClass = corlib->getClass("System.Collections.Generic", "List`1");
-		if(mSystemGenericListClass == nullptr)
-			BS_EXCEPT(InvalidStateException, "Cannot find List<T> managed class.");
-
-		mSystemGenericDictionaryClass = corlib->getClass("System.Collections.Generic", "Dictionary`2");
-		if(mSystemGenericDictionaryClass == nullptr)
-			BS_EXCEPT(InvalidStateException, "Cannot find Dictionary<TKey, TValue> managed class.");
-
-		mSystemTypeClass = corlib->getClass("System", "Type");
-		if (mSystemTypeClass == nullptr)
-			BS_EXCEPT(InvalidStateException, "Cannot find Type managed class.");
-
-		mSerializeObjectAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "SerializeObject");
-		if(mSerializeObjectAttribute == nullptr)
-			BS_EXCEPT(InvalidStateException, "Cannot find SerializableObject managed class.");
-
-		mDontSerializeFieldAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "DontSerializeField");
-		if(mDontSerializeFieldAttribute == nullptr)
-			BS_EXCEPT(InvalidStateException, "Cannot find DontSerializeField managed class.");
-
-		mComponentClass = bansheeEngineAssembly->getClass("BansheeEngine", "Component");
-		if(mComponentClass == nullptr)
-			BS_EXCEPT(InvalidStateException, "Cannot find Component managed class.");
-
-		mMissingComponentClass = bansheeEngineAssembly->getClass("BansheeEngine", "MissingComponent");
-		if (mMissingComponentClass == nullptr)
-			BS_EXCEPT(InvalidStateException, "Cannot find MissingComponent managed class.");
-
-		mSceneObjectClass = bansheeEngineAssembly->getClass("BansheeEngine", "SceneObject");
-		if(mSceneObjectClass == nullptr)
-			BS_EXCEPT(InvalidStateException, "Cannot find SceneObject managed class.");
-
-		mSerializeFieldAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "SerializeField");
-		if(mSerializeFieldAttribute == nullptr)
-			BS_EXCEPT(InvalidStateException, "Cannot find SerializeField managed class.");
-
-		mHideInInspectorAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "HideInInspector");
-		if(mHideInInspectorAttribute == nullptr)
-			BS_EXCEPT(InvalidStateException, "Cannot find HideInInspector managed class.");
-
-		mBaseTypesInitialized = true;
-	}
-
-	bool ScriptAssemblyManager::getSerializableObjectInfo(const String& ns, const String& typeName, std::shared_ptr<ManagedSerializableObjectInfo>& outInfo)
-	{
-		String fullName = ns + "." + typeName;
-		for(auto& curAssembly : mAssemblyInfos)
-		{
-			if (curAssembly.second == nullptr)
-				continue;
-
-			auto iterFind = curAssembly.second->mTypeNameToId.find(fullName);
-			if(iterFind != curAssembly.second->mTypeNameToId.end())
-			{
-				outInfo = curAssembly.second->mObjectInfos[iterFind->second];
-
-				return true;
-			}
-		}
-
-		return false;
-	}
-
-	bool ScriptAssemblyManager::hasSerializableObjectInfo(const String& ns, const String& typeName)
-	{
-		String fullName = ns + "." + typeName;
-		for(auto& curAssembly : mAssemblyInfos)
-		{
-			auto iterFind = curAssembly.second->mTypeNameToId.find(fullName);
-			if(iterFind != curAssembly.second->mTypeNameToId.end())
-				return true;
-		}
-
-		return false;
-	}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsScriptAssemblyManager.h"
+#include "BsManagedSerializableObjectInfo.h"
+#include "BsMonoManager.h"
+#include "BsMonoAssembly.h"
+#include "BsMonoClass.h"
+#include "BsMonoField.h"
+#include "BsMonoMethod.h"
+#include "BsMonoProperty.h"
+#include "BsScriptManagedResource.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 "BsScriptPhysicsMaterial.h"
+#include "BsScriptPhysicsMesh.h"
+#include "BsScriptPrefab.h"
+
+namespace BansheeEngine
+{
+	ScriptAssemblyManager::ScriptAssemblyManager()
+		:mBaseTypesInitialized(false), mSerializeObjectAttribute(nullptr), mDontSerializeFieldAttribute(nullptr), 
+		mComponentClass(nullptr), mSceneObjectClass(nullptr), mSerializeFieldAttribute(nullptr), mHideInInspectorAttribute(nullptr), 
+		mSystemArrayClass(nullptr), mSystemGenericListClass(nullptr), mSystemGenericDictionaryClass(nullptr), mMissingComponentClass(nullptr),
+		mSystemTypeClass(nullptr)
+	{
+
+	}
+
+	ScriptAssemblyManager::~ScriptAssemblyManager()
+	{
+
+	}
+
+	Vector<String> ScriptAssemblyManager::getScriptAssemblies() const
+	{
+		Vector<String> initializedAssemblies;
+		for (auto& assemblyPair : mAssemblyInfos)
+			initializedAssemblies.push_back(assemblyPair.first);
+
+		return initializedAssemblies;
+	}
+
+	void ScriptAssemblyManager::loadAssemblyInfo(const String& assemblyName)
+	{
+		if(!mBaseTypesInitialized)
+			initializeBaseTypes();
+
+		// Process all classes and fields
+		UINT32 mUniqueTypeId = 1;
+
+		MonoAssembly* curAssembly = MonoManager::instance().getAssembly(assemblyName);
+		if(curAssembly == nullptr)
+			return;
+
+		std::shared_ptr<ManagedSerializableAssemblyInfo> assemblyInfo = bs_shared_ptr_new<ManagedSerializableAssemblyInfo>();
+		assemblyInfo->mName = assemblyName;
+
+		mAssemblyInfos[assemblyName] = assemblyInfo;
+
+		MonoClass* managedResourceClass = ScriptManagedResource::getMetaData()->scriptClass;
+
+		// Populate class data
+		const Vector<MonoClass*>& allClasses = curAssembly->getAllClasses();
+		for(auto& curClass : allClasses)
+		{
+			if ((curClass->isSubClassOf(mComponentClass) || curClass->isSubClassOf(managedResourceClass) ||
+				curClass->hasAttribute(mSerializeObjectAttribute)) && curClass != mComponentClass && curClass != managedResourceClass)
+			{
+				std::shared_ptr<ManagedSerializableTypeInfoObject> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoObject>();
+				typeInfo->mTypeNamespace = curClass->getNamespace();
+				typeInfo->mTypeName = curClass->getTypeName();
+				typeInfo->mTypeId = mUniqueTypeId++;
+
+				MonoType* monoType = mono_class_get_type(curClass->_getInternalClass());
+				int monoPrimitiveType = mono_type_get_type(monoType);
+
+				if(monoPrimitiveType == MONO_TYPE_VALUETYPE)
+					typeInfo->mValueType = true;
+				else
+					typeInfo->mValueType = false;
+
+				std::shared_ptr<ManagedSerializableObjectInfo> objInfo = bs_shared_ptr_new<ManagedSerializableObjectInfo>();
+
+				objInfo->mTypeInfo = typeInfo;
+				objInfo->mMonoClass = curClass;
+
+				assemblyInfo->mTypeNameToId[objInfo->getFullTypeName()] = typeInfo->mTypeId;
+				assemblyInfo->mObjectInfos[typeInfo->mTypeId] = objInfo;
+			}
+		}
+
+		// Populate field data
+		for(auto& curClassInfo : assemblyInfo->mObjectInfos)
+		{
+			std::shared_ptr<ManagedSerializableObjectInfo> objInfo = curClassInfo.second;
+
+			UINT32 mUniqueFieldId = 1;
+			const Vector<MonoField*>& fields = objInfo->mMonoClass->getAllFields();
+
+			for(auto& field : fields)
+			{
+				if(field->isStatic())
+					continue;
+
+				ManagedSerializableTypeInfoPtr typeInfo = getTypeInfo(field->getType());
+				if (typeInfo == nullptr)
+					continue;
+
+				std::shared_ptr<ManagedSerializableFieldInfo> fieldInfo = bs_shared_ptr_new<ManagedSerializableFieldInfo>();
+				fieldInfo->mFieldId = mUniqueFieldId++;
+				fieldInfo->mName = field->getName();
+				fieldInfo->mMonoField = field;
+				fieldInfo->mTypeInfo = typeInfo;
+				fieldInfo->mParentTypeId = objInfo->mTypeInfo->mTypeId;
+				
+				MonoFieldVisibility visibility = field->getVisibility();
+				if (visibility == MonoFieldVisibility::Public)
+				{
+					if (!field->hasAttribute(mDontSerializeFieldAttribute))
+						fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Serializable);
+
+					if (!field->hasAttribute(mHideInInspectorAttribute))
+						fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Inspectable);
+				}
+				else
+				{
+					if (field->hasAttribute(mSerializeFieldAttribute))
+						fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Serializable);
+				}
+
+				objInfo->mFieldNameToId[fieldInfo->mName] = fieldInfo->mFieldId;
+				objInfo->mFields[fieldInfo->mFieldId] = fieldInfo;
+			}
+		}
+
+		// Form parent/child connections
+		for(auto& curClass : assemblyInfo->mObjectInfos)
+		{
+			MonoClass* base = curClass.second->mMonoClass->getBaseClass();
+			while(base != nullptr)
+			{
+				std::shared_ptr<ManagedSerializableObjectInfo> baseObjInfo;
+				if(getSerializableObjectInfo(base->getNamespace(), base->getTypeName(), baseObjInfo))
+				{
+					curClass.second->mBaseClass = baseObjInfo;
+					baseObjInfo->mDerivedClasses.push_back(curClass.second);
+
+					break;
+				}
+
+				base = base->getBaseClass();
+			}
+		}
+	}
+
+	void ScriptAssemblyManager::clearAssemblyInfo()
+	{
+		clearScriptObjects();
+		mAssemblyInfos.clear();
+	}
+
+	ManagedSerializableTypeInfoPtr ScriptAssemblyManager::getTypeInfo(MonoClass* monoClass)
+	{
+		if(!mBaseTypesInitialized)
+			BS_EXCEPT(InvalidStateException, "Calling determineType without previously initializing base types.");
+
+		MonoType* monoType = mono_class_get_type(monoClass->_getInternalClass());
+		int monoPrimitiveType = mono_type_get_type(monoType);
+		
+		// If enum get the enum base data type
+		bool isEnum = mono_class_is_enum(monoClass->_getInternalClass()) == 1;
+		if (isEnum)
+		{
+			MonoType* underlyingType = mono_type_get_underlying_type(monoType);
+			monoPrimitiveType = mono_type_get_type(underlyingType);
+		}
+
+		//  Determine field type
+		switch(monoPrimitiveType)
+		{
+		case MONO_TYPE_BOOLEAN:
+			{
+				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::Bool;
+				return typeInfo;
+			}
+		case MONO_TYPE_CHAR:
+			{
+				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::Char;
+				return typeInfo;
+			}
+		case MONO_TYPE_I1:
+			{
+				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::I8;
+				return typeInfo;
+			}
+		case MONO_TYPE_U1:
+			{
+				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::U8;
+				return typeInfo;
+			}
+		case MONO_TYPE_I2:
+			{
+				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::I16;
+				return typeInfo;
+			}
+		case MONO_TYPE_U2:
+			{
+				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::U16;
+				return typeInfo;
+			}
+		case MONO_TYPE_I4:
+			{
+				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::I32;
+				return typeInfo;
+			}
+		case MONO_TYPE_U4:
+			{
+				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::U32;
+				return typeInfo;
+			}
+		case MONO_TYPE_I8:
+			{
+				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::I64;
+				return typeInfo;
+			}
+		case MONO_TYPE_U8:
+			{
+				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::U64;
+				return typeInfo;
+			}
+		case MONO_TYPE_STRING:
+			{
+				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::String;
+				return typeInfo;
+			}
+		case MONO_TYPE_R4:
+			{
+				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::Float;
+				return typeInfo;
+			}
+		case MONO_TYPE_R8:
+			{
+				std::shared_ptr<ManagedSerializableTypeInfoPrimitive> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::Double;
+				return typeInfo;
+			}
+		case MONO_TYPE_CLASS:
+			if(monoClass->isSubClassOf(ScriptResource::getMetaData()->scriptClass) || monoClass->isSubClassOf(mSceneObjectClass) || monoClass->isSubClassOf(mComponentClass))
+			{
+				std::shared_ptr<ManagedSerializableTypeInfoRef> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoRef>();
+				typeInfo->mTypeNamespace = monoClass->getNamespace();
+				typeInfo->mTypeName = monoClass->getTypeName();
+
+				if (monoClass->isSubClassOf(ScriptTexture2D::getMetaData()->scriptClass))
+					typeInfo->mType = ScriptReferenceType::Texture2D;
+				else if (monoClass->isSubClassOf(ScriptTexture3D::getMetaData()->scriptClass))
+					typeInfo->mType = ScriptReferenceType::Texture3D;
+				else if (monoClass->isSubClassOf(ScriptTextureCube::getMetaData()->scriptClass))
+					typeInfo->mType = ScriptReferenceType::TextureCube;
+				else if (monoClass->isSubClassOf(ScriptSpriteTexture::getMetaData()->scriptClass))
+					typeInfo->mType = ScriptReferenceType::SpriteTexture;
+				else if (monoClass->isSubClassOf(ScriptManagedResource::getMetaData()->scriptClass))
+					typeInfo->mType = ScriptReferenceType::ManagedResource;
+				else if (monoClass->isSubClassOf(ScriptShader::getMetaData()->scriptClass))
+					typeInfo->mType = ScriptReferenceType::Shader;
+				else if (monoClass->isSubClassOf(ScriptShaderInclude::getMetaData()->scriptClass))
+					typeInfo->mType = ScriptReferenceType::ShaderInclude;
+				else if (monoClass->isSubClassOf(ScriptMaterial::getMetaData()->scriptClass))
+					typeInfo->mType = ScriptReferenceType::Material;
+				else if (monoClass->isSubClassOf(ScriptMesh::getMetaData()->scriptClass))
+					typeInfo->mType = ScriptReferenceType::Mesh;
+				else if (monoClass->isSubClassOf(ScriptPlainText::getMetaData()->scriptClass))
+					typeInfo->mType = ScriptReferenceType::PlainText;
+				else if (monoClass->isSubClassOf(ScriptScriptCode::getMetaData()->scriptClass))
+					typeInfo->mType = ScriptReferenceType::ScriptCode;
+				else if (monoClass->isSubClassOf(ScriptPrefab::getMetaData()->scriptClass))
+					typeInfo->mType = ScriptReferenceType::Prefab;
+				else if (monoClass->isSubClassOf(ScriptFont::getMetaData()->scriptClass))
+					typeInfo->mType = ScriptReferenceType::Font;
+				else if (monoClass->isSubClassOf(ScriptStringTable::getMetaData()->scriptClass))
+					typeInfo->mType = ScriptReferenceType::StringTable;
+				else if (monoClass->isSubClassOf(ScriptGUISkin::getMetaData()->scriptClass))
+					typeInfo->mType = ScriptReferenceType::GUISkin;
+				else if (monoClass->isSubClassOf(ScriptPhysicsMaterial::getMetaData()->scriptClass))
+					typeInfo->mType = ScriptReferenceType::PhysicsMaterial;
+				else if (monoClass->isSubClassOf(ScriptPhysicsMesh::getMetaData()->scriptClass))
+					typeInfo->mType = ScriptReferenceType::PhysicsMesh;
+				else if (monoClass->isSubClassOf(mSceneObjectClass))
+					typeInfo->mType = ScriptReferenceType::SceneObject;
+				else if (monoClass->isSubClassOf(mComponentClass))
+					typeInfo->mType = ScriptReferenceType::Component;
+
+				return typeInfo;
+			}
+			else
+			{
+				std::shared_ptr<ManagedSerializableObjectInfo> objInfo;
+				if (getSerializableObjectInfo(monoClass->getNamespace(), monoClass->getTypeName(), objInfo))
+					return objInfo->mTypeInfo;
+			}
+
+			break;
+		case MONO_TYPE_VALUETYPE:
+			{
+				std::shared_ptr<ManagedSerializableObjectInfo> objInfo;
+				if (getSerializableObjectInfo(monoClass->getNamespace(), monoClass->getTypeName(), objInfo))
+					return objInfo->mTypeInfo;
+			}
+
+			break;
+		case MONO_TYPE_GENERICINST:
+			if(monoClass->getFullName() == mSystemGenericListClass->getFullName()) // Full name is part of CIL spec, so it is just fine to compare like this
+			{
+				std::shared_ptr<ManagedSerializableTypeInfoList> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoList>();
+
+				MonoProperty& itemProperty = monoClass->getProperty("Item");
+				MonoClass* itemClass = itemProperty.getReturnType();
+
+				if (itemClass != nullptr)
+					typeInfo->mElementType = getTypeInfo(itemClass);
+				
+				if (typeInfo->mElementType == nullptr)
+					return nullptr;
+
+				return typeInfo;
+			}
+			else if(monoClass->getFullName() == mSystemGenericDictionaryClass->getFullName())
+			{
+				std::shared_ptr<ManagedSerializableTypeInfoDictionary> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoDictionary>();
+
+				MonoMethod* getEnumerator = monoClass->getMethod("GetEnumerator");
+				MonoClass* enumClass = getEnumerator->getReturnType();
+
+				MonoProperty& currentProp = enumClass->getProperty("Current");
+				MonoClass* keyValuePair = currentProp.getReturnType();
+
+				MonoProperty& keyProperty = keyValuePair->getProperty("Key");
+				MonoProperty& valueProperty = keyValuePair->getProperty("Value");
+
+				MonoClass* keyClass = keyProperty.getReturnType();
+				if(keyClass != nullptr)
+					typeInfo->mKeyType = getTypeInfo(keyClass);
+
+				MonoClass* valueClass = valueProperty.getReturnType();
+				if(valueClass != nullptr)
+					typeInfo->mValueType = getTypeInfo(valueClass);
+
+				if (typeInfo->mKeyType == nullptr || typeInfo->mValueType == nullptr)
+					return nullptr;
+
+				return typeInfo;
+			}
+			break;
+		case MONO_TYPE_SZARRAY:
+		case MONO_TYPE_ARRAY:
+			{
+				std::shared_ptr<ManagedSerializableTypeInfoArray> typeInfo = bs_shared_ptr_new<ManagedSerializableTypeInfoArray>();
+
+				::MonoClass* elementClass = mono_class_get_element_class(monoClass->_getInternalClass());
+				if(elementClass != nullptr)
+				{
+					MonoClass* monoElementClass = MonoManager::instance().findClass(elementClass);
+					if(monoElementClass != nullptr)
+						typeInfo->mElementType = getTypeInfo(monoElementClass);
+				}
+
+				if (typeInfo->mElementType == nullptr)
+					return nullptr;
+
+				typeInfo->mRank = (UINT32)mono_class_get_rank(monoClass->_getInternalClass());
+
+				return typeInfo;
+			}
+		}
+
+		return nullptr;
+	}
+
+	void ScriptAssemblyManager::clearScriptObjects()
+	{
+		mBaseTypesInitialized = false;
+
+		mSystemArrayClass = nullptr;
+		mSystemGenericListClass = nullptr;
+		mSystemGenericDictionaryClass = nullptr;
+		mSystemTypeClass = nullptr;
+
+		mSerializeObjectAttribute = nullptr;
+		mDontSerializeFieldAttribute = nullptr;
+
+		mComponentClass = nullptr;
+		mSceneObjectClass = nullptr;
+		mMissingComponentClass = nullptr;
+
+		mSerializeFieldAttribute = nullptr;
+		mHideInInspectorAttribute = nullptr;
+	}
+
+	void ScriptAssemblyManager::initializeBaseTypes()
+	{
+		// Get necessary classes for detecting needed class & field information
+		MonoAssembly* corlib = MonoManager::instance().getAssembly("corlib");
+		if(corlib == nullptr)
+			BS_EXCEPT(InvalidStateException, "corlib assembly is not loaded.");
+
+		MonoAssembly* bansheeEngineAssembly = MonoManager::instance().getAssembly(ENGINE_ASSEMBLY);
+		if(bansheeEngineAssembly == nullptr)
+			BS_EXCEPT(InvalidStateException, String(ENGINE_ASSEMBLY) +  " assembly is not loaded.");
+
+		mSystemArrayClass = corlib->getClass("System", "Array");
+		if(mSystemArrayClass == nullptr)
+			BS_EXCEPT(InvalidStateException, "Cannot find System.Array managed class.");
+
+		mSystemGenericListClass = corlib->getClass("System.Collections.Generic", "List`1");
+		if(mSystemGenericListClass == nullptr)
+			BS_EXCEPT(InvalidStateException, "Cannot find List<T> managed class.");
+
+		mSystemGenericDictionaryClass = corlib->getClass("System.Collections.Generic", "Dictionary`2");
+		if(mSystemGenericDictionaryClass == nullptr)
+			BS_EXCEPT(InvalidStateException, "Cannot find Dictionary<TKey, TValue> managed class.");
+
+		mSystemTypeClass = corlib->getClass("System", "Type");
+		if (mSystemTypeClass == nullptr)
+			BS_EXCEPT(InvalidStateException, "Cannot find Type managed class.");
+
+		mSerializeObjectAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "SerializeObject");
+		if(mSerializeObjectAttribute == nullptr)
+			BS_EXCEPT(InvalidStateException, "Cannot find SerializableObject managed class.");
+
+		mDontSerializeFieldAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "DontSerializeField");
+		if(mDontSerializeFieldAttribute == nullptr)
+			BS_EXCEPT(InvalidStateException, "Cannot find DontSerializeField managed class.");
+
+		mComponentClass = bansheeEngineAssembly->getClass("BansheeEngine", "Component");
+		if(mComponentClass == nullptr)
+			BS_EXCEPT(InvalidStateException, "Cannot find Component managed class.");
+
+		mMissingComponentClass = bansheeEngineAssembly->getClass("BansheeEngine", "MissingComponent");
+		if (mMissingComponentClass == nullptr)
+			BS_EXCEPT(InvalidStateException, "Cannot find MissingComponent managed class.");
+
+		mSceneObjectClass = bansheeEngineAssembly->getClass("BansheeEngine", "SceneObject");
+		if(mSceneObjectClass == nullptr)
+			BS_EXCEPT(InvalidStateException, "Cannot find SceneObject managed class.");
+
+		mSerializeFieldAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "SerializeField");
+		if(mSerializeFieldAttribute == nullptr)
+			BS_EXCEPT(InvalidStateException, "Cannot find SerializeField managed class.");
+
+		mHideInInspectorAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "HideInInspector");
+		if(mHideInInspectorAttribute == nullptr)
+			BS_EXCEPT(InvalidStateException, "Cannot find HideInInspector managed class.");
+
+		mBaseTypesInitialized = true;
+	}
+
+	bool ScriptAssemblyManager::getSerializableObjectInfo(const String& ns, const String& typeName, std::shared_ptr<ManagedSerializableObjectInfo>& outInfo)
+	{
+		String fullName = ns + "." + typeName;
+		for(auto& curAssembly : mAssemblyInfos)
+		{
+			if (curAssembly.second == nullptr)
+				continue;
+
+			auto iterFind = curAssembly.second->mTypeNameToId.find(fullName);
+			if(iterFind != curAssembly.second->mTypeNameToId.end())
+			{
+				outInfo = curAssembly.second->mObjectInfos[iterFind->second];
+
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	bool ScriptAssemblyManager::hasSerializableObjectInfo(const String& ns, const String& typeName)
+	{
+		String fullName = ns + "." + typeName;
+		for(auto& curAssembly : mAssemblyInfos)
+		{
+			auto iterFind = curAssembly.second->mTypeNameToId.find(fullName);
+			if(iterFind != curAssembly.second->mTypeNameToId.end())
+				return true;
+		}
+
+		return false;
+	}
 }