فهرست منبع

C#: Some important Array and Dictionary interface changes

Array now implements IList instead of IList<object, object>.
Dictionary now implements IDictionary instead of IDictionary<object, object>.
Ignacio Etcheverry 6 سال پیش
والد
کامیت
92b02cb027

+ 78 - 102
modules/mono/glue/Managed/Files/Array.cs

@@ -28,7 +28,7 @@ namespace Godot.Collections
         }
     }
 
-    public class Array : IList<object>, ICollection<object>, IEnumerable<object>, IDisposable
+    public class Array : IList, IDisposable
     {
         ArraySafeHandle safeHandle;
         bool disposed = false;
@@ -56,6 +56,13 @@ namespace Godot.Collections
             return safeHandle.DangerousGetHandle();
         }
 
+        public Error Resize(int newSize)
+        {
+            return godot_icall_Array_Resize(GetPtr(), newSize);
+        }
+
+        // IDisposable
+
         public void Dispose()
         {
             if (disposed)
@@ -70,62 +77,55 @@ namespace Godot.Collections
             disposed = true;
         }
 
+        // IList
+
+        public bool IsReadOnly => false;
+
+        public bool IsFixedSize => false;
+
         public object this[int index]
         {
-            get
-            {
-                return godot_icall_Array_At(GetPtr(), index);
-            }
-            set
-            {
-                godot_icall_Array_SetAt(GetPtr(), index, value);
-            }
+            get => godot_icall_Array_At(GetPtr(), index);
+            set => godot_icall_Array_SetAt(GetPtr(), index, value);
         }
 
-        public int Count
-        {
-            get
-            {
-                return godot_icall_Array_Count(GetPtr());
-            }
-        }
+        public int Add(object value) => godot_icall_Array_Add(GetPtr(), value);
 
-        public bool IsReadOnly
-        {
-            get
-            {
-                return false;
-            }
-        }
+        public bool Contains(object value) => godot_icall_Array_Contains(GetPtr(), value);
 
-        public void Add(object item)
-        {
-            godot_icall_Array_Add(GetPtr(), item);
-        }
+        public void Clear() => godot_icall_Array_Clear(GetPtr());
 
-        public void Clear()
-        {
-            godot_icall_Array_Clear(GetPtr());
-        }
+        public int IndexOf(object value) => godot_icall_Array_IndexOf(GetPtr(), value);
 
-        public bool Contains(object item)
-        {
-            return godot_icall_Array_Contains(GetPtr(), item);
-        }
+        public void Insert(int index, object value) => godot_icall_Array_Insert(GetPtr(), index, value);
+
+        public void Remove(object value) => godot_icall_Array_Remove(GetPtr(), value);
+
+        public void RemoveAt(int index) => godot_icall_Array_RemoveAt(GetPtr(), index);
+
+        // ICollection
+
+        public int Count => godot_icall_Array_Count(GetPtr());
+
+        public object SyncRoot => this;
+
+        public bool IsSynchronized => false;
 
-        public void CopyTo(object[] array, int arrayIndex)
+        public void CopyTo(System.Array array, int index)
         {
             if (array == null)
                 throw new ArgumentNullException(nameof(array), "Value cannot be null.");
 
-            if (arrayIndex < 0)
-                throw new ArgumentOutOfRangeException(nameof(arrayIndex), "Number was less than the array's lower bound in the first dimension.");
+            if (index < 0)
+                throw new ArgumentOutOfRangeException(nameof(index), "Number was less than the array's lower bound in the first dimension.");
 
             // Internal call may throw ArgumentException
-            godot_icall_Array_CopyTo(GetPtr(), array, arrayIndex);
+            godot_icall_Array_CopyTo(GetPtr(), array, index);
         }
 
-        public IEnumerator<object> GetEnumerator()
+        // IEnumerable
+
+        public IEnumerator GetEnumerator()
         {
             int count = Count;
 
@@ -135,36 +135,6 @@ namespace Godot.Collections
             }
         }
 
