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

A lot more work on C# object serialization

Marko Pintera 12 лет назад
Родитель
Сommit
79311d0373

+ 22 - 111
GameObjectSerialization.txt

@@ -3,37 +3,30 @@ TODO
 
  ---------------------------------------
 
- Serialization:
- - Starts in ManagedComponent
- - in onSerializationStarted
-   - I find managed class from RuntimeScriptObject
-   - I query all fields of the class, and its base classes
-   - I add the fields in multiple internal arrays separated by type (int, float, ComponentRef, etc.)
-     - Those arrays are assigned to mRTTIData
-   - Data from those arrays is retrieved using various set/get functions in the RTTI using normal RTTI functionality
-     - Returned field data contains type id, field id and value
-   - I will also store a list of ReflectablePtrs pointing to SerializableObjectInfo describing each used type
-     - I should probably ensure that SerializableObjectInfo RTTI does not include children when serializing to prevent including useless data
-   - What happens when I encounter a SerializableObject?
-     - Instantiate a new instance of SerializableObject class and return a reference to it
-	   - It will have SerializableObjectRTTI which will do the same job ScriptComponentRTTI (this class) does
-	   - They should probably derive from same base class
- - in onSerializationEnded
-   - I clear mRTTIData
- - in onDeserializationStarted
-   - I create an empty set of arrays in mRTTIData
- - in onDeserializationEnded
-   - TODO - Pretty much the exact reverse of above?
-    - But make sure to gracefully handle non-existing types
+IMMEDIATE:
+ScriptSerializableObjectRTTI::onDeserializationEnded
+ - Compare stored and new SerializableObjectInfo (if it even exists)
+   - Must ensure the object info instances match
+    - (I might also want to compare type class/struct status in case it changed)
+ - Create new managed object instance
+ - Fill out the class fields (those whose types match the new SerializableObjectInfo->mFields)
 
-In RuntimeScriptObjects I need to ensure I return array types when GetSerializableObjectInfo is called
- - Arrays with different ranks should count as different types?
- - Also make sure to properly deal with generic parameters
-ScriptSerializableFieldInfoArray doesn't support multi-dimensional arrays (need to figure out how to look those up in Mono)
-Consider removing mNamespace/mTypename from SerializableFieldInfo and adding a special SerializableFieldInfo for SerializableObjects
+ScriptSerializableArrayRTTI::onDeserializationEnded
+ - Attempt to create new managed object instance
 
-Dictionaries:
- - WIll need special SerializableFieldInfo for KeyValuePair
+Need Object & Array ScriptSerializableField classes
+ManagedComponent needs to create SerializableObject and return it in its RTTI
+
+When deserializing SerializableObjectInfo base classes references won't be held anywhere (they're only pointed to by mBaseClass which is a weak_pointer)
+
+In ScriptEnginePlugin I am running RuntimeScriptObjects but never shutting it down - Right now its only for debug purposes
+
+LOW PRIORITY
+- Add Multi-dimensional arrays / Lists / Dictionaries
+  - (To get array lengths per rank I probably need to cast to System.Array and then call GetLength)
+- Ensure that unknown components retain their field data so when they are no longer unknown their data may be restored
+- Get rid of ScriptObject::createInstance and replace it with parameter in constructor
+- A way to serialize any object into a Resource (and deserialize it from Resource)
 
  ---------------------------------------
 
@@ -45,88 +38,6 @@ Dictionaries:
    - C++ method calls clone() on the scene object and creates a new "ManagedSOClone" object and parents it as a child of current SO
    - C# then retrieves a child and checks if the component is there
 
- ---------------------------------------
- C# component serialization
-
-Stage 1:
- - Test if SceneObject/Component serialization works when managed components are used
-   - Ignore managed component fields for now
- - Ensure non-existing types are handled
-
-Stage 2:
- - Get managed component field serialization working
- - SerializableObjectInfoRTTI
- - Ignore arrays and collections
-   - But delete existing array code as its obsolete
- - Don't ignore serializable objects
-
-Stage 3:
- - Support for arrays & collections
-
-Stage 4:
- - Polish: 
-     - Ensure that unknown components retain their field data so when they are no longer unknown their
-       data may be restored
-     - Get rid of ScriptObject::createInstance and replace it with parameter in constructor
- - How to deal with components like Camera?
- - A way to serialize any object into a Resource (and deserialize it from Resource)
-
-ARRAY/COLLECTION HANDLING
- - Encode arrays/lists/dictionaries as specialized SerializableObjects.
- - When decoding SerializableObjects I initialize SerializableObject with type name and namespace
-   - In case of arrays, multi-rank arrays, lists or dictionaries it will be the same
-   - createManagedInstance will instantiate a managed instance of that type
-   - Internally SerializableObjectRTTI will have special handling for arrays/lists/dictionaries
-     - Normally it would just query fields from RuntimeScriptObjects but now it will call: 
-       - RuntimeScriptObjects::getArrayFields, RuntimeScriptObjects::getListFields, etc.
-       - Dictionary entries will return special type containing two entries (or just std::pair)
-       - Multi-rank arrays will return a 1D list of entries but laid out in a specific manner so we can decode them back
- - Remove my current way of handling arrays iz SerializableFieldInfo
-
-ScriptComponent
- - C++ half of the C# component
- - Returned from SerializableComponentInfo::createInstance and created automatically whenever a managed component is created
- - Contains a managed type-name of the component
- - Has ScriptComponentRTTI
-
-ScriptComponentRTTI
- - Allows for easy and automatic serialization and deserialization
- - Saves managed component type-name
- - Uses RuntimeScriptObjects to get Serializable*Info, which is in turn used to find component fields
- - Has various methods returning arrays of fields
-  - GetPlainFields
-    - Returns FieldId -> (int, bool, byte, etc.) mapping
-  - GetStringFields
-    - Returns FieldId -> string mapping
-  - GetSerializableObjectFields
-    - Returns FieldId -> ReflectablePtr to ScriptSerializableObject (which will be serialized recursively)
-  - GetGameObjectFields
-    - Returns FieldId -> HGameObject
-  - GetResourceFields
-    - Returns FieldID -> HResource
- - Make sure to scan all base classes as well
- - When serializing all those arrays are prepared in OnSerializatioStarted
- - When deserializing they are send to the object in OnDeserializationEnded
-   - However existance for the fields is first checked by getting new copy of SerializableComponentInfo and seeing
-     which fields match
- - FieldId is just a name + type of the field.
- - When deserializing and component type name cannot be found, returns an empty ScriptComponent
-
-ScriptSerializableObject
- - Has ScriptSerializableObjectRTTI
- - When deserializing and component type name cannot be found, returns null
- - Otherwise equivalent to its ScriptComponent and ScriptComponentRTTI counterpart
-
-TO CUT DOWN ON SERIALIZATION SIZE
- - Serialize the Serializable*Info itself, and then FieldId can be just numerical ids
- - Just having the RTTI class holding a reference to Serializable*Info (and it being IReflectable) should
-   ensure only one copy of it is stored.
-
-TODO - Possibly flesh out and example with Resources or Gameobject references a bit more
- - When deserializing HResource and HGameObject handles how do I find their managed counterparts? I can create new handles
-   but they could already be loaded and it doesn't make sense to have two different handles.
- - Some kind of managed <-> native mapping?
-
  ------------------------------------------------------
  General C# component management
 

+ 0 - 33
SBansheeEngine/Include/BsManagedSerializationData.h

@@ -1,33 +0,0 @@
-#pragma once
-
-#include "BsScriptEnginePrerequisites.h"
-#include "CmIReflectable.h"
-#include <mono/jit/jit.h>
-
-namespace BansheeEngine
-{
-	class BS_SCR_BE_EXPORT ManagedSerializationDataArray : public CM::IReflectable
-	{
-
-	};
-
-	class BS_SCR_BE_EXPORT ManagedSerializationData : public CM::IReflectable
-	{
-	public:
-		static ManagedSerializationDataPtr create(MonoObject* managedInstance);
-
-	protected:
-		ManagedSerializationData(const CM::String& ns, const CM::String& typeName);
-
-		CM::String mNamespace;
-		CM::String mTypename;
-
-		/************************************************************************/
-		/* 								RTTI		                     		*/
-		/************************************************************************/
-	public:
-		friend class ManagedSerializationDataRTTI;
-		static CM::RTTITypeBase* getRTTIStatic();
-		virtual CM::RTTITypeBase* getRTTI() const;
-	};
-}

+ 0 - 56
SBansheeEngine/Include/BsManagedSerializationDataRTTI.h

@@ -1,56 +0,0 @@
-#pragma once
-
-#include "BsScriptEnginePrerequisites.h"
-#include "CmRTTIType.h"
-#include "BsManagedSerializationData.h"
-#include "CmException.h"
-
-namespace BansheeEngine
-{
-	class BS_SCR_BE_EXPORT ManagedSerializationDataRTTI : public CM::RTTIType<ManagedSerializationData, CM::IReflectable, ManagedSerializationDataRTTI>
-	{
-	private:
-		CM::String& getNamespace(ManagedSerializationData* obj)
-		{
-			return obj->mNamespace;
-		}
-
-		void setNamespace(ManagedSerializationData* obj, CM::String& val)
-		{
-			obj->mNamespace = val;
-		}
-
-		CM::String& getTypename(ManagedSerializationData* obj)
-		{
-			return obj->mTypename;
-		}
-
-		void setTypename(ManagedSerializationData* obj, CM::String& val)
-		{
-			obj->mTypename = val;
-		}
-
-	public:
-		ManagedSerializationDataRTTI()
-		{
-			addPlainField("mNamespace", 0, &ManagedSerializationDataRTTI::getNamespace, &ManagedSerializationDataRTTI::setNamespace);
-			addPlainField("mTypename", 1, &ManagedSerializationDataRTTI::getTypename, &ManagedSerializationDataRTTI::setTypename);
-		}
-
-		virtual const CM::String& getRTTIName()
-		{
-			static CM::String name = "ManagedSerializationData";
-			return name;
-		}
-
-		virtual CM::UINT32 getRTTIId()
-		{
-			return TID_ManagedSerializationData;
-		}
-
-		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
-		{
-			CM_EXCEPT(CM::InvalidStateException, "Cannot instantiate an abstract class.");
-		}
-	};
-}

+ 20 - 1
SBansheeEngine/Include/BsRuntimeScriptObjects.h

@@ -10,16 +10,35 @@ namespace BansheeEngine
 	class BS_SCR_BE_EXPORT RuntimeScriptObjects : public CM::Module<RuntimeScriptObjects>
 	{
 	public:
+		RuntimeScriptObjects();
 		~RuntimeScriptObjects();
 
 		void refreshScriptObjects(const CM::String& assemblyName);
 		bool getSerializableObjectInfo(const CM::String& ns, const CM::String& typeName, std::shared_ptr<ScriptSerializableObjectInfo>& outInfo);
 		bool hasSerializableObjectInfo(const CM::String& ns, const CM::String& typeName);
 
-		bool isArray(const MonoClass* monoClass) const;
+		bool isArray(MonoObject* object);
 	private:
 		CM::UnorderedMap<CM::String, std::shared_ptr<ScriptSerializableAssemblyInfo>>::type mAssemblyInfos;
+		bool mBaseTypesInitialized;
+
+		MonoClass* mSystemArrayClass;
+
+		MonoClass* mSerializableAttribute;
+		MonoClass* mNonSerializedAttribute;
+
+		MonoClass* mComponentClass;
+		MonoClass* mSceneObjectClass;
+
+		MonoClass* mTextureClass;
+		MonoClass* mSpriteTextureClass;
+
+		MonoClass* mSerializeFieldAttribute;
+		MonoClass* mHideInInspectorAttribute;
 
 		void clearScriptObjects(const CM::String& assemblyName);
+
+		void initializeBaseTypes();
+		ScriptSerializableTypeInfoPtr determineType(MonoClass* monoClass);
 	};
 }

+ 40 - 9
SBansheeEngine/Include/BsScriptEnginePrerequisites.h

@@ -35,30 +35,61 @@ namespace BansheeEngine
 	class ScriptSceneObject;
 	class ScriptComponent;
 	class ManagedComponent;
-	class ManagedSerializationData;
+	class ScriptSerializableFieldData;
+	class ScriptSerializableFieldKey;
+	class ScriptSerializableFieldDataEntry;
+	class ScriptSerializableTypeInfo;
+	class ScriptSerializableTypeInfoPrimitive;
+	class ScriptSerializableTypeInfoObject;
+	class ScriptSerializableTypeInfoArray;
+	class ScriptSerializableObject;
+	class ScriptSerializableArray;
 	class ScriptSerializableAssemblyInfo;
 	class ScriptSerializableObjectInfo;
 	class ScriptSerializableFieldInfo;
-	class ScriptSerializableFieldInfoPlain;
-	class ScriptSerializableFieldInfoArray;
 
 	enum TypeID_BansheeScript
 	{
 		TID_ManagedComponent = 50000,
-		TID_ManagedSerializationData = 50001,
+		TID_ScriptSerializableObject = 50001,
+		TID_ScriptSerializableArray = 50002,
 		TID_SerializableAssemblyInfo = 50004,
 		TID_SerializableObjectInfo = 50005,
 		TID_SerializableFieldInfo = 50006,
-		TID_SerializableFieldInfoPlain = 50007,
-		TID_SerializableFieldInfoArray = 50008
+		TID_SerializableTypeInfo = 50007,
+		TID_SerializableTypeInfoPrimitive = 50008,
+		TID_SerializableTypeInfoObject = 50009,
+		TID_SerializableTypeInfoArray = 50010,
+		TID_SerializableFieldData = 50011,
+		TID_SerializableFieldKey = 50012,
+		TID_SerializableFieldDataEntry = 50013,
+		TID_SerializableFieldDataBool = 50014,
+		TID_SerializableFieldDataChar = 50015,
+		TID_SerializableFieldDataI8 = 50016,
+		TID_SerializableFieldDataU8 = 50017,
+		TID_SerializableFieldDataI16 = 50018,
+		TID_SerializableFieldDataU16 = 50019,
+		TID_SerializableFieldDataI32 = 50020,
+		TID_SerializableFieldDataU32 = 50021,
+		TID_SerializableFieldDataI64 = 50022,
+		TID_SerializableFieldDataU64 = 50023,
+		TID_SerializableFieldDataFloat = 50024,
+		TID_SerializableFieldDataDouble = 50025,
+		TID_SerializableFieldDataString = 50026,
+		TID_SerializableFieldDataResourceRef = 50027,
+		TID_SerializableFieldDataGameObjectRef = 50028
 	};
 
 	static const char* BansheeEngineAssemblyName = "MBansheeEngine";
 
-	typedef std::shared_ptr<ManagedSerializationData> ManagedSerializationDataPtr;
+	typedef std::shared_ptr<ScriptSerializableFieldData> ScriptSerializableFieldDataPtr;
+	typedef std::shared_ptr<ScriptSerializableFieldKey> ScriptSerializableFieldKeyPtr;
+	typedef std::shared_ptr<ScriptSerializableFieldDataEntry> ScriptSerializableFieldDataEntryPtr;
+	typedef std::shared_ptr<ScriptSerializableTypeInfo> ScriptSerializableTypeInfoPtr;
+	typedef std::shared_ptr<ScriptSerializableObject> ScriptSerializableObjectPtr;
+	typedef std::shared_ptr<ScriptSerializableArray> ScriptSerializableArrayPtr;
 	typedef std::shared_ptr<ScriptSerializableAssemblyInfo> ScriptSerializableAssemblyInfoPtr;
 	typedef std::shared_ptr<ScriptSerializableObjectInfo> ScriptSerializableObjectInfoPtr;
 	typedef std::shared_ptr<ScriptSerializableFieldInfo> ScriptSerializableFieldInfoPtr;
-	typedef std::shared_ptr<ScriptSerializableFieldInfoPlain> ScriptSerializableFieldInfoPlainPtr;
-	typedef std::shared_ptr<ScriptSerializableFieldInfoArray> ScriptSerializableFieldInfoArrayPtr;
+	typedef std::shared_ptr<ScriptSerializableTypeInfoArray> ScriptSerializableTypeInfoArrayPtr;
 }

+ 44 - 0
SBansheeEngine/Include/BsScriptSerializableArray.h

@@ -0,0 +1,44 @@
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+#include "CmIReflectable.h"
+#include <mono/jit/jit.h>
+
+namespace BansheeEngine
+{
+	class BS_SCR_BE_EXPORT ScriptSerializableArray : public CM::IReflectable
+	{
+	private:
+		struct ConstructPrivately {};
+
+	public:
+		ScriptSerializableArray(const ConstructPrivately& dummy, const ScriptSerializableTypeInfoArrayPtr& typeInfo, MonoObject* managedInstance);
+		ScriptSerializableArray(const ConstructPrivately& dummy);
+
+		static ScriptSerializableArrayPtr create(MonoObject* managedInstance, const ScriptSerializableTypeInfoArrayPtr& typeInfo);
+
+	protected:
+		ScriptSerializableTypeInfoArrayPtr mArrayTypeInfo;
+		CM::Vector<ScriptSerializableFieldDataPtr>::type mArrayEntries;
+		MonoObject* mManagedInstance;
+		::MonoClass* mClass;
+		CM::UINT32 mNumElements;
+
+		void setFieldData(CM::UINT32 arrayIdx, const ScriptSerializableFieldDataPtr& val);
+		ScriptSerializableFieldDataPtr getFieldData(CM::UINT32 arrayIdx);
+
+		void setValue(CM::UINT32 arrayIdx, void* val);
+		void* getValue(CM::UINT32 arrayIdx);
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+		
+		static ScriptSerializableArrayPtr createEmpty();
+
+	public:
+		friend class ScriptSerializableArrayRTTI;
+		static CM::RTTITypeBase* getRTTIStatic();
+		virtual CM::RTTITypeBase* getRTTI() const;
+	};
+}

+ 73 - 0
SBansheeEngine/Include/BsScriptSerializableArrayRTTI.h

