Browse Source

WIP - C# object serialization (Does not compile)

Marko Pintera 11 years ago
parent
commit
3956823710
49 changed files with 586 additions and 105 deletions
  1. 13 2
      BansheeMono/Include/BsMonoClass.h
  2. 17 0
      BansheeMono/Include/BsMonoField.h
  3. 1 1
      BansheeMono/Source/BsMonoAssembly.cpp
  4. 44 8
      BansheeMono/Source/BsMonoClass.cpp
  5. 52 1
      BansheeMono/Source/BsMonoField.cpp
  6. 10 5
      BansheeMono/Source/BsMonoManager.cpp
  7. 6 1
      GameObjectSerialization.txt
  8. 2 0
      MBansheeEngine/Component.cs
  9. 12 0
      MBansheeEngine/DbgComponent.cs
  10. 9 0
      MBansheeEngine/HideInInspector.cs
  11. 3 0
      MBansheeEngine/MBansheeEngine.csproj
  12. 9 0
      MBansheeEngine/SerializeField.cs
  13. 2 0
      SBansheeEditor/Include/BsScriptEditorPrerequisites.h
  14. 1 1
      SBansheeEditor/Source/BsScriptEditorGUI.cpp
  15. 1 1
      SBansheeEditor/Source/BsScriptEditorPlugin.cpp
  16. 4 4
      SBansheeEditor/Source/BsScriptEditorWindow.cpp
  17. 74 14
      SBansheeEngine/Include/BsRuntimeScriptObjects.h
  18. 7 3
      SBansheeEngine/Include/BsScriptComponent.h
  19. 2 0
      SBansheeEngine/Include/BsScriptEnginePrerequisites.h
  20. 13 0
      SBansheeEngine/Include/BsScriptGameObject.h
  21. 13 0
      SBansheeEngine/Include/BsScriptResource.h
  22. 5 1
      SBansheeEngine/Include/BsScriptSpriteTexture.h
  23. 4 1
      SBansheeEngine/Include/BsScriptTexture2D.h
  24. 2 0
      SBansheeEngine/SBansheeEngine.vcxproj
  25. 6 0
      SBansheeEngine/SBansheeEngine.vcxproj.filters
  26. 225 34
      SBansheeEngine/Source/BsRuntimeScriptObjects.cpp
  27. 8 3
      SBansheeEngine/Source/BsScriptComponent.cpp
  28. 7 1
      SBansheeEngine/Source/BsScriptEnginePlugin.cpp
  29. 1 1
      SBansheeEngine/Source/BsScriptFont.cpp
  30. 1 1
      SBansheeEngine/Source/BsScriptGUIArea.cpp
  31. 1 1
      SBansheeEngine/Source/BsScriptGUIBase.cpp
  32. 1 1
      SBansheeEngine/Source/BsScriptGUIButton.cpp
  33. 4 4
      SBansheeEngine/Source/BsScriptGUIContent.cpp
  34. 1 1
      SBansheeEngine/Source/BsScriptGUIElementStateStyle.cpp
  35. 1 1
      SBansheeEngine/Source/BsScriptGUIElementStyle.cpp
  36. 1 1
      SBansheeEngine/Source/BsScriptGUIFixedSpace.cpp
  37. 1 1
      SBansheeEngine/Source/BsScriptGUIFlexibleSpace.cpp
  38. 1 1
      SBansheeEngine/Source/BsScriptGUIInputBox.cpp
  39. 1 1
      SBansheeEngine/Source/BsScriptGUILabel.cpp
  40. 1 1
      SBansheeEngine/Source/BsScriptGUILayout.cpp
  41. 1 1
      SBansheeEngine/Source/BsScriptGUIListBox.cpp
  42. 1 1
      SBansheeEngine/Source/BsScriptGUIScrollArea.cpp
  43. 1 1
      SBansheeEngine/Source/BsScriptGUITexture.cpp
  44. 1 1
      SBansheeEngine/Source/BsScriptGUIToggle.cpp
  45. 1 1
      SBansheeEngine/Source/BsScriptGUIToggleGroup.cpp
  46. 1 1
      SBansheeEngine/Source/BsScriptHString.cpp
  47. 6 1
      SBansheeEngine/Source/BsScriptSpriteTexture.cpp
  48. 1 1
      SBansheeEngine/Source/BsScriptStringTable.cpp
  49. 6 1
      SBansheeEngine/Source/BsScriptTexture2D.cpp

+ 13 - 2
BansheeMono/Include/BsMonoClass.h

@@ -33,9 +33,17 @@ namespace BansheeEngine
 		const CM::String& getFullName() const { return mFullName; }
 
 		MonoMethod& getMethod(const CM::String& name, CM::UINT32 numParams = 0);
-		MonoField& getField(const CM::String& name);
+		MonoField* getField(const CM::String& name) const;
 		MonoProperty& getProperty(const CM::String& name);
 		MonoObject* getAttribute(MonoClass* monoClass) const;
+		MonoClass* getBaseClass() const;
+
+		/**
+		 * @brief	Returns all fields belonging to this class.
+		 *
+		 * @note	Be aware this will not include the fields of any base classes.
+		 */
+		const CM::Vector<MonoField*>::type getAllFields() const;
 
 		bool hasAttribute(MonoClass* monoClass) const;
 		bool hasField(const CM::String& name) const;
@@ -60,7 +68,10 @@ namespace BansheeEngine
 		CM::String mFullName;
 
 		CM::UnorderedMap<MethodId, MonoMethod*, MethodId::Hash, MethodId::Equals>::type mMethods; 
-		CM::UnorderedMap<CM::String, MonoField*>::type mFields; 
+		mutable CM::UnorderedMap<CM::String, MonoField*>::type mFields; 
 		CM::UnorderedMap<CM::String, MonoProperty*>::type mProperties;
+
+		mutable bool mHasCachedFields;
+		mutable CM::Vector<MonoField*>::type mCachedFieldList;
 	};
 }

+ 17 - 0
BansheeMono/Include/BsMonoField.h

@@ -6,21 +6,38 @@
 
 namespace BansheeEngine
 {
+	enum class MonoFieldVisibility
+	{
+		Private,
+		ProtectedInternal,
+		Internal,
+		Protected,
+		Public
+	};
+
 	class BS_MONO_EXPORT MonoField
 	{
 	public:
+		const CM::String& getName() const { return mName; }
+		MonoClass* getType();
+
 		void* getValue(MonoObject* instance);
 		void setValue(MonoObject* instance, void* value);
 
 		bool hasAttribute(MonoClass* monoClass);
 		MonoObject* getAttribute(MonoClass* monoClass);
 
+		MonoFieldVisibility getVisibility();
+		bool isStatic();
+
 	private:
 		friend class MonoClass;
 
 		MonoField(MonoClassField* field);
 
+		CM::String mName;
 		MonoClassField* mField;
+		MonoClass* mFieldType;
 		void* mThunk;
 	};
 }

+ 1 - 1
BansheeMono/Source/BsMonoAssembly.cpp

@@ -32,7 +32,7 @@ namespace BansheeEngine
 	}
 
 	MonoAssembly::MonoAssembly()
-		:mIsLoaded(false), mMonoImage(nullptr), mMonoAssembly(nullptr), mIsDependency(false)
+		:mIsLoaded(false), mMonoImage(nullptr), mMonoAssembly(nullptr), mIsDependency(false), mHaveCachedClassList(false)
 	{
 
 	}

