Explorar el Código

Check in before yet another refactor

Marko Pintera hace 11 años
padre
commit
3240d3f89b

+ 35 - 24
Inspector.txt

@@ -1,10 +1,28 @@
-Needed controls:
-Array field/List field/Dictionary field
-Matrix3 field
-Matrix4 field
-GameObject field
-Resource field
--------------
+
+My SerializableArray/list/dictionary approach is BROKEN:
+ - I cannot determine their type just from an object, since object may be null. I need their parent field/collection type to do that.
+
+SerializableField
+ - Normal GetValue/SetValue 
+ - But also GetSerializableArray, GetSerializableList, GetSerializableDictionary
+
+SerializableArray
+ - Also has GetSerializableArray, GetSerializableList, GetSerializableDictionary
+
+ ------------------------------------------------
+
+My Inspector approach is BROKEN:
+ - Number of array/list/dictionary elements in a field may dynamically change. How do I handle that? Current system just keeps the static fields.
+
+Rebuilding gui N times per second is OUT OF THE QUESTION
+ - My GUI system isn't built for it
+ - e.g. If I'm currently focusing on and element or writing in an input box refreshing the GUI would break it
+ - Instead I must leave it to the user to track modifications, simply save old value and compare with new, and if it changed update the UI.
+  - I should potentially provide the user with overridable InspectableField. One that will automatically call CreateGUI when field value changes,
+    and user can then override it if he wants to draw custom controls. 
+
+-----------------------------------------------
+LESS IMPORTANT
 
 A way to close a window & destroy a GUI panel!
  - Will likely need to refactor ScriptEditorWindow as currently it performs initialization
@@ -16,11 +34,15 @@ A way to close a window & destroy a GUI panel!
 
 Ensure that setting depth for GUIArea works properly. It's not properly implemented yet.
 
-Test setting/getting field values using my SerializableObject/SerializableField interface
- - I'm guessing it won't work because of unboxing & value type issues. I might want to consider somehow 
-   refactoring managedSerializableField so that I can re-use it for setting/getting field values in general purpose case.
+Missing C++ field types:
+ - Array field/List field/Dictionary field
+ - Matrix3 field
+ - Matrix4 field
+ - GameObject field
+ - Resource field
 
 UndoRedo should work on URI type basis where it remembers object ID, and path across its fields to the field that was modified
+ - This way it wont keep an unnecessary reference to object
  - SerializableField should probably be the type responsible for handling the URI
  - Will I need two different URI types for resources and scene objects?
    - Probably, resources don't need hierarchies, but I think I should ignore resources for now as I'm not sure they will be using Inspectable system
@@ -38,22 +60,11 @@ Things to think about/do:
  - Modify C++ Editor fields so that calling setValue doesn't update the visual value until focus is lost
   - When user is currently writing in an input box I don't want refresh to overwrite that value.
  - Expand/Collapse needs to work for both Components and their sub-objects (Structs, Arrays, etc.)
- - Support for initializing SerializableObject/SerializableArray (and their fields, together with getters/setters)
  - How do I refresh currently visible inspector fields.
    - Also how will this be done with custom inspectors, when I might not use InspectableObject
- - Currently I do not have a way to creating an Inspector field for just a single field, only for an entire object
- - Finally once all other things are done implement support for multi-rank arrays, lists and dictionaries
-
-How will UndoRedo keep a reference to the object? 
- - What if the object gets destroyed? 
- - Keeping a reference will prevent the object from being destroyed.
-   - Although heavy stuff is destroyed manually via Destroy anyway
-
-STUBBED IN METHODS:
-SerializableObject
-SerializableArray
-SerializableField
-
+ - Multi-rank arrays aren't properly supported in InspectableObject
+ - Dictionaries aren't properly supported in InspectableObject
+ - Need a way to add entries to arrays/lists/dictionaries (possibly also clone and delete entries) from inspector
  ----------------------
 
  Non-inspector:

+ 125 - 51
MBansheeEditor/Inspector/InspectableObject.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Collections;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
@@ -8,69 +9,44 @@ namespace BansheeEditor
 {
     public sealed class InspectableObject
     {
+        private delegate object Getter();
+        private delegate void Setter(object value);
+
         private const int IndentAmount = 15;
 
-        private SerializableObject serializableObject;
-        private SerializableArray serializableArray;
+        private object referencedObject;
 
-        public InspectableObject(SerializableObject serializableObject)
+        public InspectableObject(object obj)
         {
-            this.serializableObject = serializableObject;
+            referencedObject = obj;
         }
 
-        public InspectableObject(SerializableArray serializableArray)
+        public void CreateGUI(GUILayout layout, SerializableField field)
         {
-            this.serializableArray = serializableArray;
-        }
-
-        public void CreateGUI(GUILayout layout)
-        {
-            if (serializableObject != null)
+            if (IsTypePrimitive(field.Type))
             {
-                foreach (var field in serializableObject.fields)
-                {
-                    CreateGUI(layout, field.Name, field.Type, field.GetValue());
-                }
+                Getter getter = () => field.GetValue<object>();
+                Setter setter = (object value) => field.SetValue(value);
+
+                CreatePrimitiveField(layout, name, type, getter, setter);
             }
-            else if (serializableArray != null)
+            else
             {
-                // TODO - Handle multi-rank arrays
-
-                int length = serializableArray.GetDimension(0);
-                for (int i = 0; i < length; i++)
-                {
-                    CreateGUI(layout, i.ToString(), serializableArray.ElementType, serializableArray.GetValue(i));
-                }
+                CreateComplexField(layout, name, type, field.GetValue<object>());
             }
-
-            // TODO - Handle List & Dictionary
         }
 
-        private void CreateGUI(GUILayout layout, string name, SerializableField.FieldType type, SerializableValue value)
+        public void CreateGUI(GUILayout layout)
         {
-            switch (type)
-            {
-                case SerializableField.FieldType.Object:
-                    CreateComplexField(layout, name, type, value);
-                    break;
-                case SerializableField.FieldType.Array:
-                    goto case SerializableField.FieldType.Object;
-                case SerializableField.FieldType.List:
-                    goto case SerializableField.FieldType.Object;
-                case SerializableField.FieldType.Dictionary:
-                    goto case SerializableField.FieldType.Object;
-                default:
-                    CreatePrimitiveField(layout, name, type, value);
-                    break;
-            }
+            CreateComplexTypeChildren(layout, SerializableField.FieldType.Object, referencedObject);
         }
 
-        private void CreatePrimitiveField(GUILayout layout, string name, SerializableField.FieldType type, SerializableValue value)
+        private void CreatePrimitiveField(GUILayout layout, string name, SerializableField.FieldType type, Getter getter, Setter setter)
         {
             layout.AddElement(new GUILabel(name)); // TODO - Use an IntEditorField, or others for other types
         }
 
-        private void CreateComplexField(GUILayout layout, string name, SerializableField.FieldType type, SerializableValue value)
+        private void CreateComplexField(GUILayout layout, string name, SerializableField.FieldType type, object obj)
         {
             layout.AddElement(new GUILabel(name)); // TODO - Add foldout and hook up its callbacks
 
@@ -79,31 +55,129 @@ namespace BansheeEditor
 
             GUILayout childContent = childLayout.AddLayoutY();
 
+            CreateComplexTypeChildren(childContent, type, obj);
+        }
+
+        private void CreateComplexTypeChildren(GUILayout layout, SerializableField.FieldType type, object obj)
+        {
+            if (obj == null)
+                return;
+
             switch (type)
             {
                 case SerializableField.FieldType.Object:
                     {
-                        SerializableObject childObj = new SerializableObject(value.GetValue<object>());
-                        InspectableObject childInspectable = new InspectableObject(childObj);
-                        childInspectable.CreateGUI(childContent);
+                        SerializableObject serializableObject = new SerializableObject(obj);
+
+                        foreach (var field in serializableObject.fields)
+                        {
+                            if (!field.Inspectable)
+                                continue;
+
+                            CreateGUI(layout, field);
+                        }
                     }
                     break;
                 case SerializableField.FieldType.Array:
                     {
-                        SerializableArray childArr = new SerializableArray(value.GetValue<object>());
-                        InspectableObject childInspectable = new InspectableObject(childArr);
-                        childInspectable.CreateGUI(childContent);
+                        SerializableArrayInfo arrayInfo = new SerializableArrayInfo(obj);
+
+                        Array array = (Array)obj;
+                        if (array.Rank > 1) // TODO - I didn't bother implementing multi-rank arrays yet but it is a simple job
+                            throw new NotImplementedException();
+
+                        if (IsTypePrimitive(arrayInfo.ElementType))
+                        {
+                            for (int i = 0; i < array.GetLength(0); i++)
+                            {
+                                int curIdx = i; // To avoid lambda passing by reference
+
+                                Getter getter = () => array.GetValue(curIdx);
+                                Setter setter = (object value) => array.SetValue(value, curIdx);
+
+                                CreatePrimitiveField(layout, i + ".", arrayInfo.ElementType, getter, setter);
+                            }
+                        }
+                        else
+                        {
+                            for (int i = 0; i < array.GetLength(0); i++)
+                            {
+                                CreateComplexField(layout, i + ".", arrayInfo.ElementType, array.GetValue(i));
+                            }
+                        }
                     }
                     break;
                 case SerializableField.FieldType.List:
-                    // TODO
+                    {
+                        SerializableListInfo listInfo = new SerializableListInfo(obj);
+                        IList list = (IList)obj;
+
+                        if (IsTypePrimitive(listInfo.ElementType))
+                        {
+                            for (int i = 0; i < list.Count; i++)
+                            {
+                                int curIdx = i; // To avoid lambda passing by reference
+
+                                Getter getter = () => list.Item[curIdx];
+                                Setter setter = (object value) => list.Item[curIdx] = value;
+
+                                CreatePrimitiveField(layout, i + ".", listInfo.ElementType, getter, setter);
+                            }
+                        }
+                        else
+                        {
+                            for (int i = 0; i < array.GetLength(0); i++)
+                            {
+                                CreateComplexField(layout, i + ".", listInfo.ElementType, list.Item[i]);
+                            }
+                        }
+                    }
                     break;
                 case SerializableField.FieldType.Dictionary:
-                    // TODO
+                    {
+                        SerializableDictionaryInfo dictionaryInfo = new SerializableDictionaryInfo(obj);
+                        IDictionary dictionary = (IDictionary)obj;
+
+                        IEnumerator enumerator = dictionary.Keys.GetEnumerator();
+                        int curIdx = 0;
+                        while (enumerator.MoveNext())
+                        {
+                            if (IsTypePrimitive(dictionaryInfo.KeyType))
+                            {
+                                Getter getter = () => enumerator.Current;
+                                Setter setter = (object value) => { }; // TODO - No setter!
+
+                                CreatePrimitiveField(layout, curIdx + ".", dictionaryInfo.KeyType, getter, setter);
+                            }
+                            else
+                            {
+                                CreateComplexField(layout, curIdx + ".", dictionaryInfo.KeyType, enumerator.Current);
+                            }
+
+                            curIdx++;
+                        }
+                    }
                     break;
                 default:
                     throw new Exception("Invalid complex field type.");
             }
         }
+
+        private bool IsTypePrimitive(SerializableField.FieldType fieldType)
+        {
+            switch (fieldType)
+            {
+                case SerializableField.FieldType.Object:
+                    return false;
+                case SerializableField.FieldType.Array:
+                    return false;
+                case SerializableField.FieldType.List:
+                    return false;
+                case SerializableField.FieldType.Dictionary:
+                    return false;
+            }
+
+            return true;
+        }
     }
 }