@@ -0,0 +1,73 @@
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+#include "CmRTTIType.h"
+#include "BsScriptSerializableArray.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BE_EXPORT ScriptSerializableArrayRTTI : public CM::RTTIType<ScriptSerializableArray, CM::IReflectable, ScriptSerializableArrayRTTI>
+	{
+	private:
+		ScriptSerializableTypeInfoArrayPtr getTypeInfo(ScriptSerializableArray* obj)
+		{
+			return obj->mArrayTypeInfo;
+		}
+
+		void setTypeInfo(ScriptSerializableArray* obj, ScriptSerializableTypeInfoArrayPtr val)
+		{
+			obj->mArrayTypeInfo = val;
+		}
+
+		ScriptSerializableFieldDataPtr getArrayEntry(ScriptSerializableArray* obj, CM::UINT32 arrayIdx)
+		{
+			return obj->mArrayEntries[arrayIdx];
+		}
+
+		void setArrayEntry(ScriptSerializableArray* obj, CM::UINT32 arrayIdx, ScriptSerializableFieldDataPtr val)
+		{
+			obj->mArrayEntries[arrayIdx] = val;
+		}
+
+		CM::UINT32 getNumArrayEntries(ScriptSerializableArray* obj)
+		{
+			return (CM::UINT32)obj->mArrayEntries.size();
+		}
+
+		void setNumArrayEntries(ScriptSerializableArray* obj, CM::UINT32 numEntries)
+		{
+			obj->mArrayEntries.resize(numEntries);
+		}
+
+	public:
+		ScriptSerializableArrayRTTI()
+		{
+			addReflectablePtrField("mArrayTypeInfo", 0, &ScriptSerializableArrayRTTI::getTypeInfo, &ScriptSerializableArrayRTTI::setTypeInfo);
+			addReflectablePtrArrayField("mArrayEntries", 1, &ScriptSerializableArrayRTTI::getArrayEntry, &ScriptSerializableArrayRTTI::getNumArrayEntries, 
+				&ScriptSerializableArrayRTTI::setArrayEntry, &ScriptSerializableArrayRTTI::setNumArrayEntries);
+		}
+
+		virtual void onDeserializationEnded(CM::IReflectable* obj)
+		{
+			ScriptSerializableArray* serializableObject = static_cast<ScriptSerializableArray*>(obj);
+
+			// TODO
+		}
+
+		virtual const CM::String& getRTTIName()
+		{
+			static CM::String name = "ScriptSerializableArray";
+			return name;
+		}
+
+		virtual CM::UINT32 getRTTIId()
+		{
+			return TID_ScriptSerializableArray;
+		}
+
+		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
+		{
+			return ScriptSerializableArray::createEmpty();
+		}
+	};
+}

+ 316 - 0
SBansheeEngine/Include/BsScriptSerializableField.h