+ 44 - 8
BansheeMono/Source/BsMonoClass.cpp

@@ -31,7 +31,7 @@ namespace BansheeEngine
 	}
 
 	MonoClass::MonoClass(const String& ns, const String& type, ::MonoClass* monoClass, const MonoAssembly* parentAssembly)
-		:mNamespace(ns), mTypeName(type), mClass(monoClass), mParentAssembly(parentAssembly)
+		:mNamespace(ns), mTypeName(type), mClass(monoClass), mParentAssembly(parentAssembly), mHasCachedFields(false)
 	{
 		mFullName = ns + "." + type;
 	}
@@ -95,23 +95,20 @@ namespace BansheeEngine
 		return mono_class_is_subclass_of(mClass, monoClass->mClass, true) != 0;
 	}
 
-	MonoField& MonoClass::getField(const String& name)
+	MonoField* MonoClass::getField(const String& name) const
 	{
 		auto iterFind = mFields.find(name);
 		if(iterFind != mFields.end())
-			return *iterFind->second;
+			return iterFind->second;
 
 		MonoClassField* field = mono_class_get_field_from_name(mClass, name.c_str());
 		if(field == nullptr)
-		{
-			String fullFieldName = mFullName + "." + name;
-			CM_EXCEPT(InvalidParametersException, "Cannot get Mono field: " + fullFieldName);
-		}
+			return nullptr;
 
 		MonoField* newField = new (cm_alloc<MonoField>()) MonoField(field);
 		mFields[name] = newField;
 
-		return *newField;
+		return newField;
 	}
 
 	MonoProperty& MonoClass::getProperty(const String& name)
@@ -133,6 +130,29 @@ namespace BansheeEngine
 		return *newProperty;
 	}
 
+	const CM::Vector<MonoField*>::type MonoClass::getAllFields() const
+	{
+		if(mHasCachedFields)
+			return mCachedFieldList;
+
+		mCachedFieldList.clear();
+
+		void* iter = nullptr;
+		MonoClassField* curClassField = mono_class_get_fields(mClass, &iter);
+		while(curClassField != nullptr)
+		{
+			const char* fieldName = mono_field_get_name(curClassField);
+			MonoField* curField = getField(fieldName);
+
+			mCachedFieldList.push_back(curField);
+
+			curClassField = mono_class_get_fields(mClass, &iter);
+		}
+
+		mHasCachedFields = true;
+		return mCachedFieldList;
+	}
+
 	MonoObject* MonoClass::invokeMethod(const String& name, MonoObject* instance, void** params, UINT32 numParams)
 	{
 		return getMethod(name, numParams).invoke(instance, params);
@@ -167,6 +187,8 @@ namespace BansheeEngine
 		// TODO - Consider caching custom attributes or just initializing them all at load
 
 		MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_class(mClass);
+		if(attrInfo == nullptr)
+			return false;
 
 		bool hasAttr = mono_custom_attrs_has_attr(attrInfo, monoClass->_getInternalClass()) != 0;
 
@@ -180,6 +202,8 @@ namespace BansheeEngine
 		// TODO - Consider caching custom attributes or just initializing them all at load
 
 		MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_class(mClass);
+		if(attrInfo == nullptr)
+			return nullptr;
 
 		MonoObject* foundAttr = mono_custom_attrs_get_attr(attrInfo, monoClass->_getInternalClass());
 
@@ -187,4 +211,16 @@ namespace BansheeEngine
 
 		return foundAttr;
 	}
+
+	MonoClass* MonoClass::getBaseClass() const
+	{
+		::MonoClass* monoBase = mono_class_get_parent(mClass);
+		if(monoBase == nullptr)
+			return nullptr;
+
+		String ns = mono_class_get_namespace(monoBase);
+		String typeName = mono_class_get_name(monoBase);
+
+		return MonoManager::instance().findClass(ns, typeName);
+	}
 }

+ 52 - 1
BansheeMono/Source/BsMonoField.cpp

@@ -1,14 +1,35 @@
 #include "BsMonoField.h"
 #include "BsMonoClass.h"
+#include "BsMonoManager.h"
+
+#include <mono/metadata/attrdefs.h>
 
 using namespace CamelotFramework;
 
 namespace BansheeEngine
 {
 	MonoField::MonoField(MonoClassField* field)
-		:mField(field)
+		:mField(field), mFieldType(nullptr)
+	{
+		mName = mono_field_get_name(mField);
+	}
+
+	MonoClass* MonoField::getType()
 	{
+		if(mFieldType != nullptr)
+			return mFieldType;
 
+		MonoType* monoType = mono_field_get_type(mField);
+		::MonoClass* fieldClass = mono_class_from_mono_type(monoType);
+		if(fieldClass == nullptr)
+			return nullptr;	
+		
+		String ns = mono_class_get_namespace(fieldClass);
+		String typeName = mono_class_get_name(fieldClass);
+
+		mFieldType = MonoManager::instance().findClass(ns, typeName);
+
+		return mFieldType;
 	}
 
 	void* MonoField::getValue(MonoObject* instance)
@@ -29,6 +50,8 @@ namespace BansheeEngine
 
 		::MonoClass* parentClass = mono_field_get_parent(mField);
 		MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_field(parentClass, mField);
+		if(attrInfo == nullptr)
+			return false;
 
 		bool hasAttr = mono_custom_attrs_has_attr(attrInfo, monoClass->_getInternalClass()) != 0;
 		
@@ -43,6 +66,8 @@ namespace BansheeEngine
 
 		::MonoClass* parentClass = mono_field_get_parent(mField);
 		MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_field(parentClass, mField);
+		if(attrInfo == nullptr)
+			return nullptr;
 
 		MonoObject* foundAttr = mono_custom_attrs_get_attr(attrInfo, monoClass->_getInternalClass());
 
@@ -50,4 +75,30 @@ namespace BansheeEngine
 
 		return foundAttr;
 	}
+
+	MonoFieldVisibility MonoField::getVisibility()
+	{
+		uint32_t flags = mono_field_get_flags(mField);
+
+		if((flags & MONO_FIELD_ATTR_PRIVATE) != 0)
+			return MonoFieldVisibility::Private;
+		else if((flags & MONO_FIELD_ATTR_FAM_AND_ASSEM) != 0)
+			return MonoFieldVisibility::ProtectedInternal;
+		else if((flags & MONO_FIELD_ATTR_ASSEMBLY) != 0)
+			return MonoFieldVisibility::Internal;
+		else if((flags & MONO_FIELD_ATTR_FAMILY) != 0)
+			return MonoFieldVisibility::Protected;
+		else if((flags & MONO_FIELD_ATTR_PUBLIC) != 0)
+			return MonoFieldVisibility::Public;
+
+		assert(false);
+		return MonoFieldVisibility::Private;
+	}
+
+	bool MonoField::isStatic()
+	{
+		uint32_t flags = mono_field_get_flags(mField);
+
+		return (flags & MONO_FIELD_ATTR_STATIC) != 0;
+	}
 }

+ 10 - 5
BansheeMono/Source/BsMonoManager.cpp

@@ -75,7 +75,7 @@ namespace BansheeEngine
 					CM_EXCEPT(InvalidParametersException, "Unable to find class of type: \"" + meta->ns + "::" + meta->name + "\"");
 
 				if(meta->scriptClass->hasField("mCachedPtr"))
