Browse Source

Check in before yet another refactor

Marko Pintera 11 years ago
parent
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!
 A way to close a window & destroy a GUI panel!
  - Will likely need to refactor ScriptEditorWindow as currently it performs initialization
  - 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.
 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
 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
  - SerializableField should probably be the type responsible for handling the URI
  - Will I need two different URI types for resources and scene objects?
  - 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
    - 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
  - 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.
   - 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.)
  - 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.
  - How do I refresh currently visible inspector fields.
    - Also how will this be done with custom inspectors, when I might not use InspectableObject
    - 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:
  Non-inspector:

+ 125 - 51
MBansheeEditor/Inspector/InspectableObject.cs

@@ -1,4 +1,5 @@
 using System;
 using System;
+using System.Collections;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using System.Text;
 using System.Text;
@@ -8,69 +9,44 @@ namespace BansheeEditor
 {
 {
     public sealed class InspectableObject
     public sealed class InspectableObject
     {
     {
+        private delegate object Getter();
+        private delegate void Setter(object value);
+
         private const int IndentAmount = 15;
         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
             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
             layout.AddElement(new GUILabel(name)); // TODO - Add foldout and hook up its callbacks
 
 
@@ -79,31 +55,129 @@ namespace BansheeEditor
 
 
             GUILayout childContent = childLayout.AddLayoutY();
             GUILayout childContent = childLayout.AddLayoutY();
 
 
+            CreateComplexTypeChildren(childContent, type, obj);
+        }
+
+        private void CreateComplexTypeChildren(GUILayout layout, SerializableField.FieldType type, object obj)
+        {
+            if (obj == null)
+                return;
+
             switch (type)
             switch (type)
             {
             {
                 case SerializableField.FieldType.Object:
                 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;
                     break;
                 case SerializableField.FieldType.Array:
                 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;
                     break;
                 case SerializableField.FieldType.List:
                 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;
                     break;
                 case SerializableField.FieldType.Dictionary:
                 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;
                     break;
                 default:
                 default:
                     throw new Exception("Invalid complex field type.");
                     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="Resource.cs" />
     <Compile Include="SceneObject.cs" />
     <Compile Include="SceneObject.cs" />
     <Compile Include="ScriptObject.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="SerializableField.cs" />
-    <Compile Include="SerializableList.cs" />
+    <Compile Include="SerializableListInfo.cs" />
     <Compile Include="SerializableObject.cs" />
     <Compile Include="SerializableObject.cs" />
-    <Compile Include="SerializableValue.cs" />
     <Compile Include="SerializeObject.cs" />
     <Compile Include="SerializeObject.cs" />
     <Compile Include="SerializeField.cs" />
     <Compile Include="SerializeField.cs" />
     <Compile Include="SpriteTexture.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());
                 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();
             DbgSerzCls child = new DbgSerzCls();
             child.anotherValue2 = "ass";
             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");
                 Debug.Log("New value: null");
             else
             else
-                Debug.Log("New value: " + val2.GetValue<DbgSerzCls>().anotherValue2);
+                Debug.Log("New value: " + obj.fields[2].GetValue<DbgSerzCls>().anotherValue2);
         }
         }
 
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         [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
             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)
         private static FieldType DetermineFieldType(Type internalType)
         {
         {
             if (!internalType.IsArray)
             if (!internalType.IsArray)
@@ -135,6 +127,46 @@ namespace BansheeEngine
             return FieldType.Array;
             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)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern object Internal_GetValue(IntPtr nativeInstance, object instance);
         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* getSceneObjectClass() const { return mSceneObjectClass; }
 		MonoClass* getTextureClass() const { return mTextureClass; }
 		MonoClass* getTextureClass() const { return mTextureClass; }
 		MonoClass* getSpriteTextureClass() const { return mSpriteTextureClass; }
 		MonoClass* getSpriteTextureClass() const { return mSpriteTextureClass; }
+
+		ManagedSerializableTypeInfoPtr determineType(MonoClass* monoClass);
 	private:
 	private:
 		UnorderedMap<String, std::shared_ptr<ManagedSerializableAssemblyInfo>>::type mAssemblyInfos;
 		UnorderedMap<String, std::shared_ptr<ManagedSerializableAssemblyInfo>>::type mAssemblyInfos;
 		bool mBaseTypesInitialized;
 		bool mBaseTypesInitialized;
@@ -46,6 +48,5 @@ namespace BansheeEngine
 		void clearScriptObjects(const String& assemblyName);
 		void clearScriptObjects(const String& assemblyName);
 
 
 		void initializeBaseTypes();
 		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\BsScriptSceneObject.h" />
     <ClInclude Include="Include\BsManagedSerializableObjectInfoRTTI.h" />
     <ClInclude Include="Include\BsManagedSerializableObjectInfoRTTI.h" />
     <ClInclude Include="Include\BsManagedSerializableObjectRTTI.h" />
     <ClInclude Include="Include\BsManagedSerializableObjectRTTI.h" />
+    <ClInclude Include="Include\BsScriptSerializableArrayInfo.h" />
+    <ClInclude Include="Include\BsScriptSerializableDictionaryInfo.h" />
     <ClInclude Include="Include\BsScriptSerializableField.h" />
     <ClInclude Include="Include\BsScriptSerializableField.h" />
+    <ClInclude Include="Include\BsScriptSerializableListInfo.h" />
     <ClInclude Include="Include\BsScriptSerializableObject.h" />
     <ClInclude Include="Include\BsScriptSerializableObject.h" />
     <ClInclude Include="Include\BsScriptSpriteTexture.h" />
     <ClInclude Include="Include\BsScriptSpriteTexture.h" />
     <ClInclude Include="Include\BsScriptStringTable.h" />
     <ClInclude Include="Include\BsScriptStringTable.h" />
@@ -307,7 +310,10 @@
     <ClCompile Include="Source\BsManagedSerializableList.cpp" />
     <ClCompile Include="Source\BsManagedSerializableList.cpp" />
     <ClCompile Include="Source\BsManagedSerializableObject.cpp" />
     <ClCompile Include="Source\BsManagedSerializableObject.cpp" />
     <ClCompile Include="Source\BsManagedSerializableObjectInfo.cpp" />
     <ClCompile Include="Source\BsManagedSerializableObjectInfo.cpp" />
+    <ClCompile Include="Source\BsScriptSerializableArrayInfo.cpp" />
+    <ClCompile Include="Source\BsScriptSerializableDictionaryInfo.cpp" />
     <ClCompile Include="Source\BsScriptSerializableField.cpp" />
     <ClCompile Include="Source\BsScriptSerializableField.cpp" />
+    <ClCompile Include="Source\BsScriptSerializableListInfo.cpp" />
     <ClCompile Include="Source\BsScriptSerializableObject.cpp" />
     <ClCompile Include="Source\BsScriptSerializableObject.cpp" />
     <ClCompile Include="Source\BsScriptSpriteTexture.cpp" />
     <ClCompile Include="Source\BsScriptSpriteTexture.cpp" />
     <ClCompile Include="Source\BsScriptStringTable.cpp" />
     <ClCompile Include="Source\BsScriptStringTable.cpp" />

+ 18 - 0
SBansheeEngine/SBansheeEngine.vcxproj.filters

@@ -174,6 +174,15 @@
     <ClInclude Include="Include\BsScriptDebug.h">
     <ClInclude Include="Include\BsScriptDebug.h">
       <Filter>Header Files</Filter>
       <Filter>Header Files</Filter>
     </ClInclude>
     </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>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsScriptTexture2D.cpp">
     <ClCompile Include="Source\BsScriptTexture2D.cpp">
@@ -287,5 +296,14 @@
     <ClCompile Include="Source\BsScriptDebug.cpp">
     <ClCompile Include="Source\BsScriptDebug.cpp">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClCompile>
     </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>
   </ItemGroup>
 </Project>
 </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