summaryrefslogtreecommitdiff
path: root/modules/mono/glue
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mono/glue')
-rw-r--r--modules/mono/glue/collections_glue.cpp240
-rw-r--r--modules/mono/glue/collections_glue.h100
-rw-r--r--modules/mono/glue/cs_files/Array.cs335
-rw-r--r--modules/mono/glue/cs_files/Basis.cs18
-rw-r--r--modules/mono/glue/cs_files/Color.cs83
-rw-r--r--modules/mono/glue/cs_files/Dictionary.cs401
-rw-r--r--modules/mono/glue/cs_files/GD.cs40
-rw-r--r--modules/mono/glue/cs_files/MarshalUtils.cs29
-rw-r--r--modules/mono/glue/cs_files/NodeExtensions.cs45
-rw-r--r--modules/mono/glue/cs_files/ResourceLoaderExtensions.cs10
-rwxr-xr-xmodules/mono/glue/cs_files/VERSION.txt2
-rw-r--r--modules/mono/glue/glue_header.h2
12 files changed, 1246 insertions, 59 deletions
diff --git a/modules/mono/glue/collections_glue.cpp b/modules/mono/glue/collections_glue.cpp
new file mode 100644
index 0000000000..0551c1991a
--- /dev/null
+++ b/modules/mono/glue/collections_glue.cpp
@@ -0,0 +1,240 @@
+/*************************************************************************/
+/* collections_glue.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "collections_glue.h"
+
+#include <mono/metadata/exception.h>
+
+#include "../mono_gd/gd_mono_class.h"
+
+Array *godot_icall_Array_Ctor() {
+ return memnew(Array);
+}
+
+void godot_icall_Array_Dtor(Array *ptr) {
+ memdelete(ptr);
+}
+
+MonoObject *godot_icall_Array_At(Array *ptr, int index) {
+ if (index < 0 || index > ptr->size()) {
+ GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
+ return NULL;
+ }
+ return GDMonoMarshal::variant_to_mono_object(ptr->operator[](index));
+}
+
+void godot_icall_Array_SetAt(Array *ptr, int index, MonoObject *value) {
+ if (index < 0 || index > ptr->size()) {
+ GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
+ return;
+ }
+ ptr->operator[](index) = GDMonoMarshal::mono_object_to_variant(value);
+}
+
+int godot_icall_Array_Count(Array *ptr) {
+ return ptr->size();
+}
+
+void godot_icall_Array_Add(Array *ptr, MonoObject *item) {
+ ptr->append(GDMonoMarshal::mono_object_to_variant(item));
+}
+
+void godot_icall_Array_Clear(Array *ptr) {
+ ptr->clear();
+}
+
+bool godot_icall_Array_Contains(Array *ptr, MonoObject *item) {
+ return ptr->find(GDMonoMarshal::mono_object_to_variant(item)) != -1;
+}
+
+void godot_icall_Array_CopyTo(Array *ptr, MonoArray *array, int array_index) {
+ int count = ptr->size();
+
+ if (mono_array_length(array) < (array_index + count)) {
+ MonoException *exc = mono_get_exception_argument("", "Destination array was not long enough. Check destIndex and length, and the array's lower bounds.");
+ GDMonoUtils::set_pending_exception(exc);
+ return;
+ }
+
+ for (int i = 0; i < count; i++) {
+ MonoObject *boxed = GDMonoMarshal::variant_to_mono_object(ptr->operator[](i));
+ mono_array_setref(array, array_index, boxed);
+ array_index++;
+ }
+}
+
+int godot_icall_Array_IndexOf(Array *ptr, MonoObject *item) {
+ return ptr->find(GDMonoMarshal::mono_object_to_variant(item));
+}
+
+void godot_icall_Array_Insert(Array *ptr, int index, MonoObject *item) {
+ if (index < 0 || index > ptr->size()) {
+ GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
+ return;
+ }
+ ptr->insert(index, GDMonoMarshal::mono_object_to_variant(item));
+}
+
+bool godot_icall_Array_Remove(Array *ptr, MonoObject *item) {
+ int idx = ptr->find(GDMonoMarshal::mono_object_to_variant(item));
+ if (idx >= 0) {
+ ptr->remove(idx);
+ return true;
+ }
+ return false;
+}
+
+void godot_icall_Array_RemoveAt(Array *ptr, int index) {
+ if (index < 0 || index > ptr->size()) {
+ GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
+ return;
+ }
+ ptr->remove(index);
+}
+
+Dictionary *godot_icall_Dictionary_Ctor() {
+ return memnew(Dictionary);
+}
+
+void godot_icall_Dictionary_Dtor(Dictionary *ptr) {
+ memdelete(ptr);
+}
+
+MonoObject *godot_icall_Dictionary_GetValue(Dictionary *ptr, MonoObject *key) {
+ Variant *ret = ptr->getptr(GDMonoMarshal::mono_object_to_variant(key));
+ if (ret == NULL) {
+ MonoObject *exc = mono_object_new(mono_domain_get(), CACHED_CLASS(KeyNotFoundException)->get_mono_ptr());
+#ifdef DEBUG_ENABLED
+ CRASH_COND(!exc);
+#endif
+ GDMonoUtils::runtime_object_init(exc);
+ GDMonoUtils::set_pending_exception((MonoException *)exc);
+ return NULL;
+ }
+ return GDMonoMarshal::variant_to_mono_object(ret);
+}
+
+void godot_icall_Dictionary_SetValue(Dictionary *ptr, MonoObject *key, MonoObject *value) {
+ ptr->operator[](GDMonoMarshal::mono_object_to_variant(key)) = GDMonoMarshal::mono_object_to_variant(value);
+}
+
+Array *godot_icall_Dictionary_Keys(Dictionary *ptr) {
+ return memnew(Array(ptr->keys()));
+}
+
+Array *godot_icall_Dictionary_Values(Dictionary *ptr) {
+ return memnew(Array(ptr->values()));
+}
+
+int godot_icall_Dictionary_Count(Dictionary *ptr) {
+ return ptr->size();
+}
+
+void godot_icall_Dictionary_Add(Dictionary *ptr, MonoObject *key, MonoObject *value) {
+ Variant varKey = GDMonoMarshal::mono_object_to_variant(key);
+ Variant *ret = ptr->getptr(varKey);
+ if (ret != NULL) {
+ GDMonoUtils::set_pending_exception(mono_get_exception_argument("key", "An element with the same key already exists"));
+ return;
+ }
+ ptr->operator[](varKey) = GDMonoMarshal::mono_object_to_variant(value);
+}
+
+void godot_icall_Dictionary_Clear(Dictionary *ptr) {
+ ptr->clear();
+}
+
+bool godot_icall_Dictionary_Contains(Dictionary *ptr, MonoObject *key, MonoObject *value) {
+ // no dupes
+ Variant *ret = ptr->getptr(GDMonoMarshal::mono_object_to_variant(key));
+ return ret != NULL && *ret == GDMonoMarshal::mono_object_to_variant(value);
+}
+
+bool godot_icall_Dictionary_ContainsKey(Dictionary *ptr, MonoObject *key) {
+ return ptr->has(GDMonoMarshal::mono_object_to_variant(key));
+}
+
+bool godot_icall_Dictionary_RemoveKey(Dictionary *ptr, MonoObject *key) {
+ return ptr->erase_checked(GDMonoMarshal::mono_object_to_variant(key));
+}
+
+bool godot_icall_Dictionary_Remove(Dictionary *ptr, MonoObject *key, MonoObject *value) {
+ Variant varKey = GDMonoMarshal::mono_object_to_variant(key);
+
+ // no dupes
+ Variant *ret = ptr->getptr(varKey);
+ if (ret != NULL && *ret == GDMonoMarshal::mono_object_to_variant(value)) {
+ ptr->erase_checked(varKey);
+ return true;
+ }
+
+ return false;
+}
+
+bool godot_icall_Dictionary_TryGetValue(Dictionary *ptr, MonoObject *key, MonoObject **value) {
+ Variant *ret = ptr->getptr(GDMonoMarshal::mono_object_to_variant(key));
+ if (ret == NULL) {
+ *value = NULL;
+ return false;
+ }
+ *value = GDMonoMarshal::variant_to_mono_object(ret);
+ return true;
+}
+
+void godot_register_collections_icalls() {
+ mono_add_internal_call("Godot.Array::godot_icall_Array_Ctor", (void *)godot_icall_Array_Ctor);
+ mono_add_internal_call("Godot.Array::godot_icall_Array_Dtor", (void *)godot_icall_Array_Dtor);
+ mono_add_internal_call("Godot.Array::godot_icall_Array_At", (void *)godot_icall_Array_At);
+ mono_add_internal_call("Godot.Array::godot_icall_Array_SetAt", (void *)godot_icall_Array_SetAt);
+ mono_add_internal_call("Godot.Array::godot_icall_Array_Count", (void *)godot_icall_Array_Count);
+ mono_add_internal_call("Godot.Array::godot_icall_Array_Add", (void *)godot_icall_Array_Add);
+ mono_add_internal_call("Godot.Array::godot_icall_Array_Clear", (void *)godot_icall_Array_Clear);
+ mono_add_internal_call("Godot.Array::godot_icall_Array_Contains", (void *)godot_icall_Array_Contains);
+ mono_add_internal_call("Godot.Array::godot_icall_Array_CopyTo", (void *)godot_icall_Array_CopyTo);
+ mono_add_internal_call("Godot.Array::godot_icall_Array_IndexOf", (void *)godot_icall_Array_IndexOf);
+ mono_add_internal_call("Godot.Array::godot_icall_Array_Insert", (void *)godot_icall_Array_Insert);
+ mono_add_internal_call("Godot.Array::godot_icall_Array_Remove", (void *)godot_icall_Array_Remove);
+ mono_add_internal_call("Godot.Array::godot_icall_Array_RemoveAt", (void *)godot_icall_Array_RemoveAt);
+
+ mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_Ctor", (void *)godot_icall_Dictionary_Ctor);
+ mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_Dtor", (void *)godot_icall_Dictionary_Dtor);
+ mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_GetValue", (void *)godot_icall_Dictionary_GetValue);
+ mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_SetValue", (void *)godot_icall_Dictionary_SetValue);
+ mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_Keys", (void *)godot_icall_Dictionary_Keys);
+ mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_Values", (void *)godot_icall_Dictionary_Values);
+ mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_Count", (void *)godot_icall_Dictionary_Count);
+ mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_Add", (void *)godot_icall_Dictionary_Add);
+ mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_Clear", (void *)godot_icall_Dictionary_Clear);
+ mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_Contains", (void *)godot_icall_Dictionary_Contains);
+ mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_ContainsKey", (void *)godot_icall_Dictionary_ContainsKey);
+ mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_RemoveKey", (void *)godot_icall_Dictionary_RemoveKey);
+ mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_Remove", (void *)godot_icall_Dictionary_Remove);
+ mono_add_internal_call("Godot.Dictionary::godot_icall_Dictionary_TryGetValue", (void *)godot_icall_Dictionary_TryGetValue);
+}
diff --git a/modules/mono/glue/collections_glue.h b/modules/mono/glue/collections_glue.h
new file mode 100644
index 0000000000..eb5ecfb725
--- /dev/null
+++ b/modules/mono/glue/collections_glue.h
@@ -0,0 +1,100 @@
+/*************************************************************************/
+/* collections_glue.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef COLLECTIONS_GLUE_H
+#define COLLECTIONS_GLUE_H
+
+#include "core/array.h"
+
+#include "../mono_gd/gd_mono_marshal.h"
+
+// Array
+
+Array *godot_icall_Array_Ctor();
+
+void godot_icall_Array_Dtor(Array *ptr);
+
+MonoObject *godot_icall_Array_At(Array *ptr, int index);
+
+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);
+
+void godot_icall_Array_Clear(Array *ptr);
+
+bool godot_icall_Array_Contains(Array *ptr, MonoObject *item);
+
+void godot_icall_Array_CopyTo(Array *ptr, MonoArray *array, int array_index);
+
+int godot_icall_Array_IndexOf(Array *ptr, MonoObject *item);
+
+void godot_icall_Array_Insert(Array *ptr, int index, MonoObject *item);
+
+bool godot_icall_Array_Remove(Array *ptr, MonoObject *item);
+
+void godot_icall_Array_RemoveAt(Array *ptr, int index);
+
+// Dictionary
+
+Dictionary *godot_icall_Dictionary_Ctor();
+
+void godot_icall_Dictionary_Dtor(Dictionary *ptr);
+
+MonoObject *godot_icall_Dictionary_GetValue(Dictionary *ptr, MonoObject *key);
+
+void godot_icall_Dictionary_SetValue(Dictionary *ptr, MonoObject *key, MonoObject *value);
+
+Array *godot_icall_Dictionary_Keys(Dictionary *ptr);
+
+Array *godot_icall_Dictionary_Values(Dictionary *ptr);
+
+int godot_icall_Dictionary_Count(Dictionary *ptr);
+
+void godot_icall_Dictionary_Add(Dictionary *ptr, MonoObject *key, MonoObject *value);
+
+void godot_icall_Dictionary_Clear(Dictionary *ptr);
+
+bool godot_icall_Dictionary_Contains(Dictionary *ptr, MonoObject *key, MonoObject *value);
+
+bool godot_icall_Dictionary_ContainsKey(Dictionary *ptr, MonoObject *key);
+
+bool godot_icall_Dictionary_RemoveKey(Dictionary *ptr, MonoObject *key);
+
+bool godot_icall_Dictionary_Remove(Dictionary *ptr, MonoObject *key, MonoObject *value);
+
+bool godot_icall_Dictionary_TryGetValue(Dictionary *ptr, MonoObject *key, MonoObject **value);
+
+// Register internal calls
+
+void godot_register_collections_icalls();
+
+#endif // COLLECTIONS_GLUE_H
diff --git a/modules/mono/glue/cs_files/Array.cs b/modules/mono/glue/cs_files/Array.cs
new file mode 100644
index 0000000000..51f57daef4
--- /dev/null
+++ b/modules/mono/glue/cs_files/Array.cs
@@ -0,0 +1,335 @@
+using System;
+using System.Collections.Generic;
+using System.Collections;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace Godot
+{
+ class ArraySafeHandle : SafeHandle
+ {
+ public ArraySafeHandle(IntPtr handle) : base(IntPtr.Zero, true)
+ {
+ this.handle = handle;
+ }
+
+ public override bool IsInvalid
+ {
+ get
+ {
+ return handle == IntPtr.Zero;
+ }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ Array.godot_icall_Array_Dtor(handle);
+ return true;
+ }
+ }
+
+ public class Array : IList<object>, ICollection<object>, IEnumerable<object>, IDisposable
+ {
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static IntPtr godot_icall_Array_Ctor();
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_Array_Dtor(IntPtr ptr);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static object godot_icall_Array_At(IntPtr ptr, int index);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_Array_SetAt(IntPtr ptr, int index, object value);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ 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);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_Array_Clear(IntPtr ptr);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ 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);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static int godot_icall_Array_IndexOf(IntPtr ptr, object item);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_Array_Insert(IntPtr ptr, int index, object item);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static bool godot_icall_Array_Remove(IntPtr ptr, object item);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_Array_RemoveAt(IntPtr ptr, int index);
+
+ ArraySafeHandle safeHandle;
+ bool disposed = false;
+
+ public Array()
+ {
+ safeHandle = new ArraySafeHandle(godot_icall_Array_Ctor());
+ }
+
+ internal Array(ArraySafeHandle handle)
+ {
+ safeHandle = handle;
+ }
+
+ internal Array(IntPtr handle)
+ {
+ safeHandle = new ArraySafeHandle(handle);
+ }
+
+ internal IntPtr GetPtr()
+ {
+ return safeHandle.DangerousGetHandle();
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (safeHandle != null)
+ {
+ safeHandle.Dispose();
+ safeHandle = null;
+ }
+
+ disposed = true;
+ }
+
+ public object this[int index]
+ {
+ get
+ {
+ return 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 bool IsReadOnly
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public void Add(object item)
+ {
+ godot_icall_Array_Add(GetPtr(), item);
+ }
+
+ public void Clear()
+ {
+ godot_icall_Array_Clear(GetPtr());
+ }
+
+ public bool Contains(object item)
+ {
+ return godot_icall_Array_Contains(GetPtr(), item);
+ }
+
+ public void CopyTo(object[] 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.");
+
+ // Internal call may throw ArgumentException
+ godot_icall_Array_CopyTo(GetPtr(), array, arrayIndex);
+ }
+
+ public IEnumerator<object> GetEnumerator()
+ {
+ int count = Count;
+
+ for (int i = 0; i < count; i++)
+ {
+ yield return godot_icall_Array_At(GetPtr(), i);
+ }
+ }
+
+ 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);
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+ }
+
+ public class Array<T> : IList<T>, ICollection<T>, IEnumerable<T>
+ {
+ Array objectArray;
+
+ public Array()
+ {
+ objectArray = new Array();
+ }
+
+ public Array(Array array)
+ {
+ objectArray = array;
+ }
+
+ internal Array(IntPtr handle)
+ {
+ objectArray = new Array(handle);
+ }
+
+ internal Array(ArraySafeHandle handle)
+ {
+ objectArray = new Array(handle);
+ }
+
+ public static explicit operator Array(Array<T> from)
+ {
+ return from.objectArray;
+ }
+
+ public T this[int index]
+ {
+ get
+ {
+ return (T)objectArray[index];
+ }
+ set
+ {
+ objectArray[index] = value;
+ }
+ }
+
+ public int Count
+ {
+ get
+ {
+ return objectArray.Count;
+ }
+ }
+
+ public bool IsReadOnly
+ {
+ get
+ {
+ return objectArray.IsReadOnly;
+ }
+ }
+
+ public void Add(T item)
+ {
+ objectArray.Add(item);
+ }
+
+ public void Clear()
+ {
+ objectArray.Clear();
+ }
+
+ public bool Contains(T item)
+ {
+ return objectArray.Contains(item);
+ }
+
+ public void CopyTo(T[] 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 This may be quite slow because every element access is an internal call.
+ // It could be moved entirely to an internal call if we find out how to do the cast there.
+
+ int count = objectArray.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++)
+ {
+ array[arrayIndex] = (T)objectArray[i];
+ arrayIndex++;
+ }
+ }
+
+ public IEnumerator<T> GetEnumerator()
+ {
+ int count = objectArray.Count;
+
+ for (int i = 0; i < count; i++)
+ {
+ yield return (T)objectArray[i];
+ }
+ }
+
+ 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);
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+ }
+}
diff --git a/modules/mono/glue/cs_files/Basis.cs b/modules/mono/glue/cs_files/Basis.cs
index aa49a5e04f..c280d32c61 100644
--- a/modules/mono/glue/cs_files/Basis.cs
+++ b/modules/mono/glue/cs_files/Basis.cs
@@ -343,17 +343,17 @@ namespace Godot
{
var tr = this;
- real_t temp = this[0, 1];
- this[0, 1] = this[1, 0];
- this[1, 0] = temp;
+ real_t temp = tr[0, 1];
+ tr[0, 1] = tr[1, 0];
+ tr[1, 0] = temp;
- temp = this[0, 2];
- this[0, 2] = this[2, 0];
- this[2, 0] = temp;
+ temp = tr[0, 2];
+ tr[0, 2] = tr[2, 0];
+ tr[2, 0] = temp;
- temp = this[1, 2];
- this[1, 2] = this[2, 1];
- this[2, 1] = temp;
+ temp = tr[1, 2];
+ tr[1, 2] = tr[2, 1];
+ tr[2, 1] = temp;
return tr;
}
diff --git a/modules/mono/glue/cs_files/Color.cs b/modules/mono/glue/cs_files/Color.cs
index e0d6d27840..1195071bd3 100644
--- a/modules/mono/glue/cs_files/Color.cs
+++ b/modules/mono/glue/cs_files/Color.cs
@@ -293,28 +293,80 @@ namespace Godot
return res;
}
- public int ToRgba32()
+ public int ToAbgr32()
{
- int c = (byte)(r * 255);
+ int c = (byte)Math.Round(a * 255);
c <<= 8;
- c |= (byte)(g * 255);
+ c |= (byte)Math.Round(b * 255);
c <<= 8;
- c |= (byte)(b * 255);
+ c |= (byte)Math.Round(g * 255);
c <<= 8;
- c |= (byte)(a * 255);
+ c |= (byte)Math.Round(r * 255);
+
+ return c;
+ }
+
+ public long ToAbgr64()
+ {
+ long c = (ushort)Math.Round(a * 65535);
+ c <<= 16;
+ c |= (ushort)Math.Round(b * 65535);
+ c <<= 16;
+ c |= (ushort)Math.Round(g * 65535);
+ c <<= 16;
+ c |= (ushort)Math.Round(r * 65535);
return c;
}
public int ToArgb32()
{
- int c = (byte)(a * 255);
+ int c = (byte)Math.Round(a * 255);
+ c <<= 8;
+ c |= (byte)Math.Round(r * 255);
+ c <<= 8;
+ c |= (byte)Math.Round(g * 255);
+ c <<= 8;
+ c |= (byte)Math.Round(b * 255);
+
+ return c;
+ }
+
+ public long ToArgb64()
+ {
+ long c = (ushort)Math.Round(a * 65535);
+ c <<= 16;
+ c |= (ushort)Math.Round(r * 65535);
+ c <<= 16;
+ c |= (ushort)Math.Round(g * 65535);
+ c <<= 16;
+ c |= (ushort)Math.Round(b * 65535);
+
+ return c;
+ }
+
+ public int ToRgba32()
+ {
+ int c = (byte)Math.Round(r * 255);
c <<= 8;
- c |= (byte)(r * 255);
+ c |= (byte)Math.Round(g * 255);
c <<= 8;
- c |= (byte)(g * 255);
+ c |= (byte)Math.Round(b * 255);
c <<= 8;
- c |= (byte)(b * 255);
+ c |= (byte)Math.Round(a * 255);
+
+ return c;
+ }
+
+ public long ToRgba64()
+ {
+ long c = (ushort)Math.Round(r * 65535);
+ c <<= 16;
+ c |= (ushort)Math.Round(g * 65535);
+ c <<= 16;
+ c |= (ushort)Math.Round(b * 65535);
+ c <<= 16;
+ c |= (ushort)Math.Round(a * 65535);
return c;
}
@@ -353,6 +405,17 @@ namespace Godot
r = (rgba & 0xFF) / 255.0f;
}
+ public Color(long rgba)
+ {
+ a = (rgba & 0xFFFF) / 65535.0f;
+ rgba >>= 16;
+ b = (rgba & 0xFFFF) / 65535.0f;
+ rgba >>= 16;
+ g = (rgba & 0xFFFF) / 65535.0f;
+ rgba >>= 16;
+ r = (rgba & 0xFFFF) / 65535.0f;
+ }
+
private static int _parse_col(string str, int ofs)
{
int ig = 0;
@@ -392,7 +455,7 @@ namespace Godot
private String _to_hex(float val)
{
- var v = (int) Mathf.Clamp(val * 255.0f, 0, 255);
+ int v = Mathf.RoundToInt(Mathf.Clamp(val * 255, 0, 255));
var ret = string.Empty;
diff --git a/modules/mono/glue/cs_files/Dictionary.cs b/modules/mono/glue/cs_files/Dictionary.cs
new file mode 100644
index 0000000000..57a1960ad9
--- /dev/null
+++ b/modules/mono/glue/cs_files/Dictionary.cs
@@ -0,0 +1,401 @@
+using System;
+using System.Collections.Generic;
+using System.Collections;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace Godot
+{
+ class DictionarySafeHandle : SafeHandle
+ {
+ public DictionarySafeHandle(IntPtr handle) : base(IntPtr.Zero, true)
+ {
+ this.handle = handle;
+ }
+
+ public override bool IsInvalid
+ {
+ get
+ {
+ return handle == IntPtr.Zero;
+ }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ Dictionary.godot_icall_Dictionary_Dtor(handle);
+ return true;
+ }
+ }
+
+ public class Dictionary :
+ IDictionary<object, object>,
+ ICollection<KeyValuePair<object, object>>,
+ IEnumerable<KeyValuePair<object, object>>,
+ IDisposable
+ {
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static IntPtr godot_icall_Dictionary_Ctor();
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_Dictionary_Dtor(IntPtr ptr);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static object godot_icall_Dictionary_GetValue(IntPtr ptr, object key);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_Dictionary_SetValue(IntPtr ptr, object key, object value);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static IntPtr godot_icall_Dictionary_Keys(IntPtr ptr);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static IntPtr godot_icall_Dictionary_Values(IntPtr ptr);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static int godot_icall_Dictionary_Count(IntPtr ptr);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_Dictionary_Add(IntPtr ptr, object key, object value);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_Dictionary_Clear(IntPtr ptr);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static bool godot_icall_Dictionary_Contains(IntPtr ptr, object key, object value);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static bool godot_icall_Dictionary_ContainsKey(IntPtr ptr, object key);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static bool godot_icall_Dictionary_RemoveKey(IntPtr ptr, object key);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static bool godot_icall_Dictionary_Remove(IntPtr ptr, object key, object value);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static bool godot_icall_Dictionary_TryGetValue(IntPtr ptr, object key, out object value);
+
+ DictionarySafeHandle safeHandle;
+ bool disposed = false;
+
+ public Dictionary()
+ {
+ safeHandle = new DictionarySafeHandle(godot_icall_Dictionary_Ctor());
+ }
+
+ internal Dictionary(DictionarySafeHandle handle)
+ {
+ safeHandle = handle;
+ }
+
+ internal Dictionary(IntPtr handle)
+ {
+ safeHandle = new DictionarySafeHandle(handle);
+ }
+
+ internal IntPtr GetPtr()
+ {
+ return safeHandle.DangerousGetHandle();
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposed)
+ return;
+
+ if (safeHandle != null)
+ {
+ safeHandle.Dispose();
+ safeHandle = null;
+ }
+
+ disposed = true;
+ }
+
+ public object this[object key]
+ {
+ get
+ {
+ return godot_icall_Dictionary_GetValue(GetPtr(), key);
+ }
+ set
+ {
+ godot_icall_Dictionary_SetValue(GetPtr(), key, value);
+ }
+ }
+
+ public ICollection<object> Keys
+ {
+ get
+ {
+ IntPtr handle = godot_icall_Dictionary_Keys(GetPtr());
+ return new Array(new ArraySafeHandle(handle));
+ }
+ }
+
+ public ICollection<object> Values
+ {
+ get
+ {
+ IntPtr handle = godot_icall_Dictionary_Values(GetPtr());
+ return new Array(new ArraySafeHandle(handle));
+ }
+ }
+
+ public int Count
+ {
+ get
+ {
+ return godot_icall_Dictionary_Count(GetPtr());
+ }
+ }
+
+ public bool IsReadOnly
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public void Add(object key, object value)
+ {
+ godot_icall_Dictionary_Add(GetPtr(), key, value);
+ }
+
+ public void Add(KeyValuePair<object, object> item)
+ {
+ Add(item.Key, item.Value);
+ }
+
+ 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 ContainsKey(object key)
+ {
+ return godot_icall_Dictionary_ContainsKey(GetPtr(), key);
+ }
+
+ public void CopyTo(KeyValuePair<object, object>[] array, int arrayIndex)
+ {
+ // TODO 3 internal calls, can reduce to 1
+ 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;
+
+ 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]);
+ }
+ }
+
+ public bool Remove(object key)
+ {
+ return godot_icall_Dictionary_RemoveKey(GetPtr(), key);
+ }
+
+ public bool Remove(KeyValuePair<object, object> item)
+ {
+ return godot_icall_Dictionary_Remove(GetPtr(), item.Key, item.Value);
+ }
+
+ 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;
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+ }
+
+
+ public class Dictionary<TKey, TValue> :
+ IDictionary<TKey, TValue>,
+ ICollection<KeyValuePair<TKey, TValue>>,
+ IEnumerable<KeyValuePair<TKey, TValue>>
+ {
+ Dictionary objectDict;
+
+ public Dictionary()
+ {
+ objectDict = new Dictionary();
+ }
+
+ public Dictionary(Dictionary dictionary)
+ {
+ objectDict = dictionary;
+ }
+
+ internal Dictionary(IntPtr handle)
+ {
+ objectDict = new Dictionary(handle);
+ }
+
+ internal Dictionary(DictionarySafeHandle handle)
+ {
+ objectDict = new Dictionary(handle);
+ }
+
+ public static explicit operator Dictionary(Dictionary<TKey, TValue> from)
+ {
+ return from.objectDict;
+ }
+
+ public TValue this[TKey key]
+ {
+ get
+ {
+ return (TValue)objectDict[key];
+ }
+ set
+ {
+ objectDict[key] = value;
+ }
+ }
+
+ public ICollection<TKey> Keys
+ {
+ get
+ {
+ IntPtr handle = Dictionary.godot_icall_Dictionary_Keys(objectDict.GetPtr());
+ return new Array<TKey>(new ArraySafeHandle(handle));
+ }
+ }
+
+ public ICollection<TValue> Values
+ {
+ get
+ {
+ IntPtr handle = Dictionary.godot_icall_Dictionary_Values(objectDict.GetPtr());
+ return new Array<TValue>(new ArraySafeHandle(handle));
+ }
+ }
+
+ public int Count
+ {
+ get
+ {
+ return objectDict.Count;
+ }
+ }
+
+ public bool IsReadOnly
+ {
+ get
+ {
+ return objectDict.IsReadOnly;
+ }
+ }
+
+ public void Add(TKey key, TValue value)
+ {
+ objectDict.Add(key, value);
+ }
+
+ public void Add(KeyValuePair<TKey, TValue> item)
+ {
+ objectDict.Add(item.Key, item.Value);
+ }
+
+ public void Clear()
+ {
+ objectDict.Clear();
+ }
+
+ public bool Contains(KeyValuePair<TKey, TValue> item)
+ {
+ 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)
+ {
+ // TODO 3 internal calls, can reduce to 1
+ Array<TKey> keys = (Array<TKey>)Keys;
+ Array<TValue> values = (Array<TValue>)Values;
+ int count = Count;
+
+ for (int i = 0; i < count; i++)
+ {
+ // TODO 2 internal calls, can reduce to 1
+ array[arrayIndex] = new KeyValuePair<TKey, TValue>(keys[i], values[i]);
+ arrayIndex++;
+ }
+ }
+
+ public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
+ {
+ // TODO 3 internal calls, can reduce to 1
+ Array<TKey> keys = (Array<TKey>)Keys;
+ Array<TValue> values = (Array<TValue>)Values;
+ int count = Count;
+
+ for (int i = 0; i < count; i++)
+ {
+ // TODO 2 internal calls, can reduce to 1
+ yield return new KeyValuePair<TKey, TValue>(keys[i], values[i]);
+ }
+ }
+
+ 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 = objectDict.TryGetValue(key, out retValue);
+ value = found ? (TValue)retValue : default(TValue);
+ return found;
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+ }
+}
diff --git a/modules/mono/glue/cs_files/GD.cs b/modules/mono/glue/cs_files/GD.cs
index ec1534cb9a..43de9156f2 100644
--- a/modules/mono/glue/cs_files/GD.cs
+++ b/modules/mono/glue/cs_files/GD.cs
@@ -1,4 +1,9 @@
using System;
+#if REAL_T_IS_DOUBLE
+using real_t = System.Double;
+#else
+using real_t = System.Single;
+#endif
// TODO: Add comments describing what this class does. It is not obvious.
@@ -16,22 +21,22 @@ namespace Godot
return NativeCalls.godot_icall_Godot_convert(what, type);
}
- public static float Db2Linear(float db)
+ public static real_t Db2Linear(real_t db)
{
- return (float)Math.Exp(db * 0.11512925464970228420089957273422);
+ return (real_t)Math.Exp(db * 0.11512925464970228420089957273422);
}
- public static float Dectime(float value, float amount, float step)
+ public static real_t DecTime(real_t value, real_t amount, real_t step)
{
- float sgn = value < 0 ? -1.0f : 1.0f;
- float val = Mathf.Abs(value);
+ real_t sgn = Mathf.Sign(value);
+ real_t val = Mathf.Abs(value);
val -= amount * step;
- if (val < 0.0f)
- val = 0.0f;
+ if (val < 0)
+ val = 0;
return val * sgn;
}
- public static FuncRef Funcref(Object instance, string funcname)
+ public static FuncRef FuncRef(Object instance, string funcname)
{
var ret = new FuncRef();
ret.SetInstance(instance);
@@ -49,9 +54,9 @@ namespace Godot
return NativeCalls.godot_icall_Godot_instance_from_id(instanceId);
}
- public static double Linear2Db(double linear)
+ public static real_t Linear2Db(real_t linear)
{
- return Math.Log(linear) * 8.6858896380650365530225783783321;
+ return (real_t)(Math.Log(linear) * 8.6858896380650365530225783783321);
}
public static Resource Load(string path)
@@ -59,6 +64,11 @@ namespace Godot
return ResourceLoader.Load(path);
}
+ public static T Load<T>(string path) where T : Godot.Resource
+ {
+ return (T) ResourceLoader.Load(path);
+ }
+
public static void Print(params object[] what)
{
NativeCalls.godot_icall_Godot_print(what);
@@ -69,22 +79,22 @@ namespace Godot
Print(System.Environment.StackTrace);
}
- public static void Printerr(params object[] what)
+ public static void PrintErr(params object[] what)
{
NativeCalls.godot_icall_Godot_printerr(what);
}
- public static void Printraw(params object[] what)
+ public static void PrintRaw(params object[] what)
{
NativeCalls.godot_icall_Godot_printraw(what);
}
- public static void Prints(params object[] what)
+ public static void PrintS(params object[] what)
{
NativeCalls.godot_icall_Godot_prints(what);
}
- public static void Printt(params object[] what)
+ public static void PrintT(params object[] what)
{
NativeCalls.godot_icall_Godot_printt(what);
}
@@ -183,7 +193,7 @@ namespace Godot
return NativeCalls.godot_icall_Godot_var2str(var);
}
- public static WeakRef Weakref(Object obj)
+ public static WeakRef WeakRef(Object obj)
{
return NativeCalls.godot_icall_Godot_weakref(Object.GetPtr(obj));
}
diff --git a/modules/mono/glue/cs_files/MarshalUtils.cs b/modules/mono/glue/cs_files/MarshalUtils.cs
index ff4477cc6c..6ad4b3dcb2 100644
--- a/modules/mono/glue/cs_files/MarshalUtils.cs
+++ b/modules/mono/glue/cs_files/MarshalUtils.cs
@@ -1,36 +1,17 @@
using System;
-using System.Collections.Generic;
namespace Godot
{
- internal static class MarshalUtils
+ static class MarshalUtils
{
- private static Dictionary<object, object> ArraysToDictionary(object[] keys, object[] values)
+ static bool IsArrayGenericType(Type type)
{
- var ret = new Dictionary<object, object>();
-
- for (int i = 0; i < keys.Length; i++)
- {
- ret.Add(keys[i], values[i]);
- }
-
- return ret;
- }
-
- private static void DictionaryToArrays(Dictionary<object, object> from, out object[] keysTo, out object[] valuesTo)
- {
- var keys = from.Keys;
- keysTo = new object[keys.Count];
- keys.CopyTo(keysTo, 0);
-
- var values = from.Values;
- valuesTo = new object[values.Count];
- values.CopyTo(valuesTo, 0);
+ return type.GetGenericTypeDefinition() == typeof(Array<>);
}
- private static Type GetDictionaryType()
+ static bool IsDictionaryGenericType(Type type)
{
- return typeof(Dictionary<object, object>);
+ return type.GetGenericTypeDefinition() == typeof(Dictionary<, >);
}
}
}
diff --git a/modules/mono/glue/cs_files/NodeExtensions.cs b/modules/mono/glue/cs_files/NodeExtensions.cs
new file mode 100644
index 0000000000..71534d7782
--- /dev/null
+++ b/modules/mono/glue/cs_files/NodeExtensions.cs
@@ -0,0 +1,45 @@
+namespace Godot
+{
+ public partial class Node
+ {
+ public T GetNode<T>(NodePath path) where T : Godot.Node
+ {
+ return (T)GetNode(path);
+ }
+
+ public T GetNodeOrNull<T>(NodePath path) where T : Godot.Node
+ {
+ return GetNode(path) as T;
+ }
+
+ public T GetChild<T>(int idx) where T : Godot.Node
+ {
+ return (T)GetChild(idx);
+ }
+
+ public T GetChildOrNull<T>(int idx) where T : Godot.Node
+ {
+ return GetChild(idx) as T;
+ }
+
+ public T GetOwner<T>() where T : Godot.Node
+ {
+ return (T)GetOwner();
+ }
+
+ public T GetOwnerOrNull<T>() where T : Godot.Node
+ {
+ return GetOwner() as T;
+ }
+
+ public T GetParent<T>() where T : Godot.Node
+ {
+ return (T)GetParent();
+ }
+
+ public T GetParentOrNull<T>() where T : Godot.Node
+ {
+ return GetParent() as T;
+ }
+ }
+}
diff --git a/modules/mono/glue/cs_files/ResourceLoaderExtensions.cs b/modules/mono/glue/cs_files/ResourceLoaderExtensions.cs
new file mode 100644
index 0000000000..ceecc589e6
--- /dev/null
+++ b/modules/mono/glue/cs_files/ResourceLoaderExtensions.cs
@@ -0,0 +1,10 @@
+namespace Godot
+{
+ public static partial class ResourceLoader
+ {
+ public static T Load<T>(string path) where T : Godot.Resource
+ {
+ return (T) Load(path);
+ }
+ }
+}
diff --git a/modules/mono/glue/cs_files/VERSION.txt b/modules/mono/glue/cs_files/VERSION.txt
index b8626c4cff..7f8f011eb7 100755
--- a/modules/mono/glue/cs_files/VERSION.txt
+++ b/modules/mono/glue/cs_files/VERSION.txt
@@ -1 +1 @@
-4
+7
diff --git a/modules/mono/glue/glue_header.h b/modules/mono/glue/glue_header.h
index cedc8e9992..6a6f3062b4 100644
--- a/modules/mono/glue/glue_header.h
+++ b/modules/mono/glue/glue_header.h
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "builtin_types_glue.h"
+#include "collections_glue.h"
#include "../csharp_script.h"
#include "../mono_gd/gd_mono_class.h"
@@ -308,4 +309,5 @@ MonoObject *godot_icall_Godot_weakref(Object *p_obj) {
void godot_register_header_icalls() {
godot_register_builtin_type_icalls();
+ godot_register_collections_icalls();
}