-					meta->thisPtrField = &meta->scriptClass->getField("mCachedPtr");
+					meta->thisPtrField = meta->scriptClass->getField("mCachedPtr");
 				else
 					meta->thisPtrField = nullptr;
 
@@ -89,11 +89,16 @@ namespace BansheeEngine
 		{
 			mIsCoreLoaded = true;
 
-			MonoAssembly* mscorlib = new (cm_alloc<MonoAssembly>()) MonoAssembly();
-			mAssemblies["mscorlib"] = mscorlib;
-			mscorlib->loadAsDependency(assembly->mMonoImage, "mscorlib");
+			MonoImage* existingImage = mono_image_loaded("mscorlib");
+			if(existingImage != nullptr)
+			{
+				MonoAssembly* mscorlib = new (cm_alloc<MonoAssembly>()) MonoAssembly();
+				mAssemblies["mscorlib"] = mscorlib;
 
-			mIsCoreLoaded = true;
+				mscorlib->loadAsDependency(existingImage, "mscorlib");
+			}
+			else
+				loadAssembly("mscorlib", "mscorlib", "");			
 		}
 
 		return *assembly;

+ 6 - 1
GameObjectSerialization.txt

@@ -86,4 +86,9 @@ Inspector
 
 TODO - When reloading scripts how to handle restoring references?
 TODO - When I destroy a Component, how will I refresh the inspector to let it know that something has changed
-  - Can happen from C# and C++
+  - Can happen from C# and C++
+
+  -------------------------------------------------------
+
+  Other:
+  Instantiating mono generic classes: http://stackoverflow.com/questions/17628411/get-generic-type-using-mono-embedded

+ 2 - 0
MBansheeEngine/Component.cs

@@ -12,5 +12,7 @@ namespace BansheeEngine
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_CreateInstance(Component instance, string ns, string type);
+
+        private int dbgBase;
     }
 }

+ 12 - 0
MBansheeEngine/DbgComponent.cs

@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BansheeEngine
+{
+    class DbgComponent : Component
+    {
+        private int a;
+    }
+}

+ 9 - 0
MBansheeEngine/HideInInspector.cs

@@ -0,0 +1,9 @@
+using System;
+
+namespace BansheeEngine
+{
+    [AttributeUsage(AttributeTargets.Field)]
+    public sealed class HideInInspector : Attribute
+    {
+    }
+}

+ 3 - 0
MBansheeEngine/MBansheeEngine.csproj

@@ -45,6 +45,7 @@
     <Compile Include="BuiltinResources.cs" />
     <Compile Include="Color.cs" />
     <Compile Include="Component.cs" />
+    <Compile Include="DbgComponent.cs" />
     <Compile Include="Font.cs" />
     <Compile Include="GUI\GUI.cs" />
     <Compile Include="GUI\GUIArea.cs" />
@@ -67,6 +68,7 @@
     <Compile Include="GUI\GUITexture.cs" />
     <Compile Include="GUI\GUIToggle.cs" />
     <Compile Include="GUI\GUIToggleGroup.cs" />
+    <Compile Include="HideInInspector.cs" />
     <Compile Include="LocString.cs" />
     <Compile Include="Math\MathEx.cs" />
     <Compile Include="Math\Matrix3.cs" />
@@ -76,6 +78,7 @@
     <Compile Include="Math\Quaternion.cs" />
     <Compile Include="Resource.cs" />
     <Compile Include="ScriptObject.cs" />
+    <Compile Include="SerializeField.cs" />
     <Compile Include="SpriteTexture.cs" />
     <Compile Include="StringTable.cs" />
     <Compile Include="Texture2D.cs" />

+ 9 - 0
MBansheeEngine/SerializeField.cs

@@ -0,0 +1,9 @@
+using System;
+
+namespace BansheeEngine
+{
+    [AttributeUsage(AttributeTargets.Field)]
+    public sealed class SerializeField : Attribute
+    {
+    }
+}

+ 2 - 0
SBansheeEditor/Include/BsScriptEditorPrerequisites.h

@@ -22,4 +22,6 @@
 namespace BansheeEditor
 {
 	class ScriptEditorWindow;
+
+	static const char* BansheeEditorAssemblyName = "MBansheeEditor";
 }

+ 1 - 1
SBansheeEditor/Source/BsScriptEditorGUI.cpp

@@ -23,7 +23,7 @@ namespace BansheeEditor
 
 	void ScriptEditorGUI::initMetaData()
 	{
-		metaData = ScriptMeta("MBansheeEditor", "BansheeEditor", "EditorGUI", &ScriptEditorGUI::initRuntimeData);
+		metaData = ScriptMeta(BansheeEditorAssemblyName, "BansheeEditor", "EditorGUI", &ScriptEditorGUI::initRuntimeData);
 
 		MonoManager::registerScriptType(&metaData);
 	}

+ 1 - 1
SBansheeEditor/Source/BsScriptEditorPlugin.cpp