-        public int IndexOf(object item)
-        {
-            return godot_icall_Array_IndexOf(GetPtr(), item);
-        }
-
-        public void Insert(int index, object item)
-        {
-            godot_icall_Array_Insert(GetPtr(), index, item);
-        }
-
-        public bool Remove(object item)
-        {
-            return godot_icall_Array_Remove(GetPtr(), item);
-        }
-
-        public void RemoveAt(int index)
-        {
-            godot_icall_Array_RemoveAt(GetPtr(), index);
-        }
-
-        public Error Resize(int newSize)
-        {
-            return godot_icall_Array_Resize(GetPtr(), newSize);
-        }
-
-        IEnumerator IEnumerable.GetEnumerator()
-        {
-            return GetEnumerator();
-        }
-
         [MethodImpl(MethodImplOptions.InternalCall)]
         internal extern static IntPtr godot_icall_Array_Ctor();
 
@@ -184,7 +154,7 @@ namespace Godot.Collections
         internal extern static int godot_icall_Array_Count(IntPtr ptr);
 
         [MethodImpl(MethodImplOptions.InternalCall)]
-        internal extern static void godot_icall_Array_Add(IntPtr ptr, object item);
+        internal extern static int godot_icall_Array_Add(IntPtr ptr, object item);
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         internal extern static void godot_icall_Array_Clear(IntPtr ptr);
@@ -193,7 +163,7 @@ namespace Godot.Collections
         internal extern static bool godot_icall_Array_Contains(IntPtr ptr, object item);
 
         [MethodImpl(MethodImplOptions.InternalCall)]
-        internal extern static void godot_icall_Array_CopyTo(IntPtr ptr, object[] array, int arrayIndex);
+        internal extern static void godot_icall_Array_CopyTo(IntPtr ptr, System.Array array, int arrayIndex);
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         internal extern static int godot_icall_Array_IndexOf(IntPtr ptr, object item);
@@ -246,11 +216,23 @@ namespace Godot.Collections
             objectArray = new Array(handle);
         }
 
+        internal IntPtr GetPtr()
+        {
+            return objectArray.GetPtr();
+        }
+
         public static explicit operator Array(Array<T> from)
         {
             return from.objectArray;
         }
 
+        public Error Resize(int newSize)
+        {
+            return objectArray.Resize(newSize);
+        }
+
+        // IList<T>
+
         public T this[int index]
         {
             get
@@ -263,6 +245,23 @@ namespace Godot.Collections
             }
         }
 
+        public int IndexOf(T item)
+        {
+            return objectArray.IndexOf(item);
+        }
+
+        public void Insert(int index, T item)
+        {
+            objectArray.Insert(index, item);
+        }
+
+        public void RemoveAt(int index)
+        {
+            objectArray.RemoveAt(index);
+        }
+
+        // ICollection<T>
+
         public int Count
         {
             get
@@ -317,6 +316,13 @@ namespace Godot.Collections
             }
         }
 
+        public bool Remove(T item)
+        {
+            return Array.godot_icall_Array_Remove(GetPtr(), item);
+        }
+
+        // IEnumerable<T>
+
         public IEnumerator<T> GetEnumerator()
         {
             int count = objectArray.Count;
@@ -327,39 +333,9 @@ namespace Godot.Collections
             }
         }
 
-        public int IndexOf(T item)
-        {
-            return objectArray.IndexOf(item);
-        }
-
-        public void Insert(int index, T item)
-        {
-            objectArray.Insert(index, item);
-        }
-
-        public bool Remove(T item)
-        {
-            return objectArray.Remove(item);
-        }
-
-        public void RemoveAt(int index)
-        {
-            objectArray.RemoveAt(index);
-        }
-
-        public Error Resize(int newSize)
-        {
-            return objectArray.Resize(newSize);
-        }
-
         IEnumerator IEnumerable.GetEnumerator()
         {
             return GetEnumerator();
         }
