mirror of
https://github.com/godotengine/godot.git
synced 2024-11-27 09:16:35 +08:00
Fix get_all_delegates method for generic classes
If the class is generic, we must get its generic type definition and use it to retrieve the delegates.
This commit is contained in:
parent
892a5a72cd
commit
d28be4d580
@ -79,6 +79,18 @@ namespace Godot
|
||||
/// </exception>
|
||||
private static bool TypeIsGenericIDictionary(Type type) => type.GetGenericTypeDefinition() == typeof(IDictionary<,>);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the generic type definition of <paramref name="type"/>.
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// Thrown when the given <paramref name="type"/> is not a generic type.
|
||||
/// That is, <see cref="Type.IsGenericType"/> returns <see langword="false"/>.
|
||||
/// </exception>
|
||||
private static void GetGenericTypeDefinition(Type type, out Type genericTypeDefinition)
|
||||
{
|
||||
genericTypeDefinition = type.GetGenericTypeDefinition();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the element type for the given <paramref name="arrayType"/>.
|
||||
/// </summary>
|
||||
|
@ -177,6 +177,8 @@ void CachedData::clear_godot_api_cache() {
|
||||
methodthunk_MarshalUtils_TypeIsGenericICollection.nullify();
|
||||
methodthunk_MarshalUtils_TypeIsGenericIDictionary.nullify();
|
||||
|
||||
methodthunk_MarshalUtils_GetGenericTypeDefinition.nullify();
|
||||
|
||||
methodthunk_MarshalUtils_ArrayGetElementType.nullify();
|
||||
methodthunk_MarshalUtils_DictionaryGetKeyValueTypes.nullify();
|
||||
|
||||
@ -299,6 +301,8 @@ void update_godot_api_cache() {
|
||||
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericICollection, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericICollection", 1));
|
||||
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericIDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericIDictionary", 1));
|
||||
|
||||
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GetGenericTypeDefinition, GODOT_API_CLASS(MarshalUtils)->get_method("GetGenericTypeDefinition", 2));
|
||||
|
||||
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, ArrayGetElementType, GODOT_API_CLASS(MarshalUtils)->get_method("ArrayGetElementType", 2));
|
||||
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, DictionaryGetKeyValueTypes, GODOT_API_CLASS(MarshalUtils)->get_method("DictionaryGetKeyValueTypes", 3));
|
||||
|
||||
|
@ -148,6 +148,8 @@ struct CachedData {
|
||||
GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericICollection;
|
||||
GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericIDictionary;
|
||||
|
||||
GDMonoMethodThunk<MonoReflectionType *, MonoReflectionType **> methodthunk_MarshalUtils_GetGenericTypeDefinition;
|
||||
|
||||
GDMonoMethodThunk<MonoReflectionType *, MonoReflectionType **> methodthunk_MarshalUtils_ArrayGetElementType;
|
||||
GDMonoMethodThunk<MonoReflectionType *, MonoReflectionType **, MonoReflectionType **> methodthunk_MarshalUtils_DictionaryGetKeyValueTypes;
|
||||
|
||||
|
@ -464,9 +464,18 @@ const Vector<GDMonoClass *> &GDMonoClass::get_all_delegates() {
|
||||
return delegates_list;
|
||||
}
|
||||
|
||||
// If the class is generic we must use the generic type definition.
|
||||
MonoClass *klass = mono_class;
|
||||
if (mono_type_get_type(get_mono_type()) == MONO_TYPE_GENERICINST) {
|
||||
MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), get_mono_type());
|
||||
GDMonoUtils::Marshal::get_generic_type_definition(reftype, &reftype);
|
||||
MonoType *type = mono_reflection_type_get_type(reftype);
|
||||
klass = mono_class_from_mono_type(type);
|
||||
}
|
||||
|
||||
void *iter = nullptr;
|
||||
MonoClass *raw_class = nullptr;
|
||||
while ((raw_class = mono_class_get_nested_types(mono_class, &iter)) != nullptr) {
|
||||
while ((raw_class = mono_class_get_nested_types(klass, &iter)) != nullptr) {
|
||||
if (mono_class_is_delegate(raw_class)) {
|
||||
StringName name = String::utf8(mono_class_get_name(raw_class));
|
||||
|
||||
|
@ -614,6 +614,12 @@ bool type_is_generic_idictionary(MonoReflectionType *p_reftype) {
|
||||
return (bool)res;
|
||||
}
|
||||
|
||||
void get_generic_type_definition(MonoReflectionType *p_reftype, MonoReflectionType **r_generic_reftype) {
|
||||
MonoException *exc = nullptr;
|
||||
CACHED_METHOD_THUNK(MarshalUtils, GetGenericTypeDefinition).invoke(p_reftype, r_generic_reftype, &exc);
|
||||
UNHANDLED_EXCEPTION(exc);
|
||||
}
|
||||
|
||||
void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype) {
|
||||
MonoException *exc = nullptr;
|
||||
CACHED_METHOD_THUNK(MarshalUtils, ArrayGetElementType).invoke(p_array_reftype, r_elem_reftype, &exc);
|
||||
|
@ -62,6 +62,8 @@ bool type_is_generic_ienumerable(MonoReflectionType *p_reftype);
|
||||
bool type_is_generic_icollection(MonoReflectionType *p_reftype);
|
||||
bool type_is_generic_idictionary(MonoReflectionType *p_reftype);
|
||||
|
||||
void get_generic_type_definition(MonoReflectionType *p_reftype, MonoReflectionType **r_generic_reftype);
|
||||
|
||||
void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype);
|
||||
void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user