Browse Source

Add concatenation support and a new ctor to Godot.Collections.Array

(cherry picked from commit a4dcd48d16f79418b0f709d94ac250df5acf4c3a)
Aaron Franke 5 years ago
parent
commit
ea3bbbe0f2

+ 34 - 0
modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs

@@ -44,6 +44,15 @@ namespace Godot.Collections
                 Add(element);
         }
 
+        public Array(params object[] array) : this()
+        {
+            if (array == null)
+            {
+                throw new NullReferenceException($"Parameter '{nameof(array)} cannot be null.'");
+            }
+            safeHandle = new ArraySafeHandle(godot_icall_Array_Ctor_MonoArray(array));
+        }
+
         internal Array(ArraySafeHandle handle)
         {
             safeHandle = handle;
@@ -72,6 +81,11 @@ namespace Godot.Collections
             return godot_icall_Array_Resize(GetPtr(), newSize);
         }
 
+        public static Array operator +(Array left, Array right)
+        {
+            return new Array(godot_icall_Array_Concatenate(left.GetPtr(), right.GetPtr()));
+        }
+
         // IDisposable
 
         public void Dispose()
@@ -154,6 +168,9 @@ namespace Godot.Collections
         [MethodImpl(MethodImplOptions.InternalCall)]
         internal extern static IntPtr godot_icall_Array_Ctor();
 
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        internal extern static IntPtr godot_icall_Array_Ctor_MonoArray(System.Array array);
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         internal extern static void godot_icall_Array_Dtor(IntPtr ptr);
 
@@ -175,6 +192,9 @@ namespace Godot.Collections
         [MethodImpl(MethodImplOptions.InternalCall)]
         internal extern static void godot_icall_Array_Clear(IntPtr ptr);
 
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        internal extern static IntPtr godot_icall_Array_Concatenate(IntPtr left, IntPtr right);
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         internal extern static bool godot_icall_Array_Contains(IntPtr ptr, object item);
 
@@ -231,6 +251,15 @@ namespace Godot.Collections
             objectArray = new Array(collection);
         }
 
+        public Array(params T[] array) : this()
+        {
+            if (array == null)
+            {
+                throw new NullReferenceException($"Parameter '{nameof(array)} cannot be null.'");
+            }
+            objectArray = new Array(array);
+        }
+
         public Array(Array array)
         {
             objectArray = array;
@@ -266,6 +295,11 @@ namespace Godot.Collections
             return objectArray.Resize(newSize);
         }
 
+        public static Array<T> operator +(Array<T> left, Array<T> right)
+        {
+            return new Array<T>(left.objectArray + right.objectArray);
+        }
+
         // IList<T>
 
         public T this[int index]

+ 23 - 0
modules/mono/glue/collections_glue.cpp

@@ -103,10 +103,31 @@ void godot_icall_Array_CopyTo(Array *ptr, MonoArray *array, int array_index) {
 	}
 }
 
+Array *godot_icall_Array_Ctor_MonoArray(MonoArray *mono_array) {
+	Array *godot_array = memnew(Array);
+	unsigned int count = mono_array_length(mono_array);
+	godot_array->resize(count);
+	for (unsigned int i = 0; i < count; i++) {
+		MonoObject *item = mono_array_get(mono_array, MonoObject *, i);
+		godot_icall_Array_SetAt(godot_array, i, item);
+	}
+	return godot_array;
+}
+
 Array *godot_icall_Array_Duplicate(Array *ptr, MonoBoolean deep) {
 	return memnew(Array(ptr->duplicate(deep)));
 }
 
+Array *godot_icall_Array_Concatenate(Array *left, Array *right) {
+	int count = left->size() + right->size();
+	Array *new_array = memnew(Array(left->duplicate(false)));
+	new_array->resize(count);
+	for (unsigned int i = 0; i < (unsigned int)right->size(); i++) {
+		new_array->operator[](i + left->size()) = right->operator[](i);
+	}
+	return new_array;
+}
+
 int godot_icall_Array_IndexOf(Array *ptr, MonoObject *item) {
 	return ptr->find(GDMonoMarshal::mono_object_to_variant(item));
 }
@@ -283,6 +304,7 @@ MonoString *godot_icall_Dictionary_ToString(Dictionary *ptr) {
 
 void godot_register_collections_icalls() {
 	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Ctor", (void *)godot_icall_Array_Ctor);
+	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Ctor_MonoArray", (void *)godot_icall_Array_Ctor_MonoArray);
 	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Dtor", (void *)godot_icall_Array_Dtor);
 	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_At", (void *)godot_icall_Array_At);
 	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_At_Generic", (void *)godot_icall_Array_At_Generic);
@@ -290,6 +312,7 @@ void godot_register_collections_icalls() {
 	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Count", (void *)godot_icall_Array_Count);
 	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Add", (void *)godot_icall_Array_Add);
 	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Clear", (void *)godot_icall_Array_Clear);
+	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Concatenate", (void *)godot_icall_Array_Concatenate);
 	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Contains", (void *)godot_icall_Array_Contains);
 	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_CopyTo", (void *)godot_icall_Array_CopyTo);
 	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Duplicate", (void *)godot_icall_Array_Duplicate);