-
-        internal IntPtr GetPtr()
-        {
-            return objectArray.GetPtr();
-        }
     }
 }

+ 117 - 116
modules/mono/glue/Managed/Files/Dictionary.cs

@@ -29,9 +29,7 @@ namespace Godot.Collections
     }
 
     public class Dictionary :
-        IDictionary<object, object>,
-        ICollection<KeyValuePair<object, object>>,
-        IEnumerable<KeyValuePair<object, object>>,
+        IDictionary,
         IDisposable
     {
         DictionarySafeHandle safeHandle;
@@ -74,19 +72,9 @@ namespace Godot.Collections
             disposed = true;
         }
 
-        public object this[object key]
-        {
-            get
-            {
-                return godot_icall_Dictionary_GetValue(GetPtr(), key);
-            }
-            set
-            {
-                godot_icall_Dictionary_SetValue(GetPtr(), key, value);
-            }
-        }
+        // IDictionary
 
-        public ICollection<object> Keys
+        public ICollection Keys
         {
             get
             {
@@ -95,7 +83,7 @@ namespace Godot.Collections
             }
         }
 
-        public ICollection<object> Values
+        public ICollection Values
         {
             get
             {
@@ -104,97 +92,97 @@ namespace Godot.Collections
             }
         }
 
-        public int Count
-        {
-            get
-            {
-                return godot_icall_Dictionary_Count(GetPtr());
-            }
-        }
+        public bool IsFixedSize => false;
 
-        public bool IsReadOnly
-        {
-            get
-            {
-                return false;
-            }
-        }
+        public bool IsReadOnly => false;
 
-        public void Add(object key, object value)
+        public object this[object key]
         {
-            godot_icall_Dictionary_Add(GetPtr(), key, value);
+            get => godot_icall_Dictionary_GetValue(GetPtr(), key);
+            set => godot_icall_Dictionary_SetValue(GetPtr(), key, value);
         }
 
-        public void Add(KeyValuePair<object, object> item)
-        {
-            Add(item.Key, item.Value);
-        }
+        public void Add(object key, object value) => godot_icall_Dictionary_Add(GetPtr(), key, value);
 
-        public void Clear()
-        {
-            godot_icall_Dictionary_Clear(GetPtr());
-        }
+        public void Clear() => godot_icall_Dictionary_Clear(GetPtr());
 
-        public bool Contains(KeyValuePair<object, object> item)
-        {
-            return godot_icall_Dictionary_Contains(GetPtr(), item.Key, item.Value);
-        }
+        public bool Contains(object key) => godot_icall_Dictionary_ContainsKey(GetPtr(), key);
 
-        public bool ContainsKey(object key)
-        {
-            return godot_icall_Dictionary_ContainsKey(GetPtr(), key);
-        }
+        public IDictionaryEnumerator GetEnumerator() => new DictionaryEnumerator(this);
+
+        public void Remove(object key) => godot_icall_Dictionary_RemoveKey(GetPtr(), key);
+
+        // ICollection
+
+        public object SyncRoot => this;
 
-        public void CopyTo(KeyValuePair<object, object>[] array, int arrayIndex)
+        public bool IsSynchronized => false;
+
+        public int Count => godot_icall_Dictionary_Count(GetPtr());
+
+        public void CopyTo(System.Array array, int index)
         {
-            // TODO 3 internal calls, can reduce to 1
+            // TODO Can be done with single internal call
+
+            if (array == null)
+                throw new ArgumentNullException(nameof(array), "Value cannot be null.");
+
+            if (index < 0)
+                throw new ArgumentOutOfRangeException(nameof(index), "Number was less than the array's lower bound in the first dimension.");
+
             Array keys = (Array)Keys;
             Array values = (Array)Values;
             int count = Count;
 
+            if (array.Length < (index + count))
+                throw new ArgumentException("Destination array was not long enough. Check destIndex and length, and the array's lower bounds.");
+
             for (int i = 0; i < count; i++)
             {
-                // TODO 2 internal calls, can reduce to 1
-                array[arrayIndex] = new KeyValuePair<object, object>(keys[i], values[i]);
-                arrayIndex++;
+                array.SetValue(new DictionaryEntry(keys[i], values[i]), index);
+                index++;
             }
         }
 