@@ -17,7 +17,7 @@ namespace BansheeEditor
 	extern "C" BS_SCR_BED_EXPORT void* loadPlugin()
 	{
 		const CM::String ENGINE_ASSEMBLY_PATH = "..\\..\\Assemblies\\MBansheeEditor.dll";
-		const CM::String ENGINE_ASSEMBLY_NAME = "MBansheeEditor";
+		const CM::String ENGINE_ASSEMBLY_NAME = BansheeEditorAssemblyName;
 		const CM::String ASSEMBLY_ENTRY_POINT = "ProgramEd::Main";
 
 		BS::MonoAssembly& assembly = MonoManager::instance().loadAssembly(ENGINE_ASSEMBLY_PATH, ENGINE_ASSEMBLY_NAME, ASSEMBLY_ENTRY_POINT);

+ 4 - 4
SBansheeEditor/Source/BsScriptEditorWindow.cpp

@@ -28,7 +28,7 @@ namespace BansheeEditor
 
 	void ScriptEditorWindow::initMetaData()
 	{
-		metaData = ScriptMeta("MBansheeEditor", "BansheeEditor", "EditorWindow", &ScriptEditorWindow::initRuntimeData);
+		metaData = ScriptMeta(BansheeEditorAssemblyName, "BansheeEditor", "EditorWindow", &ScriptEditorWindow::initRuntimeData);
 
 		MonoManager::registerScriptType(&metaData);
 	}
@@ -75,13 +75,13 @@ namespace BansheeEditor
 
 	void ScriptEditorWindow::registerManagedEditorWindows()
 	{
-		BS::MonoAssembly* assembly = MonoManager::instance().getAssembly("MBansheeEditor");
+		BS::MonoAssembly* assembly = MonoManager::instance().getAssembly(BansheeEditorAssemblyName);
 
 		if(assembly != nullptr)
 		{
 			BS::MonoClass* editorWindowClass = assembly->getClass("BansheeEditor", "EditorWindow");
 
-			CM::Vector<BS::MonoClass*>::type allClasses = assembly->getAllClasses();
+			const CM::Vector<BS::MonoClass*>::type& allClasses = assembly->getAllClasses();
 			for(auto& curClass : allClasses)
 			{
 				if(curClass->isSubClassOf(editorWindowClass) && curClass != editorWindowClass)
@@ -96,7 +96,7 @@ namespace BansheeEditor
 
 	EditorWidgetBase* ScriptEditorWindow::openEditorWidgetCallback(CM::String ns, CM::String type, EditorWidgetContainer& parentContainer)
 	{
-		BS::MonoAssembly* assembly = MonoManager::instance().getAssembly("MBansheeEditor");
+		BS::MonoAssembly* assembly = MonoManager::instance().getAssembly(BansheeEditorAssemblyName);
 
 		if(assembly == nullptr)
 			return nullptr;

+ 74 - 14
SBansheeEngine/Include/BsRuntimeScriptObjects.h

@@ -5,7 +5,7 @@
 
 namespace BansheeEngine
 {
-	enum class ScriptPrimitiveType
+	enum class ScriptFieldType
 	{
 		Bool,
 		Char,
@@ -17,15 +17,13 @@ namespace BansheeEngine
 		U32,
 		I64,
 		U64,
-		String
-	};
-
-	enum class ScriptFieldType
-	{
-		Primitive,
-		Complex,
+		Float,
+		Double,
+		String,
+		SerializableObject,
 		ResourceRef,
-		GameObjectRef
+		GameObjectRef,
+		Other
 	};
 
 	enum class ScriptFieldFlags
@@ -43,11 +41,62 @@ namespace BansheeEngine
 		CM::String mName;
 		CM::String mTypeNamespace;
 		CM::String mTypeName;
+		CM::UINT32 mFieldId;
 
 		ScriptFieldType mType;
 		ScriptFieldFlags mFlags;
 
 		MonoField* mMonoField;
+
+		CM::UINT32 getNumArrayElement(MonoObject* obj);
+		void setNumArrayElements(MonoObject* obj, CM::UINT32 numElements);
+
+		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 setResource(MonoObject* obj,const CM::HResource& resource, CM::UINT32 arrayIdx = 0);
+		CM::HResource getResource(MonoObject* obj,CM::UINT32 arrayIdx = 0);
+
+		void setGameObject(MonoObject* obj,const CM::HGameObject& gameObject, CM::UINT32 arrayIdx = 0);
+		CM::HGameObject getGameObject(MonoObject* obj,CM::UINT32 arrayIdx = 0);
+
+		// TODO - Set/Get for SerializableObject
 	};
 
 	struct BS_SCR_BE_EXPORT SerializableObjectInfo
@@ -57,10 +106,21 @@ namespace BansheeEngine
 
 		CM::String mNamespace;
 		CM::String mTypeName;
+		CM::UINT32 mTypeId;
 
 		MonoClass* mMonoClass;
 
-		CM::UnorderedMap<CM::String, SerializableFieldInfo*>::type mFields;
+		CM::UnorderedMap<CM::String, CM::UINT32>::type mFieldNameToId;
+		CM::UnorderedMap<CM::UINT32, SerializableFieldInfo*>::type mFields;
+
+		std::weak_ptr<SerializableObjectInfo> mBaseClass;
+		CM::Vector<std::weak_ptr<SerializableObjectInfo>>::type mDerivedClasses;
+	};
+
+	struct BS_SCR_BE_EXPORT SerializableAssemblyInfo
+	{
+		CM::UnorderedMap<CM::String, CM::UINT32>::type mTypeNameToId;
+		CM::UnorderedMap<CM::UINT32, std::shared_ptr<SerializableObjectInfo>>::type mObjectInfos;
 	};
 
 	class BS_SCR_BE_EXPORT RuntimeScriptObjects : public CM::Module<RuntimeScriptObjects>
@@ -68,11 +128,11 @@ namespace BansheeEngine
 	public:
 		~RuntimeScriptObjects();
 
-		void refreshScriptObjects();
-
+		void refreshScriptObjects(const CM::String& assemblyName);
+		bool getSerializableObjectInfo(const CM::String& ns, const CM::String& typeName, std::shared_ptr<SerializableObjectInfo>& outInfo);
 	private:
-		CM::UnorderedMap<CM::String, SerializableObjectInfo*>::type mObjectInfos;
+		CM::UnorderedMap<CM::String, std::shared_ptr<SerializableAssemblyInfo>>::type mAssemblyInfos;
 
-		void clearScriptObjects();
+		void clearScriptObjects(const CM::String& assemblyName);
 	};
 }

+ 7 - 3
SBansheeEngine/Include/BsScriptComponent.h

@@ -1,24 +1,28 @@
 #pragma once
 
 #include "BsScriptEnginePrerequisites.h"
+#include "BsScriptGameObject.h"
 #include "BsScriptObject.h"
 #include "CmFont.h"
 
 namespace BansheeEngine
 {
-	class BS_SCR_BE_EXPORT ScriptComponent : public ScriptObject<ScriptComponent>
+	class BS_SCR_BE_EXPORT ScriptComponent : public ScriptGameObject, public ScriptObject<ScriptComponent>
 	{
 	public:
 		static void initMetaData();
 
+		virtual CM::HGameObject getNativeHandle() const { return mManagedComponent; }
+		virtual void setNativeHandle(const CM::HGameObject& gameObject);
+
 	private:
 		static void internal_createInstance(MonoObject* instance, MonoString* ns, MonoString* typeName);
 		static void internal_destroyInstance(ScriptComponent* nativeInstance);
 
 		static void initRuntimeData();
 
-		ScriptComponent(ManagedComponent* managedComponent);
+		ScriptComponent(const CM::GameObjectHandle<ManagedComponent>& managedComponent);
 
-		ManagedComponent* mManagedComponent;
+		CM::GameObjectHandle<ManagedComponent> mManagedComponent;
 	};
 }

+ 2 - 0
SBansheeEngine/Include/BsScriptEnginePrerequisites.h

@@ -36,4 +36,6 @@ namespace BansheeEngine
 	{
 		TID_ManagedComponent = 50000
 	};
+
+	static const char* BansheeEngineAssemblyName = "MBansheeEngine";
 }

+ 13 - 0
SBansheeEngine/Include/BsScriptGameObject.h

@@ -0,0 +1,13 @@
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BE_EXPORT ScriptGameObject
+	{
+	public:
+		virtual CM::HGameObject getNativeHandle() const = 0;
+		virtual void setNativeHandle(const CM::HGameObject& gameObject) = 0;
+	};
+}

+ 13 - 0
SBansheeEngine/Include/BsScriptResource.h

@@ -0,0 +1,13 @@
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BE_EXPORT ScriptResource
+	{
+	public:
+		virtual CM::HResource getNativeHandle() const = 0;
+		virtual void setNativeHandle(const CM::HResource& resource) = 0;
+	};
+}

+ 5 - 1
SBansheeEngine/Include/BsScriptSpriteTexture.h

@@ -1,17 +1,21 @@
 #pragma once
 
 #include "BsScriptEnginePrerequisites.h"
