Skip to content

Commit

Permalink
Merge pull request godotengine#29079 from neikeq/oopsie
Browse files Browse the repository at this point in the history
Fix C# build error in MarshalUtils debug code
  • Loading branch information
neikeq authored May 21, 2019
2 parents 00232b1 + 9b76c56 commit e2375f4
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 27 deletions.
4 changes: 2 additions & 2 deletions modules/mono/glue/Managed/Files/Extensions/NodeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ public T GetChildOrNull<T>(int idx) where T : class

public T GetOwner<T>() where T : class
{
return (T)(object)GetOwner();
return (T)(object)Owner;
}

public T GetOwnerOrNull<T>() where T : class
{
return GetOwner() as T;
return Owner as T;
}

public T GetParent<T>() where T : class
Expand Down
40 changes: 39 additions & 1 deletion modules/mono/glue/Managed/Files/MarshalUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ static bool TypeIsGenericArray(Type type)

/// <summary>
/// Returns <see langword="true"/> if the generic type definition of <paramref name="type"/>
/// is <see cref="Godot.Collections.Dictionary{T}"/>; otherwise returns <see langword="false"/>.
/// is <see cref="Godot.Collections.Dictionary{TKey, TValue}"/>; otherwise returns <see langword="false"/>.
/// </summary>
/// <exception cref="System.InvalidOperationException">
/// <paramref name="type"/> is not a generic type. That is, IsGenericType returns false.
Expand All @@ -45,6 +45,44 @@ static void DictionaryGetKeyValueTypes(Type dictionaryType, out Type keyType, ou
valueType = genericArgs[1];
}

static bool GenericIEnumerableIsAssignableFromType(Type type)
{
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
return true;

foreach (var interfaceType in type.GetInterfaces())
{
if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
return true;
}

Type baseType = type.BaseType;

if (baseType == null)
return false;

return GenericIEnumerableIsAssignableFromType(baseType);
}

static bool GenericIDictionaryIsAssignableFromType(Type type)
{
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary<,>))
return true;

foreach (var interfaceType in type.GetInterfaces())
{
if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IDictionary<,>))
return true;
}

Type baseType = type.BaseType;

if (baseType == null)
return false;

return GenericIDictionaryIsAssignableFromType(baseType);
}

static bool GenericIEnumerableIsAssignableFromType(Type type, out Type elementType)
{
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
Expand Down
5 changes: 3 additions & 2 deletions modules/mono/glue/Managed/IgnoredFiles/Node.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ public Node GetNode(NodePath path)
throw new NotImplementedException();
}

public Node GetOwner()
public Node Owner
{
throw new NotImplementedException();
get => throw new NotImplementedException();
set => throw new NotImplementedException();
}

public Node GetParent()
Expand Down
24 changes: 8 additions & 16 deletions modules/mono/mono_gd/gd_mono_marshal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,17 +161,15 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) {

MonoReflectionType *reftype = mono_type_get_object(SCRIPTS_DOMAIN, type_class->get_mono_type());

MonoReflectionType *key_reftype, *value_reftype;
if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) {
if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype)) {
return Variant::DICTIONARY;
}

if (type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
return Variant::DICTIONARY;
}

MonoReflectionType *elem_reftype;
if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype, &elem_reftype)) {
if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype)) {
return Variant::ARRAY;
}

Expand All @@ -193,16 +191,14 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) {

// The order in which we check the following interfaces is very important (dictionaries and generics first)

MonoReflectionType *key_reftype, *value_reftype;
if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype))
if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype))
return Variant::DICTIONARY;

if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
return Variant::DICTIONARY;
}

MonoReflectionType *elem_reftype;
if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype, &elem_reftype))
if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype))
return Variant::ARRAY;

if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
Expand Down Expand Up @@ -850,17 +846,15 @@ Variant mono_object_to_variant(MonoObject *p_obj) {

MonoReflectionType *reftype = mono_type_get_object(SCRIPTS_DOMAIN, type_class->get_mono_type());

MonoReflectionType *key_reftype, *value_reftype;
if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) {
if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype)) {
return GDMonoUtils::Marshal::generic_idictionary_to_dictionary(p_obj);
}