-        public IEnumerator<KeyValuePair<object, object>> GetEnumerator()
+        // IEnumerable
+
+        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
+
+        private class DictionaryEnumerator : IDictionaryEnumerator
         {
-            // TODO 3 internal calls, can reduce to 1
-            Array keys = (Array)Keys;
-            Array values = (Array)Values;
-            int count = Count;
+            Array keys;
+            Array values;
+            int count;
+            int index = -1;
 
-            for (int i = 0; i < count; i++)
+            public DictionaryEnumerator(Dictionary dictionary)
             {
-                // TODO 2 internal calls, can reduce to 1
-                yield return new KeyValuePair<object, object>(keys[i], values[i]);
+                // TODO 3 internal calls, can reduce to 1
+                keys = (Array)dictionary.Keys;
+                values = (Array)dictionary.Values;
+                count = dictionary.Count;
             }
-        }
 
-        public bool Remove(object key)
-        {
-            return godot_icall_Dictionary_RemoveKey(GetPtr(), key);
-        }
+            public object Current => Entry;
 
-        public bool Remove(KeyValuePair<object, object> item)
-        {
-            return godot_icall_Dictionary_Remove(GetPtr(), item.Key, item.Value);
-        }
+            public DictionaryEntry Entry =>
+                // TODO 2 internal calls, can reduce to 1
+                new DictionaryEntry(keys[index], values[index]);
 
-        public bool TryGetValue(object key, out object value)
-        {
-            object retValue;
-            bool found = godot_icall_Dictionary_TryGetValue(GetPtr(), key, out retValue);
-            value = found ? retValue : default(object);
-            return found;
-        }
+            public object Key => Entry.Key;
 
-        IEnumerator IEnumerable.GetEnumerator()
-        {
-            return GetEnumerator();
+            public object Value => Entry.Value;
+
+            public bool MoveNext()
+            {
+                index++;
+                return index < count;
+            }
+
+            public void Reset()
+            {
+                index = -1;
+            }
         }
 
         [MethodImpl(MethodImplOptions.InternalCall)]
@@ -250,9 +238,7 @@ namespace Godot.Collections
     }
 
     public class Dictionary<TKey, TValue> :
-        IDictionary<TKey, TValue>,
-        ICollection<KeyValuePair<TKey, TValue>>,
-        IEnumerable<KeyValuePair<TKey, TValue>>
+        IDictionary<TKey, TValue>
     {
         Dictionary objectDict;
 
@@ -289,6 +275,13 @@ namespace Godot.Collections
             return from.objectDict;
         }
 
+        internal IntPtr GetPtr()
+        {
+            return objectDict.GetPtr();
+        }
+
+        // IDictionary<TKey, TValue>
+
         public TValue this[TKey key]
         {
             get
@@ -319,6 +312,31 @@ namespace Godot.Collections
             }
         }
 
+        public void Add(TKey key, TValue value)
+        {
+            objectDict.Add(key, value);
+        }
+
+        public bool ContainsKey(TKey key)
+        {
+            return objectDict.Contains(key);
+        }
+
+        public bool Remove(TKey key)
+        {
+            return Dictionary.godot_icall_Dictionary_RemoveKey(GetPtr(), key);
+        }
+
+        public bool TryGetValue(TKey key, out TValue value)
+        {
+            object retValue;
+            bool found = Dictionary.godot_icall_Dictionary_TryGetValue_Generic(GetPtr(), key, out retValue, valTypeEncoding, valTypeClass);
+            value = found ? (TValue)retValue : default(TValue);
+            return found;
+        }
+
+        // ICollection<KeyValuePair<TKey, TValue>>
+
         public int Count
         {
             get
@@ -335,11 +353,6 @@ namespace Godot.Collections
             }
         }
 
