Merge pull request #22460 from neikeq/issue-22403

Mono: Fix not creating generic Array or Dictionary where expected
This commit is contained in:
Ignacio Etcheverry 2018-09-27 00:38:39 +02:00 committed by GitHub
commit 2e87703136
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 179 additions and 62 deletions

View file

@ -1174,7 +1174,7 @@ bool CSharpInstance::set(const StringName &p_name, const Variant &p_value) {
GDMonoProperty *property = script->script_class->get_property(p_name); GDMonoProperty *property = script->script_class->get_property(p_name);
if (property) { if (property) {
property->set_value(mono_object, GDMonoMarshal::variant_to_mono_object(p_value)); property->set_value(mono_object, GDMonoMarshal::variant_to_mono_object(p_value, property->get_type()));
return true; return true;
} }

View file

@ -128,7 +128,7 @@ namespace Godot.Collections
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
yield return godot_icall_Array_At(GetPtr(), i); yield return this[i];
} }
} }
@ -166,6 +166,9 @@ namespace Godot.Collections
[MethodImpl(MethodImplOptions.InternalCall)] [MethodImpl(MethodImplOptions.InternalCall)]
internal extern static object godot_icall_Array_At(IntPtr ptr, int index); 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)] [MethodImpl(MethodImplOptions.InternalCall)]
internal extern static void godot_icall_Array_SetAt(IntPtr ptr, int index, object value); internal extern static void godot_icall_Array_SetAt(IntPtr ptr, int index, object value);
@ -195,12 +198,23 @@ namespace Godot.Collections
[MethodImpl(MethodImplOptions.InternalCall)] [MethodImpl(MethodImplOptions.InternalCall)]
internal extern static void godot_icall_Array_RemoveAt(IntPtr ptr, int index); 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> public class Array<T> : IList<T>, ICollection<T>, IEnumerable<T>
{ {
Array objectArray; 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() public Array()
{ {
objectArray = new Array(); objectArray = new Array();
@ -230,7 +244,7 @@ namespace Godot.Collections
{ {
get get
{ {
return (T)objectArray[index]; return (T)Array.godot_icall_Array_At_Generic(GetPtr(), index, elemTypeEncoding, elemTypeClass);
} }
set set
{ {
@ -287,7 +301,7 @@ namespace Godot.Collections
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
array[arrayIndex] = (T)objectArray[i]; array[arrayIndex] = (T)this[i];
arrayIndex++; arrayIndex++;
} }
} }
@ -298,7 +312,7 @@ namespace Godot.Collections
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
yield return (T)objectArray[i]; yield return (T)this[i];
} }
} }

View file