if (type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
return GDMonoUtils::Marshal::idictionary_to_dictionary(p_obj);
}

MonoReflectionType *elem_reftype;
if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype, &elem_reftype)) {
if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype)) {
return GDMonoUtils::Marshal::enumerable_to_array(p_obj);
}

Expand Down Expand Up @@ -888,17 +882,15 @@ Variant mono_object_to_variant(MonoObject *p_obj) {

// The order in which we check the following interfaces is very important (dictionaries and generics first)

MonoReflectionType *key_reftype, *value_reftype;
if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) {
if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype)) {
return GDMonoUtils::Marshal::generic_idictionary_to_dictionary(p_obj);
}

if (type.type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
return GDMonoUtils::Marshal::idictionary_to_dictionary(p_obj);
}

MonoReflectionType *elem_reftype;
if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype, &elem_reftype)) {
if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype)) {
return GDMonoUtils::Marshal::enumerable_to_array(p_obj);
}

Expand Down
28 changes: 24 additions & 4 deletions modules/mono/mono_gd/gd_mono_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ void MonoCache::clear_members() {

methodthunk_MarshalUtils_GenericIEnumerableIsAssignableFromType = NULL;
methodthunk_MarshalUtils_GenericIDictionaryIsAssignableFromType = NULL;
methodthunk_MarshalUtils_GenericIEnumerableIsAssignableFromType_with_info = NULL;
methodthunk_MarshalUtils_GenericIDictionaryIsAssignableFromType_with_info = NULL;

methodthunk_MarshalUtils_MakeGenericArrayType = NULL;
methodthunk_MarshalUtils_MakeGenericDictionaryType = NULL;
Expand Down Expand Up @@ -282,8 +284,10 @@ void update_godot_api_cache() {
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, ArrayGetElementType, (ArrayGetElementType)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("ArrayGetElementType", 2));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, DictionaryGetKeyValueTypes, (DictionaryGetKeyValueTypes)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("DictionaryGetKeyValueTypes", 3));

CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIEnumerableIsAssignableFromType, (GenericIEnumerableIsAssignableFromType)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("GenericIEnumerableIsAssignableFromType", 2));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIDictionaryIsAssignableFromType, (GenericIDictionaryIsAssignableFromType)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("GenericIDictionaryIsAssignableFromType", 3));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIEnumerableIsAssignableFromType, (GenericIEnumerableIsAssignableFromType)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("GenericIEnumerableIsAssignableFromType", 1));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIDictionaryIsAssignableFromType, (GenericIDictionaryIsAssignableFromType)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("GenericIDictionaryIsAssignableFromType", 1));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIEnumerableIsAssignableFromType_with_info, (GenericIEnumerableIsAssignableFromType_with_info)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("GenericIEnumerableIsAssignableFromType", 2));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIEnumerableIsAssignableFromType_with_info, (GenericIEnumerableIsAssignableFromType_with_info)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("GenericIDictionaryIsAssignableFromType", 3));

CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, MakeGenericArrayType, (MakeGenericArrayType)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("MakeGenericArrayType", 1));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, MakeGenericDictionaryType, (MakeGenericDictionaryType)GODOT_API_CLASS(MarshalUtils)->get_method_thunk("MakeGenericDictionaryType", 2));
Expand Down Expand Up @@ -787,16 +791,32 @@ void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoRefl
UNLIKELY_UNHANDLED_EXCEPTION(exc);
}

MonoBoolean generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_elem_reftype) {
MonoBoolean generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype) {
GenericIEnumerableIsAssignableFromType thunk = CACHED_METHOD_THUNK(MarshalUtils, GenericIEnumerableIsAssignableFromType);
MonoException *exc = NULL;
MonoBoolean res = invoke_method_thunk(thunk, p_reftype, &exc);
UNLIKELY_UNHANDLED_EXCEPTION(exc);
return res;
}