+#include "BsScriptResource.h"
 #include "BsScriptObject.h"
 
 namespace BansheeEngine
 {
-	class BS_SCR_BE_EXPORT ScriptSpriteTexture : public ScriptObject<ScriptSpriteTexture>
+	class BS_SCR_BE_EXPORT ScriptSpriteTexture : public ScriptResource, public ScriptObject<ScriptSpriteTexture>
 	{
 	public:
 		static void initMetaData();
 
 		const HSpriteTexture& getInternalValue() const { return mTexture; }
 
+		CM::HResource getNativeHandle() const { return mTexture; }
+		void setNativeHandle(const CM::HResource& resource);
+
 	private:
 		static void internal_createInstance(MonoObject* instance);
 		static void internal_destroyInstance(ScriptSpriteTexture* nativeInstance);

+ 4 - 1
SBansheeEngine/Include/BsScriptTexture2D.h

@@ -1,18 +1,21 @@
 #pragma once
 
 #include "BsScriptEnginePrerequisites.h"
+#include "BsScriptResource.h"
 #include "BsScriptObject.h"
 #include "CmTexture.h"
 
 namespace BansheeEngine
 {
-	class BS_SCR_BE_EXPORT ScriptTexture2D : public ScriptObject<ScriptTexture2D>
+	class BS_SCR_BE_EXPORT ScriptTexture2D : public ScriptResource, public ScriptObject<ScriptTexture2D>
 	{
 	public:
 		static void initMetaData();
 
 		void* getNativeRaw() const { return mTexture.get(); }
 
+		CM::HResource getNativeHandle() const { return mTexture; }
+		void setNativeHandle(const CM::HResource& resource);
 	private:
 		static void internal_createInstance(MonoObject* instance, CM::UINT32 format, CM::UINT32 width, CM::UINT32 height, bool hasMipmaps, bool gammaCorrection);
 		static void internal_destroyInstance(ScriptTexture2D* nativeInstance);

+ 2 - 0
SBansheeEngine/SBansheeEngine.vcxproj

@@ -231,6 +231,7 @@
     <ClInclude Include="Include\BsRuntimeScriptObjects.h" />
     <ClInclude Include="Include\BsScriptComponent.h" />
     <ClInclude Include="Include\BsScriptEnginePrerequisites.h" />
+    <ClInclude Include="Include\BsScriptGameObject.h" />
     <ClInclude Include="Include\BsScriptGUIButton.h" />
     <ClInclude Include="Include\BsScriptGUIFixedSpace.h" />
     <ClInclude Include="Include\BsScriptGUIFlexibleSpace.h" />
@@ -250,6 +251,7 @@
     <ClInclude Include="Include\BsScriptHString.h" />
     <ClInclude Include="Include\BsScriptMacros.h" />
     <ClInclude Include="Include\BsScriptObject.h" />
+    <ClInclude Include="Include\BsScriptResource.h" />
     <ClInclude Include="Include\BsScriptSpriteTexture.h" />
     <ClInclude Include="Include\BsScriptStringTable.h" />
     <ClInclude Include="Include\BsScriptTexture2D.h" />

+ 6 - 0
SBansheeEngine/SBansheeEngine.vcxproj.filters

@@ -99,6 +99,12 @@
     <ClInclude Include="Include\BsManagedComponentRTTI.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsScriptResource.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsScriptGameObject.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsScriptTexture2D.cpp">

+ 225 - 34
SBansheeEngine/Source/BsRuntimeScriptObjects.cpp

@@ -1,11 +1,15 @@
 #include "BsRuntimeScriptObjects.h"
+#include "BsMonoManager.h"
+#include "BsMonoAssembly.h"
+#include "BsMonoClass.h"
+#include "BsMonoField.h"
 
 using namespace CamelotFramework;
 
 namespace BansheeEngine
 {
 	SerializableObjectInfo::SerializableObjectInfo()
-		:mMonoClass(nullptr)
+		:mMonoClass(nullptr), mTypeId(0)
 	{
 
 	}
@@ -19,7 +23,7 @@ namespace BansheeEngine
 	}
 
 	SerializableFieldInfo::SerializableFieldInfo()
-		:mMonoField(nullptr), mType(ScriptFieldType::Primitive), mFlags((ScriptFieldFlags)0)
+		:mMonoField(nullptr), mType(ScriptFieldType::Other), mFlags((ScriptFieldFlags)0), mFieldId(0)
 	{
 
 	}
@@ -31,50 +35,237 @@ namespace BansheeEngine
 
 	RuntimeScriptObjects::~RuntimeScriptObjects()
 	{
-		clearScriptObjects();
+
 	}
 
-	void RuntimeScriptObjects::refreshScriptObjects()
+	void RuntimeScriptObjects::refreshScriptObjects(const String& assemblyName)
 	{
-		clearScriptObjects();
-
-		// Scan all loaded assemblies
-		//  - find classes deriving from Component (make sure even non-direct descendants from Component are considered)
-		//  - find classes implementing [Serializable] attribute
-		//  - If multiple copies of the same class are found ignore them
-		// Create dummy SerializableObjectInfo entries in the map so I can quickly look up serializable objects
-		//  SerializableObjectInfo should know if object is Component or [Serializable]
-		// Go through all of their fields
-		//  Depending on attributes and visibility, mark them as inspectable and/or serializable
-		//  Ensure to only get fields of that EXACT class, not its base
+		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* componentClass = bansheeEngineAssembly->getClass("BansheeEngine", "Component");
+		if(componentClass == nullptr)
+			CM_EXCEPT(InvalidStateException, "Cannot find Component managed class.");
+
+		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;
+
+		MonoAssembly* curAssembly = MonoManager::instance().getAssembly(assemblyName);
+		if(curAssembly == nullptr)
+			return;
+
+		std::shared_ptr<SerializableAssemblyInfo> assemblyInfo = cm_shared_ptr<SerializableAssemblyInfo>();
+		mAssemblyInfos[assemblyName] = assemblyInfo;
+
+		const Vector<MonoClass*>::type& allClasses = curAssembly->getAllClasses();
+
+		for(auto& curClass : allClasses)
+		{
+			if((curClass->isSubClassOf(componentClass) || curClass->hasAttribute(serializableAttribute)) && curClass != componentClass)
+			{
+				std::shared_ptr<SerializableObjectInfo> objInfo = cm_shared_ptr<SerializableObjectInfo>();
+
+				objInfo->mTypeId = mUniqueTypeId++;
+				objInfo->mTypeName = curClass->getTypeName();
+				objInfo->mNamespace = curClass->getNamespace();
+				objInfo->mMonoClass = curClass;
+
+				::MonoClass* baseClass = mono_class_get_parent(curClass->_getInternalClass());
+				if(baseClass != nullptr)
+				{
+					String dbgName = mono_class_get_name(baseClass);
+				}
+
+				String fullTypeName = objInfo->mNamespace + "." + objInfo->mTypeName;
+				assemblyInfo->mTypeNameToId[fullTypeName] = objInfo->mTypeId;
+				assemblyInfo->mObjectInfos[objInfo->mTypeId] = objInfo;
+
+				CM::UINT32 mUniqueFieldId = 1;
+				const CM::Vector<MonoField*>::type& fields = curClass->getAllFields();
+
+				for(auto& field : fields)
+				{
+					if(field->isStatic())
+						continue;
+
+					SerializableFieldInfo* fieldInfo = cm_new<SerializableFieldInfo>();
+					fieldInfo->mFieldId = mUniqueFieldId++;
+					fieldInfo->mMonoField = field;
+					fieldInfo->mName = field->getName();
+
+					MonoClass* fieldType = field->getType();
+					fieldInfo->mTypeNamespace = fieldType->getNamespace();
+					fieldInfo->mTypeName = fieldType->getTypeName();
+					
+					MonoType* monoType = mono_class_get_type(fieldType->_getInternalClass());
+					int monoPrimitiveType = mono_type_get_type(monoType);
+					
+					// TODO - We don't support nested arrays or multi-dimensional arrays
+					bool isSupportedType = true;
+					if(monoPrimitiveType == MONO_TYPE_ARRAY) 
+					{
+						::MonoClass* elementClass = mono_class_get_element_class(fieldType->_getInternalClass());
+						if(elementClass != nullptr)
+						{
+							monoType = mono_class_get_type(elementClass);
+							monoPrimitiveType = mono_type_get_type(monoType);
+						}
+
+						fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Array);
+					}
+					// TODO - Also check for List and get its generic primitive
+
+					//  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:
+						// TODO - Check for Resource or GameObject ref, or SerializableObject
+						break;
+					case MONO_TYPE_VALUETYPE:
+						// TODO - Check for SerializableObject
+						break;
+					}
+					
+					if(fieldInfo->mType != ScriptFieldType::Other)
+					{
+						MonoFieldVisibility visibility = field->getVisibility();
+						if(visibility == MonoFieldVisibility::Public)
+						{
+							if(!field->hasAttribute(nonSerializedAttribute))
+								fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Serializable);
+
+							if(!field->hasAttribute(hideInInspectorAttribute))
+								fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Inspectable);
+						}
+						else
+						{
+							if(field->hasAttribute(serializeFieldAttribute))
+								fieldInfo->mFlags = (ScriptFieldFlags)((UINT32)fieldInfo->mFlags | (UINT32)ScriptFieldFlags::Serializable);
+						}
+					}
+
+					objInfo->mFieldNameToId[fieldInfo->mName] = fieldInfo->mFieldId;
+					objInfo->mFields[fieldInfo->mFieldId] = fieldInfo;
+				}
+			}
+		}
+
+		// Form parent/child connections
+		for(auto& curClass : assemblyInfo->mObjectInfos)
+		{
+			MonoClass* base = curClass.second->mMonoClass->getBaseClass();
+			while(base != nullptr)
+			{
+				std::shared_ptr<SerializableObjectInfo> baseObjInfo;
+				if(getSerializableObjectInfo(base->getNamespace(), base->getTypeName(), baseObjInfo))
+				{
+					curClass.second->mBaseClass = baseObjInfo;
+					baseObjInfo->mDerivedClasses.push_back(curClass.second);
+
+					break;
+				}
+
+				base = base->getBaseClass();
+			}
+		}
+	
+		// TODO - How to handle arrays and/or Lists (or collections in general?)
+
+		// TODO - In BsScriptEnginePlugin.cpp I create RuntimeScriptObjects class but never destroy it, for debug purposes. Remember to remove that.
+
+		// TODO - Figure our field type (primitive, gameobject ref, etc.) - Should I do this here or while serializing? Probably here.
+		//    - Add easy way to modify those fields (depending on their type) - Maybe make them virtual
 		//  Detect field type:
 		//   - Primitive - straightforward just check for primitive types
 		//   - GameObjectHandle - check if object is SceneObject or derives from Component
 		//   - SerializableObject - check if object is SerializableObject
 		//   - ResourceHandle - derives from Resource
-		
-		// TODO - How will I serialize SerializableObjects?
-		//  - We don't do any instance tracking for SerializableObjects. Each one will be deserialized and serialized
-		//    as its own separate instance.
-		
-		// TODO - Each class will need an unique ID
-		//      - So will each field within a class
-		//      - Will likely need two maps
-		//        - ns.type -> id
-		//        - id -> SerializableObjectInfo*
-
-		// TODO - For each class search its base class (if it has one) and see if it is Component
-		//  or child of COmponent. If it is, set up the parent/child fields in SerializableObjectInfo.
-
-		// TODO - SerializableObjectInfo needs to be IReflectable and its referenced children
-		// should be shared pointers
+
+		// TOOD - Make SerializableObjectInfo IReflectable and create its RTTI
 	}
 
