summaryrefslogtreecommitdiff
path: root/modules/mono/glue
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mono/glue')
-rw-r--r--modules/mono/glue/Managed/Files/Array.cs22
-rw-r--r--modules/mono/glue/Managed/Files/Dictionary.cs21
-rw-r--r--modules/mono/glue/collections_glue.cpp53
-rw-r--r--modules/mono/glue/collections_glue.h10
4 files changed, 100 insertions, 6 deletions
diff --git a/modules/mono/glue/Managed/Files/Array.cs b/modules/mono/glue/Managed/Files/Array.cs
index c80cb7cc83..d5a35d7ae0 100644
--- a/modules/mono/glue/Managed/Files/Array.cs
+++ b/modules/mono/glue/Managed/Files/Array.cs
@@ -128,7 +128,7 @@ namespace Godot.Collections
for (int i = 0; i < count; i++)
{
- yield return godot_icall_Array_At(GetPtr(), i);
+ yield return this[i];
}
}
@@ -167,6 +167,9 @@ namespace Godot.Collections
internal extern static object godot_icall_Array_At(IntPtr ptr, int index);
[MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static object godot_icall_Array_At_Generic(IntPtr ptr, int index, int elemTypeEncoding, IntPtr elemTypeClass);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
internal extern static void godot_icall_Array_SetAt(IntPtr ptr, int index, object value);
[MethodImpl(MethodImplOptions.InternalCall)]
@@ -195,12 +198,23 @@ namespace Godot.Collections
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern static void godot_icall_Array_RemoveAt(IntPtr ptr, int index);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_Array_Generic_GetElementTypeInfo(Type elemType, out int elemTypeEncoding, out IntPtr elemTypeClass);
}
public class Array<T> : IList<T>, ICollection<T>, IEnumerable<T>
{
Array objectArray;
+ internal static int elemTypeEncoding;
+ internal static IntPtr elemTypeClass;
+
+ static Array()
+ {
+ Array.godot_icall_Array_Generic_GetElementTypeInfo(typeof(T), out elemTypeEncoding, out elemTypeClass);
+ }
+
public Array()
{
objectArray = new Array();
@@ -230,7 +244,7 @@ namespace Godot.Collections
{
get
{
- return (T)objectArray[index];
+ return (T)Array.godot_icall_Array_At_Generic(GetPtr(), index, elemTypeEncoding, elemTypeClass);
}
set
{
@@ -287,7 +301,7 @@ namespace Godot.Collections
for (int i = 0; i < count; i++)
{
- array[arrayIndex] = (T)objectArray[i];
+ array[arrayIndex] = (T)this[i];
arrayIndex++;
}
}
@@ -298,7 +312,7 @@ namespace Godot.Collections
for (int i = 0; i < count; i++)
{
- yield return (T)objectArray[i];
+ yield return (T)this[i];
}
}
diff --git a/modules/mono/glue/Managed/Files/Dictionary.cs b/modules/mono/glue/Managed/Files/Dictionary.cs
index 523e48c31a..7695f03cd6 100644
--- a/modules/mono/glue/Managed/Files/Dictionary.cs
+++ b/modules/mono/glue/Managed/Files/Dictionary.cs
@@ -204,6 +204,9 @@ namespace Godot.Collections
internal extern static object godot_icall_Dictionary_GetValue(IntPtr ptr, object key);
[MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static object godot_icall_Dictionary_GetValue_Generic(IntPtr ptr, object key, int valTypeEncoding, IntPtr valTypeClass);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
internal extern static void godot_icall_Dictionary_SetValue(IntPtr ptr, object key, object value);
[MethodImpl(MethodImplOptions.InternalCall)]
@@ -235,6 +238,12 @@ namespace Godot.Collections
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern static bool godot_icall_Dictionary_TryGetValue(IntPtr ptr, object key, out object value);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static bool godot_icall_Dictionary_TryGetValue_Generic(IntPtr ptr, object key, out object value, int valTypeEncoding, IntPtr valTypeClass);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static void godot_icall_Dictionary_Generic_GetValueTypeInfo(Type valueType, out int valTypeEncoding, out IntPtr valTypeClass);
}
public class Dictionary<TKey, TValue> :
@@ -244,6 +253,14 @@ namespace Godot.Collections
{
Dictionary objectDict;
+ internal static int valTypeEncoding;
+ internal static IntPtr valTypeClass;
+
+ static Dictionary()
+ {
+ Dictionary.godot_icall_Dictionary_Generic_GetValueTypeInfo(typeof(TValue), out valTypeEncoding, out valTypeClass);
+ }
+
public Dictionary()
{
objectDict = new Dictionary();
@@ -273,7 +290,7 @@ namespace Godot.Collections
{
get
{
- return (TValue)objectDict[key];
+ return (TValue)Dictionary.godot_icall_Dictionary_GetValue_Generic(objectDict.GetPtr(), key, valTypeEncoding, valTypeClass);
}
set
{
@@ -382,7 +399,7 @@ namespace Godot.Collections
public bool TryGetValue(TKey key, out TValue value)
{
object retValue;
- bool found = objectDict.TryGetValue(key, out retValue);
+ bool found = Dictionary.godot_icall_Dictionary_TryGetValue_Generic(GetPtr(), key, out retValue, valTypeEncoding, valTypeClass);
value = found ? (TValue)retValue : default(TValue);
return found;
}
diff --git a/modules/mono/glue/collections_glue.cpp b/modules/mono/glue/collections_glue.cpp
index d9dba1c60d..059e2ff6de 100644
--- a/modules/mono/glue/collections_glue.cpp
+++ b/modules/mono/glue/collections_glue.cpp
@@ -53,6 +53,14 @@ MonoObject *godot_icall_Array_At(Array *ptr, int index) {
return GDMonoMarshal::variant_to_mono_object(ptr->operator[](index));
}
+MonoObject *godot_icall_Array_At_Generic(Array *ptr, int index, uint32_t type_encoding, GDMonoClass *type_class) {
+ 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), ManagedType(type_encoding, type_class));
+}
+
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());
@@ -122,6 +130,14 @@ void godot_icall_Array_RemoveAt(Array *ptr, int index) {
ptr->remove(index);
}
+void godot_icall_Array_Generic_GetElementTypeInfo(MonoReflectionType *refltype, uint32_t *type_encoding, GDMonoClass **type_class) {
+ MonoType *elem_type = mono_reflection_type_get_type(refltype);
+
+ *type_encoding = mono_type_get_type(elem_type);
+ MonoClass *type_class_raw = mono_class_from_mono_type(elem_type);
+ *type_class = GDMono::get_singleton()->get_class(type_class_raw);
+}
+
Dictionary *godot_icall_Dictionary_Ctor() {
return memnew(Dictionary);
}
@@ -144,6 +160,20 @@ MonoObject *godot_icall_Dictionary_GetValue(Dictionary *ptr, MonoObject *key) {
return GDMonoMarshal::variant_to_mono_object(ret);
}
+MonoObject *godot_icall_Dictionary_GetValue_Generic(Dictionary *ptr, MonoObject *key, uint32_t type_encoding, GDMonoClass *type_class) {
+ 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, ManagedType(type_encoding, type_class));
+}
+
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);
}
@@ -211,10 +241,29 @@ bool godot_icall_Dictionary_TryGetValue(Dictionary *ptr, MonoObject *key, MonoOb
return true;
}
+bool godot_icall_Dictionary_TryGetValue_Generic(Dictionary *ptr, MonoObject *key, MonoObject **value, uint32_t type_encoding, GDMonoClass *type_class) {
+ Variant *ret = ptr->getptr(GDMonoMarshal::mono_object_to_variant(key));
+ if (ret == NULL) {
+ *value = NULL;
+ return false;
+ }
+ *value = GDMonoMarshal::variant_to_mono_object(ret, ManagedType(type_encoding, type_class));
+ return true;
+}
+
+void godot_icall_Dictionary_Generic_GetValueTypeInfo(MonoReflectionType *refltype, uint32_t *type_encoding, GDMonoClass **type_class) {
+ MonoType *value_type = mono_reflection_type_get_type(refltype);
+
+ *type_encoding = mono_type_get_type(value_type);
+ MonoClass *type_class_raw = mono_class_from_mono_type(value_type);
+ *type_class = GDMono::get_singleton()->get_class(type_class_raw);
+}
+
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_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);
mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_SetAt", (void *)godot_icall_Array_SetAt);
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);
@@ -225,10 +274,12 @@ void godot_register_collections_icalls() {
mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Insert", (void *)godot_icall_Array_Insert);
mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Remove", (void *)godot_icall_Array_Remove);
mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_RemoveAt", (void *)godot_icall_Array_RemoveAt);
+ mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Generic_GetElementTypeInfo", (void *)godot_icall_Array_Generic_GetElementTypeInfo);
mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Ctor", (void *)godot_icall_Dictionary_Ctor);
mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Dtor", (void *)godot_icall_Dictionary_Dtor);
mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_GetValue", (void *)godot_icall_Dictionary_GetValue);
+ mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_GetValue_Generic", (void *)godot_icall_Dictionary_GetValue_Generic);
mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_SetValue", (void *)godot_icall_Dictionary_SetValue);
mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Keys", (void *)godot_icall_Dictionary_Keys);
mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Values", (void *)godot_icall_Dictionary_Values);
@@ -240,6 +291,8 @@ void godot_register_collections_icalls() {
mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_RemoveKey", (void *)godot_icall_Dictionary_RemoveKey);
mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Remove", (void *)godot_icall_Dictionary_Remove);
mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_TryGetValue", (void *)godot_icall_Dictionary_TryGetValue);
+ mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_TryGetValue_Generic", (void *)godot_icall_Dictionary_TryGetValue_Generic);
+ mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Generic_GetValueTypeInfo", (void *)godot_icall_Dictionary_Generic_GetValueTypeInfo);
}
#endif // MONO_GLUE_ENABLED
diff --git a/modules/mono/glue/collections_glue.h b/modules/mono/glue/collections_glue.h
index fa8e4c28aa..b9b1338510 100644
--- a/modules/mono/glue/collections_glue.h
+++ b/modules/mono/glue/collections_glue.h
@@ -45,6 +45,8 @@ void godot_icall_Array_Dtor(Array *ptr);
MonoObject *godot_icall_Array_At(Array *ptr, int index);
+MonoObject *godot_icall_Array_At_Generic(Array *ptr, int index, uint32_t type_encoding, GDMonoClass *type_class);
+
void godot_icall_Array_SetAt(Array *ptr, int index, MonoObject *value);
int godot_icall_Array_Count(Array *ptr);
@@ -65,6 +67,8 @@ bool godot_icall_Array_Remove(Array *ptr, MonoObject *item);
void godot_icall_Array_RemoveAt(Array *ptr, int index);
+void godot_icall_Array_Generic_GetElementTypeInfo(MonoReflectionType *refltype, uint32_t *type_encoding, GDMonoClass **type_class);
+
// Dictionary
Dictionary *godot_icall_Dictionary_Ctor();
@@ -73,6 +77,8 @@ void godot_icall_Dictionary_Dtor(Dictionary *ptr);
MonoObject *godot_icall_Dictionary_GetValue(Dictionary *ptr, MonoObject *key);
+MonoObject *godot_icall_Dictionary_GetValue_Generic(Dictionary *ptr, MonoObject *key, uint32_t type_encoding, GDMonoClass *type_class);
+
void godot_icall_Dictionary_SetValue(Dictionary *ptr, MonoObject *key, MonoObject *value);
Array *godot_icall_Dictionary_Keys(Dictionary *ptr);
@@ -95,6 +101,10 @@ bool godot_icall_Dictionary_Remove(Dictionary *ptr, MonoObject *key, MonoObject
bool godot_icall_Dictionary_TryGetValue(Dictionary *ptr, MonoObject *key, MonoObject **value);
+bool godot_icall_Dictionary_TryGetValue_Generic(Dictionary *ptr, MonoObject *key, MonoObject **value, uint32_t type_encoding, GDMonoClass *type_class);
+
+void godot_icall_Dictionary_Generic_GetValueTypeInfo(MonoReflectionType *refltype, uint32_t *type_encoding, GDMonoClass **type_class);
+
// Register internal calls
void godot_register_collections_icalls();