+ 3 - 4
MBansheeEngine/MBansheeEngine.csproj

@@ -84,12 +84,11 @@
     <Compile Include="Resource.cs" />
     <Compile Include="SceneObject.cs" />
     <Compile Include="ScriptObject.cs" />
-    <Compile Include="SerializableArray.cs" />
-    <Compile Include="SerializableDictionary.cs" />
+    <Compile Include="SerializableArrayInfo.cs" />
+    <Compile Include="SerializableDictionaryInfo.cs" />
     <Compile Include="SerializableField.cs" />
-    <Compile Include="SerializableList.cs" />
+    <Compile Include="SerializableListInfo.cs" />
     <Compile Include="SerializableObject.cs" />
-    <Compile Include="SerializableValue.cs" />
     <Compile Include="SerializeObject.cs" />
     <Compile Include="SerializeField.cs" />
     <Compile Include="SpriteTexture.cs" />

+ 7 - 9
MBansheeEngine/Program.cs

@@ -116,23 +116,21 @@ namespace BansheeEngine
                 Debug.Log(i + ". " + obj.fields[i].Name + " - " + obj.fields[i].Type.ToString());
             }
 
-            SerializableValue val = obj.fields[0].GetValue();
-            Debug.Log("Old value: " + val.GetValue<int>());
-            val.SetValue<int>(33);
-            Debug.Log("New value: " + val.GetValue<int>());
 