-	void RuntimeScriptObjects::clearScriptObjects()
+	void RuntimeScriptObjects::clearScriptObjects(const CM::String& assemblyName)
 	{
-		for(auto& scriptObject : mObjectInfos)
+		mAssemblyInfos.erase(assemblyName);
+	}
+
+	bool RuntimeScriptObjects::getSerializableObjectInfo(const CM::String& ns, const CM::String& typeName, std::shared_ptr<SerializableObjectInfo>& outInfo)
+	{
+		String fullName = ns + "." + typeName;
+		for(auto& curAssembly : mAssemblyInfos)
 		{
-			cm_delete(scriptObject.second);
+			auto iterFind = curAssembly.second->mTypeNameToId.find(fullName);
+			if(iterFind != curAssembly.second->mTypeNameToId.end())
+			{
+				outInfo = curAssembly.second->mObjectInfos[iterFind->first];
+
+				return true;
+			}
 		}
+
+		return false;
 	}
 }

+ 8 - 3
SBansheeEngine/Source/BsScriptComponent.cpp

@@ -9,7 +9,7 @@ using namespace CamelotFramework;
 
 namespace BansheeEngine
 {
-	ScriptComponent::ScriptComponent(ManagedComponent* managedComponent)
+	ScriptComponent::ScriptComponent(const CM::GameObjectHandle<ManagedComponent>& managedComponent)
 		:mManagedComponent(managedComponent)
 	{
 
@@ -17,7 +17,7 @@ namespace BansheeEngine
 
 	void ScriptComponent::initMetaData()
 	{
-		metaData = ScriptMeta("MBansheeEngine", "BansheeEngine", "Component", &ScriptComponent::initRuntimeData);
+		metaData = ScriptMeta(BansheeEngineAssemblyName, "BansheeEngine", "Component", &ScriptComponent::initRuntimeData);
 
 		MonoManager::registerScriptType(&metaData);
 	}
@@ -32,7 +32,7 @@ namespace BansheeEngine
 	{
 		// TODO - Just a placeholder
 
-		ScriptComponent* nativeInstance = new (cm_alloc<ScriptComponent>()) ScriptComponent(nullptr);
+		ScriptComponent* nativeInstance = new (cm_alloc<ScriptComponent>()) ScriptComponent(GameObjectHandle<ManagedComponent>());
 		nativeInstance->createInstance(instance);
 
 		metaData.thisPtrField->setValue(instance, nativeInstance);
@@ -43,4 +43,9 @@ namespace BansheeEngine
 		nativeInstance->destroyInstance();
 		cm_delete(nativeInstance);
 	}
+
+	void ScriptComponent::setNativeHandle(const CM::HGameObject& gameObject)
+	{
+		mManagedComponent = static_object_cast<ManagedComponent>(gameObject);
+	}
 }

+ 7 - 1
SBansheeEngine/Source/BsScriptEnginePlugin.cpp

@@ -2,6 +2,9 @@
 #include "BsMonoManager.h"
 #include "BsMonoAssembly.h"
 
+// DEBUG ONLY
+#include "BsRuntimeScriptObjects.h"
+
 using namespace CamelotFramework;
 
 namespace BansheeEngine
@@ -15,11 +18,14 @@ namespace BansheeEngine
 	extern "C" BS_SCR_BE_EXPORT void* loadPlugin()
 	{
 		const CM::String ENGINE_ASSEMBLY_PATH = "..\\..\\Assemblies\\MBansheeEngine.dll";
-		const CM::String ENGINE_ASSEMBLY_NAME = "MBansheeEngine";
+		const CM::String ENGINE_ASSEMBLY_NAME = BansheeEngineAssemblyName;
 		const CM::String ASSEMBLY_ENTRY_POINT = "Program::Main";
 		
 		MonoManager::instance().loadAssembly(ENGINE_ASSEMBLY_PATH, ENGINE_ASSEMBLY_NAME, ASSEMBLY_ENTRY_POINT);
 
+		RuntimeScriptObjects::startUp(cm_new<RuntimeScriptObjects>());
+		RuntimeScriptObjects::instance().refreshScriptObjects(BansheeEngineAssemblyName);
+
 		return nullptr;
 	}
 }