MonoBoolean generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype) {
GenericIDictionaryIsAssignableFromType thunk = CACHED_METHOD_THUNK(MarshalUtils, GenericIDictionaryIsAssignableFromType);
MonoException *exc = NULL;
MonoBoolean res = invoke_method_thunk(thunk, p_reftype, &exc);
UNLIKELY_UNHANDLED_EXCEPTION(exc);
return res;
}

MonoBoolean generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_elem_reftype) {
GenericIEnumerableIsAssignableFromType_with_info thunk = CACHED_METHOD_THUNK(MarshalUtils, GenericIEnumerableIsAssignableFromType_with_info);
MonoException *exc = NULL;
MonoBoolean res = invoke_method_thunk(thunk, p_reftype, r_elem_reftype, &exc);
UNLIKELY_UNHANDLED_EXCEPTION(exc);
return res;
}

MonoBoolean generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype) {
GenericIDictionaryIsAssignableFromType thunk = CACHED_METHOD_THUNK(MarshalUtils, GenericIDictionaryIsAssignableFromType);
GenericIDictionaryIsAssignableFromType_with_info thunk = CACHED_METHOD_THUNK(MarshalUtils, GenericIDictionaryIsAssignableFromType_with_info);
MonoException *exc = NULL;
MonoBoolean res = invoke_method_thunk(thunk, p_reftype, r_key_reftype, r_value_reftype, &exc);
UNLIKELY_UNHANDLED_EXCEPTION(exc);
Expand Down
10 changes: 8 additions & 2 deletions modules/mono/mono_gd/gd_mono_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,10 @@ typedef MonoBoolean (*TypeIsGenericDictionary)(MonoReflectionType *, MonoExcepti
typedef void (*ArrayGetElementType)(MonoReflectionType *, MonoReflectionType **, MonoException **);
typedef void (*DictionaryGetKeyValueTypes)(MonoReflectionType *, MonoReflectionType **, MonoReflectionType **, MonoException **);

typedef MonoBoolean (*GenericIEnumerableIsAssignableFromType)(MonoReflectionType *, MonoReflectionType **, MonoException **);
typedef MonoBoolean (*GenericIDictionaryIsAssignableFromType)(MonoReflectionType *, MonoReflectionType **, MonoReflectionType **, MonoException **);
typedef MonoBoolean (*GenericIEnumerableIsAssignableFromType)(MonoReflectionType *, MonoException **);
typedef MonoBoolean (*GenericIDictionaryIsAssignableFromType)(MonoReflectionType *, MonoException **);
typedef MonoBoolean (*GenericIEnumerableIsAssignableFromType_with_info)(MonoReflectionType *, MonoReflectionType **, MonoException **);
typedef MonoBoolean (*GenericIDictionaryIsAssignableFromType_with_info)(MonoReflectionType *, MonoReflectionType **, MonoReflectionType **, MonoException **);

typedef MonoReflectionType *(*MakeGenericArrayType)(MonoReflectionType *, MonoException **);
typedef MonoReflectionType *(*MakeGenericDictionaryType)(MonoReflectionType *, MonoReflectionType *, MonoException **);
Expand All @@ -82,6 +84,8 @@ MonoBoolean type_is_generic_dictionary(MonoReflectionType *p_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);

MonoBoolean generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype);
MonoBoolean generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype);
MonoBoolean generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_elem_reftype);
MonoBoolean generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype);

Expand Down Expand Up @@ -197,6 +201,8 @@ struct MonoCache {

GenericIEnumerableIsAssignableFromType methodthunk_MarshalUtils_GenericIEnumerableIsAssignableFromType;
GenericIDictionaryIsAssignableFromType methodthunk_MarshalUtils_GenericIDictionaryIsAssignableFromType;
GenericIEnumerableIsAssignableFromType_with_info methodthunk_MarshalUtils_GenericIEnumerableIsAssignableFromType_with_info;
GenericIDictionaryIsAssignableFromType_with_info methodthunk_MarshalUtils_GenericIDictionaryIsAssignableFromType_with_info;

MakeGenericArrayType methodthunk_MarshalUtils_MakeGenericArrayType;
MakeGenericDictionaryType methodthunk_MarshalUtils_MakeGenericDictionaryType;
Expand Down

0 comments on commit e2375f4

Please sign in to comment.