@@ -0,0 +1,316 @@
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+#include "CmIReflectable.h"
+#include <mono/jit/jit.h>
+
+namespace BansheeEngine
+{
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldKey : public CM::IReflectable
+	{
+	public:
+		static ScriptSerializableFieldKeyPtr create(CM::UINT16 typeId, CM::UINT16 fieldId);
+
+		CM::UINT16 mTypeId;
+		CM::UINT16 mFieldId;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class ScriptSerializableFieldDataKeyRTTI;
+		static CM::RTTITypeBase* getRTTIStatic();
+		virtual CM::RTTITypeBase* getRTTI() const;
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldData : public CM::IReflectable
+	{
+	public:
+		static ScriptSerializableFieldDataPtr create(const ScriptSerializableTypeInfoPtr& typeInfo, void* value);
+		virtual void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo) = 0;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class ScriptSerializableFieldDataRTTI;
+		static CM::RTTITypeBase* getRTTIStatic();
+		virtual CM::RTTITypeBase* getRTTI() const;
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataEntry : public CM::IReflectable
+	{
+	public:
+		static ScriptSerializableFieldDataEntryPtr create(const ScriptSerializableFieldKeyPtr& key, const ScriptSerializableFieldDataPtr& value);
+
+		ScriptSerializableFieldKeyPtr mKey;
+		ScriptSerializableFieldDataPtr mValue;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class ScriptSerializableFieldDataEntryRTTI;
+		static CM::RTTITypeBase* getRTTIStatic();
+		virtual CM::RTTITypeBase* getRTTI() const;
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataBool : public ScriptSerializableFieldData
+	{
+	public:
+		bool value;
+
+		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class ScriptSerializableFieldDataBoolRTTI;
+		static CM::RTTITypeBase* getRTTIStatic();
+		virtual CM::RTTITypeBase* getRTTI() const;
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataChar : public ScriptSerializableFieldData
+	{
+	public:
+		wchar_t value;
+
+		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class ScriptSerializableFieldDataCharRTTI;
+		static CM::RTTITypeBase* getRTTIStatic();
+		virtual CM::RTTITypeBase* getRTTI() const;
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataI8 : public ScriptSerializableFieldData
+	{
+	public:
+		CM::INT8 value;
+
+		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class ScriptSerializableFieldDataI8RTTI;
+		static CM::RTTITypeBase* getRTTIStatic();
+		virtual CM::RTTITypeBase* getRTTI() const;
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataU8 : public ScriptSerializableFieldData
+	{
+	public:
+		CM::UINT8 value;
+
+		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class ScriptSerializableFieldDataU8RTTI;
+		static CM::RTTITypeBase* getRTTIStatic();
+		virtual CM::RTTITypeBase* getRTTI() const;
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataI16 : public ScriptSerializableFieldData
+	{
+	public:
+		CM::INT16 value;
+
+		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class ScriptSerializableFieldDataI16RTTI;
+		static CM::RTTITypeBase* getRTTIStatic();
+		virtual CM::RTTITypeBase* getRTTI() const;
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataU16 : public ScriptSerializableFieldData
+	{
+	public:
+		CM::UINT16 value;
+
+		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class ScriptSerializableFieldDataU16RTTI;
+		static CM::RTTITypeBase* getRTTIStatic();
+		virtual CM::RTTITypeBase* getRTTI() const;
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataI32 : public ScriptSerializableFieldData
+	{
+	public:
+		CM::INT32 value;
+
+		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class ScriptSerializableFieldDataI32RTTI;
+		static CM::RTTITypeBase* getRTTIStatic();
+		virtual CM::RTTITypeBase* getRTTI() const;
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataU32 : public ScriptSerializableFieldData
+	{
+	public:
+		CM::UINT32 value;
+
+		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class ScriptSerializableFieldDataU32RTTI;
+		static CM::RTTITypeBase* getRTTIStatic();
+		virtual CM::RTTITypeBase* getRTTI() const;
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataI64 : public ScriptSerializableFieldData
+	{
+	public:
+		CM::INT64 value;
+
+		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class ScriptSerializableFieldDataI64RTTI;
+		static CM::RTTITypeBase* getRTTIStatic();
+		virtual CM::RTTITypeBase* getRTTI() const;
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataU64 : public ScriptSerializableFieldData
+	{
+	public:
+		CM::UINT64 value;
+
+		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class ScriptSerializableFieldDataU64RTTI;
+		static CM::RTTITypeBase* getRTTIStatic();
+		virtual CM::RTTITypeBase* getRTTI() const;
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataFloat : public ScriptSerializableFieldData
+	{
+	public:
+		float value;
+
+		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class ScriptSerializableFieldDataFloatRTTI;
+		static CM::RTTITypeBase* getRTTIStatic();
+		virtual CM::RTTITypeBase* getRTTI() const;
+	};
+
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataDouble : public ScriptSerializableFieldData
+	{
+	public:
+		double value;
+
+		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class ScriptSerializableFieldDataDoubleRTTI;
+		static CM::RTTITypeBase* getRTTIStatic();
+		virtual CM::RTTITypeBase* getRTTI() const;
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataString : public ScriptSerializableFieldData
+	{
+	public:
+		CM::WString value;
+
+		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class ScriptSerializableFieldDataStringRTTI;
+		static CM::RTTITypeBase* getRTTIStatic();
+		virtual CM::RTTITypeBase* getRTTI() const;
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataResourceRef : public ScriptSerializableFieldData
+	{
+	public:
+		CM::HResource value;
+
+		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class ScriptSerializableFieldDataResourceRefRTTI;
+		static CM::RTTITypeBase* getRTTIStatic();
+		virtual CM::RTTITypeBase* getRTTI() const;
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataGameObjectRef : public ScriptSerializableFieldData
+	{
+	public:
+		CM::HGameObject value;
+
+		void* getValue(const ScriptSerializableTypeInfoPtr& typeInfo);
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class ScriptSerializableFieldDataGameObjectRefRTTI;
+		static CM::RTTITypeBase* getRTTIStatic();
+		virtual CM::RTTITypeBase* getRTTI() const;
+	};
+}

+ 537 - 0
SBansheeEngine/Include/BsScriptSerializableFieldRTTI.h

@@ -0,0 +1,537 @@
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+#include "CmRTTIType.h"
+#include "BsScriptSerializableField.h"
+#include "CmException.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldKeyRTTI : public CM::RTTIType<ScriptSerializableFieldKey, CM::IReflectable, ScriptSerializableFieldKeyRTTI>
+	{
+	private:
+		CM::UINT16& getTypeId(ScriptSerializableFieldKey* obj) { return obj->mTypeId; }
+		void setTypeId(ScriptSerializableFieldKey* obj, CM::UINT16& val) { obj->mTypeId = val; }
+
+		CM::UINT16& getFieldId(ScriptSerializableFieldKey* obj) { return obj->mFieldId; }
+		void setFieldId(ScriptSerializableFieldKey* obj, CM::UINT16& val) { obj->mFieldId = val; }
+
+	public:
+		ScriptSerializableFieldKeyRTTI()
+		{
+			addPlainField("mTypeId", 0, &ScriptSerializableFieldKeyRTTI::getTypeId, &ScriptSerializableFieldKeyRTTI::setTypeId);
+			addPlainField("mFieldId", 1, &ScriptSerializableFieldKeyRTTI::getFieldId, &ScriptSerializableFieldKeyRTTI::setFieldId);
+		}
+
+		virtual const CM::String& getRTTIName()
+		{
+			static CM::String name = "SerializableFieldKey";
+			return name;
+		}
+
+		virtual CM::UINT32 getRTTIId()
+		{
+			return TID_SerializableFieldKey;
+		}
+
+		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
+		{
+			return CM::cm_shared_ptr<ScriptSerializableFieldKey>();
+		}
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataRTTI : public CM::RTTIType<ScriptSerializableFieldData, CM::IReflectable, ScriptSerializableFieldDataRTTI>
+	{
+	private:
+
+	public:
+		ScriptSerializableFieldDataRTTI()
+		{
+
+		}
+
+		virtual const CM::String& getRTTIName()
+		{
+			static CM::String name = "SerializableFieldData";
+			return name;
+		}
+
+		virtual CM::UINT32 getRTTIId()
+		{
+			return TID_SerializableFieldData;
+		}
+
+		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
+		{
+			CM_EXCEPT(CM::InvalidStateException, "Cannot instantiate an abstract class.");
+		}
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataEntryRTTI : public CM::RTTIType<ScriptSerializableFieldDataEntry, CM::IReflectable, ScriptSerializableFieldDataEntryRTTI>
+	{
+	private:
+		ScriptSerializableFieldKeyPtr getKey(ScriptSerializableFieldDataEntry* obj)	{ return obj->mKey; }
+		void setKey(ScriptSerializableFieldDataEntry* obj, ScriptSerializableFieldKeyPtr val) { obj->mKey = val; }
+
+		ScriptSerializableFieldDataPtr getValue(ScriptSerializableFieldDataEntry* obj) { return obj->mValue; }
+		void setValue(ScriptSerializableFieldDataEntry* obj, ScriptSerializableFieldDataPtr val) { obj->mValue = val; }
+
+	public:
+		ScriptSerializableFieldDataEntryRTTI()
+		{
+			addReflectablePtrField("mKey", 0, &ScriptSerializableFieldDataEntryRTTI::getKey, &ScriptSerializableFieldDataEntryRTTI::setKey);
+			addReflectablePtrField("mValue", 1, &ScriptSerializableFieldDataEntryRTTI::getValue, &ScriptSerializableFieldDataEntryRTTI::setValue);
+		}
+
+		virtual const CM::String& getRTTIName()
+		{
+			static CM::String name = "SerializableFieldDataEntry";
+			return name;
+		}
+
+		virtual CM::UINT32 getRTTIId()
+		{
+			return TID_SerializableFieldDataEntry;
+		}
+
+		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
+		{
+			return CM::cm_shared_ptr<ScriptSerializableFieldDataEntry>();
+		}
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataBoolRTTI : public CM::RTTIType<ScriptSerializableFieldDataBool, ScriptSerializableFieldData, ScriptSerializableFieldDataBoolRTTI>
+	{
+	private:
+		bool& getValue(ScriptSerializableFieldDataBool* obj) { return obj->value; }
+		void setValue(ScriptSerializableFieldDataBool* obj, bool& val) { obj->value = val; }
+
+	public:
+		ScriptSerializableFieldDataBoolRTTI()
+		{
+			addPlainField("mValue", 0, &ScriptSerializableFieldDataBoolRTTI::getValue, &ScriptSerializableFieldDataBoolRTTI::setValue);
+		}
+
+		virtual const CM::String& getRTTIName()
+		{
+			static CM::String name = "SerializableFieldDataBool";
+			return name;
+		}
+
+		virtual CM::UINT32 getRTTIId()
+		{
+			return TID_SerializableFieldDataBool;
+		}
+
+		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
+		{
+			return CM::cm_shared_ptr<ScriptSerializableFieldDataBool>();
+		}
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataCharRTTI : public CM::RTTIType<ScriptSerializableFieldDataChar, ScriptSerializableFieldData, ScriptSerializableFieldDataCharRTTI>
+	{
+	private:
+		wchar_t& getValue(ScriptSerializableFieldDataChar* obj) { return obj->value; }
+		void setValue(ScriptSerializableFieldDataChar* obj, wchar_t& val) { obj->value = val; }
+
+	public:
+		ScriptSerializableFieldDataCharRTTI()
+		{
+			addPlainField("mValue", 0, &ScriptSerializableFieldDataCharRTTI::getValue, &ScriptSerializableFieldDataCharRTTI::setValue);
+		}
+
+		virtual const CM::String& getRTTIName()
+		{
+			static CM::String name = "SerializableFieldDataChar";
+			return name;
+		}
+
+		virtual CM::UINT32 getRTTIId()
+		{
+			return TID_SerializableFieldDataChar;
+		}
+
+		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
+		{
+			return CM::cm_shared_ptr<ScriptSerializableFieldDataBool>();
+		}
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataI8RTTI : public CM::RTTIType<ScriptSerializableFieldDataI8, ScriptSerializableFieldData, ScriptSerializableFieldDataI8RTTI>
+	{
+	private:
+		CM::INT8& getValue(ScriptSerializableFieldDataI8* obj) { return obj->value; }
+		void setValue(ScriptSerializableFieldDataI8* obj, CM::INT8& val) { obj->value = val; }
+
+	public:
+		ScriptSerializableFieldDataI8RTTI()
+		{
+			addPlainField("mValue", 0, &ScriptSerializableFieldDataI8RTTI::getValue, &ScriptSerializableFieldDataI8RTTI::setValue);
+		}
+
+		virtual const CM::String& getRTTIName()
+		{
+			static CM::String name = "SerializableFieldDataI8";
+			return name;
+		}
+
+		virtual CM::UINT32 getRTTIId()
+		{
+			return TID_SerializableFieldDataI8;
+		}
+
+		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
+		{
+			return CM::cm_shared_ptr<ScriptSerializableFieldDataI8>();
+		}
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataU8RTTI : public CM::RTTIType<ScriptSerializableFieldDataU8, ScriptSerializableFieldData, ScriptSerializableFieldDataU8RTTI>
+	{
+	private:
+		CM::UINT8& getValue(ScriptSerializableFieldDataU8* obj) { return obj->value; }
+		void setValue(ScriptSerializableFieldDataU8* obj, CM::UINT8& val) { obj->value = val; }
+
+	public:
+		ScriptSerializableFieldDataU8RTTI()
+		{
+			addPlainField("mValue", 0, &ScriptSerializableFieldDataU8RTTI::getValue, &ScriptSerializableFieldDataU8RTTI::setValue);
+		}
+
+		virtual const CM::String& getRTTIName()
+		{
+			static CM::String name = "SerializableFieldDataU8";
+			return name;
+		}
+
+		virtual CM::UINT32 getRTTIId()
+		{
+			return TID_SerializableFieldDataU8;
+		}
+
+		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
+		{
+			return CM::cm_shared_ptr<ScriptSerializableFieldDataU8>();
+		}
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataI16RTTI : public CM::RTTIType<ScriptSerializableFieldDataI16, ScriptSerializableFieldData, ScriptSerializableFieldDataI16RTTI>
+	{
+	private:
+		CM::INT16& getValue(ScriptSerializableFieldDataI16* obj) { return obj->value; }
+		void setValue(ScriptSerializableFieldDataI16* obj, CM::INT16& val) { obj->value = val; }
+
+	public:
+		ScriptSerializableFieldDataI16RTTI()
+		{
+			addPlainField("mValue", 0, &ScriptSerializableFieldDataI16RTTI::getValue, &ScriptSerializableFieldDataI16RTTI::setValue);
+		}
+
+		virtual const CM::String& getRTTIName()
+		{
+			static CM::String name = "SerializableFieldDataI16";
+			return name;
+		}
+
+		virtual CM::UINT32 getRTTIId()
+		{
+			return TID_SerializableFieldDataI16;
+		}
+
+		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
+		{
+			return CM::cm_shared_ptr<ScriptSerializableFieldDataI16>();
+		}
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataU16RTTI : public CM::RTTIType<ScriptSerializableFieldDataU16, ScriptSerializableFieldData, ScriptSerializableFieldDataU16RTTI>
+	{
+	private:
+		CM::UINT16& getValue(ScriptSerializableFieldDataU16* obj) { return obj->value; }
+		void setValue(ScriptSerializableFieldDataU16* obj, CM::UINT16& val) { obj->value = val; }
+
+	public:
+		ScriptSerializableFieldDataU16RTTI()
+		{
+			addPlainField("mValue", 0, &ScriptSerializableFieldDataU16RTTI::getValue, &ScriptSerializableFieldDataU16RTTI::setValue);
+		}
+
+		virtual const CM::String& getRTTIName()
+		{
+			static CM::String name = "SerializableFieldDataU16";
+			return name;
+		}
+
+		virtual CM::UINT32 getRTTIId()
+		{
+			return TID_SerializableFieldDataU16;
+		}
+
+		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
+		{
+			return CM::cm_shared_ptr<ScriptSerializableFieldDataU16>();
+		}
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataI32RTTI : public CM::RTTIType<ScriptSerializableFieldDataI32, ScriptSerializableFieldData, ScriptSerializableFieldDataI32RTTI>
+	{
+	private:
+		CM::INT32& getValue(ScriptSerializableFieldDataI32* obj) { return obj->value; }
+		void setValue(ScriptSerializableFieldDataI32* obj, CM::INT32& val) { obj->value = val; }
+
+	public:
+		ScriptSerializableFieldDataI32RTTI()
+		{
+			addPlainField("mValue", 0, &ScriptSerializableFieldDataI32RTTI::getValue, &ScriptSerializableFieldDataI32RTTI::setValue);
+		}
+
+		virtual const CM::String& getRTTIName()
+		{
+			static CM::String name = "SerializableFieldDataI32";
+			return name;
+		}
+
+		virtual CM::UINT32 getRTTIId()
+		{
+			return TID_SerializableFieldDataI32;
+		}
+
+		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
+		{
+			return CM::cm_shared_ptr<ScriptSerializableFieldDataI32>();
+		}
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataU32RTTI : public CM::RTTIType<ScriptSerializableFieldDataU32, ScriptSerializableFieldData, ScriptSerializableFieldDataU32RTTI>
+	{
+	private:
+		CM::UINT32& getValue(ScriptSerializableFieldDataU32* obj) { return obj->value; }
+		void setValue(ScriptSerializableFieldDataU32* obj, CM::UINT32& val) { obj->value = val; }
+
+	public:
+		ScriptSerializableFieldDataU32RTTI()
+		{
+			addPlainField("mValue", 0, &ScriptSerializableFieldDataU32RTTI::getValue, &ScriptSerializableFieldDataU32RTTI::setValue);
+		}
+
+		virtual const CM::String& getRTTIName()
+		{
+			static CM::String name = "SerializableFieldDataU32";
+			return name;
+		}
+
+		virtual CM::UINT32 getRTTIId()
+		{
+			return TID_SerializableFieldDataU32;
+		}
+
+		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
+		{
+			return CM::cm_shared_ptr<ScriptSerializableFieldDataU32>();
+		}
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataI64RTTI : public CM::RTTIType<ScriptSerializableFieldDataI64, ScriptSerializableFieldData, ScriptSerializableFieldDataI64RTTI>
+	{
+	private:
+		CM::INT64& getValue(ScriptSerializableFieldDataI64* obj) { return obj->value; }
+		void setValue(ScriptSerializableFieldDataI64* obj, CM::INT64& val) { obj->value = val; }
+
+	public:
+		ScriptSerializableFieldDataI64RTTI()
+		{
+			addPlainField("mValue", 0, &ScriptSerializableFieldDataI64RTTI::getValue, &ScriptSerializableFieldDataI64RTTI::setValue);
+		}
+
+		virtual const CM::String& getRTTIName()
+		{
+			static CM::String name = "SerializableFieldDataI64";
+			return name;
+		}
+
+		virtual CM::UINT32 getRTTIId()
+		{
+			return TID_SerializableFieldDataI64;
+		}
+
+		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
+		{
+			return CM::cm_shared_ptr<ScriptSerializableFieldDataI64>();
+		}
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataU64RTTI : public CM::RTTIType<ScriptSerializableFieldDataU64, ScriptSerializableFieldData, ScriptSerializableFieldDataU64RTTI>
+	{
+	private:
+		CM::UINT64& getValue(ScriptSerializableFieldDataU64* obj) { return obj->value; }
+		void setValue(ScriptSerializableFieldDataU64* obj, CM::UINT64& val) { obj->value = val; }
+
+	public:
+		ScriptSerializableFieldDataU64RTTI()
+		{
+			addPlainField("mValue", 0, &ScriptSerializableFieldDataU64RTTI::getValue, &ScriptSerializableFieldDataU64RTTI::setValue);
+		}
+
+		virtual const CM::String& getRTTIName()
+		{
+			static CM::String name = "SerializableFieldDataU64";
+			return name;
+		}
+
+		virtual CM::UINT32 getRTTIId()
+		{
+			return TID_SerializableFieldDataU64;
+		}
+
+		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
+		{
+			return CM::cm_shared_ptr<ScriptSerializableFieldDataU64>();
+		}
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataFloatRTTI : public CM::RTTIType<ScriptSerializableFieldDataFloat, ScriptSerializableFieldData, ScriptSerializableFieldDataFloatRTTI>
+	{
+	private:
+		float& getValue(ScriptSerializableFieldDataFloat* obj) { return obj->value; }
+		void setValue(ScriptSerializableFieldDataFloat* obj, float& val) { obj->value = val; }
+
+	public:
+		ScriptSerializableFieldDataFloatRTTI()
+		{
+			addPlainField("mValue", 0, &ScriptSerializableFieldDataFloatRTTI::getValue, &ScriptSerializableFieldDataFloatRTTI::setValue);
+		}
+
+		virtual const CM::String& getRTTIName()
+		{
+			static CM::String name = "SerializableFieldDataFloat";
+			return name;
+		}
+
+		virtual CM::UINT32 getRTTIId()
+		{
+			return TID_SerializableFieldDataFloat;
+		}
+
+		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
+		{
+			return CM::cm_shared_ptr<ScriptSerializableFieldDataFloat>();
+		}
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataDoubleRTTI : public CM::RTTIType<ScriptSerializableFieldDataDouble, ScriptSerializableFieldData, ScriptSerializableFieldDataDoubleRTTI>
+	{
+	private:
+		double& getValue(ScriptSerializableFieldDataDouble* obj) { return obj->value; }
+		void setValue(ScriptSerializableFieldDataDouble* obj, double& val) { obj->value = val; }
+
+	public:
+		ScriptSerializableFieldDataDoubleRTTI()
+		{
+			addPlainField("mValue", 0, &ScriptSerializableFieldDataDoubleRTTI::getValue, &ScriptSerializableFieldDataDoubleRTTI::setValue);
+		}
+
+		virtual const CM::String& getRTTIName()
+		{
+			static CM::String name = "SerializableFieldDataDouble";
+			return name;
+		}
+
+		virtual CM::UINT32 getRTTIId()
+		{
+			return TID_SerializableFieldDataDouble;
+		}
+
+		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
+		{
+			return CM::cm_shared_ptr<ScriptSerializableFieldDataDouble>();
+		}
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataStringRTTI : public CM::RTTIType<ScriptSerializableFieldDataString, ScriptSerializableFieldData, ScriptSerializableFieldDataStringRTTI>
+	{
+	private:
+		CM::WString& getValue(ScriptSerializableFieldDataString* obj) { return obj->value; }
+		void setValue(ScriptSerializableFieldDataString* obj, CM::WString& val) { obj->value = val; }
+
+	public:
+		ScriptSerializableFieldDataStringRTTI()
+		{
+			addPlainField("mValue", 0, &ScriptSerializableFieldDataStringRTTI::getValue, &ScriptSerializableFieldDataStringRTTI::setValue);
+		}
+
+		virtual const CM::String& getRTTIName()
+		{
+			static CM::String name = "SerializableFieldDataString";
+			return name;
+		}
+
+		virtual CM::UINT32 getRTTIId()
+		{
+			return TID_SerializableFieldDataString;
+		}
+
+		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
+		{
+			return CM::cm_shared_ptr<ScriptSerializableFieldDataString>();
+		}
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataResourceRefRTTI : public CM::RTTIType<ScriptSerializableFieldDataResourceRef, ScriptSerializableFieldData, ScriptSerializableFieldDataResourceRefRTTI>
+	{
+	private:
+		CM::HResource& getValue(ScriptSerializableFieldDataResourceRef* obj) { return obj->value; }
+		void setValue(ScriptSerializableFieldDataResourceRef* obj, CM::HResource& val) { obj->value = val; }
+
+	public:
+		ScriptSerializableFieldDataResourceRefRTTI()
+		{
+			addReflectableField("mValue", 0, &ScriptSerializableFieldDataResourceRefRTTI::getValue, &ScriptSerializableFieldDataResourceRefRTTI::setValue);
+		}
+
+		virtual const CM::String& getRTTIName()
+		{
+			static CM::String name = "SerializableFieldDataResourceRef";
+			return name;
+		}
+
+		virtual CM::UINT32 getRTTIId()
+		{
+			return TID_SerializableFieldDataResourceRef;
+		}
+
+		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
+		{
+			return CM::cm_shared_ptr<ScriptSerializableFieldDataResourceRef>();
+		}
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldDataGameObjectRefRTTI : public CM::RTTIType<ScriptSerializableFieldDataGameObjectRef, ScriptSerializableFieldData, ScriptSerializableFieldDataGameObjectRefRTTI>
+	{
+	private:
+		CM::HGameObject& getValue(ScriptSerializableFieldDataGameObjectRef* obj) { return obj->value; }
+		void setValue(ScriptSerializableFieldDataGameObjectRef* obj, CM::HGameObject& val) { obj->value = val; }
+
+	public:
+		ScriptSerializableFieldDataGameObjectRefRTTI()
+		{
+			addReflectableField("mValue", 0, &ScriptSerializableFieldDataGameObjectRefRTTI::getValue, &ScriptSerializableFieldDataGameObjectRefRTTI::setValue);
+		}
+
+		virtual const CM::String& getRTTIName()
+		{
+			static CM::String name = "SerializableFieldDataGameObjectRef";
+			return name;
+		}
+
+		virtual CM::UINT32 getRTTIId()
+		{
+			return TID_SerializableFieldDataGameObjectRef;
+		}
+
+		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
+		{
+			return CM::cm_shared_ptr<ScriptSerializableFieldDataGameObjectRef>();
+		}
+	};
+}

+ 42 - 0
SBansheeEngine/Include/BsScriptSerializableObject.h

@@ -0,0 +1,42 @@
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+#include "CmIReflectable.h"
+#include <mono/jit/jit.h>
+
+namespace BansheeEngine
+{
+	class BS_SCR_BE_EXPORT ScriptSerializableObject : public CM::IReflectable
+	{
+	private:
+		struct ConstructPrivately {};
+
+	public:
+		ScriptSerializableObject(const ConstructPrivately& dummy, ScriptSerializableObjectInfoPtr objInfo, MonoObject* managedInstance);
+		ScriptSerializableObject(const ConstructPrivately& dummy);
+
+		static ScriptSerializableObjectPtr create(MonoObject* managedInstance);
+
+	protected:
+		ScriptSerializableObjectInfoPtr mObjInfo;
+		MonoObject* mManagedInstance;
+		CM::Vector<ScriptSerializableFieldDataEntryPtr>::type mFieldEntries;
+
+		void setFieldData(const ScriptSerializableFieldInfoPtr& fieldInfo, const ScriptSerializableFieldDataPtr& val);
+		ScriptSerializableFieldDataPtr getFieldData(const ScriptSerializableFieldInfoPtr& fieldInfo);
+
+		void setValue(const ScriptSerializableFieldInfoPtr& fieldInfo, void* val);
+		void* getValue(const ScriptSerializableFieldInfoPtr& fieldInfo);
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+		
+		static ScriptSerializableObjectPtr createEmpty();
+
+	public:
+		friend class ScriptSerializableObjectRTTI;
+		static CM::RTTITypeBase* getRTTIStatic();
+		virtual CM::RTTITypeBase* getRTTI() const;
+	};
+}

+ 46 - 107
SBansheeEngine/Include/BsScriptSerializableObjectInfo.h

@@ -6,7 +6,7 @@
 
 namespace BansheeEngine
 {
-	enum class ScriptFieldType
+	enum class ScriptPrimitiveType
 	{
 		Bool,
 		Char,
@@ -21,13 +21,10 @@ namespace BansheeEngine
 		Float,
 		Double,
 		String,
-		SerializableObjectValue,
-		SerializableObjectRef,
 		TextureRef,
 		SpriteTextureRef,
 		SceneObjectRef,
-		ComponentRef,
-		Other
+		ComponentRef
 	};
 
 	enum class ScriptFieldFlags
@@ -36,147 +33,88 @@ namespace BansheeEngine
 		Inspectable = 0x02
 	};
 
-	struct BS_SCR_BE_EXPORT ScriptSerializableFieldInfo : public CM::IReflectable
+	class BS_SCR_BE_EXPORT ScriptSerializableTypeInfo : public CM::IReflectable
 	{
-		ScriptSerializableFieldInfo();
-		virtual ~ScriptSerializableFieldInfo() { }
-
-		CM::String mName;
-		CM::String mTypeNamespace;
-		CM::String mTypeName;
-		CM::UINT32 mFieldId;
-
-		ScriptFieldType mType;
-		ScriptFieldFlags mFlags;
-
-		MonoField* mMonoField;
-
-		virtual bool isArray() const = 0;
-		virtual bool isReferenceType() const = 0;
-
-		bool isNull(MonoObject* obj);
-		void setNull(MonoObject* obj);
-
-		virtual CM::UINT32 getNumArrayElements(MonoObject* obj, CM::UINT32 dimension) = 0;
-		virtual void setNumArrayElements(MonoObject* obj, CM::UINT32 numElements, CM::UINT32 dimension, bool discardExisting = true) = 0;
-
-		void setU8(MonoObject* obj, CM::UINT8 val, CM::UINT32 arrayIdx = 0);
-		CM::UINT8 getU8(MonoObject* obj, CM::UINT32 arrayIdx = 0);
-
-		void setI8(MonoObject* obj, CM::INT8 val, CM::UINT32 arrayIdx = 0);
-		CM::INT8 getI8(MonoObject* obj, CM::UINT32 arrayIdx = 0);
-
-		void setU16(MonoObject* obj, CM::UINT16 val, CM::UINT32 arrayIdx = 0);
-		CM::UINT16 getU16(MonoObject* obj, CM::UINT32 arrayIdx = 0);
-
-		void setI16(MonoObject* obj, CM::INT16 val, CM::UINT32 arrayIdx = 0);
-		CM::INT16 getI16(MonoObject* obj, CM::UINT32 arrayIdx = 0);
-
-		void setU32(MonoObject* obj, CM::UINT32 val, CM::UINT32 arrayIdx = 0);
-		CM::UINT32 getU32(MonoObject* obj, CM::UINT32 arrayIdx = 0);
-
-		void setI32(MonoObject* obj, CM::INT32 val, CM::UINT32 arrayIdx = 0);
-		CM::INT32 getI32(MonoObject* obj, CM::UINT32 arrayIdx = 0);
-
-		void setU64(MonoObject* obj, CM::UINT64 val, CM::UINT32 arrayIdx = 0);
-		CM::UINT64 getU64(MonoObject* obj, CM::UINT32 arrayIdx = 0);
-
-		void setI64(MonoObject* obj, CM::INT64 val, CM::UINT32 arrayIdx = 0);
-		CM::INT64 getI64(MonoObject* obj, CM::UINT32 arrayIdx = 0);
-
-		void setBool(MonoObject* obj, bool val, CM::UINT32 arrayIdx = 0);
-		bool getBool(MonoObject* obj, CM::UINT32 arrayIdx = 0);
-
-		void setChar(MonoObject* obj, wchar_t val, CM::UINT32 arrayIdx = 0);
-		wchar_t getChar(MonoObject* obj, CM::UINT32 arrayIdx = 0);
-
-		void setFloat(MonoObject* obj, float val, CM::UINT32 arrayIdx = 0);
-		float getFloat(MonoObject* obj, CM::UINT32 arrayIdx = 0);
-
-		void setDouble(MonoObject* obj, double val, CM::UINT32 arrayIdx = 0);
-		double getDouble(MonoObject* obj, CM::UINT32 arrayIdx = 0);
-
-		void setString(MonoObject* obj, const CM::WString& val, CM::UINT32 arrayIdx = 0);
-		CM::WString getString(MonoObject* obj, CM::UINT32 arrayIdx = 0);
-
-		void setTexture(MonoObject* obj, const CM::HTexture& resource, CM::UINT32 arrayIdx = 0);
-		CM::HTexture getTexture(MonoObject* obj, CM::UINT32 arrayIdx = 0);
-
-		void setSpriteTexture(MonoObject* obj, const HSpriteTexture& resource, CM::UINT32 arrayIdx = 0);
-		HSpriteTexture getSpriteTexture(MonoObject* obj, CM::UINT32 arrayIdx = 0);
-
-		void setSceneObject(MonoObject* obj, const CM::HSceneObject& sceneObject, CM::UINT32 arrayIdx = 0);
-		CM::HSceneObject getSceneObject(MonoObject* obj, CM::UINT32 arrayIdx = 0);
-
-		void setComponent(MonoObject* obj, const CM::HComponent& component, CM::UINT32 arrayIdx = 0);
-		CM::HComponent getComponent(MonoObject* obj, CM::UINT32 arrayIdx = 0);
 
-		void setSerializableObject(MonoObject* obj, const MonoObject* value, CM::UINT32 arrayIdx = 0);
-		MonoObject* getSerializableObject(MonoObject* obj, CM::UINT32 arrayIdx = 0);
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+	public:
+		friend class ScriptSerializableTypeInfoRTTI;
+		static CM::RTTITypeBase* getRTTIStatic();
+		virtual CM::RTTITypeBase* getRTTI() const;
+	};
 
-	protected:
-		virtual void setValue(MonoObject* obj, void* val, CM::UINT32 arrayIdx = 0) = 0;
-		virtual void* getValue(MonoObject* obj, CM::UINT32 arrayIdx = 0) = 0;
+	class BS_SCR_BE_EXPORT ScriptSerializableTypeInfoPrimitive : public ScriptSerializableTypeInfo
+	{
+	public:
+		ScriptPrimitiveType mType;
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 	public:
-		friend class ScriptSerializableFieldInfoRTTI;
+		friend class ScriptSerializableTypeInfoPrimitiveRTTI;
 		static CM::RTTITypeBase* getRTTIStatic();
 		virtual CM::RTTITypeBase* getRTTI() const;
 	};
 
-	struct BS_SCR_BE_EXPORT ScriptSerializableFieldInfoPlain : public ScriptSerializableFieldInfo
+	class BS_SCR_BE_EXPORT ScriptSerializableTypeInfoObject : public ScriptSerializableTypeInfo
 	{
 	public:
-		virtual bool isArray() const { return false; }
-		virtual bool isReferenceType() const;
+		CM::String mTypeNamespace;
+		CM::String mTypeName;
 
-		virtual CM::UINT32 getNumArrayElements(MonoObject* obj, CM::UINT32 dimension);
-		virtual void setNumArrayElements(MonoObject* obj, CM::UINT32 numElements, CM::UINT32 dimension, bool discardExisting = true);
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+	public:
+		friend class ScriptSerializableTypeInfoObjectRTTI;
+		static CM::RTTITypeBase* getRTTIStatic();
+		virtual CM::RTTITypeBase* getRTTI() const;
+	};
 
-	protected:
-		virtual void setValue(MonoObject* obj, void* val, CM::UINT32 arrayIdx = 0);
-		virtual void* getValue(MonoObject* obj, CM::UINT32 arrayIdx = 0);
+	class BS_SCR_BE_EXPORT ScriptSerializableTypeInfoArray : public ScriptSerializableTypeInfo
+	{
+	public:
+		ScriptSerializableTypeInfoPtr mElementType;
+		CM::UINT32 mRank;
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 	public:
-		friend class ScriptSerializableFieldInfoPlainRTTI;
+		friend class ScriptSerializableTypeInfoArrayRTTI;
 		static CM::RTTITypeBase* getRTTIStatic();
 		virtual CM::RTTITypeBase* getRTTI() const;
 	};
 
-	struct BS_SCR_BE_EXPORT ScriptSerializableFieldInfoArray : public ScriptSerializableFieldInfo
+	class BS_SCR_BE_EXPORT ScriptSerializableFieldInfo : public ScriptSerializableTypeInfo
 	{
 	public:
-		ScriptSerializableFieldInfoArray();
-
-		CM::UINT8 mArrayDimensions;
+		ScriptSerializableFieldInfo();
+		virtual ~ScriptSerializableFieldInfo() { }
 
-		virtual bool isArray() const { return true; }
-		virtual bool isReferenceType() const { return true; }
+		CM::String mName;
+		CM::UINT32 mFieldId;
 
-		virtual CM::UINT32 getNumArrayElements(MonoObject* obj, CM::UINT32 dimension);
-		virtual void setNumArrayElements(MonoObject* obj, CM::UINT32 numElements, CM::UINT32 dimension, bool discardExisting = true);
+		ScriptSerializableTypeInfoPtr mTypeInfo;
+		ScriptFieldFlags mFlags;
 
-	protected:
-		virtual void setValue(MonoObject* obj, void* val, CM::UINT32 arrayIdx = 0);
-		virtual void* getValue(MonoObject* obj, CM::UINT32 arrayIdx = 0);
+		MonoField* mMonoField;
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/
 		/************************************************************************/
 	public:
-		friend class ScriptSerializableFieldInfoArrayRTTI;
+		friend class ScriptSerializableFieldInfoRTTI;
 		static CM::RTTITypeBase* getRTTIStatic();
 		virtual CM::RTTITypeBase* getRTTI() const;
 	};
 
-	struct BS_SCR_BE_EXPORT ScriptSerializableObjectInfo : public CM::IReflectable
+	class BS_SCR_BE_EXPORT ScriptSerializableObjectInfo : public CM::IReflectable
 	{
+	public:
 		ScriptSerializableObjectInfo();
 
 		CM::String mNamespace;
@@ -202,8 +140,9 @@ namespace BansheeEngine
 		virtual CM::RTTITypeBase* getRTTI() const;
 	};
 
-	struct BS_SCR_BE_EXPORT ScriptSerializableAssemblyInfo : public CM::IReflectable
+	class BS_SCR_BE_EXPORT ScriptSerializableAssemblyInfo : public CM::IReflectable
 	{
+	public:
 		CM::String mName;
 
 		CM::UnorderedMap<CM::String, CM::UINT32>::type mTypeNameToId;

+ 128 - 51
SBansheeEngine/Include/BsScriptSerializableObjectInfoRTTI.h

@@ -29,14 +29,14 @@ namespace BansheeEngine
 			return iter->second;
 		}
 
-		void setSerializableObjectInfo(ScriptSerializableAssemblyInfo* obj, UINT32 idx, ScriptSerializableObjectInfoPtr val) 
+		void setSerializableObjectInfo(ScriptSerializableAssemblyInfo* obj, CM::UINT32 idx, ScriptSerializableObjectInfoPtr val) 
 		{ 
 			obj->mTypeNameToId[val->getFullTypeName()] = val->mTypeId;
 			obj->mObjectInfos[val->mTypeId] = val;
 		}
 		
-		UINT32 getSerializableObjectInfoArraySize(ScriptSerializableAssemblyInfo* obj) { return (UINT32)obj->mObjectInfos.size(); }
-		void setSerializableObjectInfoArraySize(ScriptSerializableAssemblyInfo* obj, UINT32 size) {  }
+		CM::UINT32 getSerializableObjectInfoArraySize(ScriptSerializableAssemblyInfo* obj) { return (CM::UINT32)obj->mObjectInfos.size(); }
+		void setSerializableObjectInfoArraySize(ScriptSerializableAssemblyInfo* obj, CM::UINT32 size) {  }
 
 	public:
 		ScriptSerializableAssemblyInfoRTTI()
@@ -60,7 +60,7 @@ namespace BansheeEngine
 
 		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
 		{
-			return cm_shared_ptr<ScriptSerializableAssemblyInfo>();
+			return CM::cm_shared_ptr<ScriptSerializableAssemblyInfo>();
 		}
 	};
 
@@ -116,14 +116,14 @@ namespace BansheeEngine
 			return iter->second;
 		}
 
-		void setSerializableFieldInfo(ScriptSerializableObjectInfo* obj, UINT32 idx, ScriptSerializableFieldInfoPtr val) 
+		void setSerializableFieldInfo(ScriptSerializableObjectInfo* obj, CM::UINT32 idx, ScriptSerializableFieldInfoPtr val) 
 		{ 
 			obj->mFieldNameToId[val->mName] = val->mFieldId;
 			obj->mFields[val->mFieldId] = val;
 		}
 
-		UINT32 getSerializableFieldInfoArraySize(ScriptSerializableObjectInfo* obj) { return (UINT32)obj->mFields.size(); }
-		void setSerializableFieldInfoArraySize(ScriptSerializableObjectInfo* obj, UINT32 size) {  }
+		CM::UINT32 getSerializableFieldInfoArraySize(ScriptSerializableObjectInfo* obj) { return (CM::UINT32)obj->mFields.size(); }
+		void setSerializableFieldInfoArraySize(ScriptSerializableObjectInfo* obj, CM::UINT32 size) {  }
 
 	public:
 		ScriptSerializableObjectInfoRTTI()
@@ -151,31 +151,21 @@ namespace BansheeEngine
 
 		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
 		{
-			return cm_shared_ptr<ScriptSerializableObjectInfo>();
+			return CM::cm_shared_ptr<ScriptSerializableObjectInfo>();
 		}
 	};
 
 	class BS_SCR_BE_EXPORT ScriptSerializableFieldInfoRTTI : public CM::RTTIType<ScriptSerializableFieldInfo, CM::IReflectable, ScriptSerializableFieldInfoRTTI>
 	{
 	private:
-		CM::String& getTypeNamespace(ScriptSerializableFieldInfo* obj)
+		ScriptSerializableTypeInfoPtr getTypeInfo(ScriptSerializableFieldInfo* obj)
 		{
-			return obj->mTypeNamespace;
-		}
-
-		void setTypeNamespace(ScriptSerializableFieldInfo* obj, CM::String& val)
-		{
-			obj->mTypeNamespace = val;
+			return obj->mTypeInfo;
 		}
 
-		CM::String& getTypeName(ScriptSerializableFieldInfo* obj)
+		void setTypeInfo(ScriptSerializableFieldInfo* obj, ScriptSerializableTypeInfoPtr val)
 		{
-			return obj->mTypeName;
-		}
-
-		void setTypeName(ScriptSerializableFieldInfo* obj, CM::String& val)
-		{
-			obj->mTypeName = val;
+			obj->mTypeInfo = val;
 		}
 
 		CM::String& getName(ScriptSerializableFieldInfo* obj)
@@ -200,9 +190,7 @@ namespace BansheeEngine
 
 		CM::UINT32& getFlags(ScriptSerializableFieldInfo* obj)
 		{
-			CM::UINT32 flags = (CM::UINT32)obj->mFlags;
-
-			return flags;
+			return (CM::UINT32&)obj->mFlags;
 		}
 
 		void setFlags(ScriptSerializableFieldInfo* obj, CM::UINT32& val)
@@ -210,97 +198,186 @@ namespace BansheeEngine
 			obj->mFlags = (ScriptFieldFlags)val;
 		}
 
-		CM::UINT32& getType(ScriptSerializableFieldInfo* obj)
+	public:
+		ScriptSerializableFieldInfoRTTI()
 		{
-			CM::UINT32 flags = (CM::UINT32)obj->mType;
+			addPlainField("mName", 0, &ScriptSerializableFieldInfoRTTI::getName, &ScriptSerializableFieldInfoRTTI::setName);
+			addReflectablePtrField("mTypeInfo", 1, &ScriptSerializableFieldInfoRTTI::getTypeInfo, &ScriptSerializableFieldInfoRTTI::setTypeInfo);
+			addPlainField("mFieldId", 2, &ScriptSerializableFieldInfoRTTI::getFieldId, &ScriptSerializableFieldInfoRTTI::setFieldId);
+			addPlainField("mFlags", 3, &ScriptSerializableFieldInfoRTTI::getFlags, &ScriptSerializableFieldInfoRTTI::setFlags);
+		}
 
-			return flags;
+		virtual const CM::String& getRTTIName()
+		{
+			static CM::String name = "ScriptSerializableFieldInfo";
+			return name;
 		}
 
-		void setType(ScriptSerializableFieldInfo* obj, CM::UINT32& val)
+		virtual CM::UINT32 getRTTIId()
 		{
-			obj->mType = (ScriptFieldType)val;
+			return TID_SerializableFieldInfo;
 		}
 
+		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
+		{
+			return CM::cm_shared_ptr<ScriptSerializableFieldInfo>();
+		}
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableTypeInfoRTTI : public CM::RTTIType<ScriptSerializableTypeInfo, CM::IReflectable, ScriptSerializableTypeInfoRTTI>
+	{
+	private:
+
 	public:
-		ScriptSerializableFieldInfoRTTI()
+		ScriptSerializableTypeInfoRTTI()
 		{
-			addPlainField("mName", 0, &ScriptSerializableFieldInfoRTTI::getName, &ScriptSerializableFieldInfoRTTI::setName);
-			addPlainField("mTypeNamespace", 1, &ScriptSerializableFieldInfoRTTI::getTypeNamespace, &ScriptSerializableFieldInfoRTTI::setTypeNamespace);
-			addPlainField("mTypeName", 2, &ScriptSerializableFieldInfoRTTI::getTypeName, &ScriptSerializableFieldInfoRTTI::setTypeName);
-			addPlainField("mFieldId", 3, &ScriptSerializableFieldInfoRTTI::getFieldId, &ScriptSerializableFieldInfoRTTI::setFieldId);
-			addPlainField("mFlags", 4, &ScriptSerializableFieldInfoRTTI::getFlags, &ScriptSerializableFieldInfoRTTI::setFlags);
-			addPlainField("mType", 5, &ScriptSerializableFieldInfoRTTI::getType, &ScriptSerializableFieldInfoRTTI::setType);
+
 		}
 
 		virtual const CM::String& getRTTIName()
 		{
-			static CM::String name = "ScriptSerializableFieldInfo";
+			static CM::String name = "ScriptSerializableTypeInfo";
 			return name;
 		}
 
 		virtual CM::UINT32 getRTTIId()
 		{
-			return TID_SerializableFieldInfo;
+			return TID_SerializableTypeInfo;
 		}
 
 		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
 		{
-			CM_EXCEPT(CM::InvalidStateException, "Cannot instantiate an abstract class.");
+			return CM::cm_shared_ptr<ScriptSerializableTypeInfo>();
 		}
 	};
 
-	class BS_SCR_BE_EXPORT ScriptSerializableFieldInfoPlainRTTI : public CM::RTTIType<ScriptSerializableFieldInfoPlain, ScriptSerializableFieldInfo, ScriptSerializableFieldInfoPlainRTTI>
+	class BS_SCR_BE_EXPORT ScriptSerializableTypeInfoPrimitiveRTTI : public CM::RTTIType<ScriptSerializableTypeInfoPrimitive, ScriptSerializableTypeInfo, ScriptSerializableTypeInfoPrimitiveRTTI>
 	{
 	private:
+		ScriptPrimitiveType& getType(ScriptSerializableTypeInfoPrimitive* obj)
+		{
+			return obj->mType;
+		}
 
-	public:
-		ScriptSerializableFieldInfoPlainRTTI()
+		void setType(ScriptSerializableTypeInfoPrimitive* obj, ScriptPrimitiveType& val)
 		{
+			obj->mType = val;
+		}
 
+	public:
+		ScriptSerializableTypeInfoPrimitiveRTTI()
+		{
+			addPlainField("mType", 0, &ScriptSerializableTypeInfoPrimitiveRTTI::getType, &ScriptSerializableTypeInfoPrimitiveRTTI::setType);
 		}
 
 		virtual const CM::String& getRTTIName()
 		{
-			static CM::String name = "ScriptSerializableFieldInfoPlain";
+			static CM::String name = "ScriptSerializableTypeInfoPrimitive";
 			return name;
 		}
 
 		virtual CM::UINT32 getRTTIId()
 		{
-			return TID_SerializableFieldInfoPlain;
+			return TID_SerializableTypeInfoPrimitive;
 		}
 
 		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
 		{
-			return cm_shared_ptr<ScriptSerializableFieldInfoPlain>();
+			return CM::cm_shared_ptr<ScriptSerializableTypeInfoPrimitive>();
 		}
 	};
 
-	class BS_SCR_BE_EXPORT ScriptSerializableFieldInfoArrayRTTI : public CM::RTTIType<ScriptSerializableFieldInfoArray, ScriptSerializableFieldInfo, ScriptSerializableFieldInfoArrayRTTI>
+	class BS_SCR_BE_EXPORT ScriptSerializableTypeInfoObjectRTTI : public CM::RTTIType<ScriptSerializableTypeInfoObject, ScriptSerializableTypeInfo, ScriptSerializableTypeInfoObjectRTTI>
 	{
 	private:
+		CM::String& getTypeNamespace(ScriptSerializableTypeInfoObject* obj)
+		{
+			return obj->mTypeNamespace;
+		}
+
+		void setTypeNamespace(ScriptSerializableTypeInfoObject* obj, CM::String& val)
+		{
+			obj->mTypeNamespace = val;
+		}
+
+		CM::String& getTypeName(ScriptSerializableTypeInfoObject* obj)
+		{
+			return obj->mTypeName;
+		}
+
+		void setTypeName(ScriptSerializableTypeInfoObject* obj, CM::String& val)
+		{
+			obj->mTypeName = val;
+		}
 
 	public:
-		ScriptSerializableFieldInfoArrayRTTI()
+		ScriptSerializableTypeInfoObjectRTTI()
+		{
+			addPlainField("mTypeName", 0, &ScriptSerializableTypeInfoObjectRTTI::getTypeName, &ScriptSerializableTypeInfoObjectRTTI::setTypeName);
+			addPlainField("mTypeNamespace", 1, &ScriptSerializableTypeInfoObjectRTTI::getTypeNamespace, &ScriptSerializableTypeInfoObjectRTTI::setTypeNamespace);
+		}
+
+		virtual const CM::String& getRTTIName()
 		{
+			static CM::String name = "ScriptSerializableTypeInfoObject";
+			return name;
+		}
+
+		virtual CM::UINT32 getRTTIId()
+		{
+			return TID_SerializableTypeInfoObject;
+		}
 
+		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
+		{
+			return CM::cm_shared_ptr<ScriptSerializableTypeInfoObject>();
+		}
+	};
+
+	class BS_SCR_BE_EXPORT ScriptSerializableTypeInfoArrayRTTI : public CM::RTTIType<ScriptSerializableTypeInfoArray, ScriptSerializableTypeInfo, ScriptSerializableTypeInfoArrayRTTI>
+	{
+	private:
+		ScriptSerializableTypeInfoPtr getElementType(ScriptSerializableTypeInfoArray* obj)
+		{
+			return obj->mElementType;
+		}
+
+		void setElementType(ScriptSerializableTypeInfoArray* obj, ScriptSerializableTypeInfoPtr val)
+		{
+			obj->mElementType = val;
+		}
+
+		CM::UINT32& getRank(ScriptSerializableTypeInfoArray* obj)
+		{
+			return obj->mRank;
+		}
+
+		void setRank(ScriptSerializableTypeInfoArray* obj, CM::UINT32& val)
+		{
+			obj->mRank = val;
+		}
+
+	public:
+		ScriptSerializableTypeInfoArrayRTTI()
+		{
+			addReflectablePtrField("mElementType", 0, &ScriptSerializableTypeInfoArrayRTTI::getElementType, &ScriptSerializableTypeInfoArrayRTTI::setElementType);
+			addPlainField("mRank", 1, &ScriptSerializableTypeInfoArrayRTTI::getRank, &ScriptSerializableTypeInfoArrayRTTI::setRank);
 		}
 
 		virtual const CM::String& getRTTIName()
 		{
-			static CM::String name = "ScriptSerializableFieldInfoArray";
+			static CM::String name = "ScriptSerializableTypeInfoArray";
 			return name;
 		}
 
 		virtual CM::UINT32 getRTTIId()
 		{
-			return TID_SerializableFieldInfoArray;
+			return TID_SerializableTypeInfoArray;
 		}
 
 		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
 		{
-			return cm_shared_ptr<ScriptSerializableFieldInfoArray>();
+			return CM::cm_shared_ptr<ScriptSerializableTypeInfoArray>();
 		}
 	};
 }

+ 73 - 0
SBansheeEngine/Include/BsScriptSerializableObjectRTTI.h

@@ -0,0 +1,73 @@
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+#include "CmRTTIType.h"
+#include "BsScriptSerializableObject.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BE_EXPORT ScriptSerializableObjectRTTI : public CM::RTTIType<ScriptSerializableObject, CM::IReflectable, ScriptSerializableObjectRTTI>
+	{
+	private:
+		ScriptSerializableObjectInfoPtr getInfo(ScriptSerializableObject* obj)
+		{
+			return obj->mObjInfo;
+		}
+
+		void setInfo(ScriptSerializableObject* obj, ScriptSerializableObjectInfoPtr val)
+		{
+			obj->mObjInfo = val;
+		}
+
+		ScriptSerializableFieldDataEntryPtr getFieldEntry(ScriptSerializableObject* obj, CM::UINT32 arrayIdx)
+		{
+			return obj->mFieldEntries[arrayIdx];
+		}
+
+		void setFieldsEntry(ScriptSerializableObject* obj, CM::UINT32 arrayIdx, ScriptSerializableFieldDataEntryPtr val)
+		{
+			obj->mFieldEntries[arrayIdx] = val;
+		}
+
+		CM::UINT32 getNumFieldEntries(ScriptSerializableObject* obj)
+		{
+			return (CM::UINT32)obj->mFieldEntries.size();
+		}
+
+		void setNumFieldEntries(ScriptSerializableObject* obj, CM::UINT32 numEntries)
+		{
+			obj->mFieldEntries.resize(numEntries);
+		}
+
+	public:
+		ScriptSerializableObjectRTTI()
+		{
+			addReflectablePtrField("mObjInfo", 0, &ScriptSerializableObjectRTTI::getInfo, &ScriptSerializableObjectRTTI::setInfo);
+			addReflectablePtrArrayField("mFieldEntries", 1, &ScriptSerializableObjectRTTI::getFieldEntry, &ScriptSerializableObjectRTTI::getNumFieldEntries, 
+				&ScriptSerializableObjectRTTI::setFieldsEntry, &ScriptSerializableObjectRTTI::setNumFieldEntries);
+		}
+
+		virtual void onDeserializationEnded(CM::IReflectable* obj)
+		{
+			ScriptSerializableObject* serializableObject = static_cast<ScriptSerializableObject*>(obj);
+			
+			// TODO
+		}
+
+		virtual const CM::String& getRTTIName()
+		{
+			static CM::String name = "ScriptSerializableObject";
+			return name;
+		}
+
+		virtual CM::UINT32 getRTTIId()
+		{
+			return TID_ScriptSerializableObject;
+		}
+
+		virtual std::shared_ptr<CM::IReflectable> newRTTIObject()
+		{
+			return ScriptSerializableObject::createEmpty();
+		}
+	};
+}

+ 9 - 3
SBansheeEngine/SBansheeEngine.vcxproj

@@ -228,8 +228,11 @@
   <ItemGroup>
     <ClInclude Include="Include\BsManagedComponent.h" />
     <ClInclude Include="Include\BsManagedComponentRTTI.h" />
-    <ClInclude Include="Include\BsManagedSerializationData.h" />
-    <ClInclude Include="Include\BsManagedSerializationDataRTTI.h" />
+    <ClInclude Include="Include\BsScriptSerializableArray.h" />
+    <ClInclude Include="Include\BsScriptSerializableArrayRTTI.h" />
+    <ClInclude Include="Include\BsScriptSerializableField.h" />
+    <ClInclude Include="Include\BsScriptSerializableFieldRTTI.h" />
+    <ClInclude Include="Include\BsScriptSerializableObject.h" />
     <ClInclude Include="Include\BsRuntimeScriptObjects.h" />
     <ClInclude Include="Include\BsScriptComponent.h" />
     <ClInclude Include="Include\BsScriptEnginePrerequisites.h" />
@@ -258,6 +261,7 @@
     <ClInclude Include="Include\BsScriptResourceManager.h" />
     <ClInclude Include="Include\BsScriptSceneObject.h" />
     <ClInclude Include="Include\BsScriptSerializableObjectInfoRTTI.h" />
+    <ClInclude Include="Include\BsScriptSerializableObjectRTTI.h" />
     <ClInclude Include="Include\BsScriptSpriteTexture.h" />
     <ClInclude Include="Include\BsScriptStringTable.h" />
     <ClInclude Include="Include\BsScriptTexture2D.h" />
@@ -266,7 +270,6 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsManagedComponent.cpp" />
-    <ClCompile Include="Source\BsManagedSerializationData.cpp" />
     <ClCompile Include="Source\BsRuntimeScriptObjects.cpp" />
     <ClCompile Include="Source\BsScriptComponent.cpp" />
     <ClCompile Include="Source\BsScriptEnginePlugin.cpp" />
@@ -290,6 +293,9 @@
     <ClCompile Include="Source\BsScriptGUIInputBox.cpp" />
     <ClCompile Include="Source\BsScriptResourceManager.cpp" />
     <ClCompile Include="Source\BsScriptSceneObject.cpp" />
+    <ClCompile Include="Source\BsScriptSerializableArray.cpp" />
+    <ClCompile Include="Source\BsScriptSerializableField.cpp" />
+    <ClCompile Include="Source\BsScriptSerializableObject.cpp" />
     <ClCompile Include="Source\BsScriptSerializableObjectInfo.cpp" />
     <ClCompile Include="Source\BsScriptSpriteTexture.cpp" />
     <ClCompile Include="Source\BsScriptStringTable.cpp" />

+ 24 - 6
SBansheeEngine/SBansheeEngine.vcxproj.filters

@@ -114,16 +114,28 @@
     <ClInclude Include="Include\BsScriptSceneObject.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="Include\BsManagedSerializationData.h">
+    <ClInclude Include="Include\BsScriptSerializableObjectInfo.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="Include\BsManagedSerializationDataRTTI.h">
+    <ClInclude Include="Include\BsScriptSerializableObjectInfoRTTI.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="Include\BsScriptSerializableObjectInfo.h">
+    <ClInclude Include="Include\BsScriptSerializableArray.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="Include\BsScriptSerializableObjectInfoRTTI.h">
+    <ClInclude Include="Include\BsScriptSerializableObject.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsScriptSerializableObjectRTTI.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsScriptSerializableField.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsScriptSerializableArrayRTTI.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsScriptSerializableFieldRTTI.h">
       <Filter>Header Files</Filter>
     </ClInclude>
   </ItemGroup>
@@ -212,10 +224,16 @@
     <ClCompile Include="Source\BsScriptSceneObject.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="Source\BsManagedSerializationData.cpp">
+    <ClCompile Include="Source\BsScriptSerializableObjectInfo.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="Source\BsScriptSerializableObjectInfo.cpp">
+    <ClCompile Include="Source\BsScriptSerializableObject.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsScriptSerializableArray.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsScriptSerializableField.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
   </ItemGroup>

+ 0 - 28
SBansheeEngine/Source/BsManagedSerializationData.cpp

@@ -1,28 +0,0 @@
-#include "BsManagedSerializationData.h"
-#include "BsManagedSerializationDataRTTI.h"
-
-using namespace CamelotFramework;
-
-namespace BansheeEngine
-{
-	ManagedSerializationDataPtr ManagedSerializationData::create(MonoObject* managedInstance)
-	{
-
-	}
-
-	ManagedSerializationData::ManagedSerializationData(const CM::String& ns, const CM::String& typeName)
-		:mNamespace(ns), mTypename(typeName)
-	{
-
-	}
-
-	RTTITypeBase* ManagedSerializationData::getRTTIStatic()
-	{
-		return ManagedSerializationDataRTTI::instance();
-	}
-
-	RTTITypeBase* ManagedSerializationData::getRTTI() const
-	{
-		return ManagedSerializationData::getRTTIStatic();
-	}
-}

+ 264 - 158
SBansheeEngine/Source/BsRuntimeScriptObjects.cpp

@@ -11,6 +11,14 @@ using namespace CamelotFramework;
 
 namespace BansheeEngine
 {
+	RuntimeScriptObjects::RuntimeScriptObjects()
+		:mBaseTypesInitialized(false), mSerializableAttribute(nullptr), mNonSerializedAttribute(nullptr), 
+		mComponentClass(nullptr), mSceneObjectClass(nullptr), mTextureClass(nullptr), mSpriteTextureClass(nullptr),
+		mSerializeFieldAttribute(nullptr), mHideInInspectorAttribute(nullptr), mSystemArrayClass(nullptr)
+	{
+
+	}
+
 	RuntimeScriptObjects::~RuntimeScriptObjects()
 	{
 
@@ -20,51 +28,9 @@ namespace BansheeEngine
 	{
 		clearScriptObjects(assemblyName);
 
-		// Get necessary classes for detecting needed class & field information
-		MonoAssembly* mscorlib = MonoManager::instance().getAssembly("mscorlib");
-		if(mscorlib == nullptr)
-			CM_EXCEPT(InvalidStateException, "mscorlib assembly is not loaded.");
-
-		MonoAssembly* bansheeEngineAssembly = MonoManager::instance().getAssembly(BansheeEngineAssemblyName);
-		if(bansheeEngineAssembly == nullptr)
-			CM_EXCEPT(InvalidStateException, String(BansheeEngineAssemblyName) +  " assembly is not loaded.");
-
-		MonoClass* serializableAttribute = mscorlib->getClass("System", "SerializableAttribute");
-		if(serializableAttribute == nullptr)
-			CM_EXCEPT(InvalidStateException, "Cannot find SerializableAttribute managed class.");
-
-		MonoClass* nonSerializedAttribute = mscorlib->getClass("System", "NonSerializedAttribute");
-		if(nonSerializedAttribute == nullptr)
-			CM_EXCEPT(InvalidStateException, "Cannot find NonSerializedAttribute managed class.");
-
-		MonoClass* genericListClass = mscorlib->getClass("System", "List`1");
-		if(genericListClass == nullptr)
-			CM_EXCEPT(InvalidStateException, "Cannot find List<T> managed class.");
-
-		MonoClass* componentClass = bansheeEngineAssembly->getClass("BansheeEngine", "Component");
-		if(componentClass == nullptr)
-			CM_EXCEPT(InvalidStateException, "Cannot find Component managed class.");
-
-		MonoClass* sceneObjectClass = bansheeEngineAssembly->getClass("BansheeEngine", "SceneObject");
-		if(sceneObjectClass == nullptr)
-			CM_EXCEPT(InvalidStateException, "Cannot find SceneObject managed class.");
-
-		MonoClass* textureClass = bansheeEngineAssembly->getClass("BansheeEngine", "Texture2D");
-		if(textureClass == nullptr)
-			CM_EXCEPT(InvalidStateException, "Cannot find Texture2D managed class.");
-
-		MonoClass* spriteTextureClass = bansheeEngineAssembly->getClass("BansheeEngine", "SpriteTexture");
-		if(spriteTextureClass == nullptr)
-			CM_EXCEPT(InvalidStateException, "Cannot find SpriteTexture managed class.");
+		if(!mBaseTypesInitialized)
+			initializeBaseTypes();
 
-		MonoClass* serializeFieldAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "SerializeField");
-		if(serializeFieldAttribute == nullptr)
-			CM_EXCEPT(InvalidStateException, "Cannot find SerializeField managed class.");
-
-		MonoClass* hideInInspectorAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "HideInInspector");
-		if(hideInInspectorAttribute == nullptr)
-			CM_EXCEPT(InvalidStateException, "Cannot find HideInInspector managed class.");
-		
 		// Process all classes and fields
 		CM::UINT32 mUniqueTypeId = 1;
 
@@ -81,7 +47,7 @@ namespace BansheeEngine
 		const Vector<MonoClass*>::type& allClasses = curAssembly->getAllClasses();
 		for(auto& curClass : allClasses)
 		{
-			if((curClass->isSubClassOf(componentClass) || curClass->hasAttribute(serializableAttribute)) && curClass != componentClass)
+			if((curClass->isSubClassOf(mComponentClass) || curClass->hasAttribute(mSerializableAttribute)) && curClass != mComponentClass)
 			{
 				std::shared_ptr<ScriptSerializableObjectInfo> objInfo = cm_shared_ptr<ScriptSerializableObjectInfo>();
 
@@ -112,132 +78,27 @@ namespace BansheeEngine
 				if(field->isStatic())
 					continue;
 
-				MonoClass* fieldType = field->getType();
-				MonoClass* fieldElementClass = fieldType;
-				MonoType* monoType = mono_class_get_type(fieldType->_getInternalClass());
-				int monoPrimitiveType = mono_type_get_type(monoType);
-
-				std::shared_ptr<ScriptSerializableFieldInfo> fieldInfo = nullptr;
-
-				bool isSupportedType = true;
-				if(monoPrimitiveType == MONO_TYPE_ARRAY) 
-				{
-					std::shared_ptr<ScriptSerializableFieldInfoArray> arrayFieldInfo = cm_shared_ptr<ScriptSerializableFieldInfoArray>();
-					arrayFieldInfo->mArrayDimensions = (UINT32)mono_class_get_rank(fieldType->_getInternalClass());
-
-					fieldInfo = arrayFieldInfo;
-
-					::MonoClass* elementClass = mono_class_get_element_class(fieldType->_getInternalClass());
-					if(elementClass != nullptr)
-					{
-						monoType = mono_class_get_type(elementClass);
-						monoPrimitiveType = mono_type_get_type(monoType);
-
-						::MonoClass* elementClass = mono_type_get_class(monoType);
-						String elementNs = mono_class_get_namespace(elementClass);
-						String elementTypeName = mono_class_get_name(elementClass);
-
-						fieldElementClass = MonoManager::instance().findClass(elementNs, elementTypeName);
-					}
-				}
-				else if(monoPrimitiveType == MONO_TYPE_CLASS)
-				{
-					// TODO - Check for List or Dictionary
-					
-					// If not List/Dictionary
-					fieldInfo = cm_shared_ptr<ScriptSerializableFieldInfoPlain>();
-				}
-				else
-				{
-					fieldInfo = cm_shared_ptr<ScriptSerializableFieldInfoPlain>();
-				}
+				std::shared_ptr<ScriptSerializableFieldInfo> fieldInfo = cm_shared_ptr<ScriptSerializableFieldInfo>();
 
 				fieldInfo->mFieldId = mUniqueFieldId++;
-				fieldInfo->mMonoField = field;
 				fieldInfo->mName = field->getName();
-
-				fieldInfo->mTypeNamespace = fieldType->getNamespace();
-				fieldInfo->mTypeName = fieldType->getTypeName();
-
-				//  Determine field type
-				switch(monoPrimitiveType) // TODO - If array I need to get underlying type
-				{
-				case MONO_TYPE_BOOLEAN:
-					fieldInfo->mType = ScriptFieldType::Bool;
-					break;
-				case MONO_TYPE_CHAR:
-					fieldInfo->mType = ScriptFieldType::Char;
-					break;
-				case MONO_TYPE_I1:
-					fieldInfo->mType = ScriptFieldType::I8;
-					break;
-				case MONO_TYPE_U1:
-					fieldInfo->mType = ScriptFieldType::U8;
-					break;
-				case MONO_TYPE_I2:
-					fieldInfo->mType = ScriptFieldType::I16;
-					break;
-				case MONO_TYPE_U2:
-					fieldInfo->mType = ScriptFieldType::U16;
-					break;
-				case MONO_TYPE_I4:
-					fieldInfo->mType = ScriptFieldType::I32;
-					break;
-				case MONO_TYPE_U4:
-					fieldInfo->mType = ScriptFieldType::U32;
-					break;
-				case MONO_TYPE_I8:
-					fieldInfo->mType = ScriptFieldType::U64;
-					break;
-				case MONO_TYPE_U8:
-					fieldInfo->mType = ScriptFieldType::U64;
-					break;
-				case MONO_TYPE_STRING:
-					fieldInfo->mType = ScriptFieldType::String;
-					break;
-				case MONO_TYPE_R4:
-					fieldInfo->mType = ScriptFieldType::Float;
-					break;
-				case MONO_TYPE_R8:
-					fieldInfo->mType = ScriptFieldType::Double;
-					break;
-				case MONO_TYPE_CLASS:
-					if(fieldElementClass->isSubClassOf(textureClass))
-						fieldInfo->mType = ScriptFieldType::TextureRef;
-					else if(fieldElementClass->isSubClassOf(spriteTextureClass))
-						fieldInfo->mType = ScriptFieldType::SpriteTextureRef;
-					else if(fieldElementClass->isSubClassOf(sceneObjectClass))
-						fieldInfo->mType = ScriptFieldType::SceneObjectRef;
-					else if(fieldElementClass->isSubClassOf(componentClass))
-						fieldInfo->mType = ScriptFieldType::ComponentRef;
-					else
-					{
-						if(hasSerializableObjectInfo(fieldElementClass->getNamespace(), fieldElementClass->getTypeName())) // TODO - Ensure this checks for array types
-							fieldInfo->mType = ScriptFieldType::SerializableObjectRef;
-					}
-
-					break;
-				case MONO_TYPE_VALUETYPE:
-					if(hasSerializableObjectInfo(fieldElementClass->getNamespace(), fieldElementClass->getTypeName()))
-						fieldInfo->mType = ScriptFieldType::SerializableObjectValue;
-
-					break;
-				}
-
-				if(fieldInfo->mType != ScriptFieldType::Other)
+				fieldInfo->mMonoField = field;
+				fieldInfo->mTypeInfo = determineType(field->getType());
+				
+				if(fieldInfo->mTypeInfo != nullptr)
 				{
 					MonoFieldVisibility visibility = field->getVisibility();
 					if(visibility == MonoFieldVisibility::Public)
 					{
-						if(!field->hasAttribute(nonSerializedAttribute))
+						if(!field->hasAttribute(mNonSerializedAttribute))
 							fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Serializable);
 
-						if(!field->hasAttribute(hideInInspectorAttribute))
+						if(!field->hasAttribute(mHideInInspectorAttribute))
 							fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Inspectable);
 					}
 					else
 					{
-						if(field->hasAttribute(serializeFieldAttribute))
+						if(field->hasAttribute(mSerializeFieldAttribute))
 							fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Serializable);
 					}
 				}
@@ -267,9 +128,245 @@ namespace BansheeEngine
 		}
 	}
 
+	ScriptSerializableTypeInfoPtr RuntimeScriptObjects::determineType(MonoClass* monoClass)
+	{
+		if(!mBaseTypesInitialized)
+			CM_EXCEPT(InvalidStateException, "Calling determineType without previously initializing base types.");
+
+		MonoType* monoType = mono_class_get_type(monoClass->_getInternalClass());
+		int monoPrimitiveType = mono_type_get_type(monoType);
+
+		//  Determine field type
+		switch(monoPrimitiveType)
+		{
+		case MONO_TYPE_BOOLEAN:
+			{
+				std::shared_ptr<ScriptSerializableTypeInfoPrimitive> typeInfo = cm_shared_ptr<ScriptSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::Bool;
+				return typeInfo;
+			}
+		case MONO_TYPE_CHAR:
+			{
+				std::shared_ptr<ScriptSerializableTypeInfoPrimitive> typeInfo = cm_shared_ptr<ScriptSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::Char;
+				return typeInfo;
+			}
+		case MONO_TYPE_I1:
+			{
+				std::shared_ptr<ScriptSerializableTypeInfoPrimitive> typeInfo = cm_shared_ptr<ScriptSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::I8;
+				return typeInfo;
+			}
+		case MONO_TYPE_U1:
+			{
+				std::shared_ptr<ScriptSerializableTypeInfoPrimitive> typeInfo = cm_shared_ptr<ScriptSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::U8;
+				return typeInfo;
+			}
+		case MONO_TYPE_I2:
+			{
+				std::shared_ptr<ScriptSerializableTypeInfoPrimitive> typeInfo = cm_shared_ptr<ScriptSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::I16;
+				return typeInfo;
+			}
+		case MONO_TYPE_U2:
+			{
+				std::shared_ptr<ScriptSerializableTypeInfoPrimitive> typeInfo = cm_shared_ptr<ScriptSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::U16;
+				return typeInfo;
+			}
+		case MONO_TYPE_I4:
+			{
+				std::shared_ptr<ScriptSerializableTypeInfoPrimitive> typeInfo = cm_shared_ptr<ScriptSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::I32;
+				return typeInfo;
+			}
+		case MONO_TYPE_U4:
+			{
+				std::shared_ptr<ScriptSerializableTypeInfoPrimitive> typeInfo = cm_shared_ptr<ScriptSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::U32;
+				return typeInfo;
+			}
+		case MONO_TYPE_I8:
+			{
+				std::shared_ptr<ScriptSerializableTypeInfoPrimitive> typeInfo = cm_shared_ptr<ScriptSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::I64;
+				return typeInfo;
+			}
+		case MONO_TYPE_U8:
+			{
+				std::shared_ptr<ScriptSerializableTypeInfoPrimitive> typeInfo = cm_shared_ptr<ScriptSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::U64;
+				return typeInfo;
+			}
+		case MONO_TYPE_STRING:
+			{
+				std::shared_ptr<ScriptSerializableTypeInfoPrimitive> typeInfo = cm_shared_ptr<ScriptSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::String;
+				return typeInfo;
+			}
+		case MONO_TYPE_R4:
+			{
+				std::shared_ptr<ScriptSerializableTypeInfoPrimitive> typeInfo = cm_shared_ptr<ScriptSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::Float;
+				return typeInfo;
+			}
+		case MONO_TYPE_R8:
+			{
+				std::shared_ptr<ScriptSerializableTypeInfoPrimitive> typeInfo = cm_shared_ptr<ScriptSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::Double;
+				return typeInfo;
+			}
+		case MONO_TYPE_CLASS:
+			if(monoClass->isSubClassOf(mTextureClass))
+			{
+				std::shared_ptr<ScriptSerializableTypeInfoPrimitive> typeInfo = cm_shared_ptr<ScriptSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::TextureRef;
+				return typeInfo;
+			}
+			else if(monoClass->isSubClassOf(mSpriteTextureClass))
+			{
+				std::shared_ptr<ScriptSerializableTypeInfoPrimitive> typeInfo = cm_shared_ptr<ScriptSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::SpriteTextureRef;
+				return typeInfo;
+			}
+			else if(monoClass->isSubClassOf(mSceneObjectClass))
+			{
+				std::shared_ptr<ScriptSerializableTypeInfoPrimitive> typeInfo = cm_shared_ptr<ScriptSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::SceneObjectRef;
+				return typeInfo;
+			}
+			else if(monoClass->isSubClassOf(mComponentClass))
+			{
+				std::shared_ptr<ScriptSerializableTypeInfoPrimitive> typeInfo = cm_shared_ptr<ScriptSerializableTypeInfoPrimitive>();
+				typeInfo->mType = ScriptPrimitiveType::ComponentRef;
+				return typeInfo;
+			}
+			else
+			{
+				if(hasSerializableObjectInfo(monoClass->getNamespace(), monoClass->getTypeName()))
+				{
+					std::shared_ptr<ScriptSerializableTypeInfoObject> typeInfo = cm_shared_ptr<ScriptSerializableTypeInfoObject>();
+					typeInfo->mTypeNamespace = monoClass->getNamespace();
+					typeInfo->mTypeName = monoClass->getTypeName();
+
+					return typeInfo;
+				}
+				else
+				{
+					// TODO - Later check for List or Dictionary here
+				}
+			}
+
+			break;
+		case MONO_TYPE_VALUETYPE:
+			if(hasSerializableObjectInfo(monoClass->getNamespace(), monoClass->getTypeName()))
+			{
+				std::shared_ptr<ScriptSerializableTypeInfoObject> typeInfo = cm_shared_ptr<ScriptSerializableTypeInfoObject>();
+				typeInfo->mTypeNamespace = monoClass->getNamespace();
+				typeInfo->mTypeName = monoClass->getTypeName();
+
+				return typeInfo;
+			}
+
+			break;
+		case MONO_TYPE_ARRAY:
+			{
+				std::shared_ptr<ScriptSerializableTypeInfoArray> typeInfo = cm_shared_ptr<ScriptSerializableTypeInfoArray>();
+
+				::MonoClass* elementClass = mono_class_get_element_class(monoClass->_getInternalClass());
+				if(elementClass != nullptr)
+				{
+					monoType = mono_class_get_type(elementClass);
+					monoPrimitiveType = mono_type_get_type(monoType);
+
+					::MonoClass* elementClass = mono_type_get_class(monoType);
+					String elementNs = mono_class_get_namespace(elementClass);
+					String elementTypeName = mono_class_get_name(elementClass);
+
+					MonoClass* monoElementClass = MonoManager::instance().findClass(elementNs, elementTypeName);
+					if(monoElementClass != nullptr)
+						typeInfo->mElementType = determineType(monoElementClass);
+				}
+
+				typeInfo->mRank = (UINT32)mono_class_get_rank(monoClass->_getInternalClass());
+
+				return typeInfo;
+			}
+		}
+
+		return nullptr;
+	}
+
 	void RuntimeScriptObjects::clearScriptObjects(const CM::String& assemblyName)
 	{
 		mAssemblyInfos.erase(assemblyName);
+
+		mBaseTypesInitialized = false;
+
+		mSystemArrayClass = nullptr;
+
+		mSerializableAttribute = nullptr;
+		mNonSerializedAttribute = nullptr;
+
+		mComponentClass = nullptr;
+		mSceneObjectClass = nullptr;
+
+		mTextureClass = nullptr;
+		mSpriteTextureClass = nullptr;
+
+		mSerializeFieldAttribute = nullptr;
+		mHideInInspectorAttribute = nullptr;
+	}
+
+	void RuntimeScriptObjects::initializeBaseTypes()
+	{
+		// Get necessary classes for detecting needed class & field information
+		MonoAssembly* mscorlib = MonoManager::instance().getAssembly("mscorlib");
+		if(mscorlib == nullptr)
+			CM_EXCEPT(InvalidStateException, "mscorlib assembly is not loaded.");
+
+		MonoAssembly* bansheeEngineAssembly = MonoManager::instance().getAssembly(BansheeEngineAssemblyName);
+		if(bansheeEngineAssembly == nullptr)
+			CM_EXCEPT(InvalidStateException, String(BansheeEngineAssemblyName) +  " assembly is not loaded.");
+
+		mSystemArrayClass = mscorlib->getClass("System", "Array");
+		if(mSystemArrayClass == nullptr)
+			CM_EXCEPT(InvalidStateException, "Cannot find System.Array managed class.");
+
+		mSerializableAttribute = mscorlib->getClass("System", "SerializableAttribute");
+		if(mSerializableAttribute == nullptr)
+			CM_EXCEPT(InvalidStateException, "Cannot find SerializableAttribute managed class.");
+
+		mNonSerializedAttribute = mscorlib->getClass("System", "NonSerializedAttribute");
+		if(mNonSerializedAttribute == nullptr)
+			CM_EXCEPT(InvalidStateException, "Cannot find NonSerializedAttribute managed class.");
+
+		mComponentClass = bansheeEngineAssembly->getClass("BansheeEngine", "Component");
+		if(mComponentClass == nullptr)
+			CM_EXCEPT(InvalidStateException, "Cannot find Component managed class.");
+
+		mSceneObjectClass = bansheeEngineAssembly->getClass("BansheeEngine", "SceneObject");
+		if(mSceneObjectClass == nullptr)
+			CM_EXCEPT(InvalidStateException, "Cannot find SceneObject managed class.");
+
+		mTextureClass = bansheeEngineAssembly->getClass("BansheeEngine", "Texture2D");
+		if(mTextureClass == nullptr)
+			CM_EXCEPT(InvalidStateException, "Cannot find Texture2D managed class.");
+
+		mSpriteTextureClass = bansheeEngineAssembly->getClass("BansheeEngine", "SpriteTexture");
+		if(mSpriteTextureClass == nullptr)
+			CM_EXCEPT(InvalidStateException, "Cannot find SpriteTexture managed class.");
+
+		mSerializeFieldAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "SerializeField");
+		if(mSerializeFieldAttribute == nullptr)
+			CM_EXCEPT(InvalidStateException, "Cannot find SerializeField managed class.");
+
+		mHideInInspectorAttribute = bansheeEngineAssembly->getClass("BansheeEngine", "HideInInspector");
+		if(mHideInInspectorAttribute == nullptr)
+			CM_EXCEPT(InvalidStateException, "Cannot find HideInInspector managed class.");
+
+		mBaseTypesInitialized = true;
 	}
 
 	bool RuntimeScriptObjects::getSerializableObjectInfo(const CM::String& ns, const CM::String& typeName, std::shared_ptr<ScriptSerializableObjectInfo>& outInfo)
@@ -301,4 +398,13 @@ namespace BansheeEngine
 
 		return false;
 	}
+
+	bool RuntimeScriptObjects::isArray(MonoObject* object)
+	{
+		if(!mBaseTypesInitialized)
+			CM_EXCEPT(InvalidStateException, "Calling isArray without previously initializing base types.");
+
+		::MonoClass* monoClass = mono_object_get_class(object);
+		return mono_class_is_subclass_of(monoClass, mSystemArrayClass->_getInternalClass(), false) != 0;
+	}
 }

+ 91 - 0
SBansheeEngine/Source/BsScriptSerializableArray.cpp

@@ -0,0 +1,91 @@
+#include "BsScriptSerializableArray.h"
+#include "BsScriptSerializableArrayRTTI.h"
+#include "BsMonoManager.h"
+#include "BsRuntimeScriptObjects.h"
+#include "BsScriptSerializableField.h"
+
+using namespace CamelotFramework;
+
+namespace BansheeEngine
+{
+	ScriptSerializableArray::ScriptSerializableArray(const ConstructPrivately& dummy)
+		:mManagedInstance(nullptr), mNumElements(0), mClass(nullptr)
+	{
+
+	}
+
+	ScriptSerializableArray::ScriptSerializableArray(const ConstructPrivately& dummy, const ScriptSerializableTypeInfoArrayPtr& typeInfo, MonoObject* managedInstance)
+		:mArrayTypeInfo(typeInfo), mManagedInstance(managedInstance), mNumElements(0)
+	{
+		mClass = mono_object_get_class(mManagedInstance);
+		mNumElements = (UINT32)mono_array_length((MonoArray*)mManagedInstance);
+
+		mArrayEntries.resize(mNumElements);
+		for(UINT32 i = 0; i < mNumElements; i++)
+		{
+			mArrayEntries[i] = getFieldData(i);
+		}
+	}
+
+	ScriptSerializableArrayPtr ScriptSerializableArray::create(MonoObject* managedInstance, const ScriptSerializableTypeInfoArrayPtr& typeInfo)
+	{
+		if(!RuntimeScriptObjects::instance().isArray(managedInstance))
+			return nullptr;
+
+		return cm_shared_ptr<ScriptSerializableArray>(ConstructPrivately(), typeInfo, managedInstance);
+	}
+
+	ScriptSerializableArrayPtr ScriptSerializableArray::createEmpty()
+	{
+		return cm_shared_ptr<ScriptSerializableArray>(ConstructPrivately());
+	}
+
+	void ScriptSerializableArray::setFieldData(CM::UINT32 arrayIdx, const ScriptSerializableFieldDataPtr& val)
+	{
+		setValue(arrayIdx, val->getValue(mArrayTypeInfo->mElementType));
+	}
+
+	ScriptSerializableFieldDataPtr ScriptSerializableArray::getFieldData(CM::UINT32 arrayIdx)
+	{
+		return ScriptSerializableFieldData::create(mArrayTypeInfo->mElementType, getValue(arrayIdx));
+	}
+	
+	void ScriptSerializableArray::setValue(CM::UINT32 arrayIdx, void* val)
+	{
+		if(arrayIdx >= mNumElements)
+			CM_EXCEPT(InvalidParametersException, "Array index out of range: " + toString(arrayIdx) + ". Valid range is [0, " + toString(mNumElements) + ")");
+
+		MonoArray* array = (MonoArray*)mManagedInstance;
+		UINT32 elemSize = mono_array_element_size(mClass);
+	
+		UINT32 numElems = (UINT32)mono_array_length(array);
+		assert(arrayIdx < numElems);
+	
+		void* elemAddr = mono_array_addr_with_size(array, elemSize, arrayIdx);
+		memcpy(elemAddr, val, elemSize);
+	}
+	
+	void* ScriptSerializableArray::getValue(CM::UINT32 arrayIdx)
+	{
+		if(arrayIdx >= mNumElements)
+			CM_EXCEPT(InvalidParametersException, "Array index out of range: " + toString(arrayIdx) + ". Valid range is [0, " + toString(mNumElements) + ")");
+
+		MonoArray* array = (MonoArray*)mManagedInstance;
+		UINT32 elemSize = mono_array_element_size(mClass);
+	
+		UINT32 numElems = (UINT32)mono_array_length(array);
+		assert(arrayIdx < numElems);
+	
+		return mono_array_addr_with_size(array, elemSize, arrayIdx);
+	}
+
+	RTTITypeBase* ScriptSerializableArray::getRTTIStatic()
+	{
+		return ScriptSerializableArrayRTTI::instance();
+	}
+
+	RTTITypeBase* ScriptSerializableArray::getRTTI() const
+	{
+		return ScriptSerializableArray::getRTTIStatic();
+	}
+}

+ 574 - 0
SBansheeEngine/Source/BsScriptSerializableField.cpp

@@ -0,0 +1,574 @@
+#include "BsScriptSerializableField.h"
+#include "BsScriptSerializableObjectInfo.h"
+#include "BsScriptSerializableFieldRTTI.h"
+#include "BsMonoUtil.h"
+#include "BsMonoManager.h"
+#include "BsScriptResourceManager.h"
+#include "BsScriptGameObjectManager.h"
+#include "BsScriptTexture2D.h"
+#include "BsScriptSpriteTexture.h"
+#include "BsScriptSceneObject.h"
+#include "BsScriptComponent.h"
+
+using namespace CamelotFramework;
+
+namespace BansheeEngine
+{
+	ScriptSerializableFieldKeyPtr ScriptSerializableFieldKey::create(CM::UINT16 typeId, CM::UINT16 fieldId)
+	{
+		ScriptSerializableFieldKeyPtr fieldKey = cm_shared_ptr<ScriptSerializableFieldKey>();
+		fieldKey->mTypeId = typeId;
+		fieldKey->mFieldId = fieldId;
+
+		return fieldKey;
+	}
+
+	ScriptSerializableFieldDataEntryPtr ScriptSerializableFieldDataEntry::create(const ScriptSerializableFieldKeyPtr& key, const ScriptSerializableFieldDataPtr& value)
+	{
+		ScriptSerializableFieldDataEntryPtr fieldDataEntry = cm_shared_ptr<ScriptSerializableFieldDataEntry>();
+		fieldDataEntry->mKey = key;
+		fieldDataEntry->mValue = value;
+
+		return fieldDataEntry;
+	}
+
+	ScriptSerializableFieldDataPtr ScriptSerializableFieldData::create(const ScriptSerializableTypeInfoPtr& typeInfo, void* value)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ScriptSerializableTypeInfoPrimitive>(typeInfo);
+			switch (primitiveTypeInfo->mType)
+			{
+			case ScriptPrimitiveType::Bool:
+				{
+					auto fieldData = cm_shared_ptr<ScriptSerializableFieldDataBool>();
+					memcpy(&fieldData->value, value, sizeof(fieldData->value));
+					return fieldData;
+				}
+			case ScriptPrimitiveType::Char:
+				{
+					auto fieldData = cm_shared_ptr<ScriptSerializableFieldDataChar>();
+					memcpy(&fieldData->value, value, sizeof(fieldData->value));
+					return fieldData;
+				}
+			case ScriptPrimitiveType::I8:
+				{
+					auto fieldData = cm_shared_ptr<ScriptSerializableFieldDataI8>();
+					memcpy(&fieldData->value, value, sizeof(fieldData->value));
+					return fieldData;
+				}
+			case ScriptPrimitiveType::U8:
+				{
+					auto fieldData = cm_shared_ptr<ScriptSerializableFieldDataU8>();
+					memcpy(&fieldData->value, value, sizeof(fieldData->value));
+					return fieldData;
+				}
+			case ScriptPrimitiveType::I16:
+				{
+					auto fieldData = cm_shared_ptr<ScriptSerializableFieldDataI16>();
+					memcpy(&fieldData->value, value, sizeof(fieldData->value));
+					return fieldData;
+				}
+			case ScriptPrimitiveType::U16:
+				{
+					auto fieldData = cm_shared_ptr<ScriptSerializableFieldDataU16>();
+					memcpy(&fieldData->value, value, sizeof(fieldData->value));
+					return fieldData;
+				}
+			case ScriptPrimitiveType::I32:
+				{
+					auto fieldData = cm_shared_ptr<ScriptSerializableFieldDataI32>();
+					memcpy(&fieldData->value, value, sizeof(fieldData->value));
+					return fieldData;
+				}
+			case ScriptPrimitiveType::U32:
+				{
+					auto fieldData = cm_shared_ptr<ScriptSerializableFieldDataU32>();
+					memcpy(&fieldData->value, value, sizeof(fieldData->value));
+					return fieldData;
+				}
+			case ScriptPrimitiveType::I64:
+				{
+					auto fieldData = cm_shared_ptr<ScriptSerializableFieldDataI64>();
+					memcpy(&fieldData->value, value, sizeof(fieldData->value));
+					return fieldData;
+				}
+			case ScriptPrimitiveType::U64:
+				{
+					auto fieldData = cm_shared_ptr<ScriptSerializableFieldDataU64>();
+					memcpy(&fieldData->value, value, sizeof(fieldData->value));
+					return fieldData;
+				}
+			case ScriptPrimitiveType::Float:
+				{
+					auto fieldData = cm_shared_ptr<ScriptSerializableFieldDataFloat>();
+					memcpy(&fieldData->value, value, sizeof(fieldData->value));
+					return fieldData;
+				}
+			case ScriptPrimitiveType::Double:
+				{
+					auto fieldData = cm_shared_ptr<ScriptSerializableFieldDataDouble>();
+					memcpy(&fieldData->value, value, sizeof(fieldData->value));
+					return fieldData;
+				}
+			case ScriptPrimitiveType::String:
+				{
+					auto fieldData = cm_shared_ptr<ScriptSerializableFieldDataString>();
+					if(value != nullptr)
+						fieldData->value = MonoUtil::monoToWString((MonoString*)value);
+					return fieldData;
+				}
+			case ScriptPrimitiveType::TextureRef:
+				{
+					auto fieldData = cm_shared_ptr<ScriptSerializableFieldDataResourceRef>();
+
+					if(value != nullptr)
+					{
+						MonoObject* managedInstance = (MonoObject*)value;
+
+						ScriptTexture2D* scriptTexture2D = ScriptTexture2D::toNative(managedInstance);
+						fieldData->value = static_resource_cast<ScriptTexture2D>(scriptTexture2D->getNativeHandle());
+					}
+
+					return fieldData;
+				}
+			case ScriptPrimitiveType::SpriteTextureRef:
+				{
+					auto fieldData = cm_shared_ptr<ScriptSerializableFieldDataResourceRef>();
+					
+					if(value != nullptr)
+					{
+						MonoObject* managedInstance = (MonoObject*)value;
+
+						ScriptSpriteTexture* scriptSpriteTexture = ScriptSpriteTexture::toNative(managedInstance);
+						fieldData->value = static_resource_cast<SpriteTexture>(scriptSpriteTexture->getNativeHandle());
+					}
+
+					return fieldData;
+				}
+			case ScriptPrimitiveType::SceneObjectRef:
+				{
+					auto fieldData = cm_shared_ptr<ScriptSerializableFieldDataGameObjectRef>();
+
+					if(value != nullptr)
+					{
+						MonoObject* managedInstance = (MonoObject*)value;
+
+						ScriptSceneObject* scriptSceneObject = ScriptSceneObject::toNative(managedInstance);
+						fieldData->value = static_object_cast<SceneObject>(scriptSceneObject->getNativeHandle());
+					}
+
+					return fieldData;
+				}
+			case ScriptPrimitiveType::ComponentRef:
+				{
+					auto fieldData = cm_shared_ptr<ScriptSerializableFieldDataGameObjectRef>();
+
+					if(value != nullptr)
+					{
+						MonoObject* managedInstance = (MonoObject*)value;
+
+						ScriptComponent* scriptComponent = ScriptComponent::toNative(managedInstance);
+						fieldData->value = static_object_cast<Component>(scriptComponent->getNativeHandle());
+					}
+
+					return fieldData;
+				}
+			}
+		}
+
+		return nullptr;
+	}
+
+	void* ScriptSerializableFieldDataBool::getValue(const ScriptSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ScriptSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::Bool)
+				return &value;
+		}
+
+		CM_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+	}
+
+	void* ScriptSerializableFieldDataChar::getValue(const ScriptSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ScriptSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::Char)
+				return &value;
+		}
+
+		CM_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+	}
+
+	void* ScriptSerializableFieldDataI8::getValue(const ScriptSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ScriptSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::I8)
+				return &value;
+		}
+
+		CM_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+	}
+
+	void* ScriptSerializableFieldDataU8::getValue(const ScriptSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ScriptSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::U8)
+				return &value;
+		}
+
+		CM_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+	}
+
+	void* ScriptSerializableFieldDataI16::getValue(const ScriptSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ScriptSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::I16)
+				return &value;
+		}
+
+		CM_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+	}
+
+	void* ScriptSerializableFieldDataU16::getValue(const ScriptSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ScriptSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::U16)
+				return &value;
+		}
+
+		CM_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+	}
+
+	void* ScriptSerializableFieldDataI32::getValue(const ScriptSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ScriptSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::I32)
+				return &value;
+		}
+
+		CM_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+	}
+
+	void* ScriptSerializableFieldDataU32::getValue(const ScriptSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ScriptSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::U32)
+				return &value;
+		}
+
+		CM_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+	}
+
+	void* ScriptSerializableFieldDataI64::getValue(const ScriptSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ScriptSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::I64)
+				return &value;
+		}
+
+		CM_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+	}
+
+	void* ScriptSerializableFieldDataU64::getValue(const ScriptSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ScriptSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::U64)
+				return &value;
+		}
+
+		CM_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+	}
+
+	void* ScriptSerializableFieldDataFloat::getValue(const ScriptSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ScriptSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::Float)
+				return &value;
+		}
+
+		CM_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+	}
+
+	void* ScriptSerializableFieldDataDouble::getValue(const ScriptSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ScriptSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::Double)
+				return &value;
+		}
+
+		CM_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+	}
+
+	void* ScriptSerializableFieldDataString::getValue(const ScriptSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ScriptSerializableTypeInfoPrimitive>(typeInfo);
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::String)
+			{
+				return MonoUtil::wstringToMono(MonoManager::instance().getDomain(), value);
+			}
+		}
+
+		CM_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+	}
+
+	void* ScriptSerializableFieldDataResourceRef::getValue(const ScriptSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ScriptSerializableTypeInfoPrimitive>(typeInfo);
+
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::TextureRef)
+			{
+				ScriptTexture2D* scriptResource = ScriptResourceManager::instance().getScriptTexture(value);
+				if(scriptResource == nullptr)
+					scriptResource = ScriptResourceManager::instance().createScriptTexture(value);
+
+				return scriptResource->getManagedInstance();
+			}
+			else if(primitiveTypeInfo->mType == ScriptPrimitiveType::SpriteTextureRef)
+			{
+				ScriptSpriteTexture* scriptResource = ScriptResourceManager::instance().getScriptSpriteTexture(value);
+				if(scriptResource == nullptr)
+					scriptResource = ScriptResourceManager::instance().createScriptSpriteTexture(value);
+
+				return scriptResource->getManagedInstance();
+			}
+		}
+
+		CM_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+	}
+
+	void* ScriptSerializableFieldDataGameObjectRef::getValue(const ScriptSerializableTypeInfoPtr& typeInfo)
+	{
+		if(typeInfo->getTypeId() == TID_SerializableTypeInfoPrimitive)
+		{
+			auto primitiveTypeInfo = std::static_pointer_cast<ScriptSerializableTypeInfoPrimitive>(typeInfo);
+
+			if(primitiveTypeInfo->mType == ScriptPrimitiveType::SceneObjectRef)
+			{
+				ScriptSceneObject* scriptSceneObject = ScriptGameObjectManager::instance().getScriptSceneObject(value);
+				if(scriptSceneObject == nullptr)
+					scriptSceneObject = ScriptGameObjectManager::instance().createScriptSceneObject(value);
+
+				return scriptSceneObject->getManagedInstance();
+			}
+			else if(primitiveTypeInfo->mType == ScriptPrimitiveType::SpriteTextureRef)
+			{
+				ScriptComponent* scriptComponent = ScriptGameObjectManager::instance().getScriptComponent(value);
+				if(scriptComponent == nullptr)
+					scriptComponent = ScriptGameObjectManager::instance().createScriptComponent(value);
+
+				return scriptComponent->getManagedInstance();
+			}
+		}
+
+		CM_EXCEPT(InvalidParametersException, "Requesting an invalid type in serializable field.");
+	}
+
+	RTTITypeBase* ScriptSerializableFieldKey::getRTTIStatic()
+	{
+		return ScriptSerializableFieldKeyRTTI::instance();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldKey::getRTTI() const
+	{
+		return ScriptSerializableFieldKey::getRTTIStatic();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldData::getRTTIStatic()
+	{
+		return ScriptSerializableFieldDataRTTI::instance();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldData::getRTTI() const
+	{
+		return ScriptSerializableFieldData::getRTTIStatic();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataEntry::getRTTIStatic()
+	{
+		return ScriptSerializableFieldDataEntryRTTI::instance();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataEntry::getRTTI() const
+	{
+		return ScriptSerializableFieldDataEntry::getRTTIStatic();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataBool::getRTTIStatic()
+	{
+		return ScriptSerializableFieldDataBoolRTTI::instance();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataBool::getRTTI() const
+	{
+		return ScriptSerializableFieldDataBool::getRTTIStatic();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataChar::getRTTIStatic()
+	{
+		return ScriptSerializableFieldDataCharRTTI::instance();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataChar::getRTTI() const
+	{
+		return ScriptSerializableFieldDataChar::getRTTIStatic();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataI8::getRTTIStatic()
+	{
+		return ScriptSerializableFieldDataI8RTTI::instance();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataI8::getRTTI() const
+	{
+		return ScriptSerializableFieldDataI8::getRTTIStatic();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataU8::getRTTIStatic()
+	{
+		return ScriptSerializableFieldDataU8RTTI::instance();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataU8::getRTTI() const
+	{
+		return ScriptSerializableFieldDataU8::getRTTIStatic();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataI16::getRTTIStatic()
+	{
+		return ScriptSerializableFieldDataI16RTTI::instance();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataI16::getRTTI() const
+	{
+		return ScriptSerializableFieldDataI16::getRTTIStatic();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataU16::getRTTIStatic()
+	{
+		return ScriptSerializableFieldDataU16RTTI::instance();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataU16::getRTTI() const
+	{
+		return ScriptSerializableFieldDataU16::getRTTIStatic();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataI32::getRTTIStatic()
+	{
+		return ScriptSerializableFieldDataI32RTTI::instance();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataI32::getRTTI() const
+	{
+		return ScriptSerializableFieldDataI32::getRTTIStatic();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataU32::getRTTIStatic()
+	{
+		return ScriptSerializableFieldDataU32RTTI::instance();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataU32::getRTTI() const
+	{
+		return ScriptSerializableFieldDataU32::getRTTIStatic();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataI64::getRTTIStatic()
+	{
+		return ScriptSerializableFieldDataI64RTTI::instance();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataI64::getRTTI() const
+	{
+		return ScriptSerializableFieldDataI64::getRTTIStatic();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataU64::getRTTIStatic()
+	{
+		return ScriptSerializableFieldDataU64RTTI::instance();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataU64::getRTTI() const
+	{
+		return ScriptSerializableFieldDataU64::getRTTIStatic();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataFloat::getRTTIStatic()
+	{
+		return ScriptSerializableFieldDataFloatRTTI::instance();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataFloat::getRTTI() const
+	{
+		return ScriptSerializableFieldDataFloat::getRTTIStatic();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataDouble::getRTTIStatic()
+	{
+		return ScriptSerializableFieldDataDoubleRTTI::instance();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataDouble::getRTTI() const
+	{
+		return ScriptSerializableFieldDataDouble::getRTTIStatic();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataString::getRTTIStatic()
+	{
+		return ScriptSerializableFieldDataStringRTTI::instance();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataString::getRTTI() const
+	{
+		return ScriptSerializableFieldDataString::getRTTIStatic();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataResourceRef::getRTTIStatic()
+	{
+		return ScriptSerializableFieldDataResourceRefRTTI::instance();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataResourceRef::getRTTI() const
+	{
+		return ScriptSerializableFieldDataResourceRef::getRTTIStatic();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataGameObjectRef::getRTTIStatic()
+	{
+		return ScriptSerializableFieldDataGameObjectRefRTTI::instance();
+	}
+
+	RTTITypeBase* ScriptSerializableFieldDataGameObjectRef::getRTTI() const
+	{
+		return ScriptSerializableFieldDataGameObjectRef::getRTTIStatic();
+	}
+}

+ 97 - 0
SBansheeEngine/Source/BsScriptSerializableObject.cpp

@@ -0,0 +1,97 @@
+#include "BsScriptSerializableObject.h"
+#include "BsScriptSerializableObjectRTTI.h"
+#include "BsScriptSerializableObjectInfo.h"
+#include "BsScriptSerializableField.h"
+#include "BsRuntimeScriptObjects.h"
+#include "BsMonoField.h"
+
+using namespace CamelotFramework;
+
+namespace BansheeEngine
+{
+	ScriptSerializableObject::ScriptSerializableObject(const ConstructPrivately& dummy)
+		:mManagedInstance(nullptr)
+	{
+
+	}
+
+	ScriptSerializableObject::ScriptSerializableObject(const ConstructPrivately& dummy, ScriptSerializableObjectInfoPtr objInfo, MonoObject* managedInstance)
+		:mObjInfo(objInfo), mManagedInstance(managedInstance)
+	{
+		ScriptSerializableObjectInfoPtr curType = mObjInfo;
+
+		UINT32 numFields = 0;
+		while(curType != nullptr)
+		{
+			numFields += (UINT32)mObjInfo->mFields.size();
+			curType = curType->mBaseClass.lock();
+		}
+
+		mFieldEntries.resize(numFields);
+		curType = mObjInfo;
+		UINT32 curIdx = 0;
+		while(curType != nullptr)
+		{
+			numFields += (UINT32)mObjInfo->mFields.size();
+
+			for(auto& field : mObjInfo->mFields)
+			{
+				ScriptSerializableFieldKeyPtr fieldKey = ScriptSerializableFieldKey::create(curType->mTypeId, field.second->mFieldId);
+				ScriptSerializableFieldDataPtr fieldData = getFieldData(field.second);
+
+				mFieldEntries[curIdx] = ScriptSerializableFieldDataEntry::create(fieldKey, fieldData);
+				curIdx++;
+			}
+
+			curType = curType->mBaseClass.lock();
+		}
+	}
+
+	ScriptSerializableObjectPtr ScriptSerializableObject::create(MonoObject* managedInstance)
+	{
+		::MonoClass* monoClass = mono_object_get_class(managedInstance);
+		String elementNs = mono_class_get_namespace(monoClass);
+		String elementTypeName = mono_class_get_name(monoClass);
+
+		ScriptSerializableObjectInfoPtr objInfo;
+		if(!RuntimeScriptObjects::instance().getSerializableObjectInfo(elementNs, elementTypeName, objInfo))
+			return nullptr;
+
+		return cm_shared_ptr<ScriptSerializableObject>(ConstructPrivately(), objInfo, managedInstance);
+	}
+
+	ScriptSerializableObjectPtr ScriptSerializableObject::createEmpty()
+	{
+		return cm_shared_ptr<ScriptSerializableObject>(ConstructPrivately());
+	}
+
+	void ScriptSerializableObject::setFieldData(const ScriptSerializableFieldInfoPtr& fieldInfo, const ScriptSerializableFieldDataPtr& val)
+	{
+		setValue(fieldInfo, val->getValue(fieldInfo->mTypeInfo));
+	}
+
+	ScriptSerializableFieldDataPtr ScriptSerializableObject::getFieldData(const ScriptSerializableFieldInfoPtr& fieldInfo)
+	{
+		return ScriptSerializableFieldData::create(fieldInfo->mTypeInfo, getValue(fieldInfo));
+	}
+
+	void ScriptSerializableObject::setValue(const ScriptSerializableFieldInfoPtr& fieldInfo, void* val)
+	{
+		fieldInfo->mMonoField->setValue(mManagedInstance, val);
+	}
+
+	void* ScriptSerializableObject::getValue(const ScriptSerializableFieldInfoPtr& fieldInfo)
+	{
+		return fieldInfo->mMonoField->getValue(mManagedInstance);
+	}
+
+	RTTITypeBase* ScriptSerializableObject::getRTTIStatic()
+	{
+		return ScriptSerializableObjectRTTI::instance();
+	}
+
+	RTTITypeBase* ScriptSerializableObject::getRTTI() const
+	{
+		return ScriptSerializableObject::getRTTIStatic();
+	}
+}

+ 17 - 436
SBansheeEngine/Source/BsScriptSerializableObjectInfo.cpp

@@ -42,353 +42,11 @@ namespace BansheeEngine
 	}
 
 	ScriptSerializableFieldInfo::ScriptSerializableFieldInfo()
-		:mMonoField(nullptr), mType(ScriptFieldType::Other), mFlags((ScriptFieldFlags)0), mFieldId(0), mArrayDimensions(0)
+		:mMonoField(nullptr), mFlags((ScriptFieldFlags)0), mFieldId(0)
 	{
 
 	}
 
-	bool ScriptSerializableFieldInfo::isNull(MonoObject* obj)
-	{
-		assert(isReferenceType());
-
-		void* val = mMonoField->getValue(obj);
-
-		return val == nullptr;
-	}
-
-	void ScriptSerializableFieldInfo::setNull(MonoObject* obj)
-	{
-		assert(isReferenceType());
-
-		mMonoField->setValue(obj, nullptr);
-	}
-
-	void ScriptSerializableFieldInfo::setU8(MonoObject* obj, UINT8 val, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::U8);
-
-		setValue(obj, &val, arrayIdx);
-	}
-
-	UINT8 ScriptSerializableFieldInfo::getU8(MonoObject* obj, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::U8);
-
-		return *(UINT8*)getValue(obj, arrayIdx);
-	}
-
-	void ScriptSerializableFieldInfo::setI8(MonoObject* obj, INT8 val, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::I8);
-
-		setValue(obj, &val, arrayIdx);
-	}
-
-	INT8 ScriptSerializableFieldInfo::getI8(MonoObject* obj, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::I8);
-
-		return *(INT8*)getValue(obj, arrayIdx);
-	}
-
-	void ScriptSerializableFieldInfo::setU16(MonoObject* obj, UINT16 val, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::U16);
-
-		setValue(obj, &val, arrayIdx);
-	}
-
-	UINT16 ScriptSerializableFieldInfo::getU16(MonoObject* obj, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::U16);
-
-		return *(UINT16*)getValue(obj, arrayIdx);
-	}
-
-	void ScriptSerializableFieldInfo::setI16(MonoObject* obj, INT16 val, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::I16);
-
-		setValue(obj, &val, arrayIdx);
-	}
-
-	INT16 ScriptSerializableFieldInfo::getI16(MonoObject* obj, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::I16);
-
-		return *(INT16*)getValue(obj, arrayIdx);
-	}
-
-	void ScriptSerializableFieldInfo::setU32(MonoObject* obj, UINT32 val, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::U32);
-
-		setValue(obj, &val, arrayIdx);
-	}
-
-	UINT32 ScriptSerializableFieldInfo::getU32(MonoObject* obj, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::U32);
-
-		return *(UINT32*)getValue(obj, arrayIdx);
-	}
-
-	void ScriptSerializableFieldInfo::setI32(MonoObject* obj, INT32 val, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::I32);
-
-		setValue(obj, &val, arrayIdx);
-	}
-
-	INT32 ScriptSerializableFieldInfo::getI32(MonoObject* obj, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::I32);
-
-		return *(INT32*)getValue(obj, arrayIdx);
-	}
-
-	void ScriptSerializableFieldInfo::setU64(MonoObject* obj, UINT64 val, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::U64);
-
-		setValue(obj, &val, arrayIdx);
-	}
-
-	UINT64 ScriptSerializableFieldInfo::getU64(MonoObject* obj, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::U64);
-
-		return *(UINT64*)getValue(obj, arrayIdx);
-	}
-
-	void ScriptSerializableFieldInfo::setI64(MonoObject* obj, INT64 val, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::I64);
-
-		setValue(obj, &val, arrayIdx);
-	}
-
-	INT64 ScriptSerializableFieldInfo::getI64(MonoObject* obj, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::I64);
-
-		return *(INT64*)getValue(obj, arrayIdx);
-	}
-
-	void ScriptSerializableFieldInfo::setBool(MonoObject* obj, bool val, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::Bool);
-
-		setValue(obj, &val, arrayIdx);
-	}
-
-	bool ScriptSerializableFieldInfo::getBool(MonoObject* obj, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::Bool);
-
-		return *(bool*)getValue(obj, arrayIdx);
-	}
-
-	void ScriptSerializableFieldInfo::setChar(MonoObject* obj, wchar_t val, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::Char);
-
-		setValue(obj, &val, arrayIdx);
-	}
-
-	wchar_t ScriptSerializableFieldInfo::getChar(MonoObject* obj, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::Char);
-
-		return *(wchar_t*)getValue(obj, arrayIdx);
-	}
-
-	void ScriptSerializableFieldInfo::setFloat(MonoObject* obj, float val, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::Float);
-
-		setValue(obj, &val, arrayIdx);
-	}
-
-	float ScriptSerializableFieldInfo::getFloat(MonoObject* obj, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::Float);
-
-		return *(float*)getValue(obj, arrayIdx);
-	}
-
-	void ScriptSerializableFieldInfo::setDouble(MonoObject* obj, double val, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::Double);
-
-		setValue(obj, &val, arrayIdx);
-	}
-
-	double ScriptSerializableFieldInfo::getDouble(MonoObject* obj, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::Double);
-
-		return *(double*)getValue(obj, arrayIdx);
-	}
-
-	void ScriptSerializableFieldInfo::setString(MonoObject* obj, const WString& val, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::String);
-
-		MonoString* str = MonoUtil::wstringToMono(MonoManager::instance().getDomain(), val);
-		setValue(obj, str, arrayIdx);
-	}
-
-	WString ScriptSerializableFieldInfo::getString(MonoObject* obj, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::String);
-
-		MonoString* str = (MonoString*)getValue(obj, arrayIdx);
-		if(str == nullptr)
-			return L"";
-
-		return MonoUtil::monoToWString(str);
-	}
-
-	void ScriptSerializableFieldInfo::setTexture(MonoObject* obj, const HTexture& resource, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::TextureRef);
-
-		if(resource == nullptr)
-		{
-			setValue(obj, nullptr, arrayIdx);
-		}
-		else
-		{
-			ScriptTexture2D* scriptResource = ScriptResourceManager::instance().getScriptTexture(resource);
-			if(scriptResource == nullptr)
-				scriptResource = ScriptResourceManager::instance().createScriptTexture(resource);
-
-			MonoObject* managedInstance = scriptResource->getManagedInstance();
-			setValue(obj, (void*)managedInstance, arrayIdx);
-		}
-	}
-
-	CM::HTexture ScriptSerializableFieldInfo::getTexture(MonoObject* obj, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::TextureRef);
-
-		MonoObject* managedInstance = (MonoObject*)getValue(obj, arrayIdx);
-		if(managedInstance == nullptr)
-			return HTexture();
-
-		ScriptTexture2D* scriptResource = ScriptTexture2D::toNative(managedInstance);
-		return static_resource_cast<Texture>(scriptResource->getNativeHandle());
-	}
-
-	void ScriptSerializableFieldInfo::setSpriteTexture(MonoObject* obj, const HSpriteTexture& resource, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::SpriteTextureRef);
-
-		if(resource == nullptr)
-		{
-			setValue(obj, nullptr, arrayIdx);
-		}
-		else
-		{
-			ScriptSpriteTexture* scriptResource = ScriptResourceManager::instance().getScriptSpriteTexture(resource);
-			if(scriptResource == nullptr)
-				scriptResource = ScriptResourceManager::instance().createScriptSpriteTexture(resource);
-
-			MonoObject* managedInstance = scriptResource->getManagedInstance();
-			setValue(obj, (void*)managedInstance, arrayIdx);
-		}
-	}
-
-	HSpriteTexture ScriptSerializableFieldInfo::getSpriteTexture(MonoObject* obj, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::SpriteTextureRef);
-
-		MonoObject* managedInstance = (MonoObject*)getValue(obj, arrayIdx);
-		if(managedInstance == nullptr)
-			return HTexture();
-
-		ScriptSpriteTexture* scriptResource = ScriptSpriteTexture::toNative(managedInstance);
-		return static_resource_cast<SpriteTexture>(scriptResource->getNativeHandle());
-	}
-
-	void ScriptSerializableFieldInfo::setSceneObject(MonoObject* obj, const HSceneObject& sceneObject, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::SceneObjectRef);
-
-		if(sceneObject == nullptr)
-		{
-			setValue(obj, nullptr, arrayIdx);
-		}
-		else
-		{
-			ScriptSceneObject* scriptSceneObject = ScriptGameObjectManager::instance().getScriptSceneObject(sceneObject);
-			if(scriptSceneObject == nullptr)
-				scriptSceneObject = ScriptGameObjectManager::instance().createScriptSceneObject(sceneObject);
-
-			MonoObject* managedInstance = scriptSceneObject->getManagedInstance();
-			setValue(obj, (void*)managedInstance, arrayIdx);
-		}
-	}
-
-	HSceneObject ScriptSerializableFieldInfo::getSceneObject(MonoObject* obj, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::SceneObjectRef);
-
-		MonoObject* managedInstance = (MonoObject*)getValue(obj, arrayIdx);
-		if(managedInstance == nullptr)
-			return HSceneObject();
-
-		ScriptSceneObject* scriptSceneObject = ScriptSceneObject::toNative(managedInstance);
-		return static_object_cast<SceneObject>(scriptSceneObject->getNativeHandle());
-	}
-
-	void ScriptSerializableFieldInfo::setComponent(MonoObject* obj, const HComponent& component, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::ComponentRef);
-
-		if(component == nullptr)
-		{
-			setValue(obj, nullptr, arrayIdx);
-		}
-		else
-		{
-			ScriptComponent* scriptComponent = ScriptGameObjectManager::instance().getScriptComponent(component);
-			if(scriptComponent == nullptr)
-				scriptComponent = ScriptGameObjectManager::instance().createScriptComponent(component);
-
-			MonoObject* managedInstance = scriptComponent->getManagedInstance();
-			setValue(obj, (void*)managedInstance, arrayIdx);
-		}
-	}
-
-	HComponent ScriptSerializableFieldInfo::getComponent(MonoObject* obj, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::ComponentRef);
-
-		MonoObject* managedInstance = (MonoObject*)getValue(obj, arrayIdx);
-		if(managedInstance == nullptr)
-			return HComponent();
-
-		ScriptComponent* scriptComponent = ScriptComponent::toNative(managedInstance);
-		return static_object_cast<Component>(scriptComponent->getNativeHandle());
-	}
-
-
-	void ScriptSerializableFieldInfo::setSerializableObject(MonoObject* obj, const MonoObject* value, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::SerializableObjectRef || mType == ScriptFieldType::SerializableObjectValue);
-
-		setValue(obj, (void*)value, arrayIdx);
-	}
-
-	MonoObject* ScriptSerializableFieldInfo::getSerializableObject(MonoObject* obj, UINT32 arrayIdx)
-	{
-		assert(mType == ScriptFieldType::SerializableObjectRef || mType == ScriptFieldType::SerializableObjectValue);
-
-		return (MonoObject*)getValue(obj, arrayIdx);
-	}
-
 	RTTITypeBase* ScriptSerializableFieldInfo::getRTTIStatic()
 	{
 		return ScriptSerializableFieldInfoRTTI::instance();
@@ -399,120 +57,43 @@ namespace BansheeEngine
 		return ScriptSerializableFieldInfo::getRTTIStatic();
 	}
 