@ -203,6 +203,9 @@ namespace Godot.Collections
[MethodImpl(MethodImplOptions.InternalCall)] [MethodImpl(MethodImplOptions.InternalCall)]
internal extern static object godot_icall_Dictionary_GetValue(IntPtr ptr, object key); 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)] [MethodImpl(MethodImplOptions.InternalCall)]
internal extern static void godot_icall_Dictionary_SetValue(IntPtr ptr, object key, object value); internal extern static void godot_icall_Dictionary_SetValue(IntPtr ptr, object key, object value);
@ -235,6 +238,12 @@ namespace Godot.Collections
[MethodImpl(MethodImplOptions.InternalCall)] [MethodImpl(MethodImplOptions.InternalCall)]
internal extern static bool godot_icall_Dictionary_TryGetValue(IntPtr ptr, object key, out object value); 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> : public class Dictionary<TKey, TValue> :
@ -244,6 +253,14 @@ namespace Godot.Collections
{ {
Dictionary objectDict; 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() public Dictionary()
{ {
objectDict = new Dictionary(); objectDict = new Dictionary();
@ -273,7 +290,7 @@ namespace Godot.Collections
{ {
get get
{ {
return (TValue)objectDict[key]; return (TValue)Dictionary.godot_icall_Dictionary_GetValue_Generic(objectDict.GetPtr(), key, valTypeEncoding, valTypeClass);
} }
set set
{ {
@ -382,7 +399,7 @@ namespace Godot.Collections
public bool TryGetValue(TKey key, out TValue value) public bool TryGetValue(TKey key, out TValue value)
{ {
object retValue; 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); value = found ? (TValue)retValue : default(TValue);
return found; return found;
} }

View file

@ -53,6 +53,14 @@ MonoObject *godot_icall_Array_At(Array *ptr, int index) {
return GDMonoMarshal::variant_to_mono_object(ptr->operator[](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) { void godot_icall_Array_SetAt(Array *ptr, int index, MonoObject *value) {
if (index < 0 || index > ptr->size()) { if (index < 0 || index > ptr->size()) {
GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range()); 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); 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() { Dictionary *godot_icall_Dictionary_Ctor() {
return memnew(Dictionary); return memnew(Dictionary);
} }
@ -144,6 +160,20 @@ MonoObject *godot_icall_Dictionary_GetValue(Dictionary *ptr, MonoObject *key) {
return GDMonoMarshal::variant_to_mono_object(ret); 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) { 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); 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; 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() { 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", (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_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", (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_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_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_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_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_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_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_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_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", (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_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_Keys", (void *)godot_icall_Dictionary_Keys);
mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Values", (void *)godot_icall_Dictionary_Values); 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_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_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", (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 #endif // MONO_GLUE_ENABLED

View file

@ -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(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); void godot_icall_Array_SetAt(Array *ptr, int index, MonoObject *value);
int godot_icall_Array_Count(Array *ptr); 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_RemoveAt(Array *ptr, int index);
void godot_icall_Array_Generic_GetElementTypeInfo(MonoReflectionType *refltype, uint32_t *type_encoding, GDMonoClass **type_class);
// Dictionary // Dictionary
Dictionary *godot_icall_Dictionary_Ctor(); 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(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); void godot_icall_Dictionary_SetValue(Dictionary *ptr, MonoObject *key, MonoObject *value);
Array *godot_icall_Dictionary_Keys(Dictionary *ptr); 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(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 // Register internal calls
void godot_register_collections_icalls(); void godot_register_collections_icalls();

View file

@ -259,14 +259,15 @@ void GDMono::initialize() {
// The following assemblies are not required at initialization // The following assemblies are not required at initialization
#ifdef MONO_GLUE_ENABLED #ifdef MONO_GLUE_ENABLED
if (_load_api_assemblies()) { if (_load_api_assemblies()) {
if (!core_api_assembly_out_of_sync && !editor_api_assembly_out_of_sync && GDMonoUtils::mono_cache.godot_api_cache_updated) { // Everything is fine with the api assemblies, load the project assembly
// Everything is fine with the api assemblies, load the project assembly _load_project_assembly();
_load_project_assembly(); } else {
} else { if ((core_api_assembly && (core_api_assembly_out_of_sync || !GDMonoUtils::mono_cache.godot_api_cache_updated)) ||
(editor_api_assembly && editor_api_assembly_out_of_sync)) {
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
// The assembly was successfully loaded, but the full api could not be cached. // The assembly was successfully loaded, but the full api could not be cached.
// This is most likely an outdated assembly loaded because of an invalid version in the metadata, // This is most likely an outdated assembly loaded because of an invalid version in the
// so we invalidate the version in the metadata and unload the script domain. // metadata, so we invalidate the version in the metadata and unload the script domain.
if (core_api_assembly_out_of_sync) { if (core_api_assembly_out_of_sync) {
ERR_PRINT("The loaded Core API assembly is out of sync"); ERR_PRINT("The loaded Core API assembly is out of sync");
@ -290,12 +291,12 @@ void GDMono::initialize() {
#else #else
ERR_PRINT("The loaded API assembly is invalid"); ERR_PRINT("The loaded API assembly is invalid");
CRASH_NOW(); CRASH_NOW();
#endif #endif // TOOLS_ENABLED
} }
} }
#else #else
print_verbose("Mono: Glue disabled, ignoring script assemblies."); print_verbose("Mono: Glue disabled, ignoring script assemblies.");
#endif #endif // MONO_GLUE_ENABLED
print_verbose("Mono: INITIALIZED"); print_verbose("Mono: INITIALIZED");
} }
@ -448,8 +449,10 @@ bool GDMono::_load_core_api_assembly() {
return true; return true;
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
if (metadata_is_api_assembly_invalidated(APIAssembly::API_CORE)) if (metadata_is_api_assembly_invalidated(APIAssembly::API_CORE)) {
print_verbose("Mono: Skipping loading of Core API assembly because it was invalidated");
return false; return false;
}
#endif #endif
bool success = load_assembly(API_ASSEMBLY_NAME, &core_api_assembly); bool success = load_assembly(API_ASSEMBLY_NAME, &core_api_assembly);
@ -460,8 +463,12 @@ bool GDMono::_load_core_api_assembly() {
core_api_assembly_out_of_sync = GodotSharpBindings::get_core_api_hash() != api_assembly_ver.godot_api_hash || core_api_assembly_out_of_sync = GodotSharpBindings::get_core_api_hash() != api_assembly_ver.godot_api_hash ||
GodotSharpBindings::get_bindings_version() != api_assembly_ver.bindings_version || GodotSharpBindings::get_bindings_version() != api_assembly_ver.bindings_version ||
CS_GLUE_VERSION != api_assembly_ver.cs_glue_version; CS_GLUE_VERSION != api_assembly_ver.cs_glue_version;
#endif if (!core_api_assembly_out_of_sync) {
GDMonoUtils::update_godot_api_cache();
}
#else
GDMonoUtils::update_godot_api_cache(); GDMonoUtils::update_godot_api_cache();
#endif
} }
return success; return success;
@ -474,8 +481,10 @@ bool GDMono::_load_editor_api_assembly() {
return true; return true;
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
if (metadata_is_api_assembly_invalidated(APIAssembly::API_EDITOR)) if (metadata_is_api_assembly_invalidated(APIAssembly::API_EDITOR)) {
print_verbose("Mono: Skipping loading of Editor API assembly because it was invalidated");
return false; return false;
}
#endif #endif
bool success = load_assembly(EDITOR_API_ASSEMBLY_NAME, &editor_api_assembly); bool success = load_assembly(EDITOR_API_ASSEMBLY_NAME, &editor_api_assembly);
@ -533,16 +542,22 @@ bool GDMono::_load_api_assemblies() {
if (OS::get_singleton()->is_stdout_verbose()) if (OS::get_singleton()->is_stdout_verbose())
print_error("Mono: Failed to load Core API assembly"); print_error("Mono: Failed to load Core API assembly");
return false; return false;
} else {
#ifdef TOOLS_ENABLED
if (!_load_editor_api_assembly()) {
if (OS::get_singleton()->is_stdout_verbose())
print_error("Mono: Failed to load Editor API assembly");
return false;
}
#endif
} }
if (core_api_assembly_out_of_sync || !GDMonoUtils::mono_cache.godot_api_cache_updated)
return false;
#ifdef TOOLS_ENABLED
if (!_load_editor_api_assembly()) {
if (OS::get_singleton()->is_stdout_verbose())
print_error("Mono: Failed to load Editor API assembly");
return false;
}
if (editor_api_assembly_out_of_sync)
return false;
#endif
return true; return true;
} }
@ -708,43 +723,42 @@ Error GDMono::reload_scripts_domain() {
#ifdef MONO_GLUE_ENABLED #ifdef MONO_GLUE_ENABLED
if (!_load_api_assemblies()) { if (!_load_api_assemblies()) {
return ERR_CANT_OPEN; if ((core_api_assembly && (core_api_assembly_out_of_sync || !GDMonoUtils::mono_cache.godot_api_cache_updated)) ||
(editor_api_assembly && editor_api_assembly_out_of_sync)) {
// The assembly was successfully loaded, but the full api could not be cached.
// This is most likely an outdated assembly loaded because of an invalid version in the
// metadata, so we invalidate the version in the metadata and unload the script domain.
if (core_api_assembly_out_of_sync) {
ERR_PRINT("The loaded Core API assembly is out of sync");
metadata_set_api_assembly_invalidated(APIAssembly::API_CORE, true);
} else if (!GDMonoUtils::mono_cache.godot_api_cache_updated) {
ERR_PRINT("The loaded Core API assembly is in sync, but the cache update failed");
metadata_set_api_assembly_invalidated(APIAssembly::API_CORE, true);
}
if (editor_api_assembly_out_of_sync) {
ERR_PRINT("The loaded Editor API assembly is out of sync");
metadata_set_api_assembly_invalidated(APIAssembly::API_EDITOR, true);
}
Error err = _unload_scripts_domain();
if (err != OK) {
WARN_PRINT("Mono: Failed to unload scripts domain");
}
return ERR_CANT_RESOLVE;
} else {
return ERR_CANT_OPEN;
}
} }
if (!core_api_assembly_out_of_sync && !editor_api_assembly_out_of_sync && GDMonoUtils::mono_cache.godot_api_cache_updated) { if (!_load_project_assembly()) {
// Everything is fine with the api assemblies, load the project assembly
_load_project_assembly();
} else {
// The assembly was successfully loaded, but the full api could not be cached.
// This is most likely an outdated assembly loaded because of an invalid version in the metadata,
// so we invalidate the version in the metadata and unload the script domain.
if (core_api_assembly_out_of_sync) {
ERR_PRINT("The loaded Core API assembly is out of sync");
metadata_set_api_assembly_invalidated(APIAssembly::API_CORE, true);
} else if (!GDMonoUtils::mono_cache.godot_api_cache_updated) {
ERR_PRINT("The loaded Core API assembly is in sync, but the cache update failed");
metadata_set_api_assembly_invalidated(APIAssembly::API_CORE, true);
}
if (editor_api_assembly_out_of_sync) {
ERR_PRINT("The loaded Editor API assembly is out of sync");
metadata_set_api_assembly_invalidated(APIAssembly::API_EDITOR, true);
}
Error err = _unload_scripts_domain();
if (err != OK) {
WARN_PRINT("Mono: Failed to unload scripts domain");
}
return ERR_CANT_RESOLVE;
}
if (!_load_project_assembly())
return ERR_CANT_OPEN; return ERR_CANT_OPEN;
}
#else #else
print_verbose("Mono: Glue disabled, ignoring script assemblies."); print_verbose("Mono: Glue disabled, ignoring script assemblies.");
#endif #endif // MONO_GLUE_ENABLED
return OK; return OK;
} }

View file

@ -44,9 +44,14 @@ struct ManagedType {
int type_encoding; int type_encoding;
GDMonoClass *type_class; GDMonoClass *type_class;
ManagedType() { ManagedType() :
type_encoding = 0; type_encoding(0),
type_class = NULL; type_class(NULL) {
}
ManagedType(int p_type_encoding, GDMonoClass *p_type_class) :
type_encoding(p_type_encoding),
type_class(p_type_class) {
} }
}; };

View file

@ -97,10 +97,14 @@ _FORCE_INLINE_ MonoString *mono_string_from_godot(const String &p_string) {
MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_type); MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_type);
MonoObject *variant_to_mono_object(const Variant *p_var); MonoObject *variant_to_mono_object(const Variant *p_var);
_FORCE_INLINE_ MonoObject *variant_to_mono_object(Variant p_var) { _FORCE_INLINE_ MonoObject *variant_to_mono_object(const Variant &p_var) {
return variant_to_mono_object(&p_var); return variant_to_mono_object(&p_var);
} }
_FORCE_INLINE_ MonoObject *variant_to_mono_object(const Variant &p_var, const ManagedType &p_type) {
return variant_to_mono_object(&p_var, p_type);
}
Variant mono_object_to_variant(MonoObject *p_obj); Variant mono_object_to_variant(MonoObject *p_obj);
// Array // Array