-            SerializableValue val2 = obj.fields[2].GetValue();
+            Debug.Log("Old value: " + obj.fields[0].GetValue<int>());
+            val.SetValue<int>(33);
+            Debug.Log("New value: " + obj.fields[0].GetValue<int>());
 
-            Debug.Log("Old value: " + (val2.GetValue<DbgSerzCls>() == null));
+            Debug.Log("Old value: " + (obj.fields[2].GetValue<DbgSerzCls>() == null));
 
             DbgSerzCls child = new DbgSerzCls();
             child.anotherValue2 = "ass";
-            val2.SetValue<DbgSerzCls>(child);
+            obj.fields[2].SetValue<DbgSerzCls>(child);
 
-            if (val2.GetValue<DbgSerzCls>() == null)
+            if (obj.fields[2].GetValue<DbgSerzCls>() == null)
                 Debug.Log("New value: null");
             else
-                Debug.Log("New value: " + val2.GetValue<DbgSerzCls>().anotherValue2);
+                Debug.Log("New value: " + obj.fields[2].GetValue<DbgSerzCls>().anotherValue2);
         }
 
         [MethodImpl(MethodImplOptions.InternalCall)]

+ 0 - 79
MBansheeEngine/SerializableArray.cs

@@ -1,79 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.CompilerServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace BansheeEngine
-{
-    public sealed class SerializableArray : ScriptObject
-    {
-        private object referencedObject;
-        private SerializableField.FieldType elementType;
-        private Type internalElementType;
-        private int[] dimensions;
-
-        public SerializableArray(object obj)
-        {
-            Internal_CreateInstance(this, obj);
-
-            referencedObject = obj;
-        }
-
-        public int GetDimension(int rank)
-        {
-            return dimensions[rank];
-        }
-
-        public SerializableField.FieldType ElementType
-        {
-            get { return elementType; }
-        }
-
-        public int Rank
-        {
-            get { return rank;  }
-        }
-
-        public T GetValue<T>(params int[] indexes)
-        {
-            if (typeof(T) != internalElementType)
-                throw new Exception("Attempted to retrieve a serializable value using an invalid type. Provided type: " + typeof(T) + ". Needed type: " + internalElementType);
-
-            return (T)Internal_GetValue(mCachedPtr, ArrayIndexesToId(indexes));
-        }
-
-        public void SetValue<T>(T value, params int[] indexes)
-        {
-            if (typeof(T) != internalElementType)
-                throw new Exception("Attempted to set a serializable value using an invalid type. Provided type: " + typeof(T) + ". Needed type: " + internalElementType);
-
-            Internal_SetValue(mCachedPtr, ArrayIndexesToId(indexes), value);
-        }
-
-        private int ArrayIndexesToId(params int[] indexes)
-        {
-            int index = 0;
-            int prevDimensionSize = 1;
-
-            for (int i = dimensions.Length - 1; i >= 0; i--)
-            {
-                index += indexes[i] * prevDimensionSize;
-
-                prevDimensionSize *= dimensions[i];
-            }
-
-            return index;
-        }
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_CreateInstance(SerializableArray instance, object obj);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_SetValue(IntPtr nativeInstance, int elementId, object value);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern object Internal_GetValue(IntPtr nativeInstance, int elementId);
-    }
-}