-	bool ScriptSerializableFieldInfoPlain::isReferenceType() const
-	{
-		return (mType == ScriptFieldType::TextureRef || mType == ScriptFieldType::SpriteTextureRef || 
-			mType == ScriptFieldType::SceneObjectRef || mType == ScriptFieldType::ComponentRef || mType == ScriptFieldType::SerializableObjectRef);
-	}
-
-	CM::UINT32 ScriptSerializableFieldInfoPlain::getNumArrayElements(MonoObject* obj, CM::UINT32 dimension)
+	RTTITypeBase* ScriptSerializableTypeInfo::getRTTIStatic()
 	{
-		assert(false);
-
-		return 0;
-	}
-
-	void ScriptSerializableFieldInfoPlain::setNumArrayElements(MonoObject* obj, CM::UINT32 numElements, CM::UINT32 dimension, bool discardExisting)
-	{
-		assert(false);
+		return ScriptSerializableTypeInfoRTTI::instance();
 	}
 
-	void ScriptSerializableFieldInfoPlain::setValue(MonoObject* obj, void* val, CM::UINT32 arrayIdx)
+	RTTITypeBase* ScriptSerializableTypeInfo::getRTTI() const
 	{
-		assert(arrayIdx == 0);
-
-		mMonoField->setValue(obj, val);
+		return ScriptSerializableTypeInfo::getRTTIStatic();
 	}
 
