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>.
This commit is contained in:
Ignacio Etcheverry 2019-03-04 21:31:04 +01:00
parent 506ff1f065
commit 92b02cb027
5 changed files with 212 additions and 223 deletions

View file

@ -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 CopyTo(object[] array, int arrayIndex)
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(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();
}
}
}

View file

@ -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
public bool IsFixedSize => false;
public bool IsReadOnly => false;
public object this[object key]
{
get
{
return godot_icall_Dictionary_Count(GetPtr());
}
get => godot_icall_Dictionary_GetValue(GetPtr(), key);
set => godot_icall_Dictionary_SetValue(GetPtr(), key, value);
}
public bool IsReadOnly
{
get
{
return false;
}
}
public void Add(object key, object value) => godot_icall_Dictionary_Add(GetPtr(), key, 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 Add(KeyValuePair<object, object> item)
{
Add(item.Key, item.Value);
}
public bool Contains(object key) => godot_icall_Dictionary_ContainsKey(GetPtr(), key);
public void Clear()
{
godot_icall_Dictionary_Clear(GetPtr());
}
public IDictionaryEnumerator GetEnumerator() => new DictionaryEnumerator(this);
public bool Contains(KeyValuePair<object, object> item)
{
return godot_icall_Dictionary_Contains(GetPtr(), item.Key, item.Value);
}
public void Remove(object key) => godot_icall_Dictionary_RemoveKey(GetPtr(), key);
public bool ContainsKey(object key)
{
return godot_icall_Dictionary_ContainsKey(GetPtr(), key);
}
// ICollection
public void CopyTo(KeyValuePair<object, object>[] array, int arrayIndex)
public object SyncRoot => this;
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;
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++;
}
}
public IEnumerator<KeyValuePair<object, object>> GetEnumerator()
{
// TODO 3 internal calls, can reduce to 1
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
yield return new KeyValuePair<object, object>(keys[i], values[i]);
array.SetValue(new DictionaryEntry(keys[i], values[i]), index);
index++;
}
}
public bool Remove(object key)
{
return godot_icall_Dictionary_RemoveKey(GetPtr(), key);
}
// IEnumerable
public bool Remove(KeyValuePair<object, object> item)
{
return godot_icall_Dictionary_Remove(GetPtr(), item.Key, item.Value);
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public bool TryGetValue(object key, out object value)
private class DictionaryEnumerator : IDictionaryEnumerator
{
object retValue;
bool found = godot_icall_Dictionary_TryGetValue(GetPtr(), key, out retValue);
value = found ? retValue : default(object);
return found;
}
Array keys;
Array values;
int count;
int index = -1;
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
public DictionaryEnumerator(Dictionary dictionary)
{
// TODO 3 internal calls, can reduce to 1
keys = (Array)dictionary.Keys;
values = (Array)dictionary.Values;
count = dictionary.Count;
}
public object Current => Entry;
public DictionaryEntry Entry =>
// TODO 2 internal calls, can reduce to 1
new DictionaryEntry(keys[index], values[index]);
public object Key => Entry.Key;
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();
}
}
}

View file

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

View file

@ -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) {

View file

@ -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);