+ 0 - 11
MBansheeEngine/SerializableDictionary.cs

@@ -1,11 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace BansheeEngine
-{
-    class SerializableDictionary
-    {
-    }
-}

+ 28 - 0
MBansheeEngine/SerializableDictionaryInfo.cs

@@ -0,0 +1,28 @@
+using System.Runtime.CompilerServices;
+
+namespace BansheeEngine
+{
+    public sealed class SerializableDictionaryInfo : ScriptObject
+    {
+        private SerializableField.FieldType keyType;
+        private SerializableField.FieldType valueType;
+
+        public SerializableField.FieldType KeyType
+        {
+            get { return keyType; }
+        }
+
+        public SerializableField.FieldType ValueType
+        {
+            get { return valueType; }
+        }
+
+        public SerializableDictionaryInfo(object obj)
+        {
+            Internal_CreateInstance(this, obj);
+        }
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_CreateInstance(SerializableDictionaryInfo instance, object obj);
+    }
+}

+ 40 - 8
MBansheeEngine/SerializableField.cs

@@ -62,14 +62,6 @@ namespace BansheeEngine
             get { return (flags & 0x01) != 0; } // Flags as defined in native code in BsManagedSerializableObjectInfo.h
         }
 
-        public SerializableValue GetValue()
-        {
-            SerializableValue.Getter getValue = () => Internal_GetValue(mCachedPtr, parent.referencedObject);
-            SerializableValue.Setter setValue = (object value) => Internal_SetValue(mCachedPtr, parent.referencedObject, value);
-
-            return new SerializableValue(internalType, getValue, setValue);
-        }
-
         private static FieldType DetermineFieldType(Type internalType)
         {
             if (!internalType.IsArray)
@@ -135,6 +127,46 @@ namespace BansheeEngine
             return FieldType.Array;
         }
 
+        public T GetValue<T>()
+        {
+            if (!typeof(T).IsAssignableFrom(internalType))
+                throw new Exception("Attempted to retrieve a serializable value using an invalid type. Provided type: " + typeof(T) + ". Needed type: " + internalType);
+
+            return (T)Internal_GetValue(mCachedPtr, parent.referencedObject);
+        }
+
+        public void SetValue<T>(T value)
+        {
+            if (!typeof(T).IsAssignableFrom(internalType))
+                throw new Exception("Attempted to set a serializable value using an invalid type. Provided type: " + typeof(T) + ". Needed type: " + internalType);
+
+            Internal_SetValue(mCachedPtr, parent.referencedObject, value);
+        }
+
+        public SerializableArrayInfo GetSerializableArrayInfo()
+        {
+            if (type != FieldType.Array)
+                throw new Exception("Attempting to retrieve array information from a field that doesn't contain an array.");
+
+            return new SerializableArrayInfo(GetValue<object>());
+        }
+
+        public SerializableListInfo GetSerializableListInfo()
+        {
+            if (type != FieldType.List)
+                throw new Exception("Attempting to retrieve array information from a field that doesn't contain an array.");
+
+            return new SerializableListInfo(GetValue<object>());
+        }
+
+        public SerializableDictionaryInfo GetSerializableDictionaryInfo()
+        {
+            if (type != FieldType.Dictionary)
+                throw new Exception("Attempting to retrieve array information from a field that doesn't contain an array.");
+
+            return new SerializableDictionaryInfo(GetValue<object>());
+        }
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern object Internal_GetValue(IntPtr nativeInstance, object instance);
 