-	void* ScriptSerializableFieldInfoPlain::getValue(MonoObject* obj, CM::UINT32 arrayIdx)
+	RTTITypeBase* ScriptSerializableTypeInfoPrimitive::getRTTIStatic()
 	{
-		assert(arrayIdx == 0);
-
-		return mMonoField->getValue(obj);
+		return ScriptSerializableTypeInfoPrimitiveRTTI::instance();
 	}
 
-	RTTITypeBase* ScriptSerializableFieldInfoPlain::getRTTIStatic()
+	RTTITypeBase* ScriptSerializableTypeInfoPrimitive::getRTTI() const
 	{
-		return ScriptSerializableFieldInfoPlainRTTI::instance();
+		return ScriptSerializableTypeInfoPrimitive::getRTTIStatic();
 	}
 
-	RTTITypeBase* ScriptSerializableFieldInfoPlain::getRTTI() const
+	RTTITypeBase* ScriptSerializableTypeInfoObject::getRTTIStatic()
 	{
-		return ScriptSerializableFieldInfoPlain::getRTTIStatic();
+		return ScriptSerializableTypeInfoObjectRTTI::instance();
 	}
 
-	ScriptSerializableFieldInfoArray::ScriptSerializableFieldInfoArray()
-		:mArrayDimensions(0)
+	RTTITypeBase* ScriptSerializableTypeInfoObject::getRTTI() const
 	{
-
-	}
-
-	CM::UINT32 ScriptSerializableFieldInfoArray::getNumArrayElements(MonoObject* obj, CM::UINT32 dimension)
-	{
-		if(dimension >= mArrayDimensions)
-			CM_EXCEPT(InvalidParametersException, "Invalid array dimension: " + toString(dimension) + ". Valid range is: [0, + " + toString(mArrayDimensions - 1) + "]");
-
-		MonoArray* array = reinterpret_cast<MonoArray*>(mMonoField->getValue(obj));
-		return (UINT32)mono_array_length(array);
-	}
-
-	void ScriptSerializableFieldInfoArray::setNumArrayElements(MonoObject* obj, CM::UINT32 numElements, CM::UINT32 dimension, bool discardExisting)
-	{
-		uint32_t lengths[1] = { numElements };
-
-		MonoArray* newArray = mono_array_new_full(MonoManager::instance().getDomain(), 
-			mMonoField->getType()->_getInternalClass(), (uintptr_t*)lengths, nullptr);
-
-		if(!discardExisting)
-		{
-			MonoArray* existingArray = reinterpret_cast<MonoArray*>(mMonoField->getValue(obj));
-			UINT32 existingArrayLength = (UINT32)mono_array_length(existingArray);
-
-			UINT32 elemsToCopy = std::min(existingArrayLength, numElements);
-			int32_t elemSize = mono_array_element_size(mMonoField->getType()->_getInternalClass());
-
-			for(UINT32 i = 0; i < elemsToCopy; i++)
-			{
-				void* existingValAddr = (void*)mono_array_addr_with_size(existingArray, elemSize, (uintptr_t)i);
-				void* newValAddr = (void*)mono_array_addr_with_size(newArray, elemSize, (uintptr_t)i);
-
-				memcpy(newValAddr, existingValAddr, elemSize);
-			}
-		}
-
-		mMonoField->setValue(obj, newArray);
-	}
-
-	void ScriptSerializableFieldInfoArray::setValue( MonoObject* obj, void* val, CM::UINT32 arrayIdx)
-	{
-		MonoArray* array = (MonoArray*)mMonoField->getValue(obj);
-		UINT32 elemSize = mono_array_element_size(mMonoField->getType()->_getInternalClass());
-
-		UINT32 numElems = (UINT32)mono_array_length(array);
-		assert(arrayIdx < numElems);
-
-		void* elemAddr = mono_array_addr_with_size(array, elemSize, arrayIdx);
-		memcpy(elemAddr, val, elemSize);
-	}
-
-	void* ScriptSerializableFieldInfoArray::getValue( MonoObject* obj, CM::UINT32 arrayIdx)
-	{
-		MonoArray* array = (MonoArray*)mMonoField->getValue(obj);
-		UINT32 elemSize = mono_array_element_size(mMonoField->getType()->_getInternalClass());
-
-		UINT32 numElems = (UINT32)mono_array_length(array);
-		assert(arrayIdx < numElems);
-
-		return mono_array_addr_with_size(array, elemSize, arrayIdx);
+		return ScriptSerializableTypeInfoObject::getRTTIStatic();
 	}
 
-	RTTITypeBase* ScriptSerializableFieldInfoArray::getRTTIStatic()
+	RTTITypeBase* ScriptSerializableTypeInfoArray::getRTTIStatic()
 	{
-		return ScriptSerializableFieldInfoArrayRTTI::instance();
+		return ScriptSerializableTypeInfoArrayRTTI::instance();
 	}
 
-	RTTITypeBase* ScriptSerializableFieldInfoArray::getRTTI() const
+	RTTITypeBase* ScriptSerializableTypeInfoArray::getRTTI() const
 	{
-		return ScriptSerializableFieldInfoArray::getRTTIStatic();
+		return ScriptSerializableTypeInfoArray::getRTTIStatic();
 	}
 }