+ 1 - 1
SBansheeEngine/Source/BsScriptFont.cpp

@@ -17,7 +17,7 @@ namespace BansheeEngine
 
 	void ScriptFont::initMetaData()
 	{
-		metaData = ScriptMeta("MBansheeEngine", "BansheeEngine", "Font", &ScriptFont::initRuntimeData);
+		metaData = ScriptMeta(BansheeEngineAssemblyName, "BansheeEngine", "Font", &ScriptFont::initRuntimeData);
 
 		MonoManager::registerScriptType(&metaData);
 	}

+ 1 - 1
SBansheeEngine/Source/BsScriptGUIArea.cpp

@@ -20,7 +20,7 @@ namespace BansheeEngine
 
 	void ScriptGUIArea::initMetaData()
 	{
-		metaData = ScriptMeta("MBansheeEngine", "BansheeEngine", "GUIArea", &ScriptGUIArea::initRuntimeData);
+		metaData = ScriptMeta(BansheeEngineAssemblyName, "BansheeEngine", "GUIArea", &ScriptGUIArea::initRuntimeData);
 
 		MonoManager::registerScriptType(&metaData);
 	}

+ 1 - 1
SBansheeEngine/Source/BsScriptGUIBase.cpp

@@ -18,7 +18,7 @@ namespace BansheeEngine
 
 	void ScriptGUIBaseMeta::initMetaData()
 	{
-		metaData = ScriptMeta("MBansheeEngine", "BansheeEngine", "GUIBase", &ScriptGUIBase::initRuntimeData);
+		metaData = ScriptMeta(BansheeEngineAssemblyName, "BansheeEngine", "GUIBase", &ScriptGUIBase::initRuntimeData);
 
 		MonoManager::registerScriptType(&metaData);
 	}

+ 1 - 1
SBansheeEngine/Source/BsScriptGUIButton.cpp

@@ -31,7 +31,7 @@ namespace BansheeEngine
 
 	void ScriptGUIButton::initMetaData()
 	{
-		metaData = ScriptMeta("MBansheeEngine", "BansheeEngine", "GUIButton", &ScriptGUIButton::initRuntimeData);
+		metaData = ScriptMeta(BansheeEngineAssemblyName, "BansheeEngine", "GUIButton", &ScriptGUIButton::initRuntimeData);
 
 		MonoManager::registerScriptType(&metaData);
 	}

+ 4 - 4
SBansheeEngine/Source/BsScriptGUIContent.cpp

@@ -19,16 +19,16 @@ namespace BansheeEngine
 
 	void ScriptGUIContent::initMetaData()
 	{
-		metaData = ScriptMeta("MBansheeEngine", "BansheeEngine", "GUIContent", &ScriptGUIContent::initRuntimeData);
+		metaData = ScriptMeta(BansheeEngineAssemblyName, "BansheeEngine", "GUIContent", &ScriptGUIContent::initRuntimeData);
 
 		MonoManager::registerScriptType(&metaData);
 	}
 
 	void ScriptGUIContent::initRuntimeData()
 	{
-		mTextField = &metaData.scriptClass->getField("_text");
-		mTooltipField = &metaData.scriptClass->getField("_tooltip");
-		mImageField = &metaData.scriptClass->getField("_image");
+		mTextField = metaData.scriptClass->getField("_text");
+		mTooltipField = metaData.scriptClass->getField("_tooltip");
+		mImageField = metaData.scriptClass->getField("_image");
 	}
 
 	const CM::HString& ScriptGUIContent::getText(MonoObject* instance)

+ 1 - 1
SBansheeEngine/Source/BsScriptGUIElementStateStyle.cpp

@@ -31,7 +31,7 @@ namespace BansheeEngine
 
 	void ScriptGUIElementStateStyle::initMetaData()
 	{
-		metaData = ScriptMeta("MBansheeEngine", "BansheeEngine", "GUIElementStateStyle", &ScriptGUIElementStateStyle::initRuntimeData);
+		metaData = ScriptMeta(BansheeEngineAssemblyName, "BansheeEngine", "GUIElementStateStyle", &ScriptGUIElementStateStyle::initRuntimeData);
 
 		MonoManager::registerScriptType(&metaData);
 	}

+ 1 - 1
SBansheeEngine/Source/BsScriptGUIElementStyle.cpp

@@ -34,7 +34,7 @@ namespace BansheeEngine
 
 	void ScriptGUIElementStyle::initMetaData()
 	{
-		metaData = ScriptMeta("MBansheeEngine", "BansheeEngine", "GUIElementStyle", &ScriptGUIElementStyle::initRuntimeData);
+		metaData = ScriptMeta(BansheeEngineAssemblyName, "BansheeEngine", "GUIElementStyle", &ScriptGUIElementStyle::initRuntimeData);
 
 		MonoManager::registerScriptType(&metaData);
 	}

+ 1 - 1
SBansheeEngine/Source/BsScriptGUIFixedSpace.cpp

@@ -21,7 +21,7 @@ namespace BansheeEngine
 
 	void ScriptGUIFixedSpace::initMetaData()
 	{
-		metaData = ScriptMeta("MBansheeEngine", "BansheeEngine", "GUIFixedSpace", &ScriptGUIFixedSpace::initRuntimeData);
+		metaData = ScriptMeta(BansheeEngineAssemblyName, "BansheeEngine", "GUIFixedSpace", &ScriptGUIFixedSpace::initRuntimeData);
 
 		MonoManager::registerScriptType(&metaData);
 	}

+ 1 - 1
SBansheeEngine/Source/BsScriptGUIFlexibleSpace.cpp

@@ -21,7 +21,7 @@ namespace BansheeEngine
 
 	void ScriptGUIFlexibleSpace::initMetaData()
 	{
-		metaData = ScriptMeta("MBansheeEngine", "BansheeEngine", "GUIFlexibleSpace", &ScriptGUIFlexibleSpace::initRuntimeData);
+		metaData = ScriptMeta(BansheeEngineAssemblyName, "BansheeEngine", "GUIFlexibleSpace", &ScriptGUIFlexibleSpace::initRuntimeData);
 
 		MonoManager::registerScriptType(&metaData);
 	}

+ 1 - 1
SBansheeEngine/Source/BsScriptGUIInputBox.cpp

@@ -27,7 +27,7 @@ namespace BansheeEngine
 
 	void ScriptGUIInputBox::initMetaData()
 	{
-		metaData = ScriptMeta("MBansheeEngine", "BansheeEngine", "GUITextBox", &ScriptGUIInputBox::initRuntimeData);
+		metaData = ScriptMeta(BansheeEngineAssemblyName, "BansheeEngine", "GUITextBox", &ScriptGUIInputBox::initRuntimeData);
 
 		MonoManager::registerScriptType(&metaData);
 	}