+ 0 - 79
MBansheeEngine/SerializableList.cs

@@ -1,79 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.CompilerServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace BansheeEngine
-{
-    public sealed class SerializableList : ScriptObject
-    {
-        private object referencedObject;
-        private SerializableField.FieldType elementType;
-        private Type internalElementType;
-        private int[] dimensions;
-
-        public SerializableArray(object obj)
-        {
-            Internal_CreateInstance(this, obj);
-
-            referencedObject = obj;
-        }
-
-        public int GetDimension(int rank)
-        {
-            return dimensions[rank];
-        }
-
-        public SerializableField.FieldType ElementType
-        {
-            get { return elementType; }
-        }
-
-        public int Rank
-        {
-            get { return rank; }
-        }
-
-        public T GetValue<T>(params int[] indexes)
-        {
-            if (typeof(T) != internalElementType)
-                throw new Exception("Attempted to retrieve a serializable value using an invalid type. Provided type: " + typeof(T) + ". Needed type: " + internalElementType);
-
-            return (T)Internal_GetValue(mCachedPtr, ArrayIndexesToId(indexes));
-        }
-
-        public void SetValue<T>(T value, params int[] indexes)
-        {
-            if (typeof(T) != internalElementType)
-                throw new Exception("Attempted to set a serializable value using an invalid type. Provided type: " + typeof(T) + ". Needed type: " + internalElementType);
-
-            Internal_SetValue(mCachedPtr, ArrayIndexesToId(indexes), value);
-        }
-
-        private int ArrayIndexesToId(params int[] indexes)
-        {
-            int index = 0;
-            int prevDimensionSize = 1;
-
-            for (int i = dimensions.Length - 1; i >= 0; i--)
-            {
-                index += indexes[i] * prevDimensionSize;
-
-                prevDimensionSize *= dimensions[i];
-            }
-
-            return index;
-        }
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_CreateInstance(SerializableArray instance, object obj);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_SetValue(IntPtr nativeInstance, int elementId, object value);
-
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern object Internal_GetValue(IntPtr nativeInstance, int elementId);
-    }
-}

+ 0 - 41
MBansheeEngine/SerializableValue.cs

@@ -1,41 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace BansheeEngine
-{
-    public sealed class SerializableValue
-    {
-        internal delegate void Setter(object value);
-        internal delegate object Getter();
-
-        private Type type;
-        private Setter setter;
-        private Getter getter;
-
-        internal SerializableValue(Type type, Getter getter, Setter setter)
-        {
-            this.type = type;
-            this.getter = getter;
-            this.setter = setter;
-        }
-
-        public T GetValue<T>()
-        {
-            if (typeof (T) != type)
-                throw new Exception("Attempted to retrieve a serializable value using an invalid type. Provided type: " + typeof(T) + ". Needed type: " + type);
-
-            return (T) getter();
-        }
-
-        public void SetValue<T>(T value)
-        {
-            if (typeof(T) != type)
-                throw new Exception("Attempted to set a serializable value using an invalid type. Provided type: " + typeof(T) + ". Needed type: " + type);
-
-            setter(value);
-        }
-    }
-}

+ 2 - 1
SBansheeEngine/Include/BsRuntimeScriptObjects.h

@@ -24,6 +24,8 @@ namespace BansheeEngine
 		MonoClass* getSceneObjectClass() const { return mSceneObjectClass; }
 		MonoClass* getTextureClass() const { return mTextureClass; }
 		MonoClass* getSpriteTextureClass() const { return mSpriteTextureClass; }