-        public void Add(TKey key, TValue value)
-        {
-            objectDict.Add(key, value);
-        }
-
         public void Add(KeyValuePair<TKey, TValue> item)
         {
             objectDict.Add(item.Key, item.Value);
@@ -355,18 +368,22 @@ namespace Godot.Collections
             return objectDict.Contains(new KeyValuePair<object, object>(item.Key, item.Value));
         }
 
-        public bool ContainsKey(TKey key)
-        {
-            return objectDict.ContainsKey(key);
-        }
-
         public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
         {
+            if (array == null)
+                throw new ArgumentNullException(nameof(array), "Value cannot be null.");
+
+            if (arrayIndex < 0)
+                throw new ArgumentOutOfRangeException(nameof(arrayIndex), "Number was less than the array's lower bound in the first dimension.");
+
             // TODO 3 internal calls, can reduce to 1
             Array<TKey> keys = (Array<TKey>)Keys;
             Array<TValue> values = (Array<TValue>)Values;
             int count = Count;
 
+            if (array.Length < (arrayIndex + count))
+                throw new ArgumentException("Destination array was not long enough. Check destIndex and length, and the array's lower bounds.");
+
             for (int i = 0; i < count; i++)
             {
                 // TODO 2 internal calls, can reduce to 1
@@ -375,6 +392,13 @@ namespace Godot.Collections
             }
         }
 
+        public bool Remove(KeyValuePair<TKey, TValue> item)
+        {
+            return Dictionary.godot_icall_Dictionary_Remove(GetPtr(), item.Key, item.Value); ;
+        }
+
+        // IEnumerable<KeyValuePair<TKey, TValue>>
+
         public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
         {
             // TODO 3 internal calls, can reduce to 1
@@ -389,32 +413,9 @@ namespace Godot.Collections
             }
         }
 
-        public bool Remove(TKey key)
-        {
-            return objectDict.Remove(key);
-        }
-
-        public bool Remove(KeyValuePair<TKey, TValue> item)
-        {
-            return objectDict.Remove(new KeyValuePair<object, object>(item.Key, item.Value));
-        }
-
-        public bool TryGetValue(TKey key, out TValue value)
-        {
-            object retValue;
-            bool found = Dictionary.godot_icall_Dictionary_TryGetValue_Generic(GetPtr(), key, out retValue, valTypeEncoding, valTypeClass);
-            value = found ? (TValue)retValue : default(TValue);
-            return found;
-        }
-
         IEnumerator IEnumerable.GetEnumerator()
         {
             return GetEnumerator();
         }
-
-        internal IntPtr GetPtr()
-        {
-            return objectDict.GetPtr();
-        }
     }
 }

+ 11 - 0
modules/mono/glue/Managed/IgnoredFiles/Variant.cs

@@ -0,0 +1,11 @@
+
+namespace Godot
+{
+    public static class Variant
+    {
+        public enum Type
+        {
+
+        }
+    }
+}

+ 2 - 1
modules/mono/glue/collections_glue.cpp

@@ -73,8 +73,9 @@ int godot_icall_Array_Count(Array *ptr) {
 	return ptr->size();
 }
 
-void godot_icall_Array_Add(Array *ptr, MonoObject *item) {
+int godot_icall_Array_Add(Array *ptr, MonoObject *item) {
 	ptr->append(GDMonoMarshal::mono_object_to_variant(item));
+	return ptr->size();
 }
 
 void godot_icall_Array_Clear(Array *ptr) {

+ 1 - 1
modules/mono/glue/collections_glue.h

@@ -51,7 +51,7 @@ void godot_icall_Array_SetAt(Array *ptr, int index, MonoObject *value);
 
 int godot_icall_Array_Count(Array *ptr);
 
-void godot_icall_Array_Add(Array *ptr, MonoObject *item);
+int godot_icall_Array_Add(Array *ptr, MonoObject *item);
 
 void godot_icall_Array_Clear(Array *ptr);