+ 1 - 1
SBansheeEngine/Source/BsScriptGUILabel.cpp

@@ -26,7 +26,7 @@ namespace BansheeEngine
 
 	void ScriptGUILabel::initMetaData()
 	{
-		metaData = ScriptMeta("MBansheeEngine", "BansheeEngine", "GUILabel", &ScriptGUILabel::initRuntimeData);
+		metaData = ScriptMeta(BansheeEngineAssemblyName, "BansheeEngine", "GUILabel", &ScriptGUILabel::initRuntimeData);
 
 		MonoManager::registerScriptType(&metaData);
 	}

+ 1 - 1
SBansheeEngine/Source/BsScriptGUILayout.cpp

@@ -21,7 +21,7 @@ namespace BansheeEngine
 
 	void ScriptGUILayout::initMetaData()
 	{
-		metaData = ScriptMeta("MBansheeEngine", "BansheeEngine", "GUILayout", &ScriptGUILayout::initRuntimeData);
+		metaData = ScriptMeta(BansheeEngineAssemblyName, "BansheeEngine", "GUILayout", &ScriptGUILayout::initRuntimeData);
 
 		MonoManager::registerScriptType(&metaData);
 	}

+ 1 - 1
SBansheeEngine/Source/BsScriptGUIListBox.cpp

@@ -28,7 +28,7 @@ namespace BansheeEngine
 
 	void ScriptGUIListBox::initMetaData()
 	{
-		metaData = ScriptMeta("MBansheeEngine", "BansheeEngine", "GUIListBox", &ScriptGUIListBox::initRuntimeData);
+		metaData = ScriptMeta(BansheeEngineAssemblyName, "BansheeEngine", "GUIListBox", &ScriptGUIListBox::initRuntimeData);
 
 		MonoManager::registerScriptType(&metaData);
 	}

+ 1 - 1
SBansheeEngine/Source/BsScriptGUIScrollArea.cpp

@@ -27,7 +27,7 @@ namespace BansheeEngine
 
 	void ScriptGUIScrollArea::initMetaData()
 	{
-		metaData = ScriptMeta("MBansheeEngine", "BansheeEngine", "GUIScrollArea", &ScriptGUIScrollArea::initRuntimeData);
+		metaData = ScriptMeta(BansheeEngineAssemblyName, "BansheeEngine", "GUIScrollArea", &ScriptGUIScrollArea::initRuntimeData);
 
 		MonoManager::registerScriptType(&metaData);
 	}

+ 1 - 1
SBansheeEngine/Source/BsScriptGUITexture.cpp

@@ -27,7 +27,7 @@ namespace BansheeEngine
 
 	void ScriptGUITexture::initMetaData()
 	{
-		metaData = ScriptMeta("MBansheeEngine", "BansheeEngine", "GUITexture", &ScriptGUITexture::initRuntimeData);
+		metaData = ScriptMeta(BansheeEngineAssemblyName, "BansheeEngine", "GUITexture", &ScriptGUITexture::initRuntimeData);
 
 		MonoManager::registerScriptType(&metaData);
 	}

+ 1 - 1
SBansheeEngine/Source/BsScriptGUIToggle.cpp

@@ -34,7 +34,7 @@ namespace BansheeEngine
 
 	void ScriptGUIToggle::initMetaData()
 	{
-		metaData = ScriptMeta("MBansheeEngine", "BansheeEngine", "GUIToggle", &ScriptGUIToggle::initRuntimeData);
+		metaData = ScriptMeta(BansheeEngineAssemblyName, "BansheeEngine", "GUIToggle", &ScriptGUIToggle::initRuntimeData);
 
 		MonoManager::registerScriptType(&metaData);
 	}

+ 1 - 1
SBansheeEngine/Source/BsScriptGUIToggleGroup.cpp

@@ -19,7 +19,7 @@ namespace BansheeEngine
 
 	void ScriptGUIToggleGroup::initMetaData()
 	{
-		metaData = ScriptMeta("MBansheeEngine", "BansheeEngine", "GUIToggleGroup", &ScriptGUIToggleGroup::initRuntimeData);
+		metaData = ScriptMeta(BansheeEngineAssemblyName, "BansheeEngine", "GUIToggleGroup", &ScriptGUIToggleGroup::initRuntimeData);
 
 		MonoManager::registerScriptType(&metaData);
 	}

+ 1 - 1
SBansheeEngine/Source/BsScriptHString.cpp

@@ -15,7 +15,7 @@ namespace BansheeEngine
 
 	void ScriptHString::initMetaData()
 	{
-		metaData = ScriptMeta("MBansheeEngine", "BansheeEngine", "LocString", &ScriptHString::initRuntimeData);
+		metaData = ScriptMeta(BansheeEngineAssemblyName, "BansheeEngine", "LocString", &ScriptHString::initRuntimeData);
 
 		MonoManager::registerScriptType(&metaData);
 	}

+ 6 - 1
SBansheeEngine/Source/BsScriptSpriteTexture.cpp

@@ -17,7 +17,7 @@ namespace BansheeEngine
 
 	void ScriptSpriteTexture::initMetaData()
 	{
-		metaData = ScriptMeta("MBansheeEngine", "BansheeEngine", "SpriteTexture", &ScriptSpriteTexture::initRuntimeData);
+		metaData = ScriptMeta(BansheeEngineAssemblyName, "BansheeEngine", "SpriteTexture", &ScriptSpriteTexture::initRuntimeData);
 
 		MonoManager::registerScriptType(&metaData);
 	}
@@ -41,4 +41,9 @@ namespace BansheeEngine
 		nativeInstance->destroyInstance();
 		cm_delete(nativeInstance);
 	}
+
+	void ScriptSpriteTexture::setNativeHandle(const HResource& resource) 
+	{ 
+		mTexture = static_resource_cast<Resource>(mTexture); 
+	}
 }

+ 1 - 1
SBansheeEngine/Source/BsScriptStringTable.cpp

@@ -11,7 +11,7 @@ namespace BansheeEngine
 {
 	void ScriptStringTable::initMetaData()
 	{
-		metaData = ScriptMeta("MBansheeEngine", "BansheeEngine", "StringTable", &ScriptStringTable::initRuntimeData);
+		metaData = ScriptMeta(BansheeEngineAssemblyName, "BansheeEngine", "StringTable", &ScriptStringTable::initRuntimeData);
 
 		MonoManager::registerScriptType(&metaData);
 	}

+ 6 - 1
SBansheeEngine/Source/BsScriptTexture2D.cpp

@@ -19,7 +19,7 @@ namespace BansheeEngine
 
 	void ScriptTexture2D::initMetaData()
 	{
-		metaData = ScriptMeta("MBansheeEngine", "BansheeEngine", "Texture2D", &ScriptTexture2D::initRuntimeData);
+		metaData = ScriptMeta(BansheeEngineAssemblyName, "BansheeEngine", "Texture2D", &ScriptTexture2D::initRuntimeData);
 
 		MonoManager::registerScriptType(&metaData);
 	}
@@ -62,4 +62,9 @@ namespace BansheeEngine
 		nativeInstance->destroyInstance();
 		cm_delete(nativeInstance);
 	}
+
+	void ScriptTexture2D::setNativeHandle(const HResource& resource) 
+	{ 
+		mTexture = static_resource_cast<Resource>(mTexture); 
+	}
 }