+
+		ManagedSerializableTypeInfoPtr determineType(MonoClass* monoClass);
 	private:
 		UnorderedMap<String, std::shared_ptr<ManagedSerializableAssemblyInfo>>::type mAssemblyInfos;
 		bool mBaseTypesInitialized;
@@ -46,6 +48,5 @@ namespace BansheeEngine
 		void clearScriptObjects(const String& assemblyName);
 
 		void initializeBaseTypes();
-		ManagedSerializableTypeInfoPtr determineType(MonoClass* monoClass);
 	};
 }

+ 24 - 0
SBansheeEngine/Include/BsScriptSerializableArrayInfo.h

@@ -0,0 +1,24 @@
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+#include "BsScriptObject.h"
+
+namespace BansheeEngine
+{
+	class BS_SCR_BE_EXPORT ScriptSerializableArrayInfo : public ScriptObject<ScriptSerializableArrayInfo>
+	{
+	public:
+		static void initMetaData();
+
+	private:
+		static void internal_createInstance(MonoObject* instance, MonoObject* object);
+		static void internal_destroyInstance(ScriptSerializableArrayInfo* nativeInstance);
+
+		static void initRuntimeData();
+
+		ScriptSerializableArrayInfo();
+		~ScriptSerializableArrayInfo() {}
+
+		static MonoField* ElementTypeField;
+	};
+}

+ 0 - 0
SBansheeEngine/Include/BsScriptSerializableDictionaryInfo.h


+ 0 - 0
SBansheeEngine/Include/BsScriptSerializableListInfo.h


+ 6 - 0
SBansheeEngine/SBansheeEngine.vcxproj

@@ -267,7 +267,10 @@
     <ClInclude Include="Include\BsScriptSceneObject.h" />
     <ClInclude Include="Include\BsManagedSerializableObjectInfoRTTI.h" />
     <ClInclude Include="Include\BsManagedSerializableObjectRTTI.h" />
+    <ClInclude Include="Include\BsScriptSerializableArrayInfo.h" />
+    <ClInclude Include="Include\BsScriptSerializableDictionaryInfo.h" />
     <ClInclude Include="Include\BsScriptSerializableField.h" />
+    <ClInclude Include="Include\BsScriptSerializableListInfo.h" />
     <ClInclude Include="Include\BsScriptSerializableObject.h" />
     <ClInclude Include="Include\BsScriptSpriteTexture.h" />
     <ClInclude Include="Include\BsScriptStringTable.h" />
@@ -307,7 +310,10 @@
     <ClCompile Include="Source\BsManagedSerializableList.cpp" />
     <ClCompile Include="Source\BsManagedSerializableObject.cpp" />
     <ClCompile Include="Source\BsManagedSerializableObjectInfo.cpp" />
+    <ClCompile Include="Source\BsScriptSerializableArrayInfo.cpp" />
+    <ClCompile Include="Source\BsScriptSerializableDictionaryInfo.cpp" />
     <ClCompile Include="Source\BsScriptSerializableField.cpp" />
+    <ClCompile Include="Source\BsScriptSerializableListInfo.cpp" />
     <ClCompile Include="Source\BsScriptSerializableObject.cpp" />
     <ClCompile Include="Source\BsScriptSpriteTexture.cpp" />
     <ClCompile Include="Source\BsScriptStringTable.cpp" />

+ 18 - 0
SBansheeEngine/SBansheeEngine.vcxproj.filters

@@ -174,6 +174,15 @@
     <ClInclude Include="Include\BsScriptDebug.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsScriptSerializableArrayInfo.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsScriptSerializableDictionaryInfo.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsScriptSerializableListInfo.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsScriptTexture2D.cpp">
@@ -287,5 +296,14 @@
     <ClCompile Include="Source\BsScriptDebug.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsScriptSerializableArrayInfo.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsScriptSerializableDictionaryInfo.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsScriptSerializableListInfo.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 79 - 0
SBansheeEngine/Source/BsScriptSerializableArrayInfo.cpp

@@ -0,0 +1,79 @@
+#include "BsScriptSerializableArrayInfo.h"
+#include "BsScriptSerializableField.h"
+#include "BsScriptMeta.h"
+#include "BsMonoField.h"
+#include "BsMonoClass.h"
+#include "BsMonoManager.h"
+#include "BsRuntimeScriptObjects.h"
+#include "BsManagedSerializableArray.h"
+#include "BsManagedSerializableObjectInfo.h"
+
+namespace BansheeEngine
+{
+	MonoField* ScriptSerializableArrayInfo::ElementTypeField = nullptr;
+
+	ScriptSerializableArrayInfo::ScriptSerializableArrayInfo()
+	{
+
+	}
+
+	void ScriptSerializableArrayInfo::initMetaData()
+	{
+		metaData = ScriptMeta(BansheeEngineAssemblyName, "BansheeEngine", "SerializableArrayInfo", &ScriptSerializableArrayInfo::initRuntimeData);
+
+		MonoManager::registerScriptType(&metaData);
+	}
+
+	void ScriptSerializableArrayInfo::initRuntimeData()
+	{
+		metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptSerializableArrayInfo::internal_createInstance);
+		metaData.scriptClass->addInternalCall("Internal_DestroyInstance", &ScriptSerializableArrayInfo::internal_destroyInstance);
+
+		ElementTypeField = metaData.scriptClass->getField("elementType");
+	}
+
+	void ScriptSerializableArrayInfo::internal_createInstance(MonoObject* instance, MonoObject* object)
+	{
+		ScriptSerializableArrayInfo* nativeInstance = new (cm_alloc<ScriptSerializableArrayInfo>()) ScriptSerializableArrayInfo();
+		nativeInstance->createInstance(instance);
+
+		metaData.thisPtrField->setValue(instance, &nativeInstance);
+
+
+
+		//MonoManager::instance().findClass(mono_object_get_class(object));
+
+		//RuntimeScriptObjects::instance().determineType()
+
+		//ManagedSerializableArrayPtr serializableArray = ManagedSerializableArray::create(object);
+		//if(serializableObject == nullptr) // Object is not serializable
+		//	return;
+
+		//ManagedSerializableObjectInfoPtr objInfo = serializableObject->getObjectInfo();
+
+		//::MonoClass* serializableFieldClass = ScriptSerializableField::getMetaData()->scriptClass->_getInternalClass();
+
+		//MonoArray* serializableFieldArray = mono_array_new(MonoManager::instance().getDomain(), 
+		//	serializableFieldClass, (UINT32)objInfo->mFields.size());
+
+		//UINT32 i = 0;
+		//for(auto& field : objInfo->mFields)
+		//{
+		//	ScriptSerializableField* serializableField = ScriptSerializableField::create(instance, field.second);
+		//	MonoObject* fieldManagedInstance = serializableField->getManagedInstance();
+
+		//	void* elemAddr = mono_array_addr_with_size(serializableFieldArray, sizeof(MonoObject*), i);
+		//	memcpy(elemAddr, &fieldManagedInstance, sizeof(MonoObject*));
+
+		//	i++;
+		//}
+
+		//FieldsField->setValue(instance, serializableFieldArray);
+	}
+
+	void ScriptSerializableArrayInfo::internal_destroyInstance(ScriptSerializableArrayInfo* nativeInstance)
+	{
+		nativeInstance->~ScriptSerializableArrayInfo();
+		cm_free(nativeInstance);
+	}
+}

+ 0 - 0
SBansheeEngine/Source/BsScriptSerializableDictionaryInfo.cpp


+ 0 - 0
SBansheeEngine/Source/BsScriptSerializableListInfo.cpp