Merge pull request #40137 from neikeq/fix-clangtidy-warnings-mono

Mono/C#: Fix several clang-tidy warnings and cleanup
This commit is contained in:
Rémi Verschelde 2020-07-05 22:32:27 +02:00 committed by GitHub
commit 347a55d4c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 935 additions and 1205 deletions

View File

@ -53,8 +53,9 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
for (List<StringName>::Element *E = names.front(); E; E = E->next()) { for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
ClassDB::ClassInfo *t = ClassDB::classes.getptr(E->get()); ClassDB::ClassInfo *t = ClassDB::classes.getptr(E->get());
ERR_FAIL_COND(!t); ERR_FAIL_COND(!t);
if (t->api != p_api || !t->exposed) if (t->api != p_api || !t->exposed) {
continue; continue;
}
Dictionary class_dict; Dictionary class_dict;
classes_dict[t->name] = class_dict; classes_dict[t->name] = class_dict;
@ -72,8 +73,9 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
ERR_CONTINUE(name.empty()); ERR_CONTINUE(name.empty());
if (name[0] == '_') if (name[0] == '_') {
continue; // Ignore non-virtual methods that start with an underscore continue; // Ignore non-virtual methods that start with an underscore
}
snames.push_back(*k); snames.push_back(*k);
} }

View File

@ -125,8 +125,9 @@ void CSharpLanguage::init() {
print_line("Run this binary with '--generate-mono-glue path/to/modules/mono/glue'"); print_line("Run this binary with '--generate-mono-glue path/to/modules/mono/glue'");
#endif #endif
if (gdmono->is_runtime_initialized()) if (gdmono->is_runtime_initialized()) {
gdmono->initialize_load_assemblies(); gdmono->initialize_load_assemblies();
}
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
EditorNode::add_init_callback(&_editor_init_callback); EditorNode::add_init_callback(&_editor_init_callback);
@ -134,8 +135,13 @@ void CSharpLanguage::init() {
} }
void CSharpLanguage::finish() { void CSharpLanguage::finish() {
if (finalized) finalize();
}
void CSharpLanguage::finalize() {
if (finalized) {
return; return;
}
finalizing = true; finalizing = true;
@ -390,15 +396,17 @@ bool CSharpLanguage::supports_builtin_mode() const {
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
static String variant_type_to_managed_name(const String &p_var_type_name) { static String variant_type_to_managed_name(const String &p_var_type_name) {
if (p_var_type_name.empty()) if (p_var_type_name.empty()) {
return "object"; return "object";
}
if (!ClassDB::class_exists(p_var_type_name)) { if (!ClassDB::class_exists(p_var_type_name)) {
return p_var_type_name; return p_var_type_name;
} }
if (p_var_type_name == Variant::get_type_name(Variant::OBJECT)) if (p_var_type_name == Variant::get_type_name(Variant::OBJECT)) {
return "Godot.Object"; return "Godot.Object";
}
if (p_var_type_name == Variant::get_type_name(Variant::FLOAT)) { if (p_var_type_name == Variant::get_type_name(Variant::FLOAT)) {
#ifdef REAL_T_IS_DOUBLE #ifdef REAL_T_IS_DOUBLE
@ -408,36 +416,49 @@ static String variant_type_to_managed_name(const String &p_var_type_name) {
#endif #endif
} }
if (p_var_type_name == Variant::get_type_name(Variant::STRING)) if (p_var_type_name == Variant::get_type_name(Variant::STRING)) {
return "string"; // I prefer this one >:[ return "string"; // I prefer this one >:[
}
if (p_var_type_name == Variant::get_type_name(Variant::DICTIONARY)) if (p_var_type_name == Variant::get_type_name(Variant::DICTIONARY)) {
return "Collections.Dictionary"; return "Collections.Dictionary";
}
if (p_var_type_name == Variant::get_type_name(Variant::ARRAY)) if (p_var_type_name == Variant::get_type_name(Variant::ARRAY)) {
return "Collections.Array"; return "Collections.Array";
}
if (p_var_type_name == Variant::get_type_name(Variant::PACKED_BYTE_ARRAY)) if (p_var_type_name == Variant::get_type_name(Variant::PACKED_BYTE_ARRAY)) {
return "byte[]"; return "byte[]";
if (p_var_type_name == Variant::get_type_name(Variant::PACKED_INT32_ARRAY)) }
if (p_var_type_name == Variant::get_type_name(Variant::PACKED_INT32_ARRAY)) {
return "int[]"; return "int[]";
if (p_var_type_name == Variant::get_type_name(Variant::PACKED_INT64_ARRAY)) }
if (p_var_type_name == Variant::get_type_name(Variant::PACKED_INT64_ARRAY)) {
return "long[]"; return "long[]";
if (p_var_type_name == Variant::get_type_name(Variant::PACKED_FLOAT32_ARRAY)) }
if (p_var_type_name == Variant::get_type_name(Variant::PACKED_FLOAT32_ARRAY)) {
return "float[]"; return "float[]";
if (p_var_type_name == Variant::get_type_name(Variant::PACKED_FLOAT64_ARRAY)) }
if (p_var_type_name == Variant::get_type_name(Variant::PACKED_FLOAT64_ARRAY)) {
return "double[]"; return "double[]";
if (p_var_type_name == Variant::get_type_name(Variant::PACKED_STRING_ARRAY)) }
if (p_var_type_name == Variant::get_type_name(Variant::PACKED_STRING_ARRAY)) {
return "string[]"; return "string[]";
if (p_var_type_name == Variant::get_type_name(Variant::PACKED_VECTOR2_ARRAY)) }
if (p_var_type_name == Variant::get_type_name(Variant::PACKED_VECTOR2_ARRAY)) {
return "Vector2[]"; return "Vector2[]";
if (p_var_type_name == Variant::get_type_name(Variant::PACKED_VECTOR3_ARRAY)) }
if (p_var_type_name == Variant::get_type_name(Variant::PACKED_VECTOR3_ARRAY)) {
return "Vector3[]"; return "Vector3[]";
if (p_var_type_name == Variant::get_type_name(Variant::PACKED_COLOR_ARRAY)) }
if (p_var_type_name == Variant::get_type_name(Variant::PACKED_COLOR_ARRAY)) {
return "Color[]"; return "Color[]";
}
if (p_var_type_name == Variant::get_type_name(Variant::SIGNAL)) if (p_var_type_name == Variant::get_type_name(Variant::SIGNAL)) {
return "SignalInfo"; return "SignalInfo";
}
Variant::Type var_types[] = { Variant::Type var_types[] = {
Variant::BOOL, Variant::BOOL,
@ -462,8 +483,9 @@ static String variant_type_to_managed_name(const String &p_var_type_name) {
}; };
for (unsigned int i = 0; i < sizeof(var_types) / sizeof(Variant::Type); i++) { for (unsigned int i = 0; i < sizeof(var_types) / sizeof(Variant::Type); i++) {
if (p_var_type_name == Variant::get_type_name(var_types[i])) if (p_var_type_name == Variant::get_type_name(var_types[i])) {
return p_var_type_name; return p_var_type_name;
}
} }
return "object"; return "object";
@ -477,8 +499,9 @@ String CSharpLanguage::make_function(const String &, const String &p_name, const
for (int i = 0; i < p_args.size(); i++) { for (int i = 0; i < p_args.size(); i++) {
const String &arg = p_args[i]; const String &arg = p_args[i];
if (i > 0) if (i > 0) {
s += ", "; s += ", ";
}
s += variant_type_to_managed_name(arg.get_slice(":", 1)) + " " + escape_csharp_keyword(arg.get_slice(":", 0)); s += variant_type_to_managed_name(arg.get_slice(":", 1)) + " " + escape_csharp_keyword(arg.get_slice(":", 0));
} }
@ -516,32 +539,36 @@ String CSharpLanguage::debug_get_error() const {
} }
int CSharpLanguage::debug_get_stack_level_count() const { int CSharpLanguage::debug_get_stack_level_count() const {
if (_debug_parse_err_line >= 0) if (_debug_parse_err_line >= 0) {
return 1; return 1;
}
// TODO: StackTrace // TODO: StackTrace
return 1; return 1;
} }
int CSharpLanguage::debug_get_stack_level_line(int p_level) const { int CSharpLanguage::debug_get_stack_level_line(int p_level) const {
if (_debug_parse_err_line >= 0) if (_debug_parse_err_line >= 0) {
return _debug_parse_err_line; return _debug_parse_err_line;
}
// TODO: StackTrace // TODO: StackTrace
return 1; return 1;
} }
String CSharpLanguage::debug_get_stack_level_function(int p_level) const { String CSharpLanguage::debug_get_stack_level_function(int p_level) const {
if (_debug_parse_err_line >= 0) if (_debug_parse_err_line >= 0) {
return String(); return String();
}
// TODO: StackTrace // TODO: StackTrace
return String(); return String();
} }
String CSharpLanguage::debug_get_stack_level_source(int p_level) const { String CSharpLanguage::debug_get_stack_level_source(int p_level) const {
if (_debug_parse_err_line >= 0) if (_debug_parse_err_line >= 0) {
return _debug_parse_err_file; return _debug_parse_err_file;
}
// TODO: StackTrace // TODO: StackTrace
return String(); return String();
@ -551,15 +578,17 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::debug_get_current_stack_info()
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
// Printing an error here will result in endless recursion, so we must be careful // Printing an error here will result in endless recursion, so we must be careful
static thread_local bool _recursion_flag_ = false; static thread_local bool _recursion_flag_ = false;
if (_recursion_flag_) if (_recursion_flag_) {
return Vector<StackInfo>(); return Vector<StackInfo>();
}
_recursion_flag_ = true; _recursion_flag_ = true;
SCOPE_EXIT { _recursion_flag_ = false; }; SCOPE_EXIT { _recursion_flag_ = false; };
GD_MONO_SCOPE_THREAD_ATTACH; GD_MONO_SCOPE_THREAD_ATTACH;
if (!gdmono->is_runtime_initialized() || !GDMono::get_singleton()->get_core_api_assembly() || !GDMonoCache::cached_data.corlib_cache_updated) if (!gdmono->is_runtime_initialized() || !GDMono::get_singleton()->get_core_api_assembly() || !GDMonoCache::cached_data.corlib_cache_updated) {
return Vector<StackInfo>(); return Vector<StackInfo>();
}
MonoObject *stack_trace = mono_object_new(mono_domain_get(), CACHED_CLASS(System_Diagnostics_StackTrace)->get_mono_ptr()); MonoObject *stack_trace = mono_object_new(mono_domain_get(), CACHED_CLASS(System_Diagnostics_StackTrace)->get_mono_ptr());
@ -581,8 +610,9 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::debug_get_current_stack_info()
Vector<ScriptLanguage::StackInfo> CSharpLanguage::stack_trace_get_info(MonoObject *p_stack_trace) { Vector<ScriptLanguage::StackInfo> CSharpLanguage::stack_trace_get_info(MonoObject *p_stack_trace) {
// Printing an error here will result in endless recursion, so we must be careful // Printing an error here will result in endless recursion, so we must be careful
static thread_local bool _recursion_flag_ = false; static thread_local bool _recursion_flag_ = false;
if (_recursion_flag_) if (_recursion_flag_) {
return Vector<StackInfo>(); return Vector<StackInfo>();
}
_recursion_flag_ = true; _recursion_flag_ = true;
SCOPE_EXIT { _recursion_flag_ = false; }; SCOPE_EXIT { _recursion_flag_ = false; };
@ -599,8 +629,9 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::stack_trace_get_info(MonoObjec
int frame_count = mono_array_length(frames); int frame_count = mono_array_length(frames);
if (frame_count <= 0) if (frame_count <= 0) {
return Vector<StackInfo>(); return Vector<StackInfo>();
}
Vector<StackInfo> si; Vector<StackInfo> si;
si.resize(frame_count); si.resize(frame_count);
@ -646,8 +677,9 @@ void CSharpLanguage::pre_unsafe_unreference(Object *p_obj) {
ObjectID id = p_obj->get_instance_id(); ObjectID id = p_obj->get_instance_id();
Map<ObjectID, int>::Element *elem = unsafe_object_references.find(id); Map<ObjectID, int>::Element *elem = unsafe_object_references.find(id);
ERR_FAIL_NULL(elem); ERR_FAIL_NULL(elem);
if (--elem->value() == 0) if (--elem->value() == 0) {
unsafe_object_references.erase(elem); unsafe_object_references.erase(elem);
}
#endif #endif
} }
@ -673,8 +705,9 @@ void CSharpLanguage::frame() {
struct CSharpScriptDepSort { struct CSharpScriptDepSort {
// must support sorting so inheritance works properly (parent must be reloaded first) // must support sorting so inheritance works properly (parent must be reloaded first)
bool operator()(const Ref<CSharpScript> &A, const Ref<CSharpScript> &B) const { bool operator()(const Ref<CSharpScript> &A, const Ref<CSharpScript> &B) const {
if (A == B) if (A == B) {
return false; // shouldn't happen but.. return false; // shouldn't happen but..
}
GDMonoClass *I = B->base; GDMonoClass *I = B->base;
while (I) { while (I) {
if (I == A->script_class) { if (I == A->script_class) {
@ -717,8 +750,9 @@ void CSharpLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft
#ifdef GD_MONO_HOT_RELOAD #ifdef GD_MONO_HOT_RELOAD
bool CSharpLanguage::is_assembly_reloading_needed() { bool CSharpLanguage::is_assembly_reloading_needed() {
if (!gdmono->is_runtime_initialized()) if (!gdmono->is_runtime_initialized()) {
return false; return false;
}
GDMonoAssembly *proj_assembly = gdmono->get_project_assembly(); GDMonoAssembly *proj_assembly = gdmono->get_project_assembly();
@ -736,23 +770,27 @@ bool CSharpLanguage::is_assembly_reloading_needed() {
if (!FileAccess::exists(proj_asm_path)) { if (!FileAccess::exists(proj_asm_path)) {
// Maybe it wasn't loaded from the default path, so check this as well // Maybe it wasn't loaded from the default path, so check this as well
proj_asm_path = GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(appname_safe); proj_asm_path = GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(appname_safe);
if (!FileAccess::exists(proj_asm_path)) if (!FileAccess::exists(proj_asm_path)) {
return false; // No assembly to load return false; // No assembly to load
}
} }
if (FileAccess::get_modified_time(proj_asm_path) <= proj_assembly->get_modified_time()) if (FileAccess::get_modified_time(proj_asm_path) <= proj_assembly->get_modified_time()) {
return false; // Already up to date return false; // Already up to date
}
} else { } else {
if (!FileAccess::exists(GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(appname_safe))) if (!FileAccess::exists(GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(appname_safe))) {
return false; // No assembly to load return false; // No assembly to load
}
} }
return true; return true;
} }
void CSharpLanguage::reload_assemblies(bool p_soft_reload) { void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
if (!gdmono->is_runtime_initialized()) if (!gdmono->is_runtime_initialized()) {
return; return;
}
// There is no soft reloading with Mono. It's always hard reloading. // There is no soft reloading with Mono. It's always hard reloading.
@ -858,8 +896,9 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
CSharpInstance *csi = static_cast<CSharpInstance *>(obj->get_script_instance()); CSharpInstance *csi = static_cast<CSharpInstance *>(obj->get_script_instance());
// Call OnBeforeSerialize // Call OnBeforeSerialize
if (csi->script->script_class->implements_interface(CACHED_CLASS(ISerializationListener))) if (csi->script->script_class->implements_interface(CACHED_CLASS(ISerializationListener))) {
obj->get_script_instance()->call_multilevel(string_names.on_before_serialize); obj->get_script_instance()->call_multilevel(string_names.on_before_serialize);
}
// Save instance info // Save instance info
CSharpScript::StateBackup state; CSharpScript::StateBackup state;
@ -894,8 +933,9 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
for (const Map<ObjectID, CSharpScript::StateBackup>::Element *F = scr->pending_reload_state.front(); F; F = F->next()) { for (const Map<ObjectID, CSharpScript::StateBackup>::Element *F = scr->pending_reload_state.front(); F; F = F->next()) {
Object *obj = ObjectDB::get_instance(F->key()); Object *obj = ObjectDB::get_instance(F->key());
if (!obj) if (!obj) {
continue; continue;
}
ObjectID obj_id = obj->get_instance_id(); ObjectID obj_id = obj->get_instance_id();
@ -1092,8 +1132,9 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
} }
// Call OnAfterDeserialization // Call OnAfterDeserialization
if (csi->script->script_class->implements_interface(CACHED_CLASS(ISerializationListener))) if (csi->script->script_class->implements_interface(CACHED_CLASS(ISerializationListener))) {
obj->get_script_instance()->call_multilevel(string_names.on_after_deserialize); obj->get_script_instance()->call_multilevel(string_names.on_after_deserialize);
}
} }
} }
@ -1246,6 +1287,7 @@ void CSharpLanguage::_on_scripts_domain_unloaded() {
script_binding.inited = false; script_binding.inited = false;
} }
#ifdef GD_MONO_HOT_RELOAD
{ {
MutexLock lock(ManagedCallable::instances_mutex); MutexLock lock(ManagedCallable::instances_mutex);
@ -1255,6 +1297,7 @@ void CSharpLanguage::_on_scripts_domain_unloaded() {
managed_callable->delegate_invoke = nullptr; managed_callable->delegate_invoke = nullptr;
} }
} }
#endif
scripts_metadata_invalidated = true; scripts_metadata_invalidated = true;
} }
@ -1275,7 +1318,8 @@ void CSharpLanguage::_editor_init_callback() {
GDMonoUtils::runtime_object_init(mono_object, editor_klass, &exc); GDMonoUtils::runtime_object_init(mono_object, editor_klass, &exc);
UNHANDLED_EXCEPTION(exc); UNHANDLED_EXCEPTION(exc);
EditorPlugin *godotsharp_editor = Object::cast_to<EditorPlugin>(GDMonoMarshal::mono_object_to_variant(mono_object)); EditorPlugin *godotsharp_editor = Object::cast_to<EditorPlugin>(
GDMonoMarshal::mono_object_to_variant(mono_object).operator Object *());
CRASH_COND(godotsharp_editor == nullptr); CRASH_COND(godotsharp_editor == nullptr);
// Enable it as a plugin // Enable it as a plugin
@ -1324,7 +1368,7 @@ CSharpLanguage::CSharpLanguage() {
} }
CSharpLanguage::~CSharpLanguage() { CSharpLanguage::~CSharpLanguage() {
finish(); finalize();
singleton = nullptr; singleton = nullptr;
} }
@ -1341,8 +1385,9 @@ bool CSharpLanguage::setup_csharp_script_binding(CSharpScriptBinding &r_script_b
// ¯\_(ツ)_/¯ // ¯\_(ツ)_/¯
const ClassDB::ClassInfo *classinfo = ClassDB::classes.getptr(type_name); const ClassDB::ClassInfo *classinfo = ClassDB::classes.getptr(type_name);
while (classinfo && !classinfo->exposed) while (classinfo && !classinfo->exposed) {
classinfo = classinfo->inherits_ptr; classinfo = classinfo->inherits_ptr;
}
ERR_FAIL_NULL_V(classinfo, false); ERR_FAIL_NULL_V(classinfo, false);
type_name = classinfo->name; type_name = classinfo->name;
@ -1380,13 +1425,15 @@ void *CSharpLanguage::alloc_instance_binding_data(Object *p_object) {
MutexLock lock(language_bind_mutex); MutexLock lock(language_bind_mutex);
Map<Object *, CSharpScriptBinding>::Element *match = script_bindings.find(p_object); Map<Object *, CSharpScriptBinding>::Element *match = script_bindings.find(p_object);
if (match) if (match) {
return (void *)match; return (void *)match;
}
CSharpScriptBinding script_binding; CSharpScriptBinding script_binding;
if (!setup_csharp_script_binding(script_binding, p_object)) if (!setup_csharp_script_binding(script_binding, p_object)) {
return nullptr; return nullptr;
}
return (void *)insert_script_binding(p_object, script_binding); return (void *)insert_script_binding(p_object, script_binding);
} }
@ -1404,8 +1451,9 @@ void CSharpLanguage::free_instance_binding_data(void *p_data) {
return; return;
} }
if (finalizing) if (finalizing) {
return; // inside CSharpLanguage::finish(), all the gchandle bindings are released there return; // inside CSharpLanguage::finish(), all the gchandle bindings are released there
}
GD_MONO_ASSERT_THREAD_ATTACHED; GD_MONO_ASSERT_THREAD_ATTACHED;
@ -1444,8 +1492,9 @@ void CSharpLanguage::refcount_incremented_instance_binding(Object *p_object) {
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get(); CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
MonoGCHandleData &gchandle = script_binding.gchandle; MonoGCHandleData &gchandle = script_binding.gchandle;
if (!script_binding.inited) if (!script_binding.inited) {
return; return;
}
if (ref_owner->reference_get_count() > 1 && gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0 if (ref_owner->reference_get_count() > 1 && gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
GD_MONO_SCOPE_THREAD_ATTACH; GD_MONO_SCOPE_THREAD_ATTACH;
@ -1455,8 +1504,9 @@ void CSharpLanguage::refcount_incremented_instance_binding(Object *p_object) {
// so the owner must hold the managed side alive again to avoid it from being GCed. // so the owner must hold the managed side alive again to avoid it from being GCed.
MonoObject *target = gchandle.get_target(); MonoObject *target = gchandle.get_target();
if (!target) if (!target) {
return; // Called after the managed side was collected, so nothing to do here return; // Called after the managed side was collected, so nothing to do here
}
// Release the current weak handle and replace it with a strong handle. // Release the current weak handle and replace it with a strong handle.
MonoGCHandleData strong_gchandle = MonoGCHandleData::new_strong_handle(target); MonoGCHandleData strong_gchandle = MonoGCHandleData::new_strong_handle(target);
@ -1481,8 +1531,9 @@ bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) {
int refcount = ref_owner->reference_get_count(); int refcount = ref_owner->reference_get_count();
if (!script_binding.inited) if (!script_binding.inited) {
return refcount == 0; return refcount == 0;
}
if (refcount == 1 && !gchandle.is_released() && !gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0 if (refcount == 1 && !gchandle.is_released() && !gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
GD_MONO_SCOPE_THREAD_ATTACH; GD_MONO_SCOPE_THREAD_ATTACH;
@ -1491,8 +1542,9 @@ bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) {
// the managed instance takes responsibility of deleting the owner when GCed. // the managed instance takes responsibility of deleting the owner when GCed.
MonoObject *target = gchandle.get_target(); MonoObject *target = gchandle.get_target();
if (!target) if (!target) {
return refcount == 0; // Called after the managed side was collected, so nothing to do here return refcount == 0; // Called after the managed side was collected, so nothing to do here
}
// Release the current strong handle and replace it with a weak handle. // Release the current strong handle and replace it with a weak handle.
MonoGCHandleData weak_gchandle = MonoGCHandleData::new_weak_handle(target); MonoGCHandleData weak_gchandle = MonoGCHandleData::new_weak_handle(target);
@ -1514,8 +1566,9 @@ CSharpInstance *CSharpInstance::create_for_managed_type(Object *p_owner, CSharpS
instance->owner = p_owner; instance->owner = p_owner;
instance->gchandle = p_gchandle; instance->gchandle = p_gchandle;
if (instance->base_ref) if (instance->base_ref) {
instance->_reference_owner_unsafe(); instance->_reference_owner_unsafe();
}
p_script->instances.insert(p_owner); p_script->instances.insert(p_owner);
@ -1572,8 +1625,9 @@ bool CSharpInstance::set(const StringName &p_name, const Variant &p_value) {
MonoObject *ret = method->invoke(mono_object, args); MonoObject *ret = method->invoke(mono_object, args);
if (ret && GDMonoMarshal::unbox<MonoBoolean>(ret)) if (ret && GDMonoMarshal::unbox<MonoBoolean>(ret)) {
return true; return true;
}
break; break;
} }
@ -1658,8 +1712,9 @@ void CSharpInstance::get_properties_state_for_reloading(List<Pair<StringName, Va
ManagedType managedType; ManagedType managedType;
GDMonoField *field = script->script_class->get_field(state_pair.first); GDMonoField *field = script->script_class->get_field(state_pair.first);
if (!field) if (!field) {
continue; // Properties ignored. We get the property baking fields instead. continue; // Properties ignored. We get the property baking fields instead.
}
managedType = field->get_type(); managedType = field->get_type();
@ -1679,8 +1734,9 @@ void CSharpInstance::get_event_signals_state_for_reloading(List<Pair<StringName,
const CSharpScript::EventSignal &event_signal = E->value(); const CSharpScript::EventSignal &event_signal = E->value();
MonoDelegate *delegate_field_value = (MonoDelegate *)event_signal.field->get_value(owner_managed); MonoDelegate *delegate_field_value = (MonoDelegate *)event_signal.field->get_value(owner_managed);
if (!delegate_field_value) if (!delegate_field_value) {
continue; // Empty continue; // Empty
}
Array serialized_data; Array serialized_data;
MonoObject *managed_serialized_data = GDMonoMarshal::variant_to_mono_object(serialized_data); MonoObject *managed_serialized_data = GDMonoMarshal::variant_to_mono_object(serialized_data);
@ -1725,8 +1781,9 @@ void CSharpInstance::get_property_list(List<PropertyInfo> *p_properties) const {
if (ret) { if (ret) {
Array array = Array(GDMonoMarshal::mono_object_to_variant(ret)); Array array = Array(GDMonoMarshal::mono_object_to_variant(ret));
for (int i = 0, size = array.size(); i < size; i++) for (int i = 0, size = array.size(); i < size; i++) {
p_properties->push_back(PropertyInfo::from_dict(array.get(i))); p_properties->push_back(PropertyInfo::from_dict(array.get(i)));
}
return; return;
} }
@ -1739,20 +1796,23 @@ void CSharpInstance::get_property_list(List<PropertyInfo> *p_properties) const {
Variant::Type CSharpInstance::get_property_type(const StringName &p_name, bool *r_is_valid) const { Variant::Type CSharpInstance::get_property_type(const StringName &p_name, bool *r_is_valid) const {
if (script->member_info.has(p_name)) { if (script->member_info.has(p_name)) {
if (r_is_valid) if (r_is_valid) {
*r_is_valid = true; *r_is_valid = true;
}
return script->member_info[p_name].type; return script->member_info[p_name].type;
} }
if (r_is_valid) if (r_is_valid) {
*r_is_valid = false; *r_is_valid = false;
}
return Variant::NIL; return Variant::NIL;
} }
bool CSharpInstance::has_method(const StringName &p_method) const { bool CSharpInstance::has_method(const StringName &p_method) const {
if (!script.is_valid()) if (!script.is_valid()) {
return false; return false;
}
GD_MONO_SCOPE_THREAD_ATTACH; GD_MONO_SCOPE_THREAD_ATTACH;
@ -1868,8 +1928,9 @@ bool CSharpInstance::_unreference_owner_unsafe() {
CRASH_COND(owner == nullptr); CRASH_COND(owner == nullptr);
#endif #endif
if (!unsafe_referenced) if (!unsafe_referenced) {
return false; // Already unreferenced return false; // Already unreferenced
}
unsafe_referenced = false; unsafe_referenced = false;
@ -1912,8 +1973,9 @@ MonoObject *CSharpInstance::_internal_new_managed() {
// Tie managed to unmanaged // Tie managed to unmanaged
gchandle = MonoGCHandleData::new_strong_handle(mono_object); gchandle = MonoGCHandleData::new_strong_handle(mono_object);
if (base_ref) if (base_ref) {
_reference_owner_unsafe(); // Here, after assigning the gchandle (for the refcount_incremented callback) _reference_owner_unsafe(); // Here, after assigning the gchandle (for the refcount_incremented callback)
}
CACHED_FIELD(GodotObject, ptr)->set_value_raw(mono_object, owner); CACHED_FIELD(GodotObject, ptr)->set_value_raw(mono_object, owner);
@ -2130,7 +2192,7 @@ void CSharpInstance::_call_notification(int p_notification) {
// Custom version of _call_multilevel, optimized for _notification // Custom version of _call_multilevel, optimized for _notification
uint32_t arg = p_notification; int32_t arg = p_notification;
void *args[1] = { &arg }; void *args[1] = { &arg };
StringName method_name = CACHED_STRING_NAME(_notification); StringName method_name = CACHED_STRING_NAME(_notification);
@ -2154,8 +2216,9 @@ String CSharpInstance::to_string(bool *r_valid) {
MonoObject *mono_object = get_mono_object(); MonoObject *mono_object = get_mono_object();
if (mono_object == nullptr) { if (mono_object == nullptr) {
if (r_valid) if (r_valid) {
*r_valid = false; *r_valid = false;
}
return String(); return String();
} }
@ -2164,14 +2227,16 @@ String CSharpInstance::to_string(bool *r_valid) {
if (exc) { if (exc) {
GDMonoUtils::set_pending_exception(exc); GDMonoUtils::set_pending_exception(exc);
if (r_valid) if (r_valid) {
*r_valid = false; *r_valid = false;
}
return String(); return String();
} }
if (result == nullptr) { if (result == nullptr) {
if (r_valid) if (r_valid) {
*r_valid = false; *r_valid = false;
}
return String(); return String();
} }
@ -2342,11 +2407,13 @@ void CSharpScript::_update_member_info_no_exports() {
bool CSharpScript::_update_exports() { bool CSharpScript::_update_exports() {
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
bool is_editor = Engine::get_singleton()->is_editor_hint(); bool is_editor = Engine::get_singleton()->is_editor_hint();
if (is_editor) if (is_editor) {
placeholder_fallback_enabled = true; // until proven otherwise placeholder_fallback_enabled = true; // until proven otherwise
}
#endif #endif
if (!valid) if (!valid) {
return false; return false;
}
bool changed = false; bool changed = false;
@ -2543,8 +2610,9 @@ void CSharpScript::load_script_signals(GDMonoClass *p_class, GDMonoClass *p_nati
for (int i = delegates.size() - 1; i >= 0; --i) { for (int i = delegates.size() - 1; i >= 0; --i) {
GDMonoClass *delegate = delegates[i]; GDMonoClass *delegate = delegates[i];
if (!delegate->has_attribute(CACHED_CLASS(SignalAttribute))) if (!delegate->has_attribute(CACHED_CLASS(SignalAttribute))) {
continue; continue;
}
// Arguments are accessibles as arguments of .Invoke method // Arguments are accessibles as arguments of .Invoke method
GDMonoMethod *invoke_method = delegate->get_method(mono_get_delegate_invoke(delegate->get_mono_ptr())); GDMonoMethod *invoke_method = delegate->get_method(mono_get_delegate_invoke(delegate->get_mono_ptr()));
@ -2577,11 +2645,13 @@ void CSharpScript::load_script_signals(GDMonoClass *p_class, GDMonoClass *p_nati
GDMonoClass *field_class = field->get_type().type_class; GDMonoClass *field_class = field->get_type().type_class;
if (!mono_class_is_delegate(field_class->get_mono_ptr())) if (!mono_class_is_delegate(field_class->get_mono_ptr())) {
continue; continue;
}
if (!found_event_signals.find(field->get_name())) if (!found_event_signals.find(field->get_name())) {
continue; continue;
}
GDMonoMethod *invoke_method = field_class->get_method(mono_get_delegate_invoke(field_class->get_mono_ptr())); GDMonoMethod *invoke_method = field_class->get_method(mono_get_delegate_invoke(field_class->get_mono_ptr()));
@ -2640,14 +2710,16 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
if (p_member->is_static()) { if (p_member->is_static()) {
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
if (p_member->has_attribute(CACHED_CLASS(ExportAttribute))) if (p_member->has_attribute(CACHED_CLASS(ExportAttribute))) {
ERR_PRINT("Cannot export member because it is static: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'."); ERR_PRINT("Cannot export member because it is static: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
}
#endif #endif
return false; return false;
} }
if (member_info.has(p_member->get_name())) if (member_info.has(p_member->get_name())) {
return false; return false;
}
ManagedType type; ManagedType type;
@ -2665,15 +2737,17 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
GDMonoProperty *property = static_cast<GDMonoProperty *>(p_member); GDMonoProperty *property = static_cast<GDMonoProperty *>(p_member);
if (!property->has_getter()) { if (!property->has_getter()) {
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
if (exported) if (exported) {
ERR_PRINT("Read-only property cannot be exported: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'."); ERR_PRINT("Read-only property cannot be exported: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
}
#endif #endif
return false; return false;
} }
if (!property->has_setter()) { if (!property->has_setter()) {
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
if (exported) if (exported) {
ERR_PRINT("Write-only property (without getter) cannot be exported: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'."); ERR_PRINT("Write-only property (without getter) cannot be exported: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
}
#endif #endif
return false; return false;
} }
@ -2802,8 +2876,9 @@ int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, Manage
ManagedType elem_type; ManagedType elem_type;
if (!GDMonoMarshal::try_get_array_element_type(p_type, elem_type)) if (!GDMonoMarshal::try_get_array_element_type(p_type, elem_type)) {
return 0; return 0;
}
Variant::Type elem_variant_type = GDMonoMarshal::managed_to_variant_type(elem_type); Variant::Type elem_variant_type = GDMonoMarshal::managed_to_variant_type(elem_type);
@ -2830,15 +2905,6 @@ int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, Manage
} }
#endif #endif
void CSharpScript::_clear() {
tool = false;
valid = false;
base = nullptr;
native = nullptr;
script_class = nullptr;
}
Variant CSharpScript::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { Variant CSharpScript::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
if (unlikely(GDMono::get_singleton() == nullptr)) { if (unlikely(GDMono::get_singleton() == nullptr)) {
// Probably not the best error but eh. // Probably not the best error but eh.
@ -2871,11 +2937,7 @@ Variant CSharpScript::call(const StringName &p_method, const Variant **p_args, i
} }
void CSharpScript::_resource_path_changed() { void CSharpScript::_resource_path_changed() {
String path = get_path(); _update_name();
if (!path.empty()) {
name = get_path().get_file().get_basename();
}
} }
bool CSharpScript::_get(const StringName &p_name, Variant &r_ret) const { bool CSharpScript::_get(const StringName &p_name, Variant &r_ret) const {
@ -2931,8 +2993,9 @@ void CSharpScript::initialize_for_managed_type(Ref<CSharpScript> p_script, GDMon
GDMonoClass *base = p_script->script_class->get_parent_class(); GDMonoClass *base = p_script->script_class->get_parent_class();
if (base != p_script->native) if (base != p_script->native) {
p_script->base = base; p_script->base = base;
}
p_script->valid = true; p_script->valid = true;
p_script->tool = p_script->script_class->has_attribute(CACHED_CLASS(ToolAttribute)); p_script->tool = p_script->script_class->has_attribute(CACHED_CLASS(ToolAttribute));
@ -2958,8 +3021,9 @@ void CSharpScript::initialize_for_managed_type(Ref<CSharpScript> p_script, GDMon
while (native_top) { while (native_top) {
native_top->fetch_methods_with_godot_api_checks(p_script->native); native_top->fetch_methods_with_godot_api_checks(p_script->native);
if (native_top == CACHED_CLASS(GodotObject)) if (native_top == CACHED_CLASS(GodotObject)) {
break; break;
}
native_top = native_top->get_parent_class(); native_top = native_top->get_parent_class();
} }
@ -3005,10 +3069,11 @@ bool CSharpScript::can_instance() const {
} }
StringName CSharpScript::get_instance_base_type() const { StringName CSharpScript::get_instance_base_type() const {
if (native) if (native) {
return native->get_name(); return native->get_name();
else } else {
return StringName(); return StringName();
}
} }
CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Callable::CallError &r_error) { CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Callable::CallError &r_error) {
@ -3081,8 +3146,9 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
// Tie managed to unmanaged // Tie managed to unmanaged
instance->gchandle = MonoGCHandleData::new_strong_handle(mono_object); instance->gchandle = MonoGCHandleData::new_strong_handle(mono_object);
if (instance->base_ref) if (instance->base_ref) {
instance->_reference_owner_unsafe(); // Here, after assigning the gchandle (for the refcount_incremented callback) instance->_reference_owner_unsafe(); // Here, after assigning the gchandle (for the refcount_incremented callback)
}
{ {
MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex); MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
@ -3184,8 +3250,9 @@ String CSharpScript::get_source_code() const {
} }
void CSharpScript::set_source_code(const String &p_code) { void CSharpScript::set_source_code(const String &p_code) {
if (source == p_code) if (source == p_code) {
return; return;
}
source = p_code; source = p_code;
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
source_changed_cache = true; source_changed_cache = true;
@ -3193,8 +3260,9 @@ void CSharpScript::set_source_code(const String &p_code) {
} }
void CSharpScript::get_script_method_list(List<MethodInfo> *p_list) const { void CSharpScript::get_script_method_list(List<MethodInfo> *p_list) const {
if (!script_class) if (!script_class) {
return; return;
}
GD_MONO_SCOPE_THREAD_ATTACH; GD_MONO_SCOPE_THREAD_ATTACH;
@ -3206,8 +3274,9 @@ void CSharpScript::get_script_method_list(List<MethodInfo> *p_list) const {
} }
bool CSharpScript::has_method(const StringName &p_method) const { bool CSharpScript::has_method(const StringName &p_method) const {
if (!script_class) if (!script_class) {
return false; return false;
}
GD_MONO_SCOPE_THREAD_ATTACH; GD_MONO_SCOPE_THREAD_ATTACH;
@ -3215,8 +3284,9 @@ bool CSharpScript::has_method(const StringName &p_method) const {
} }
MethodInfo CSharpScript::get_method_info(const StringName &p_method) const { MethodInfo CSharpScript::get_method_info(const StringName &p_method) const {
if (!script_class) if (!script_class) {
return MethodInfo(); return MethodInfo();
}
GD_MONO_SCOPE_THREAD_ATTACH; GD_MONO_SCOPE_THREAD_ATTACH;
@ -3290,8 +3360,9 @@ Error CSharpScript::reload(bool p_keep_state) {
GDMonoClass *base_class = script_class->get_parent_class(); GDMonoClass *base_class = script_class->get_parent_class();
if (base_class != native) if (base_class != native) {
base = base_class; base = base_class;
}
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
// For debug builds, we must fetch from all native base methods as well. // For debug builds, we must fetch from all native base methods as well.
@ -3303,8 +3374,9 @@ Error CSharpScript::reload(bool p_keep_state) {
while (native_top) { while (native_top) {
native_top->fetch_methods_with_godot_api_checks(native); native_top->fetch_methods_with_godot_api_checks(native);
if (native_top == CACHED_CLASS(GodotObject)) if (native_top == CACHED_CLASS(GodotObject)) {
break; break;
}
native_top = native_top->get_parent_class(); native_top = native_top->get_parent_class();
} }
@ -3434,8 +3506,9 @@ void CSharpScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
const SignalParameter &param = params[i]; const SignalParameter &param = params[i];
PropertyInfo arg_info = PropertyInfo(param.type, param.name); PropertyInfo arg_info = PropertyInfo(param.type, param.name);
if (param.type == Variant::NIL && param.nil_is_variant) if (param.type == Variant::NIL && param.nil_is_variant) {
arg_info.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; arg_info.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
}
mi.arguments.push_back(arg_info); mi.arguments.push_back(arg_info);
} }
@ -3453,8 +3526,9 @@ void CSharpScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
const SignalParameter &param = params[i]; const SignalParameter &param = params[i];
PropertyInfo arg_info = PropertyInfo(param.type, param.name); PropertyInfo arg_info = PropertyInfo(param.type, param.name);
if (param.type == Variant::NIL && param.nil_is_variant) if (param.type == Variant::NIL && param.nil_is_variant) {
arg_info.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; arg_info.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
}
mi.arguments.push_back(arg_info); mi.arguments.push_back(arg_info);
} }
@ -3497,18 +3571,24 @@ int CSharpScript::get_member_line(const StringName &p_member) const {
} }
MultiplayerAPI::RPCMode CSharpScript::_member_get_rpc_mode(IMonoClassMember *p_member) const { MultiplayerAPI::RPCMode CSharpScript::_member_get_rpc_mode(IMonoClassMember *p_member) const {
if (p_member->has_attribute(CACHED_CLASS(RemoteAttribute))) if (p_member->has_attribute(CACHED_CLASS(RemoteAttribute))) {
return MultiplayerAPI::RPC_MODE_REMOTE; return MultiplayerAPI::RPC_MODE_REMOTE;
if (p_member->has_attribute(CACHED_CLASS(MasterAttribute))) }
if (p_member->has_attribute(CACHED_CLASS(MasterAttribute))) {
return MultiplayerAPI::RPC_MODE_MASTER; return MultiplayerAPI::RPC_MODE_MASTER;
if (p_member->has_attribute(CACHED_CLASS(PuppetAttribute))) }
if (p_member->has_attribute(CACHED_CLASS(PuppetAttribute))) {
return MultiplayerAPI::RPC_MODE_PUPPET; return MultiplayerAPI::RPC_MODE_PUPPET;
if (p_member->has_attribute(CACHED_CLASS(RemoteSyncAttribute))) }
if (p_member->has_attribute(CACHED_CLASS(RemoteSyncAttribute))) {
return MultiplayerAPI::RPC_MODE_REMOTESYNC; return MultiplayerAPI::RPC_MODE_REMOTESYNC;
if (p_member->has_attribute(CACHED_CLASS(MasterSyncAttribute))) }
if (p_member->has_attribute(CACHED_CLASS(MasterSyncAttribute))) {
return MultiplayerAPI::RPC_MODE_MASTERSYNC; return MultiplayerAPI::RPC_MODE_MASTERSYNC;
if (p_member->has_attribute(CACHED_CLASS(PuppetSyncAttribute))) }
if (p_member->has_attribute(CACHED_CLASS(PuppetSyncAttribute))) {
return MultiplayerAPI::RPC_MODE_PUPPETSYNC; return MultiplayerAPI::RPC_MODE_PUPPETSYNC;
}
return MultiplayerAPI::RPC_MODE_DISABLED; return MultiplayerAPI::RPC_MODE_DISABLED;
} }
@ -3583,14 +3663,27 @@ Error CSharpScript::load_source_code(const String &p_path) {
return OK; return OK;
} }
StringName CSharpScript::get_script_name() const { void CSharpScript::_update_name() {
return name; String path = get_path();
if (!path.empty()) {
name = get_path().get_file().get_basename();
}
}
void CSharpScript::_clear() {
tool = false;
valid = false;
base = nullptr;
native = nullptr;
script_class = nullptr;
} }
CSharpScript::CSharpScript() { CSharpScript::CSharpScript() {
_clear(); _clear();
_resource_path_changed(); _update_name();
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
{ {
@ -3620,8 +3713,9 @@ void CSharpScript::get_members(Set<StringName> *p_members) {
/*************** RESOURCE ***************/ /*************** RESOURCE ***************/
RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (r_error) if (r_error) {
*r_error = ERR_FILE_CANT_OPEN; *r_error = ERR_FILE_CANT_OPEN;
}
// TODO ignore anything inside bin/ and obj/ in tools builds? // TODO ignore anything inside bin/ and obj/ in tools builds?
@ -3638,8 +3732,9 @@ RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p
script->reload(); script->reload();
if (r_error) if (r_error) {
*r_error = OK; *r_error = OK;
}
return scriptres; return scriptres;
} }

View File

@ -135,7 +135,7 @@ private:
bool exports_invalidated = true; bool exports_invalidated = true;
void _update_exports_values(Map<StringName, Variant> &values, List<PropertyInfo> &propnames); void _update_exports_values(Map<StringName, Variant> &values, List<PropertyInfo> &propnames);
void _update_member_info_no_exports(); void _update_member_info_no_exports();
virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder); void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder) override;
#endif #endif
#if defined(TOOLS_ENABLED) || defined(DEBUG_ENABLED) #if defined(TOOLS_ENABLED) || defined(DEBUG_ENABLED)
@ -146,6 +146,8 @@ private:
void _clear(); void _clear();
void _update_name();
void load_script_signals(GDMonoClass *p_class, GDMonoClass *p_native_class); void load_script_signals(GDMonoClass *p_class, GDMonoClass *p_native_class);
bool _get_signal(GDMonoClass *p_class, GDMonoMethod *p_delegate_invoke, Vector<SignalParameter> &params); bool _get_signal(GDMonoClass *p_class, GDMonoMethod *p_delegate_invoke, Vector<SignalParameter> &params);
@ -169,68 +171,66 @@ private:
protected: protected:
static void _bind_methods(); static void _bind_methods();
Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override;
virtual void _resource_path_changed(); void _resource_path_changed() override;
bool _get(const StringName &p_name, Variant &r_ret) const; bool _get(const StringName &p_name, Variant &r_ret) const;
bool _set(const StringName &p_name, const Variant &p_value); bool _set(const StringName &p_name, const Variant &p_value);
void _get_property_list(List<PropertyInfo> *p_properties) const; void _get_property_list(List<PropertyInfo> *p_properties) const;
public: public:
virtual bool can_instance() const; bool can_instance() const override;
virtual StringName get_instance_base_type() const; StringName get_instance_base_type() const override;
virtual ScriptInstance *instance_create(Object *p_this); ScriptInstance *instance_create(Object *p_this) override;
virtual PlaceHolderScriptInstance *placeholder_instance_create(Object *p_this); PlaceHolderScriptInstance *placeholder_instance_create(Object *p_this) override;
virtual bool instance_has(const Object *p_this) const; bool instance_has(const Object *p_this) const override;
virtual bool has_source_code() const; bool has_source_code() const override;
virtual String get_source_code() const; String get_source_code() const override;
virtual void set_source_code(const String &p_code); void set_source_code(const String &p_code) override;
virtual Error reload(bool p_keep_state = false); Error reload(bool p_keep_state = false) override;
virtual bool has_script_signal(const StringName &p_signal) const; bool has_script_signal(const StringName &p_signal) const override;
virtual void get_script_signal_list(List<MethodInfo> *r_signals) const; void get_script_signal_list(List<MethodInfo> *r_signals) const override;
virtual bool get_property_default_value(const StringName &p_property, Variant &r_value) const; bool get_property_default_value(const StringName &p_property, Variant &r_value) const override;
virtual void get_script_property_list(List<PropertyInfo> *p_list) const; void get_script_property_list(List<PropertyInfo> *p_list) const override;
virtual void update_exports(); void update_exports() override;
void get_members(Set<StringName> *p_members) override; void get_members(Set<StringName> *p_members) override;
virtual bool is_tool() const { return tool; } bool is_tool() const override { return tool; }
virtual bool is_valid() const { return valid; } bool is_valid() const override { return valid; }
bool inherits_script(const Ref<Script> &p_script) const; bool inherits_script(const Ref<Script> &p_script) const override;
virtual Ref<Script> get_base_script() const; Ref<Script> get_base_script() const override;
virtual ScriptLanguage *get_language() const; ScriptLanguage *get_language() const override;
virtual void get_script_method_list(List<MethodInfo> *p_list) const; void get_script_method_list(List<MethodInfo> *p_list) const override;
bool has_method(const StringName &p_method) const; bool has_method(const StringName &p_method) const override;
MethodInfo get_method_info(const StringName &p_method) const; MethodInfo get_method_info(const StringName &p_method) const override;
virtual int get_member_line(const StringName &p_member) const; int get_member_line(const StringName &p_member) const override;
virtual Vector<ScriptNetData> get_rpc_methods() const; Vector<ScriptNetData> get_rpc_methods() const override;
virtual uint16_t get_rpc_method_id(const StringName &p_method) const; uint16_t get_rpc_method_id(const StringName &p_method) const override;
virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const; StringName get_rpc_method(const uint16_t p_rpc_method_id) const override;
virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const; MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const override;
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const override;
virtual Vector<ScriptNetData> get_rset_properties() const; Vector<ScriptNetData> get_rset_properties() const override;
virtual uint16_t get_rset_property_id(const StringName &p_variable) const; uint16_t get_rset_property_id(const StringName &p_variable) const override;
virtual StringName get_rset_property(const uint16_t p_variable_id) const; StringName get_rset_property(const uint16_t p_variable_id) const override;
virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const; MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const override;
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const override;
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
virtual bool is_placeholder_fallback_enabled() const { return placeholder_fallback_enabled; } bool is_placeholder_fallback_enabled() const override { return placeholder_fallback_enabled; }
#endif #endif
Error load_source_code(const String &p_path); Error load_source_code(const String &p_path);
StringName get_script_name() const;
CSharpScript(); CSharpScript();
~CSharpScript(); ~CSharpScript();
}; };
@ -249,8 +249,6 @@ class CSharpInstance : public ScriptInstance {
Ref<CSharpScript> script; Ref<CSharpScript> script;
MonoGCHandleData gchandle; MonoGCHandleData gchandle;
Vector<Callable> event_signal_callables;
bool _reference_owner_unsafe(); bool _reference_owner_unsafe();
/* /*
@ -277,18 +275,18 @@ public:
_FORCE_INLINE_ bool is_destructing_script_instance() { return destructing_script_instance; } _FORCE_INLINE_ bool is_destructing_script_instance() { return destructing_script_instance; }
virtual Object *get_owner(); Object *get_owner() override;
virtual bool set(const StringName &p_name, const Variant &p_value); bool set(const StringName &p_name, const Variant &p_value) override;
virtual bool get(const StringName &p_name, Variant &r_ret) const; bool get(const StringName &p_name, Variant &r_ret) const override;
virtual void get_property_list(List<PropertyInfo> *p_properties) const; void get_property_list(List<PropertyInfo> *p_properties) const override;
virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid) const; Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid) const override;
/* TODO */ virtual void get_method_list(List<MethodInfo> *p_list) const {} /* TODO */ void get_method_list(List<MethodInfo> *p_list) const override {}
virtual bool has_method(const StringName &p_method) const; bool has_method(const StringName &p_method) const override;
virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override;
virtual void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount); void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount) override;
virtual void call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount); void call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount) override;
void mono_object_disposed(MonoObject *p_obj); void mono_object_disposed(MonoObject *p_obj);
@ -301,29 +299,29 @@ public:
void connect_event_signals(); void connect_event_signals();
void disconnect_event_signals(); void disconnect_event_signals();
virtual void refcount_incremented(); void refcount_incremented() override;
virtual bool refcount_decremented(); bool refcount_decremented() override;
virtual Vector<ScriptNetData> get_rpc_methods() const; Vector<ScriptNetData> get_rpc_methods() const override;
virtual uint16_t get_rpc_method_id(const StringName &p_method) const; uint16_t get_rpc_method_id(const StringName &p_method) const override;
virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const; StringName get_rpc_method(const uint16_t p_rpc_method_id) const override;
virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const; MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const override;
virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const override;
virtual Vector<ScriptNetData> get_rset_properties() const; Vector<ScriptNetData> get_rset_properties() const override;
virtual uint16_t get_rset_property_id(const StringName &p_variable) const; uint16_t get_rset_property_id(const StringName &p_variable) const override;
virtual StringName get_rset_property(const uint16_t p_variable_id) const; StringName get_rset_property(const uint16_t p_variable_id) const override;
virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const; MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const override;
virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const override;
virtual void notification(int p_notification); void notification(int p_notification) override;
void _call_notification(int p_notification); void _call_notification(int p_notification);
virtual String to_string(bool *r_valid); String to_string(bool *r_valid) override;
virtual Ref<Script> get_script() const; Ref<Script> get_script() const override;
virtual ScriptLanguage *get_language(); ScriptLanguage *get_language() override;
CSharpInstance(const Ref<CSharpScript> &p_script); CSharpInstance(const Ref<CSharpScript> &p_script);
~CSharpInstance(); ~CSharpInstance();
@ -437,83 +435,90 @@ public:
} }
_FORCE_INLINE_ const Dictionary &get_scripts_metadata() { _FORCE_INLINE_ const Dictionary &get_scripts_metadata() {
if (scripts_metadata_invalidated) if (scripts_metadata_invalidated) {
_load_scripts_metadata(); _load_scripts_metadata();
}
return scripts_metadata; return scripts_metadata;
} }
_FORCE_INLINE_ ManagedCallableMiddleman *get_managed_callable_middleman() const { return managed_callable_middleman; } _FORCE_INLINE_ ManagedCallableMiddleman *get_managed_callable_middleman() const { return managed_callable_middleman; }
virtual String get_name() const; String get_name() const override;
/* LANGUAGE FUNCTIONS */ /* LANGUAGE FUNCTIONS */
virtual String get_type() const; String get_type() const override;
virtual String get_extension() const; String get_extension() const override;
virtual Error execute_file(const String &p_path); Error execute_file(const String &p_path) override;
virtual void init(); void init() override;
virtual void finish(); void finish() override;
void finalize();
/* EDITOR FUNCTIONS */ /* EDITOR FUNCTIONS */
virtual void get_reserved_words(List<String> *p_words) const; void get_reserved_words(List<String> *p_words) const override;
virtual void get_comment_delimiters(List<String> *p_delimiters) const; void get_comment_delimiters(List<String> *p_delimiters) const override;
virtual void get_string_delimiters(List<String> *p_delimiters) const; void get_string_delimiters(List<String> *p_delimiters) const override;
virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const; Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const override;
virtual bool is_using_templates(); bool is_using_templates() override;
virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script); void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) override;
/* TODO */ virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const { return true; } /* TODO */ bool validate(const String &p_script, int &r_line_error, int &r_col_error,
virtual String validate_path(const String &p_path) const; String &r_test_error, const String &p_path, List<String> *r_functions,
virtual Script *create_script() const; List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const override {
virtual bool has_named_classes() const; return true;
virtual bool supports_builtin_mode() const; }
/* TODO? */ virtual int find_function(const String &p_function, const String &p_code) const { return -1; } String validate_path(const String &p_path) const override;
virtual String make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const; Script *create_script() const override;
bool has_named_classes() const override;
bool supports_builtin_mode() const override;
/* TODO? */ int find_function(const String &p_function, const String &p_code) const override { return -1; }
String make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const override;
virtual String _get_indentation() const; virtual String _get_indentation() const;
/* TODO? */ virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const {} /* TODO? */ void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const override {}
/* TODO */ virtual void add_global_constant(const StringName &p_variable, const Variant &p_value) {} /* TODO */ void add_global_constant(const StringName &p_variable, const Variant &p_value) override {}
/* DEBUGGER FUNCTIONS */ /* DEBUGGER FUNCTIONS */
virtual String debug_get_error() const; String debug_get_error() const override;
virtual int debug_get_stack_level_count() const; int debug_get_stack_level_count() const override;
virtual int debug_get_stack_level_line(int p_level) const; int debug_get_stack_level_line(int p_level) const override;
virtual String debug_get_stack_level_function(int p_level) const; String debug_get_stack_level_function(int p_level) const override;
virtual String debug_get_stack_level_source(int p_level) const; String debug_get_stack_level_source(int p_level) const override;
/* TODO */ virtual void debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {} /* TODO */ void debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) override {}
/* TODO */ virtual void debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {} /* TODO */ void debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems, int p_max_depth) override {}
/* TODO */ virtual void debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {} /* TODO */ void debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) override {}
/* TODO */ virtual String debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) { return ""; } /* TODO */ String debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) override { return ""; }
virtual Vector<StackInfo> debug_get_current_stack_info(); Vector<StackInfo> debug_get_current_stack_info() override;
/* PROFILING FUNCTIONS */ /* PROFILING FUNCTIONS */
/* TODO */ virtual void profiling_start() {} /* TODO */ void profiling_start() override {}
/* TODO */ virtual void profiling_stop() {} /* TODO */ void profiling_stop() override {}
/* TODO */ virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) { return 0; } /* TODO */ int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) override { return 0; }
/* TODO */ virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) { return 0; } /* TODO */ int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) override { return 0; }
virtual void frame(); void frame() override;
/* TODO? */ virtual void get_public_functions(List<MethodInfo> *p_functions) const {} /* TODO? */ void get_public_functions(List<MethodInfo> *p_functions) const override {}
/* TODO? */ virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const {} /* TODO? */ void get_public_constants(List<Pair<String, Variant>> *p_constants) const override {}
virtual void reload_all_scripts(); void reload_all_scripts() override;
virtual void reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload); void reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload) override;
/* LOADER FUNCTIONS */ /* LOADER FUNCTIONS */
virtual void get_recognized_extensions(List<String> *p_extensions) const; void get_recognized_extensions(List<String> *p_extensions) const override;
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
virtual Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col); Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) override;
virtual bool overrides_external_editor(); bool overrides_external_editor() override;
#endif #endif
/* THREAD ATTACHING */ /* THREAD ATTACHING */
virtual void thread_enter(); void thread_enter() override;
virtual void thread_exit(); void thread_exit() override;
// Don't use these. I'm watching you // Don't use these. I'm watching you
virtual void *alloc_instance_binding_data(Object *p_object); void *alloc_instance_binding_data(Object *p_object) override;
virtual void free_instance_binding_data(void *p_data); void free_instance_binding_data(void *p_data) override;
virtual void refcount_incremented_instance_binding(Object *p_object); void refcount_incremented_instance_binding(Object *p_object) override;
virtual bool refcount_decremented_instance_binding(Object *p_object); bool refcount_decremented_instance_binding(Object *p_object) override;
Map<Object *, CSharpScriptBinding>::Element *insert_script_binding(Object *p_object, const CSharpScriptBinding &p_script_binding); Map<Object *, CSharpScriptBinding>::Element *insert_script_binding(Object *p_object, const CSharpScriptBinding &p_script_binding);
bool setup_csharp_script_binding(CSharpScriptBinding &r_script_binding, Object *p_object); bool setup_csharp_script_binding(CSharpScriptBinding &r_script_binding, Object *p_object);
@ -531,17 +536,17 @@ public:
class ResourceFormatLoaderCSharpScript : public ResourceFormatLoader { class ResourceFormatLoaderCSharpScript : public ResourceFormatLoader {
public: public:
virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false) override;
virtual void get_recognized_extensions(List<String> *p_extensions) const; void get_recognized_extensions(List<String> *p_extensions) const override;
virtual bool handles_type(const String &p_type) const; bool handles_type(const String &p_type) const override;
virtual String get_resource_type(const String &p_path) const; String get_resource_type(const String &p_path) const override;
}; };
class ResourceFormatSaverCSharpScript : public ResourceFormatSaver { class ResourceFormatSaverCSharpScript : public ResourceFormatSaver {
public: public:
virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0); Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0) override;
virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const; void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const override;
virtual bool recognize(const RES &p_resource) const; bool recognize(const RES &p_resource) const override;
}; };
#endif // CSHARP_SCRIPT_H #endif // CSHARP_SCRIPT_H

View File

@ -62,10 +62,8 @@
#define OPEN_BLOCK_L2 INDENT2 OPEN_BLOCK INDENT3 #define OPEN_BLOCK_L2 INDENT2 OPEN_BLOCK INDENT3
#define OPEN_BLOCK_L3 INDENT3 OPEN_BLOCK INDENT4 #define OPEN_BLOCK_L3 INDENT3 OPEN_BLOCK INDENT4
#define OPEN_BLOCK_L4 INDENT4 OPEN_BLOCK INDENT5
#define CLOSE_BLOCK_L2 INDENT2 CLOSE_BLOCK #define CLOSE_BLOCK_L2 INDENT2 CLOSE_BLOCK
#define CLOSE_BLOCK_L3 INDENT3 CLOSE_BLOCK #define CLOSE_BLOCK_L3 INDENT3 CLOSE_BLOCK
#define CLOSE_BLOCK_L4 INDENT4 CLOSE_BLOCK
#define CS_FIELD_MEMORYOWN "memoryOwn" #define CS_FIELD_MEMORYOWN "memoryOwn"
#define CS_PARAM_METHODBIND "method" #define CS_PARAM_METHODBIND "method"

View File

@ -45,8 +45,9 @@ _FORCE_INLINE_ String quoted(const String &p_str) {
} }
void _add_nodes_suggestions(const Node *p_base, const Node *p_node, PackedStringArray &r_suggestions) { void _add_nodes_suggestions(const Node *p_base, const Node *p_node, PackedStringArray &r_suggestions) {
if (p_node != p_base && !p_node->get_owner()) if (p_node != p_base && !p_node->get_owner()) {
return; return;
}
String path_relative_to_orig = p_base->get_path_to(p_node); String path_relative_to_orig = p_base->get_path_to(p_node);
@ -58,18 +59,21 @@ void _add_nodes_suggestions(const Node *p_base, const Node *p_node, PackedString
} }
Node *_find_node_for_script(Node *p_base, Node *p_current, const Ref<Script> &p_script) { Node *_find_node_for_script(Node *p_base, Node *p_current, const Ref<Script> &p_script) {
if (p_current->get_owner() != p_base && p_base != p_current) if (p_current->get_owner() != p_base && p_base != p_current) {
return nullptr; return nullptr;
}
Ref<Script> c = p_current->get_script(); Ref<Script> c = p_current->get_script();
if (c == p_script) if (c == p_script) {
return p_current; return p_current;
}
for (int i = 0; i < p_current->get_child_count(); i++) { for (int i = 0; i < p_current->get_child_count(); i++) {
Node *found = _find_node_for_script(p_base, p_current->get_child(i), p_script); Node *found = _find_node_for_script(p_base, p_current->get_child(i), p_script);
if (found) if (found) {
return found; return found;
}
} }
return nullptr; return nullptr;
@ -87,8 +91,9 @@ void _get_directory_contents(EditorFileSystemDirectory *p_dir, PackedStringArray
Node *_try_find_owner_node_in_tree(const Ref<Script> p_script) { Node *_try_find_owner_node_in_tree(const Ref<Script> p_script) {
SceneTree *tree = SceneTree::get_singleton(); SceneTree *tree = SceneTree::get_singleton();
if (!tree) if (!tree) {
return nullptr; return nullptr;
}
Node *base = tree->get_edited_scene_root(); Node *base = tree->get_edited_scene_root();
if (base) { if (base) {
base = _find_node_for_script(base, base, p_script); base = _find_node_for_script(base, base, p_script);
@ -107,8 +112,9 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr
for (List<PropertyInfo>::Element *E = project_props.front(); E; E = E->next()) { for (List<PropertyInfo>::Element *E = project_props.front(); E; E = E->next()) {
const PropertyInfo &prop = E->get(); const PropertyInfo &prop = E->get();
if (!prop.name.begins_with("input/")) if (!prop.name.begins_with("input/")) {
continue; continue;
}
String name = prop.name.substr(prop.name.find("/") + 1, prop.name.length()); String name = prop.name.substr(prop.name.find("/") + 1, prop.name.length());
suggestions.push_back(quoted(name)); suggestions.push_back(quoted(name));

View File

@ -45,8 +45,9 @@
namespace CSharpProject { namespace CSharpProject {
void add_item(const String &p_project_path, const String &p_item_type, const String &p_include) { void add_item(const String &p_project_path, const String &p_item_type, const String &p_include) {
if (!GLOBAL_DEF("mono/project/auto_update_project", true)) if (!GLOBAL_DEF("mono/project/auto_update_project", true)) {
return; return;
}
GDMonoAssembly *tools_project_editor_assembly = GDMono::get_singleton()->get_tools_project_editor_assembly(); GDMonoAssembly *tools_project_editor_assembly = GDMono::get_singleton()->get_tools_project_editor_assembly();

View File

@ -324,7 +324,7 @@ MonoObject *godot_icall_Internal_GetScriptsMetadataOrNothing(MonoReflectionType
MonoType *dict_type = mono_reflection_type_get_type(p_dict_reftype); MonoType *dict_type = mono_reflection_type_get_type(p_dict_reftype);
uint32_t type_encoding = mono_type_get_type(dict_type); int type_encoding = mono_type_get_type(dict_type);
MonoClass *type_class_raw = mono_class_from_mono_type(dict_type); MonoClass *type_class_raw = mono_class_from_mono_type(dict_type);
GDMonoClass *type_class = GDMono::get_singleton()->get_class(type_class_raw); GDMonoClass *type_class = GDMono::get_singleton()->get_class(type_class_raw);

View File

@ -75,8 +75,9 @@ Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String>
const String &ref_name = ref_info.name; const String &ref_name = ref_info.name;
if (r_assembly_dependencies.has(ref_name)) if (r_assembly_dependencies.has(ref_name)) {
continue; continue;
}
GDMonoAssembly *ref_assembly = nullptr; GDMonoAssembly *ref_assembly = nullptr;
@ -130,8 +131,9 @@ Error get_exported_assembly_dependencies(const Dictionary &p_initial_assemblies,
ERR_FAIL_COND_V_MSG(!load_success, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + assembly_name + "'."); ERR_FAIL_COND_V_MSG(!load_success, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + assembly_name + "'.");
Error err = get_assembly_dependencies(assembly, search_dirs, r_assembly_dependencies); Error err = get_assembly_dependencies(assembly, search_dirs, r_assembly_dependencies);
if (err != OK) if (err != OK) {
return err; return err;
}
} }
return OK; return OK;

View File

@ -208,8 +208,9 @@ ScriptClassParser::Token ScriptClassParser::get_token() {
tk_string += res; tk_string += res;
} else { } else {
if (code[idx] == '\n') if (code[idx] == '\n') {
line++; line++;
}
tk_string += code[idx]; tk_string += code[idx];
} }
idx++; idx++;
@ -300,15 +301,17 @@ Error ScriptClassParser::_skip_generic_type_params() {
tk = get_token(); tk = get_token();
if (tk != TK_PERIOD) if (tk != TK_PERIOD) {
break; break;
}
} }
} }
if (tk == TK_OP_LESS) { if (tk == TK_OP_LESS) {
Error err = _skip_generic_type_params(); Error err = _skip_generic_type_params();
if (err) if (err) {
return err; return err;
}
tk = get_token(); tk = get_token();
} }
@ -349,12 +352,14 @@ Error ScriptClassParser::_parse_type_full_name(String &r_full_name) {
// We don't mind if the base is generic, but we skip it any ways since this information is not needed // We don't mind if the base is generic, but we skip it any ways since this information is not needed
Error err = _skip_generic_type_params(); Error err = _skip_generic_type_params();
if (err) if (err) {
return err; return err;
}
} }
if (code[idx] != '.') // We only want to take the next token if it's a period if (code[idx] != '.') { // We only want to take the next token if it's a period
return OK; return OK;
}
tk = get_token(); tk = get_token();
@ -369,15 +374,17 @@ Error ScriptClassParser::_parse_class_base(Vector<String> &r_base) {
String name; String name;
Error err = _parse_type_full_name(name); Error err = _parse_type_full_name(name);
if (err) if (err) {
return err; return err;
}
Token tk = get_token(); Token tk = get_token();
if (tk == TK_COMMA) { if (tk == TK_COMMA) {
err = _parse_class_base(r_base); err = _parse_class_base(r_base);
if (err) if (err) {
return err; return err;
}
} else if (tk == TK_IDENTIFIER && String(value) == "where") { } else if (tk == TK_IDENTIFIER && String(value) == "where") {
err = _parse_type_constraints(); err = _parse_type_constraints();
if (err) { if (err) {
@ -433,8 +440,9 @@ Error ScriptClassParser::_parse_type_constraints() {
tk = get_token(); tk = get_token();
if (tk != TK_PERIOD) if (tk != TK_PERIOD) {
break; break;
}
} }
} }
} }
@ -452,8 +460,9 @@ Error ScriptClassParser::_parse_type_constraints() {
} }
} else if (tk == TK_OP_LESS) { } else if (tk == TK_OP_LESS) {
Error err = _skip_generic_type_params(); Error err = _skip_generic_type_params();
if (err) if (err) {
return err; return err;
}
} else if (tk == TK_CURLY_BRACKET_OPEN) { } else if (tk == TK_CURLY_BRACKET_OPEN) {
return OK; return OK;
} else { } else {
@ -522,8 +531,9 @@ Error ScriptClassParser::parse(const String &p_code) {
const NameDecl &name_decl = E->value(); const NameDecl &name_decl = E->value();
if (name_decl.type == NameDecl::NAMESPACE_DECL) { if (name_decl.type == NameDecl::NAMESPACE_DECL) {
if (E != name_stack.front()) if (E != name_stack.front()) {
class_decl.namespace_ += "."; class_decl.namespace_ += ".";
}
class_decl.namespace_ += name_decl.name; class_decl.namespace_ += name_decl.name;
} else { } else {
class_decl.name += name_decl.name + "."; class_decl.name += name_decl.name + ".";
@ -540,8 +550,9 @@ Error ScriptClassParser::parse(const String &p_code) {
if (tk == TK_COLON) { if (tk == TK_COLON) {
Error err = _parse_class_base(class_decl.base); Error err = _parse_class_base(class_decl.base);
if (err) if (err) {
return err; return err;
}
curly_stack++; curly_stack++;
type_curly_stack++; type_curly_stack++;
@ -555,8 +566,9 @@ Error ScriptClassParser::parse(const String &p_code) {
generic = true; generic = true;
Error err = _skip_generic_type_params(); Error err = _skip_generic_type_params();
if (err) if (err) {
return err; return err;
}
} else if (tk == TK_IDENTIFIER && String(value) == "where") { } else if (tk == TK_IDENTIFIER && String(value) == "where") {
Error err = _parse_type_constraints(); Error err = _parse_type_constraints();
if (err) { if (err) {
@ -584,8 +596,9 @@ Error ScriptClassParser::parse(const String &p_code) {
classes.push_back(class_decl); classes.push_back(class_decl);
} else if (OS::get_singleton()->is_stdout_verbose()) { } else if (OS::get_singleton()->is_stdout_verbose()) {
String full_name = class_decl.namespace_; String full_name = class_decl.namespace_;
if (full_name.length()) if (full_name.length()) {
full_name += "."; full_name += ".";
}
full_name += class_decl.name; full_name += class_decl.name;
OS::get_singleton()->print("Ignoring generic class declaration: %s\n", full_name.utf8().get_data()); OS::get_singleton()->print("Ignoring generic class declaration: %s\n", full_name.utf8().get_data());
} }
@ -602,8 +615,9 @@ Error ScriptClassParser::parse(const String &p_code) {
int at_level = curly_stack; int at_level = curly_stack;
Error err = _parse_namespace_name(name, curly_stack); Error err = _parse_namespace_name(name, curly_stack);
if (err) if (err) {
return err; return err;
}
NameDecl name_decl; NameDecl name_decl;
name_decl.name = name; name_decl.name = name;
@ -614,8 +628,9 @@ Error ScriptClassParser::parse(const String &p_code) {
} else if (tk == TK_CURLY_BRACKET_CLOSE) { } else if (tk == TK_CURLY_BRACKET_CLOSE) {
curly_stack--; curly_stack--;
if (name_stack.has(curly_stack)) { if (name_stack.has(curly_stack)) {
if (name_stack[curly_stack].type != NameDecl::NAMESPACE_DECL) if (name_stack[curly_stack].type != NameDecl::NAMESPACE_DECL) {
type_curly_stack--; type_curly_stack--;
}
name_stack.erase(curly_stack); name_stack.erase(curly_stack);
} }
} }
@ -628,8 +643,9 @@ Error ScriptClassParser::parse(const String &p_code) {
error = true; error = true;
} }
if (error) if (error) {
return ERR_PARSE_ERROR; return ERR_PARSE_ERROR;
}
return OK; return OK;
} }
@ -702,8 +718,9 @@ static void run_dummy_preprocessor(String &r_source, const String &p_filepath) {
// Custom join ignoring lines removed by the preprocessor // Custom join ignoring lines removed by the preprocessor
for (int i = 0; i < lines.size(); i++) { for (int i = 0; i < lines.size(); i++) {
if (i > 0 && include_lines[i - 1]) if (i > 0 && include_lines[i - 1]) {
r_source += '\n'; r_source += '\n';
}
if (include_lines[i]) { if (include_lines[i]) {
r_source += lines[i]; r_source += lines[i];

View File

@ -53,7 +53,6 @@ public:
String namespace_; String namespace_;
Vector<String> base; Vector<String> base;
bool nested; bool nested;
bool has_script_attr;
}; };
private: private:

View File

@ -40,8 +40,8 @@ private:
T *_ptr; T *_ptr;
int size; int size;
ArgumentsVector(); ArgumentsVector() = delete;
ArgumentsVector(const ArgumentsVector &); ArgumentsVector(const ArgumentsVector &) = delete;
public: public:
T *ptr() { return _ptr; } T *ptr() { return _ptr; }

View File

@ -28,10 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/ /*************************************************************************/
#include "base_object_glue.h"
#ifdef MONO_GLUE_ENABLED #ifdef MONO_GLUE_ENABLED
#include "core/class_db.h"
#include "core/object.h"
#include "core/reference.h" #include "core/reference.h"
#include "core/string_name.h" #include "core/string_name.h"
@ -39,6 +39,7 @@
#include "../mono_gd/gd_mono_cache.h" #include "../mono_gd/gd_mono_cache.h"
#include "../mono_gd/gd_mono_class.h" #include "../mono_gd/gd_mono_class.h"
#include "../mono_gd/gd_mono_internals.h" #include "../mono_gd/gd_mono_internals.h"
#include "../mono_gd/gd_mono_marshal.h"
#include "../mono_gd/gd_mono_utils.h" #include "../mono_gd/gd_mono_utils.h"
#include "../signal_awaiter_utils.h" #include "../signal_awaiter_utils.h"
#include "arguments_vector.h" #include "arguments_vector.h"
@ -140,16 +141,18 @@ MethodBind *godot_icall_Object_ClassDB_get_method(StringName *p_type, MonoString
} }
MonoObject *godot_icall_Object_weakref(Object *p_ptr) { MonoObject *godot_icall_Object_weakref(Object *p_ptr) {
if (!p_ptr) if (!p_ptr) {
return nullptr; return nullptr;
}
Ref<WeakRef> wref; Ref<WeakRef> wref;
Reference *ref = Object::cast_to<Reference>(p_ptr); Reference *ref = Object::cast_to<Reference>(p_ptr);
if (ref) { if (ref) {
REF r = ref; REF r = ref;
if (!r.is_valid()) if (!r.is_valid()) {
return nullptr; return nullptr;
}
wref.instance(); wref.instance();
wref->set_ref(r); wref->set_ref(r);
@ -241,6 +244,7 @@ void godot_register_object_icalls() {
mono_add_internal_call("Godot.Object::godot_icall_Object_Ctor", (void *)godot_icall_Object_Ctor); mono_add_internal_call("Godot.Object::godot_icall_Object_Ctor", (void *)godot_icall_Object_Ctor);
mono_add_internal_call("Godot.Object::godot_icall_Object_Disposed", (void *)godot_icall_Object_Disposed); mono_add_internal_call("Godot.Object::godot_icall_Object_Disposed", (void *)godot_icall_Object_Disposed);
mono_add_internal_call("Godot.Object::godot_icall_Reference_Disposed", (void *)godot_icall_Reference_Disposed); mono_add_internal_call("Godot.Object::godot_icall_Reference_Disposed", (void *)godot_icall_Reference_Disposed);
mono_add_internal_call("Godot.Object::godot_icall_Object_ConnectEventSignals", (void *)godot_icall_Object_ConnectEventSignals);
mono_add_internal_call("Godot.Object::godot_icall_Object_ClassDB_get_method", (void *)godot_icall_Object_ClassDB_get_method); mono_add_internal_call("Godot.Object::godot_icall_Object_ClassDB_get_method", (void *)godot_icall_Object_ClassDB_get_method);
mono_add_internal_call("Godot.Object::godot_icall_Object_ToString", (void *)godot_icall_Object_ToString); mono_add_internal_call("Godot.Object::godot_icall_Object_ToString", (void *)godot_icall_Object_ToString);
mono_add_internal_call("Godot.Object::godot_icall_Object_weakref", (void *)godot_icall_Object_weakref); mono_add_internal_call("Godot.Object::godot_icall_Object_weakref", (void *)godot_icall_Object_weakref);

View File

@ -1,73 +0,0 @@
/*************************************************************************/
/* base_object_glue.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2020 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 BASE_OBJECT_GLUE_H
#define BASE_OBJECT_GLUE_H
#ifdef MONO_GLUE_ENABLED
#include "core/class_db.h"
#include "core/object.h"
#include "../mono_gd/gd_mono_marshal.h"
Object *godot_icall_Object_Ctor(MonoObject *p_obj);
void godot_icall_Object_Disposed(MonoObject *p_obj, Object *p_ptr);
void godot_icall_Reference_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoolean p_is_finalizer);
void godot_icall_Object_ConnectEventSignals(Object *p_ptr);
MethodBind *godot_icall_Object_ClassDB_get_method(StringName *p_type, MonoString *p_method);
MonoObject *godot_icall_Object_weakref(Object *p_ptr);
Error godot_icall_SignalAwaiter_connect(Object *p_source, StringName *p_signal, Object *p_target, MonoObject *p_awaiter);
// DynamicGodotObject
MonoArray *godot_icall_DynamicGodotObject_SetMemberList(Object *p_ptr);
MonoBoolean godot_icall_DynamicGodotObject_InvokeMember(Object *p_ptr, MonoString *p_name, MonoArray *p_args, MonoObject **r_result);
MonoBoolean godot_icall_DynamicGodotObject_GetMember(Object *p_ptr, MonoString *p_name, MonoObject **r_result);
MonoBoolean godot_icall_DynamicGodotObject_SetMember(Object *p_ptr, MonoString *p_name, MonoObject *p_value);
MonoString *godot_icall_Object_ToString(Object *p_ptr);
// Register internal calls
void godot_register_object_icalls();
#endif // MONO_GLUE_ENABLED
#endif // BASE_OBJECT_GLUE_H

View File

@ -28,14 +28,15 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/ /*************************************************************************/
#include "collections_glue.h"
#ifdef MONO_GLUE_ENABLED #ifdef MONO_GLUE_ENABLED
#include <mono/metadata/exception.h> #include <mono/metadata/exception.h>
#include "core/array.h"
#include "../mono_gd/gd_mono_cache.h" #include "../mono_gd/gd_mono_cache.h"
#include "../mono_gd/gd_mono_class.h" #include "../mono_gd/gd_mono_class.h"
#include "../mono_gd/gd_mono_marshal.h"
#include "../mono_gd/gd_mono_utils.h" #include "../mono_gd/gd_mono_utils.h"
Array *godot_icall_Array_Ctor() { Array *godot_icall_Array_Ctor() {

View File

@ -1,124 +0,0 @@
/*************************************************************************/
/* collections_glue.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2020 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
#ifdef MONO_GLUE_ENABLED
#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);
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);
int godot_icall_Array_Add(Array *ptr, MonoObject *item);
void godot_icall_Array_Clear(Array *ptr);
MonoBoolean godot_icall_Array_Contains(Array *ptr, MonoObject *item);
void godot_icall_Array_CopyTo(Array *ptr, MonoArray *array, int array_index);
Array *godot_icall_Array_Duplicate(Array *ptr, MonoBoolean deep);
int godot_icall_Array_IndexOf(Array *ptr, MonoObject *item);
void godot_icall_Array_Insert(Array *ptr, int index, MonoObject *item);
MonoBoolean godot_icall_Array_Remove(Array *ptr, MonoObject *item);
void godot_icall_Array_RemoveAt(Array *ptr, int index);
Error godot_icall_Array_Resize(Array *ptr, int new_size);
void godot_icall_Array_Generic_GetElementTypeInfo(MonoReflectionType *refltype, uint32_t *type_encoding, GDMonoClass **type_class);
MonoString *godot_icall_Array_ToString(Array *ptr);
// Dictionary
Dictionary *godot_icall_Dictionary_Ctor();
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);
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);
MonoBoolean godot_icall_Dictionary_Contains(Dictionary *ptr, MonoObject *key, MonoObject *value);
MonoBoolean godot_icall_Dictionary_ContainsKey(Dictionary *ptr, MonoObject *key);
Dictionary *godot_icall_Dictionary_Duplicate(Dictionary *ptr, MonoBoolean deep);
MonoBoolean godot_icall_Dictionary_RemoveKey(Dictionary *ptr, MonoObject *key);
MonoBoolean godot_icall_Dictionary_Remove(Dictionary *ptr, MonoObject *key, MonoObject *value);
MonoBoolean godot_icall_Dictionary_TryGetValue(Dictionary *ptr, MonoObject *key, MonoObject **value);
MonoBoolean 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);
MonoString *godot_icall_Dictionary_ToString(Dictionary *ptr);
// Register internal calls
void godot_register_collections_icalls();
#endif // MONO_GLUE_ENABLED
#endif // COLLECTIONS_GLUE_H

View File

@ -28,8 +28,6 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/ /*************************************************************************/
#include "gd_glue.h"
#ifdef MONO_GLUE_ENABLED #ifdef MONO_GLUE_ENABLED
#include "core/array.h" #include "core/array.h"
@ -40,6 +38,7 @@
#include "core/variant_parser.h" #include "core/variant_parser.h"
#include "../mono_gd/gd_mono_cache.h" #include "../mono_gd/gd_mono_cache.h"
#include "../mono_gd/gd_mono_marshal.h"
#include "../mono_gd/gd_mono_utils.h" #include "../mono_gd/gd_mono_utils.h"
MonoObject *godot_icall_GD_bytes2var(MonoArray *p_bytes, MonoBoolean p_allow_objects) { MonoObject *godot_icall_GD_bytes2var(MonoArray *p_bytes, MonoBoolean p_allow_objects) {
@ -147,8 +146,9 @@ void godot_icall_GD_prints(MonoArray *p_what) {
return; return;
} }
if (i) if (i) {
str += " "; str += " ";
}
str += elem_str; str += elem_str;
} }
@ -171,8 +171,9 @@ void godot_icall_GD_printt(MonoArray *p_what) {
return; return;
} }
if (i) if (i) {
str += "\t"; str += "\t";
}
str += elem_str; str += elem_str;
} }
@ -197,7 +198,7 @@ double godot_icall_GD_rand_range(double from, double to) {
} }
uint32_t godot_icall_GD_rand_seed(uint64_t seed, uint64_t *newSeed) { uint32_t godot_icall_GD_rand_seed(uint64_t seed, uint64_t *newSeed) {
int ret = Math::rand_from_seed(&seed); uint32_t ret = Math::rand_from_seed(&seed);
*newSeed = seed; *newSeed = seed;
return ret; return ret;
} }
@ -213,10 +214,11 @@ MonoString *godot_icall_GD_str(MonoArray *p_what) {
for (int i = 0; i < what.size(); i++) { for (int i = 0; i < what.size(); i++) {
String os = what[i].operator String(); String os = what[i].operator String();
if (i == 0) if (i == 0) {
str = os; str = os;
else } else {
str += os; str += os;
}
} }
return GDMonoMarshal::mono_string_from_godot(str); return GDMonoMarshal::mono_string_from_godot(str);

View File

@ -1,86 +0,0 @@
/*************************************************************************/
/* gd_glue.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2020 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 GD_GLUE_H
#define GD_GLUE_H
#ifdef MONO_GLUE_ENABLED
#include "../mono_gd/gd_mono_marshal.h"
MonoObject *godot_icall_GD_bytes2var(MonoArray *p_bytes, MonoBoolean p_allow_objects);
MonoObject *godot_icall_GD_convert(MonoObject *p_what, int32_t p_type);
int godot_icall_GD_hash(MonoObject *p_var);
MonoObject *godot_icall_GD_instance_from_id(uint64_t p_instance_id);
void godot_icall_GD_print(MonoArray *p_what);
void godot_icall_GD_printerr(MonoArray *p_what);
void godot_icall_GD_printraw(MonoArray *p_what);
void godot_icall_GD_prints(MonoArray *p_what);
void godot_icall_GD_printt(MonoArray *p_what);
float godot_icall_GD_randf();
uint32_t godot_icall_GD_randi();
void godot_icall_GD_randomize();
double godot_icall_GD_rand_range(double from, double to);
uint32_t godot_icall_GD_rand_seed(uint64_t seed, uint64_t *newSeed);
void godot_icall_GD_seed(uint64_t p_seed);
MonoString *godot_icall_GD_str(MonoArray *p_what);
MonoObject *godot_icall_GD_str2var(MonoString *p_str);
MonoBoolean godot_icall_GD_type_exists(StringName *p_type);
MonoArray *godot_icall_GD_var2bytes(MonoObject *p_var, MonoBoolean p_full_objects);
MonoString *godot_icall_GD_var2str(MonoObject *p_var);
MonoObject *godot_icall_DefaultGodotTaskScheduler();
// Register internal calls
void godot_register_gd_icalls();
#endif // MONO_GLUE_ENABLED
#endif // GD_GLUE_H

View File

@ -30,14 +30,16 @@
#ifdef MONO_GLUE_ENABLED #ifdef MONO_GLUE_ENABLED
#include "base_object_glue.h" #include "../mono_gd/gd_mono_marshal.h"
#include "collections_glue.h"
#include "gd_glue.h" void godot_register_collections_icalls();
#include "nodepath_glue.h" void godot_register_gd_icalls();
#include "rid_glue.h" void godot_register_string_name_icalls();
#include "scene_tree_glue.h" void godot_register_nodepath_icalls();
#include "string_glue.h" void godot_register_object_icalls();
#include "string_name_glue.h" void godot_register_rid_icalls();
void godot_register_string_icalls();
void godot_register_scene_tree_icalls();
/** /**
* Registers internal calls that were not generated. This function is called * Registers internal calls that were not generated. This function is called

View File

@ -28,12 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/ /*************************************************************************/
#include "nodepath_glue.h"
#ifdef MONO_GLUE_ENABLED #ifdef MONO_GLUE_ENABLED
#include "core/node_path.h"
#include "core/ustring.h" #include "core/ustring.h"
#include "../mono_gd/gd_mono_marshal.h"
NodePath *godot_icall_NodePath_Ctor(MonoString *p_path) { NodePath *godot_icall_NodePath_Ctor(MonoString *p_path) {
return memnew(NodePath(GDMonoMarshal::mono_string_to_godot(p_path))); return memnew(NodePath(GDMonoMarshal::mono_string_to_godot(p_path)));
} }
@ -51,7 +52,7 @@ MonoBoolean godot_icall_NodePath_is_absolute(NodePath *p_ptr) {
return (MonoBoolean)p_ptr->is_absolute(); return (MonoBoolean)p_ptr->is_absolute();
} }
uint32_t godot_icall_NodePath_get_name_count(NodePath *p_ptr) { int32_t godot_icall_NodePath_get_name_count(NodePath *p_ptr) {
return p_ptr->get_name_count(); return p_ptr->get_name_count();
} }
@ -59,7 +60,7 @@ MonoString *godot_icall_NodePath_get_name(NodePath *p_ptr, uint32_t p_idx) {
return GDMonoMarshal::mono_string_from_godot(p_ptr->get_name(p_idx)); return GDMonoMarshal::mono_string_from_godot(p_ptr->get_name(p_idx));
} }
uint32_t godot_icall_NodePath_get_subname_count(NodePath *p_ptr) { int32_t godot_icall_NodePath_get_subname_count(NodePath *p_ptr) {
return p_ptr->get_subname_count(); return p_ptr->get_subname_count();
} }

View File

@ -1,68 +0,0 @@
/*************************************************************************/
/* nodepath_glue.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2020 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 NODEPATH_GLUE_H
#define NODEPATH_GLUE_H
#ifdef MONO_GLUE_ENABLED
#include "core/node_path.h"
#include "../mono_gd/gd_mono_marshal.h"
NodePath *godot_icall_NodePath_Ctor(MonoString *p_path);
void godot_icall_NodePath_Dtor(NodePath *p_ptr);
MonoString *godot_icall_NodePath_operator_String(NodePath *p_np);
MonoBoolean godot_icall_NodePath_is_absolute(NodePath *p_ptr);
uint32_t godot_icall_NodePath_get_name_count(NodePath *p_ptr);
MonoString *godot_icall_NodePath_get_name(NodePath *p_ptr, uint32_t p_idx);
uint32_t godot_icall_NodePath_get_subname_count(NodePath *p_ptr);
MonoString *godot_icall_NodePath_get_subname(NodePath *p_ptr, uint32_t p_idx);
MonoString *godot_icall_NodePath_get_concatenated_subnames(NodePath *p_ptr);
NodePath *godot_icall_NodePath_get_as_property_path(NodePath *p_ptr);
MonoBoolean godot_icall_NodePath_is_empty(NodePath *p_ptr);
// Register internal calls
void godot_register_nodepath_icalls();
#endif // MONO_GLUE_ENABLED
#endif // NODEPATH_GLUE_H

View File

@ -28,17 +28,20 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/ /*************************************************************************/
#include "rid_glue.h"
#ifdef MONO_GLUE_ENABLED #ifdef MONO_GLUE_ENABLED
#include "core/object.h"
#include "core/resource.h" #include "core/resource.h"
#include "core/rid.h"
#include "../mono_gd/gd_mono_marshal.h"
RID *godot_icall_RID_Ctor(Object *p_from) { RID *godot_icall_RID_Ctor(Object *p_from) {
Resource *res_from = Object::cast_to<Resource>(p_from); Resource *res_from = Object::cast_to<Resource>(p_from);
if (res_from) if (res_from) {
return memnew(RID(res_from->get_rid())); return memnew(RID(res_from->get_rid()));
}
return memnew(RID); return memnew(RID);
} }

View File

@ -1,53 +0,0 @@
/*************************************************************************/
/* rid_glue.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2020 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 RID_GLUE_H
#define RID_GLUE_H
#ifdef MONO_GLUE_ENABLED
#include "core/object.h"
#include "core/rid.h"
#include "../mono_gd/gd_mono_marshal.h"
RID *godot_icall_RID_Ctor(Object *p_from);
void godot_icall_RID_Dtor(RID *p_ptr);
uint32_t godot_icall_RID_get_id(RID *p_ptr);
// Register internal calls
void godot_register_rid_icalls();
#endif // MONO_GLUE_ENABLED
#endif // RID_GLUE_H

View File

@ -28,14 +28,17 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/ /*************************************************************************/
#include "scene_tree_glue.h"
#ifdef MONO_GLUE_ENABLED #ifdef MONO_GLUE_ENABLED
#include "core/array.h"
#include "core/class_db.h" #include "core/class_db.h"
#include "modules/mono/csharp_script.h" #include "core/string_name.h"
#include "modules/mono/mono_gd/gd_mono_utils.h"
#include "scene/main/node.h" #include "scene/main/node.h"
#include "scene/main/scene_tree.h"
#include "../csharp_script.h"
#include "../mono_gd/gd_mono_marshal.h"
#include "../mono_gd/gd_mono_utils.h"
Array *godot_icall_SceneTree_get_nodes_in_group_Generic(SceneTree *ptr, StringName *group, MonoReflectionType *refltype) { Array *godot_icall_SceneTree_get_nodes_in_group_Generic(SceneTree *ptr, StringName *group, MonoReflectionType *refltype) {
List<Node *> nodes; List<Node *> nodes;
@ -54,8 +57,9 @@ Array *godot_icall_SceneTree_get_nodes_in_group_Generic(SceneTree *ptr, StringNa
// If we're trying to get native objects, just check the inheritance list // If we're trying to get native objects, just check the inheritance list
StringName native_class_name = GDMonoUtils::get_native_godot_class_name(klass); StringName native_class_name = GDMonoUtils::get_native_godot_class_name(klass);
for (int i = 0; i < nodes.size(); ++i) { for (int i = 0; i < nodes.size(); ++i) {
if (ClassDB::is_parent_class(nodes[i]->get_class(), native_class_name)) if (ClassDB::is_parent_class(nodes[i]->get_class(), native_class_name)) {
ret.push_back(nodes[i]); ret.push_back(nodes[i]);
}
} }
} else { } else {
// If we're trying to get csharpscript instances, get the mono object and compare the classes // If we're trying to get csharpscript instances, get the mono object and compare the classes

View File

@ -1,50 +0,0 @@
/*************************************************************************/
/* scene_tree_glue.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2020 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 SCENE_TREE_GLUE_H
#define SCENE_TREE_GLUE_H
#ifdef MONO_GLUE_ENABLED
#include "core/array.h"
#include "core/string_name.h"
#include "scene/main/scene_tree.h"
#include "../mono_gd/gd_mono_marshal.h"
Array *godot_icall_SceneTree_get_nodes_in_group_Generic(SceneTree *ptr, StringName *group, MonoReflectionType *refltype);
// Register internal calls
void godot_register_scene_tree_icalls();
#endif // MONO_GLUE_ENABLED
#endif // SCENE_TREE_GLUE_H

View File

@ -28,14 +28,14 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/ /*************************************************************************/
#include "string_glue.h"
#ifdef MONO_GLUE_ENABLED #ifdef MONO_GLUE_ENABLED
#include "core/ustring.h" #include "core/ustring.h"
#include "core/variant.h" #include "core/variant.h"
#include "core/vector.h" #include "core/vector.h"
#include "../mono_gd/gd_mono_marshal.h"
MonoArray *godot_icall_String_md5_buffer(MonoString *p_str) { MonoArray *godot_icall_String_md5_buffer(MonoString *p_str) {
Vector<uint8_t> ret = GDMonoMarshal::mono_string_to_godot(p_str).md5_buffer(); Vector<uint8_t> ret = GDMonoMarshal::mono_string_to_godot(p_str).md5_buffer();
// TODO Check possible Array/Vector<uint8_t> problem? // TODO Check possible Array/Vector<uint8_t> problem?

View File

@ -1,56 +0,0 @@
/*************************************************************************/
/* string_glue.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2020 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 STRING_GLUE_H
#define STRING_GLUE_H
#ifdef MONO_GLUE_ENABLED
#include "../mono_gd/gd_mono_marshal.h"
MonoArray *godot_icall_String_md5_buffer(MonoString *p_str);
MonoString *godot_icall_String_md5_text(MonoString *p_str);
int godot_icall_String_rfind(MonoString *p_str, MonoString *p_what, int p_from);
int godot_icall_String_rfindn(MonoString *p_str, MonoString *p_what, int p_from);
MonoArray *godot_icall_String_sha256_buffer(MonoString *p_str);
MonoString *godot_icall_String_sha256_text(MonoString *p_str);
// Register internal calls
void godot_register_string_icalls();
#endif // MONO_GLUE_ENABLED
#endif // STRING_GLUE_H

View File

@ -28,12 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/ /*************************************************************************/
#include "string_name_glue.h"
#ifdef MONO_GLUE_ENABLED #ifdef MONO_GLUE_ENABLED
#include "core/string_name.h"
#include "core/ustring.h" #include "core/ustring.h"
#include "../mono_gd/gd_mono_marshal.h"
StringName *godot_icall_StringName_Ctor(MonoString *p_path) { StringName *godot_icall_StringName_Ctor(MonoString *p_path) {
return memnew(StringName(GDMonoMarshal::mono_string_to_godot(p_path))); return memnew(StringName(GDMonoMarshal::mono_string_to_godot(p_path)));
} }
@ -48,7 +49,7 @@ MonoString *godot_icall_StringName_operator_String(StringName *p_np) {
} }
MonoBoolean godot_icall_StringName_is_empty(StringName *p_ptr) { MonoBoolean godot_icall_StringName_is_empty(StringName *p_ptr) {
return (MonoBoolean)(p_ptr == StringName()); return (MonoBoolean)(*p_ptr == StringName());
} }
void godot_register_string_name_icalls() { void godot_register_string_name_icalls() {

View File

@ -1,54 +0,0 @@
/*************************************************************************/
/* string_name_glue.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2020 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 STRING_NAME_GLUE_H
#define STRING_NAME_GLUE_H
#ifdef MONO_GLUE_ENABLED
#include "core/string_name.h"
#include "../mono_gd/gd_mono_marshal.h"
StringName *godot_icall_StringName_Ctor(MonoString *p_path);
void godot_icall_StringName_Dtor(StringName *p_ptr);
MonoString *godot_icall_StringName_operator_String(StringName *p_np);
MonoBoolean godot_icall_StringName_is_empty(StringName *p_ptr);
// Register internal calls
void godot_register_string_name_icalls();
#endif // MONO_GLUE_ENABLED
#endif // STRING_NAME_GLUE_H

View File

@ -48,8 +48,9 @@ bool ManagedCallable::compare_equal(const CallableCustom *p_a, const CallableCus
MonoDelegate *delegate_b = (MonoDelegate *)b->delegate_handle.get_target(); MonoDelegate *delegate_b = (MonoDelegate *)b->delegate_handle.get_target();
if (!delegate_a || !delegate_b) { if (!delegate_a || !delegate_b) {
if (!delegate_a && !delegate_b) if (!delegate_a && !delegate_b) {
return true; return true;
}
return false; return false;
} }
@ -58,8 +59,9 @@ bool ManagedCallable::compare_equal(const CallableCustom *p_a, const CallableCus
} }
bool ManagedCallable::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) { bool ManagedCallable::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) {
if (compare_equal(p_a, p_b)) if (compare_equal(p_a, p_b)) {
return false; return false;
}
return p_a < p_b; return p_a < p_b;
} }

View File

@ -144,8 +144,9 @@ void gd_mono_debug_init() {
if (Engine::get_singleton()->is_editor_hint() || if (Engine::get_singleton()->is_editor_hint() ||
ProjectSettings::get_singleton()->get_resource_path().empty() || ProjectSettings::get_singleton()->get_resource_path().empty() ||
Main::is_project_manager()) { Main::is_project_manager()) {
if (da_args.size() == 0) if (da_args.size() == 0) {
return; return;
}
} }
if (da_args.length() == 0) { if (da_args.length() == 0) {
@ -423,24 +424,27 @@ void GDMono::initialize_load_assemblies() {
bool tool_assemblies_loaded = _load_tools_assemblies(); bool tool_assemblies_loaded = _load_tools_assemblies();
CRASH_COND_MSG(!tool_assemblies_loaded, "Mono: Failed to load '" TOOLS_ASM_NAME "' assemblies."); CRASH_COND_MSG(!tool_assemblies_loaded, "Mono: Failed to load '" TOOLS_ASM_NAME "' assemblies.");
if (Main::is_project_manager()) if (Main::is_project_manager()) {
return; return;
}
#endif #endif
// Load the project's main assembly. This doesn't necessarily need to succeed. // Load the project's main assembly. This doesn't necessarily need to succeed.
// The game may not be using .NET at all, or if the project does use .NET and // The game may not be using .NET at all, or if the project does use .NET and
// we're running in the editor, it may just happen to be it wasn't built yet. // we're running in the editor, it may just happen to be it wasn't built yet.
if (!_load_project_assembly()) { if (!_load_project_assembly()) {
if (OS::get_singleton()->is_stdout_verbose()) if (OS::get_singleton()->is_stdout_verbose()) {
print_error("Mono: Failed to load project assembly"); print_error("Mono: Failed to load project assembly");
}
} }
} }
bool GDMono::_are_api_assemblies_out_of_sync() { bool GDMono::_are_api_assemblies_out_of_sync() {
bool out_of_sync = core_api_assembly.assembly && (core_api_assembly.out_of_sync || !GDMonoCache::cached_data.godot_api_cache_updated); bool out_of_sync = core_api_assembly.assembly && (core_api_assembly.out_of_sync || !GDMonoCache::cached_data.godot_api_cache_updated);
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
if (!out_of_sync) if (!out_of_sync) {
out_of_sync = editor_api_assembly.assembly && editor_api_assembly.out_of_sync; out_of_sync = editor_api_assembly.assembly && editor_api_assembly.out_of_sync;
}
#endif #endif
return out_of_sync; return out_of_sync;
} }
@ -512,16 +516,17 @@ void GDMono::_init_exception_policy() {
} }
} }
void GDMono::add_assembly(uint32_t p_domain_id, GDMonoAssembly *p_assembly) { void GDMono::add_assembly(int32_t p_domain_id, GDMonoAssembly *p_assembly) {
assemblies[p_domain_id][p_assembly->get_name()] = p_assembly; assemblies[p_domain_id][p_assembly->get_name()] = p_assembly;
} }
GDMonoAssembly *GDMono::get_loaded_assembly(const String &p_name) { GDMonoAssembly *GDMono::get_loaded_assembly(const String &p_name) {
if (p_name == "mscorlib" && corlib_assembly) if (p_name == "mscorlib" && corlib_assembly) {
return corlib_assembly; return corlib_assembly;
}
MonoDomain *domain = mono_domain_get(); MonoDomain *domain = mono_domain_get();
uint32_t domain_id = domain ? mono_domain_get_id(domain) : 0; int32_t domain_id = domain ? mono_domain_get_id(domain) : 0;
GDMonoAssembly **result = assemblies[domain_id].getptr(p_name); GDMonoAssembly **result = assemblies[domain_id].getptr(p_name);
return result ? *result : nullptr; return result ? *result : nullptr;
} }
@ -556,8 +561,9 @@ bool GDMono::load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMo
GDMonoAssembly *assembly = GDMonoAssembly::load(p_name, p_aname, p_refonly, p_search_dirs); GDMonoAssembly *assembly = GDMonoAssembly::load(p_name, p_aname, p_refonly, p_search_dirs);
if (!assembly) if (!assembly) {
return false; return false;
}
*r_assembly = assembly; *r_assembly = assembly;
@ -573,8 +579,9 @@ bool GDMono::load_assembly_from(const String &p_name, const String &p_path, GDMo
GDMonoAssembly *assembly = GDMonoAssembly::load_from(p_name, p_path, p_refonly); GDMonoAssembly *assembly = GDMonoAssembly::load_from(p_name, p_path, p_refonly);
if (!assembly) if (!assembly) {
return false; return false;
}
*r_assembly = assembly; *r_assembly = assembly;
@ -594,16 +601,19 @@ ApiAssemblyInfo::Version ApiAssemblyInfo::Version::get_from_loaded_assembly(GDMo
if (nativecalls_klass) { if (nativecalls_klass) {
GDMonoField *api_hash_field = nativecalls_klass->get_field("godot_api_hash"); GDMonoField *api_hash_field = nativecalls_klass->get_field("godot_api_hash");
if (api_hash_field) if (api_hash_field) {
api_assembly_version.godot_api_hash = GDMonoMarshal::unbox<uint64_t>(api_hash_field->get_value(nullptr)); api_assembly_version.godot_api_hash = GDMonoMarshal::unbox<uint64_t>(api_hash_field->get_value(nullptr));
}
GDMonoField *binds_ver_field = nativecalls_klass->get_field("bindings_version"); GDMonoField *binds_ver_field = nativecalls_klass->get_field("bindings_version");
if (binds_ver_field) if (binds_ver_field) {
api_assembly_version.bindings_version = GDMonoMarshal::unbox<uint32_t>(binds_ver_field->get_value(nullptr)); api_assembly_version.bindings_version = GDMonoMarshal::unbox<uint32_t>(binds_ver_field->get_value(nullptr));
}
GDMonoField *cs_glue_ver_field = nativecalls_klass->get_field("cs_glue_version"); GDMonoField *cs_glue_ver_field = nativecalls_klass->get_field("cs_glue_version");
if (cs_glue_ver_field) if (cs_glue_ver_field) {
api_assembly_version.cs_glue_version = GDMonoMarshal::unbox<uint32_t>(cs_glue_ver_field->get_value(nullptr)); api_assembly_version.cs_glue_version = GDMonoMarshal::unbox<uint32_t>(cs_glue_ver_field->get_value(nullptr));
}
} }
return api_assembly_version; return api_assembly_version;
@ -614,13 +624,15 @@ String ApiAssemblyInfo::to_string(ApiAssemblyInfo::Type p_type) {
} }
bool GDMono::_load_corlib_assembly() { bool GDMono::_load_corlib_assembly() {
if (corlib_assembly) if (corlib_assembly) {
return true; return true;
}
bool success = load_assembly("mscorlib", &corlib_assembly); bool success = load_assembly("mscorlib", &corlib_assembly);
if (success) if (success) {
GDMonoCache::update_corlib_cache(); GDMonoCache::update_corlib_cache();
}
return success; return success;
} }
@ -647,12 +659,14 @@ bool GDMono::copy_prebuilt_api_assembly(ApiAssemblyInfo::Type p_api_type, const
DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
String xml_file = assembly_name + ".xml"; String xml_file = assembly_name + ".xml";
if (da->copy(src_dir.plus_file(xml_file), dst_dir.plus_file(xml_file)) != OK) if (da->copy(src_dir.plus_file(xml_file), dst_dir.plus_file(xml_file)) != OK) {
WARN_PRINT("Failed to copy '" + xml_file + "'."); WARN_PRINT("Failed to copy '" + xml_file + "'.");
}
String pdb_file = assembly_name + ".pdb"; String pdb_file = assembly_name + ".pdb";
if (da->copy(src_dir.plus_file(pdb_file), dst_dir.plus_file(pdb_file)) != OK) if (da->copy(src_dir.plus_file(pdb_file), dst_dir.plus_file(pdb_file)) != OK) {
WARN_PRINT("Failed to copy '" + pdb_file + "'."); WARN_PRINT("Failed to copy '" + pdb_file + "'.");
}
String assembly_file = assembly_name + ".dll"; String assembly_file = assembly_name + ".dll";
if (da->copy(src_dir.plus_file(assembly_file), dst_dir.plus_file(assembly_file)) != OK) { if (da->copy(src_dir.plus_file(assembly_file), dst_dir.plus_file(assembly_file)) != OK) {
@ -667,13 +681,15 @@ static bool try_get_cached_api_hash_for(const String &p_api_assemblies_dir, bool
String core_api_assembly_path = p_api_assemblies_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll"); String core_api_assembly_path = p_api_assemblies_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll");
String editor_api_assembly_path = p_api_assemblies_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll"); String editor_api_assembly_path = p_api_assemblies_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll");
if (!FileAccess::exists(core_api_assembly_path) || !FileAccess::exists(editor_api_assembly_path)) if (!FileAccess::exists(core_api_assembly_path) || !FileAccess::exists(editor_api_assembly_path)) {
return false; return false;
}
String cached_api_hash_path = p_api_assemblies_dir.plus_file("api_hash_cache.cfg"); String cached_api_hash_path = p_api_assemblies_dir.plus_file("api_hash_cache.cfg");
if (!FileAccess::exists(cached_api_hash_path)) if (!FileAccess::exists(cached_api_hash_path)) {
return false; return false;
}
Ref<ConfigFile> cfg; Ref<ConfigFile> cfg;
cfg.instance(); cfg.instance();
@ -766,8 +782,9 @@ String GDMono::update_api_assemblies_from_prebuilt(const String &p_config, const
// Note: Even if only one of the assemblies if missing or out of sync, we update both // Note: Even if only one of the assemblies if missing or out of sync, we update both
if (!api_assemblies_out_of_sync && FileAccess::exists(core_assembly_path) && FileAccess::exists(editor_assembly_path)) if (!api_assemblies_out_of_sync && FileAccess::exists(core_assembly_path) && FileAccess::exists(editor_assembly_path)) {
return String(); // No update needed return String(); // No update needed
}
print_verbose("Updating '" + p_config + "' API assemblies"); print_verbose("Updating '" + p_config + "' API assemblies");
@ -795,8 +812,9 @@ String GDMono::update_api_assemblies_from_prebuilt(const String &p_config, const
#endif #endif
bool GDMono::_load_core_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, const String &p_config, bool p_refonly) { bool GDMono::_load_core_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, const String &p_config, bool p_refonly) {
if (r_loaded_api_assembly.assembly) if (r_loaded_api_assembly.assembly) {
return true; return true;
}
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
// For the editor and the editor player we want to load it from a specific path to make sure we can keep it up to date // For the editor and the editor player we want to load it from a specific path to make sure we can keep it up to date
@ -828,8 +846,9 @@ bool GDMono::_load_core_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, c
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
bool GDMono::_load_editor_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, const String &p_config, bool p_refonly) { bool GDMono::_load_editor_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, const String &p_config, bool p_refonly) {
if (r_loaded_api_assembly.assembly) if (r_loaded_api_assembly.assembly) {
return true; return true;
}
// For the editor and the editor player we want to load it from a specific path to make sure we can keep it up to date // For the editor and the editor player we want to load it from a specific path to make sure we can keep it up to date
@ -859,30 +878,35 @@ bool GDMono::_load_editor_api_assembly(LoadedApiAssembly &r_loaded_api_assembly,
bool GDMono::_try_load_api_assemblies(LoadedApiAssembly &r_core_api_assembly, LoadedApiAssembly &r_editor_api_assembly, bool GDMono::_try_load_api_assemblies(LoadedApiAssembly &r_core_api_assembly, LoadedApiAssembly &r_editor_api_assembly,
const String &p_config, bool p_refonly, CoreApiAssemblyLoadedCallback p_callback) { const String &p_config, bool p_refonly, CoreApiAssemblyLoadedCallback p_callback) {
if (!_load_core_api_assembly(r_core_api_assembly, p_config, p_refonly)) { if (!_load_core_api_assembly(r_core_api_assembly, p_config, p_refonly)) {
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;
} }
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
if (!_load_editor_api_assembly(r_editor_api_assembly, p_config, p_refonly)) { if (!_load_editor_api_assembly(r_editor_api_assembly, p_config, p_refonly)) {
if (OS::get_singleton()->is_stdout_verbose()) if (OS::get_singleton()->is_stdout_verbose()) {
print_error("Mono: Failed to load Editor API assembly"); print_error("Mono: Failed to load Editor API assembly");
}
return false; return false;
} }
if (r_editor_api_assembly.out_of_sync) if (r_editor_api_assembly.out_of_sync) {
return false; return false;
}
#endif #endif
// Check if the core API assembly is out of sync only after trying to load the // Check if the core API assembly is out of sync only after trying to load the
// editor API assembly. Otherwise, if both assemblies are out of sync, we would // editor API assembly. Otherwise, if both assemblies are out of sync, we would
// only update the former as we won't know the latter also needs to be updated. // only update the former as we won't know the latter also needs to be updated.
if (r_core_api_assembly.out_of_sync) if (r_core_api_assembly.out_of_sync) {
return false; return false;
}
if (p_callback) if (p_callback) {
return p_callback(); return p_callback();
}
return true; return true;
} }
@ -890,8 +914,9 @@ bool GDMono::_try_load_api_assemblies(LoadedApiAssembly &r_core_api_assembly, Lo
bool GDMono::_on_core_api_assembly_loaded() { bool GDMono::_on_core_api_assembly_loaded() {
GDMonoCache::update_godot_api_cache(); GDMonoCache::update_godot_api_cache();
if (!GDMonoCache::cached_data.godot_api_cache_updated) if (!GDMonoCache::cached_data.godot_api_cache_updated) {
return false; return false;
}
get_singleton()->_install_trace_listener(); get_singleton()->_install_trace_listener();
@ -956,8 +981,9 @@ void GDMono::_load_api_assemblies() {
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
bool GDMono::_load_tools_assemblies() { bool GDMono::_load_tools_assemblies() {
if (tools_assembly && tools_project_editor_assembly) if (tools_assembly && tools_project_editor_assembly) {
return true; return true;
}
bool success = load_assembly(TOOLS_ASM_NAME, &tools_assembly) && bool success = load_assembly(TOOLS_ASM_NAME, &tools_assembly) &&
load_assembly(TOOLS_PROJECT_EDITOR_ASM_NAME, &tools_project_editor_assembly); load_assembly(TOOLS_PROJECT_EDITOR_ASM_NAME, &tools_project_editor_assembly);
@ -967,8 +993,9 @@ bool GDMono::_load_tools_assemblies() {
#endif #endif
bool GDMono::_load_project_assembly() { bool GDMono::_load_project_assembly() {
if (project_assembly) if (project_assembly) {
return true; return true;
}
String appname = ProjectSettings::get_singleton()->get("application/config/name"); String appname = ProjectSettings::get_singleton()->get("application/config/name");
String appname_safe = OS::get_singleton()->get_safe_dir_name(appname); String appname_safe = OS::get_singleton()->get_safe_dir_name(appname);
@ -1020,8 +1047,9 @@ Error GDMono::_unload_scripts_domain() {
print_verbose("Mono: Finalizing scripts domain..."); print_verbose("Mono: Finalizing scripts domain...");
if (mono_domain_get() != root_domain) if (mono_domain_get() != root_domain) {
mono_domain_set(root_domain, true); mono_domain_set(root_domain, true);
}
finalizing_scripts_domain = true; finalizing_scripts_domain = true;
@ -1111,8 +1139,9 @@ Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) {
print_verbose("Mono: Unloading domain '" + domain_name + "'..."); print_verbose("Mono: Unloading domain '" + domain_name + "'...");
if (mono_domain_get() == p_domain) if (mono_domain_get() == p_domain) {
mono_domain_set(root_domain, true); mono_domain_set(root_domain, true);
}
if (!mono_domain_finalize(p_domain, 2000)) { if (!mono_domain_finalize(p_domain, 2000)) {
ERR_PRINT("Mono: Domain finalization timeout."); ERR_PRINT("Mono: Domain finalization timeout.");
@ -1138,10 +1167,11 @@ Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) {
GDMonoClass *GDMono::get_class(MonoClass *p_raw_class) { GDMonoClass *GDMono::get_class(MonoClass *p_raw_class) {
MonoImage *image = mono_class_get_image(p_raw_class); MonoImage *image = mono_class_get_image(p_raw_class);
if (image == corlib_assembly->get_image()) if (image == corlib_assembly->get_image()) {
return corlib_assembly->get_class(p_raw_class); return corlib_assembly->get_class(p_raw_class);
}
uint32_t domain_id = mono_domain_get_id(mono_domain_get()); int32_t domain_id = mono_domain_get_id(mono_domain_get());
HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[domain_id]; HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[domain_id];
const String *k = nullptr; const String *k = nullptr;
@ -1149,9 +1179,9 @@ GDMonoClass *GDMono::get_class(MonoClass *p_raw_class) {
GDMonoAssembly *assembly = domain_assemblies.get(*k); GDMonoAssembly *assembly = domain_assemblies.get(*k);
if (assembly->get_image() == image) { if (assembly->get_image() == image) {
GDMonoClass *klass = assembly->get_class(p_raw_class); GDMonoClass *klass = assembly->get_class(p_raw_class);
if (klass) {
if (klass)
return klass; return klass;
}
} }
} }
@ -1160,24 +1190,26 @@ GDMonoClass *GDMono::get_class(MonoClass *p_raw_class) {
GDMonoClass *GDMono::get_class(const StringName &p_namespace, const StringName &p_name) { GDMonoClass *GDMono::get_class(const StringName &p_namespace, const StringName &p_name) {
GDMonoClass *klass = corlib_assembly->get_class(p_namespace, p_name); GDMonoClass *klass = corlib_assembly->get_class(p_namespace, p_name);
if (klass) if (klass) {
return klass; return klass;
}
uint32_t domain_id = mono_domain_get_id(mono_domain_get()); int32_t domain_id = mono_domain_get_id(mono_domain_get());
HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[domain_id]; HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[domain_id];
const String *k = nullptr; const String *k = nullptr;
while ((k = domain_assemblies.next(k))) { while ((k = domain_assemblies.next(k))) {
GDMonoAssembly *assembly = domain_assemblies.get(*k); GDMonoAssembly *assembly = domain_assemblies.get(*k);
klass = assembly->get_class(p_namespace, p_name); klass = assembly->get_class(p_namespace, p_name);
if (klass) if (klass) {
return klass; return klass;
}
} }
return nullptr; return nullptr;
} }
void GDMono::_domain_assemblies_cleanup(uint32_t p_domain_id) { void GDMono::_domain_assemblies_cleanup(int32_t p_domain_id) {
HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[p_domain_id]; HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[p_domain_id];
const String *k = nullptr; const String *k = nullptr;
@ -1195,8 +1227,9 @@ void GDMono::unhandled_exception_hook(MonoObject *p_exc, void *) {
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
GDMonoUtils::debug_send_unhandled_exception_error((MonoException *)p_exc); GDMonoUtils::debug_send_unhandled_exception_error((MonoException *)p_exc);
if (EngineDebugger::is_active()) if (EngineDebugger::is_active()) {
EngineDebugger::get_singleton()->poll_events(false); EngineDebugger::get_singleton()->poll_events(false);
}
#endif #endif
exit(mono_environment_exitcode_get()); exit(mono_environment_exitcode_get());
@ -1271,7 +1304,7 @@ GDMono::~GDMono() {
// Leave the rest to 'mono_jit_cleanup' // Leave the rest to 'mono_jit_cleanup'
#endif #endif
const uint32_t *k = nullptr; const int32_t *k = nullptr;
while ((k = assemblies.next(k))) { while ((k = assemblies.next(k))) {
HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies.get(*k); HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies.get(*k);
@ -1295,8 +1328,9 @@ GDMono::~GDMono() {
gdmono::android::support::cleanup(); gdmono::android::support::cleanup();
#endif #endif
if (gdmono_log) if (gdmono_log) {
memdelete(gdmono_log); memdelete(gdmono_log);
}
singleton = nullptr; singleton = nullptr;
} }
@ -1313,37 +1347,44 @@ void _GodotSharp::detach_thread() {
int32_t _GodotSharp::get_domain_id() { int32_t _GodotSharp::get_domain_id() {
MonoDomain *domain = mono_domain_get(); MonoDomain *domain = mono_domain_get();
CRASH_COND(!domain); // User must check if runtime is initialized before calling this method ERR_FAIL_NULL_V(domain, -1);
return mono_domain_get_id(domain); return mono_domain_get_id(domain);
} }
int32_t _GodotSharp::get_scripts_domain_id() { int32_t _GodotSharp::get_scripts_domain_id() {
ERR_FAIL_NULL_V_MSG(GDMono::get_singleton(),
-1, "The Mono runtime is not initialized");
MonoDomain *domain = GDMono::get_singleton()->get_scripts_domain(); MonoDomain *domain = GDMono::get_singleton()->get_scripts_domain();
CRASH_COND(!domain); // User must check if scripts domain is loaded before calling this method ERR_FAIL_NULL_V(domain, -1);
return mono_domain_get_id(domain); return mono_domain_get_id(domain);
} }
bool _GodotSharp::is_scripts_domain_loaded() { bool _GodotSharp::is_scripts_domain_loaded() {
return GDMono::get_singleton()->is_runtime_initialized() && GDMono::get_singleton()->get_scripts_domain() != nullptr; return GDMono::get_singleton() != nullptr &&
GDMono::get_singleton()->is_runtime_initialized() &&
GDMono::get_singleton()->get_scripts_domain() != nullptr;
} }
bool _GodotSharp::_is_domain_finalizing_for_unload(int32_t p_domain_id) { bool _GodotSharp::_is_domain_finalizing_for_unload(int32_t p_domain_id) {
return is_domain_finalizing_for_unload(p_domain_id); return is_domain_finalizing_for_unload(p_domain_id);
} }
bool _GodotSharp::is_domain_finalizing_for_unload() {
return is_domain_finalizing_for_unload(mono_domain_get());
}
bool _GodotSharp::is_domain_finalizing_for_unload(int32_t p_domain_id) { bool _GodotSharp::is_domain_finalizing_for_unload(int32_t p_domain_id) {
return is_domain_finalizing_for_unload(mono_domain_get_by_id(p_domain_id)); return is_domain_finalizing_for_unload(mono_domain_get_by_id(p_domain_id));
} }
bool _GodotSharp::is_domain_finalizing_for_unload(MonoDomain *p_domain) { bool _GodotSharp::is_domain_finalizing_for_unload(MonoDomain *p_domain) {
if (!p_domain) GDMono *gd_mono = GDMono::get_singleton();
return true;
if (p_domain == GDMono::get_singleton()->get_scripts_domain() && GDMono::get_singleton()->is_finalizing_scripts_domain()) ERR_FAIL_COND_V_MSG(!gd_mono || !gd_mono->is_runtime_initialized(),
false, "The Mono runtime is not initialized");
ERR_FAIL_NULL_V(p_domain, true);
if (p_domain == gd_mono->get_scripts_domain() && gd_mono->is_finalizing_scripts_domain()) {
return true; return true;
}
return mono_domain_is_unloading(p_domain); return mono_domain_is_unloading(p_domain);
} }
@ -1352,15 +1393,17 @@ bool _GodotSharp::is_runtime_shutting_down() {
} }
bool _GodotSharp::is_runtime_initialized() { bool _GodotSharp::is_runtime_initialized() {
return GDMono::get_singleton()->is_runtime_initialized(); return GDMono::get_singleton() != nullptr && GDMono::get_singleton()->is_runtime_initialized();
} }
void _GodotSharp::_reload_assemblies(bool p_soft_reload) { void _GodotSharp::_reload_assemblies(bool p_soft_reload) {
#ifdef GD_MONO_HOT_RELOAD #ifdef GD_MONO_HOT_RELOAD
CRASH_COND(CSharpLanguage::get_singleton() == nullptr);
// This method may be called more than once with `call_deferred`, so we need to check // This method may be called more than once with `call_deferred`, so we need to check
// again if reloading is needed to avoid reloading multiple times unnecessarily. // again if reloading is needed to avoid reloading multiple times unnecessarily.
if (CSharpLanguage::get_singleton()->is_assembly_reloading_needed()) if (CSharpLanguage::get_singleton()->is_assembly_reloading_needed()) {
CSharpLanguage::get_singleton()->reload_assemblies(p_soft_reload); CSharpLanguage::get_singleton()->reload_assemblies(p_soft_reload);
}
#endif #endif
} }

View File

@ -97,7 +97,7 @@ private:
MonoDomain *root_domain; MonoDomain *root_domain;
MonoDomain *scripts_domain; MonoDomain *scripts_domain;
HashMap<uint32_t, HashMap<String, GDMonoAssembly *>> assemblies; HashMap<int32_t, HashMap<String, GDMonoAssembly *>> assemblies;
GDMonoAssembly *corlib_assembly; GDMonoAssembly *corlib_assembly;
GDMonoAssembly *project_assembly; GDMonoAssembly *project_assembly;
@ -141,7 +141,7 @@ private:
Error _unload_scripts_domain(); Error _unload_scripts_domain();
#endif #endif
void _domain_assemblies_cleanup(uint32_t p_domain_id); void _domain_assemblies_cleanup(int32_t p_domain_id);
uint64_t api_core_hash; uint64_t api_core_hash;
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
@ -165,14 +165,16 @@ protected:
public: public:
#ifdef DEBUG_METHODS_ENABLED #ifdef DEBUG_METHODS_ENABLED
uint64_t get_api_core_hash() { uint64_t get_api_core_hash() {
if (api_core_hash == 0) if (api_core_hash == 0) {
api_core_hash = ClassDB::get_api_hash(ClassDB::API_CORE); api_core_hash = ClassDB::get_api_hash(ClassDB::API_CORE);
}
return api_core_hash; return api_core_hash;
} }
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
uint64_t get_api_editor_hash() { uint64_t get_api_editor_hash() {
if (api_editor_hash == 0) if (api_editor_hash == 0) {
api_editor_hash = ClassDB::get_api_hash(ClassDB::API_EDITOR); api_editor_hash = ClassDB::get_api_hash(ClassDB::API_EDITOR);
}
return api_editor_hash; return api_editor_hash;
} }
#endif // TOOLS_ENABLED #endif // TOOLS_ENABLED
@ -202,7 +204,7 @@ public:
UnhandledExceptionPolicy get_unhandled_exception_policy() const { return unhandled_exception_policy; } UnhandledExceptionPolicy get_unhandled_exception_policy() const { return unhandled_exception_policy; }
// Do not use these, unless you know what you're doing // Do not use these, unless you know what you're doing
void add_assembly(uint32_t p_domain_id, GDMonoAssembly *p_assembly); void add_assembly(int32_t p_domain_id, GDMonoAssembly *p_assembly);
GDMonoAssembly *get_loaded_assembly(const String &p_name); GDMonoAssembly *get_loaded_assembly(const String &p_name);
_FORCE_INLINE_ bool is_runtime_initialized() const { return runtime_initialized && !mono_runtime_is_shutting_down() /* stays true after shutdown finished */; } _FORCE_INLINE_ bool is_runtime_initialized() const { return runtime_initialized && !mono_runtime_is_shutting_down() /* stays true after shutdown finished */; }
@ -252,18 +254,18 @@ class ScopeDomain {
public: public:
ScopeDomain(MonoDomain *p_domain) { ScopeDomain(MonoDomain *p_domain) {
MonoDomain *prev_domain = mono_domain_get(); prev_domain = mono_domain_get();
if (prev_domain != p_domain) { if (prev_domain != p_domain) {
this->prev_domain = prev_domain;
mono_domain_set(p_domain, false); mono_domain_set(p_domain, false);
} else { } else {
this->prev_domain = nullptr; prev_domain = nullptr;
} }
} }
~ScopeDomain() { ~ScopeDomain() {
if (prev_domain) if (prev_domain) {
mono_domain_set(prev_domain, false); mono_domain_set(prev_domain, false);
}
} }
}; };
@ -276,8 +278,9 @@ public:
} }
~ScopeExitDomainUnload() { ~ScopeExitDomainUnload() {
if (domain) if (domain) {
GDMono::get_singleton()->finalize_and_unload_domain(domain); GDMono::get_singleton()->finalize_and_unload_domain(domain);
}
} }
}; };
@ -298,9 +301,6 @@ class _GodotSharp : public Object {
bool _is_domain_finalizing_for_unload(int32_t p_domain_id); bool _is_domain_finalizing_for_unload(int32_t p_domain_id);
List<NodePath *> np_delete_queue;
List<RID *> rid_delete_queue;
void _reload_assemblies(bool p_soft_reload); void _reload_assemblies(bool p_soft_reload);
protected: protected:
@ -318,7 +318,6 @@ public:
bool is_scripts_domain_loaded(); bool is_scripts_domain_loaded();
bool is_domain_finalizing_for_unload();
bool is_domain_finalizing_for_unload(int32_t p_domain_id); bool is_domain_finalizing_for_unload(int32_t p_domain_id);
bool is_domain_finalizing_for_unload(MonoDomain *p_domain); bool is_domain_finalizing_for_unload(MonoDomain *p_domain);

View File

@ -108,8 +108,9 @@ void GDMonoAssembly::assembly_load_hook(MonoAssembly *assembly, [[maybe_unused]]
#ifdef GD_MONO_HOT_RELOAD #ifdef GD_MONO_HOT_RELOAD
const char *path = mono_image_get_filename(image); const char *path = mono_image_get_filename(image);
if (FileAccess::exists(path)) if (FileAccess::exists(path)) {
gdassembly->modified_time = FileAccess::get_modified_time(path); gdassembly->modified_time = FileAccess::get_modified_time(path);
}
#endif #endif
MonoDomain *domain = mono_domain_get(); MonoDomain *domain = mono_domain_get();
@ -137,8 +138,9 @@ MonoAssembly *GDMonoAssembly::_search_hook(MonoAssemblyName *aname, [[maybe_unus
bool has_extension = name.ends_with(".dll") || name.ends_with(".exe"); bool has_extension = name.ends_with(".dll") || name.ends_with(".exe");
GDMonoAssembly *loaded_asm = GDMono::get_singleton()->get_loaded_assembly(has_extension ? name.get_basename() : name); GDMonoAssembly *loaded_asm = GDMono::get_singleton()->get_loaded_assembly(has_extension ? name.get_basename() : name);
if (loaded_asm) if (loaded_asm) {
return loaded_asm->get_assembly(); return loaded_asm->get_assembly();
}
return nullptr; return nullptr;
} }
@ -161,22 +163,25 @@ MonoAssembly *GDMonoAssembly::_load_assembly_search(const String &p_name, MonoAs
path = search_dir.plus_file(p_name); path = search_dir.plus_file(p_name);
if (FileAccess::exists(path)) { if (FileAccess::exists(path)) {
res = _real_load_assembly_from(path, p_refonly, p_aname); res = _real_load_assembly_from(path, p_refonly, p_aname);
if (res != nullptr) if (res != nullptr) {
return res; return res;
}
} }
} else { } else {
path = search_dir.plus_file(p_name + ".dll"); path = search_dir.plus_file(p_name + ".dll");
if (FileAccess::exists(path)) { if (FileAccess::exists(path)) {
res = _real_load_assembly_from(path, p_refonly, p_aname); res = _real_load_assembly_from(path, p_refonly, p_aname);
if (res != nullptr) if (res != nullptr) {
return res; return res;
}
} }
path = search_dir.plus_file(p_name + ".exe"); path = search_dir.plus_file(p_name + ".exe");
if (FileAccess::exists(path)) { if (FileAccess::exists(path)) {
res = _real_load_assembly_from(path, p_refonly, p_aname); res = _real_load_assembly_from(path, p_refonly, p_aname);
if (res != nullptr) if (res != nullptr) {
return res; return res;
}
} }
} }
} }
@ -194,16 +199,19 @@ String GDMonoAssembly::find_assembly(const String &p_name) {
if (has_extension) { if (has_extension) {
path = search_dir.plus_file(p_name); path = search_dir.plus_file(p_name);
if (FileAccess::exists(path)) if (FileAccess::exists(path)) {
return path; return path;
}
} else { } else {
path = search_dir.plus_file(p_name + ".dll"); path = search_dir.plus_file(p_name + ".dll");
if (FileAccess::exists(path)) if (FileAccess::exists(path)) {
return path; return path;
}
path = search_dir.plus_file(p_name + ".exe"); path = search_dir.plus_file(p_name + ".exe");
if (FileAccess::exists(path)) if (FileAccess::exists(path)) {
return path; return path;
}
} }
} }
@ -279,8 +287,9 @@ MonoAssembly *GDMonoAssembly::_real_load_assembly_from(const String &p_path, boo
if (!FileAccess::exists(pdb_path)) { if (!FileAccess::exists(pdb_path)) {
pdb_path = p_path.get_basename() + ".pdb"; // without .dll pdb_path = p_path.get_basename() + ".pdb"; // without .dll
if (!FileAccess::exists(pdb_path)) if (!FileAccess::exists(pdb_path)) {
goto no_pdb; goto no_pdb;
}
} }
pdb_data = FileAccess::get_file_as_array(pdb_path); pdb_data = FileAccess::get_file_as_array(pdb_path);
@ -307,8 +316,9 @@ no_pdb:
String name = String::utf8(mono_assembly_name_get_name(mono_assembly_get_name(assembly))); String name = String::utf8(mono_assembly_name_get_name(mono_assembly_get_name(assembly)));
bool has_extension = name.ends_with(".dll") || name.ends_with(".exe"); bool has_extension = name.ends_with(".dll") || name.ends_with(".exe");
GDMonoAssembly *loaded_asm = GDMono::get_singleton()->get_loaded_assembly(has_extension ? name.get_basename() : name); GDMonoAssembly *loaded_asm = GDMono::get_singleton()->get_loaded_assembly(has_extension ? name.get_basename() : name);
if (!loaded_asm) if (!loaded_asm) {
assembly_load_hook(assembly, nullptr); assembly_load_hook(assembly, nullptr);
}
} }
// Decrement refcount which was previously incremented by mono_image_open_from_data_with_name // Decrement refcount which was previously incremented by mono_image_open_from_data_with_name
@ -342,13 +352,15 @@ GDMonoClass *GDMonoAssembly::get_class(const StringName &p_namespace, const Stri
GDMonoClass **match = cached_classes.getptr(key); GDMonoClass **match = cached_classes.getptr(key);
if (match) if (match) {
return *match; return *match;
}
MonoClass *mono_class = mono_class_from_name(image, String(p_namespace).utf8(), String(p_name).utf8()); MonoClass *mono_class = mono_class_from_name(image, String(p_namespace).utf8(), String(p_name).utf8());
if (!mono_class) if (!mono_class) {
return nullptr; return nullptr;
}
GDMonoClass *wrapped_class = memnew(GDMonoClass(p_namespace, p_name, mono_class, this)); GDMonoClass *wrapped_class = memnew(GDMonoClass(p_namespace, p_name, mono_class, this));
@ -363,8 +375,9 @@ GDMonoClass *GDMonoAssembly::get_class(MonoClass *p_mono_class) {
Map<MonoClass *, GDMonoClass *>::Element *match = cached_raw.find(p_mono_class); Map<MonoClass *, GDMonoClass *>::Element *match = cached_raw.find(p_mono_class);
if (match) if (match) {
return match->value(); return match->value();
}
StringName namespace_name = mono_class_get_namespace(p_mono_class); StringName namespace_name = mono_class_get_namespace(p_mono_class);
StringName class_name = mono_class_get_name(p_mono_class); StringName class_name = mono_class_get_name(p_mono_class);
@ -383,8 +396,9 @@ GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class)
if (gdobject_class_cache_updated) { if (gdobject_class_cache_updated) {
Map<StringName, GDMonoClass *>::Element *result = gdobject_class_cache.find(p_class); Map<StringName, GDMonoClass *>::Element *result = gdobject_class_cache.find(p_class);
if (result) if (result) {
match = result->get(); match = result->get();
}
} else { } else {
List<GDMonoClass *> nested_classes; List<GDMonoClass *> nested_classes;
@ -393,18 +407,21 @@ GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class)
for (int i = 1; i < rows; i++) { for (int i = 1; i < rows; i++) {
MonoClass *mono_class = mono_class_get(image, (i + 1) | MONO_TOKEN_TYPE_DEF); MonoClass *mono_class = mono_class_get(image, (i + 1) | MONO_TOKEN_TYPE_DEF);
if (!mono_class_is_assignable_from(CACHED_CLASS_RAW(GodotObject), mono_class)) if (!mono_class_is_assignable_from(CACHED_CLASS_RAW(GodotObject), mono_class)) {
continue; continue;
}
GDMonoClass *current = get_class(mono_class); GDMonoClass *current = get_class(mono_class);
if (!current) if (!current) {
continue; continue;
}
nested_classes.push_back(current); nested_classes.push_back(current);
if (!match && current->get_name() == p_class) if (!match && current->get_name() == p_class) {
match = current; match = current;
}
while (!nested_classes.empty()) { while (!nested_classes.empty()) {
GDMonoClass *current_nested = nested_classes.front()->get(); GDMonoClass *current_nested = nested_classes.front()->get();
@ -415,8 +432,9 @@ GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class)
while (true) { while (true) {
MonoClass *raw_nested = mono_class_get_nested_types(current_nested->get_mono_ptr(), &iter); MonoClass *raw_nested = mono_class_get_nested_types(current_nested->get_mono_ptr(), &iter);
if (!raw_nested) if (!raw_nested) {
break; break;
}
GDMonoClass *nested_class = get_class(raw_nested); GDMonoClass *nested_class = get_class(raw_nested);
@ -437,8 +455,9 @@ GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class)
} }
GDMonoAssembly *GDMonoAssembly::load(const String &p_name, MonoAssemblyName *p_aname, bool p_refonly, const Vector<String> &p_search_dirs) { GDMonoAssembly *GDMonoAssembly::load(const String &p_name, MonoAssemblyName *p_aname, bool p_refonly, const Vector<String> &p_search_dirs) {
if (GDMono::get_singleton()->get_corlib_assembly() && (p_name == "mscorlib" || p_name == "mscorlib.dll")) if (GDMono::get_singleton()->get_corlib_assembly() && (p_name == "mscorlib" || p_name == "mscorlib.dll")) {
return GDMono::get_singleton()->get_corlib_assembly(); return GDMono::get_singleton()->get_corlib_assembly();
}
// We need to manually call the search hook in this case, as it won't be called in the next step // We need to manually call the search hook in this case, as it won't be called in the next step
MonoAssembly *assembly = mono_assembly_invoke_search_hook(p_aname); MonoAssembly *assembly = mono_assembly_invoke_search_hook(p_aname);
@ -456,8 +475,9 @@ GDMonoAssembly *GDMonoAssembly::load(const String &p_name, MonoAssemblyName *p_a
} }
GDMonoAssembly *GDMonoAssembly::load_from(const String &p_name, const String &p_path, bool p_refonly) { GDMonoAssembly *GDMonoAssembly::load_from(const String &p_name, const String &p_path, bool p_refonly) {
if (p_name == "mscorlib" || p_name == "mscorlib.dll") if (p_name == "mscorlib" || p_name == "mscorlib.dll") {
return GDMono::get_singleton()->get_corlib_assembly(); return GDMono::get_singleton()->get_corlib_assembly();
}
// We need to manually call the search hook in this case, as it won't be called in the next step // We need to manually call the search hook in this case, as it won't be called in the next step
MonoAssemblyName *aname = mono_assembly_name_new(p_name.utf8()); MonoAssemblyName *aname = mono_assembly_name_new(p_name.utf8());
@ -477,6 +497,7 @@ GDMonoAssembly *GDMonoAssembly::load_from(const String &p_name, const String &p_
} }
GDMonoAssembly::~GDMonoAssembly() { GDMonoAssembly::~GDMonoAssembly() {
if (image) if (image) {
unload(); unload();
}
} }

View File

@ -217,7 +217,7 @@ void update_corlib_cache() {
CACHE_METHOD_AND_CHECK(System_Diagnostics_StackTrace, ctor_Exception_bool, CACHED_CLASS(System_Diagnostics_StackTrace)->get_method_with_desc("System.Diagnostics.StackTrace:.ctor(System.Exception,bool)", true)); CACHE_METHOD_AND_CHECK(System_Diagnostics_StackTrace, ctor_Exception_bool, CACHED_CLASS(System_Diagnostics_StackTrace)->get_method_with_desc("System.Diagnostics.StackTrace:.ctor(System.Exception,bool)", true));
#endif #endif
CACHE_METHOD_THUNK_AND_CHECK(Delegate, Equals, GDMono::get_singleton()->get_corlib_assembly()->get_class("System", "Delegate")->get_method_with_desc("System.Delegate:Equals(object)", 1)); CACHE_METHOD_THUNK_AND_CHECK(Delegate, Equals, GDMono::get_singleton()->get_corlib_assembly()->get_class("System", "Delegate")->get_method_with_desc("System.Delegate:Equals(object)", true));
CACHE_CLASS_AND_CHECK(KeyNotFoundException, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Collections.Generic", "KeyNotFoundException")); CACHE_CLASS_AND_CHECK(KeyNotFoundException, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Collections.Generic", "KeyNotFoundException"));

View File

@ -81,15 +81,17 @@ bool GDMonoClass::is_assignable_from(GDMonoClass *p_from) const {
StringName GDMonoClass::get_namespace() const { StringName GDMonoClass::get_namespace() const {
GDMonoClass *nesting_class = get_nesting_class(); GDMonoClass *nesting_class = get_nesting_class();
if (!nesting_class) if (!nesting_class) {
return namespace_name; return namespace_name;
}
return nesting_class->get_namespace(); return nesting_class->get_namespace();
} }
String GDMonoClass::get_name_for_lookup() const { String GDMonoClass::get_name_for_lookup() const {
GDMonoClass *nesting_class = get_nesting_class(); GDMonoClass *nesting_class = get_nesting_class();
if (!nesting_class) if (!nesting_class) {
return class_name; return class_name;
}
return nesting_class->get_name_for_lookup() + "/" + class_name; return nesting_class->get_name_for_lookup() + "/" + class_name;
} }
@ -131,11 +133,13 @@ bool GDMonoClass::has_attribute(GDMonoClass *p_attr_class) {
ERR_FAIL_NULL_V(p_attr_class, false); ERR_FAIL_NULL_V(p_attr_class, false);
#endif #endif
if (!attrs_fetched) if (!attrs_fetched) {
fetch_attributes(); fetch_attributes();
}
if (!attributes) if (!attributes) {
return false; return false;
}
return mono_custom_attrs_has_attr(attributes, p_attr_class->get_mono_ptr()); return mono_custom_attrs_has_attr(attributes, p_attr_class->get_mono_ptr());
} }
@ -145,11 +149,13 @@ MonoObject *GDMonoClass::get_attribute(GDMonoClass *p_attr_class) {
ERR_FAIL_NULL_V(p_attr_class, nullptr); ERR_FAIL_NULL_V(p_attr_class, nullptr);
#endif #endif
if (!attrs_fetched) if (!attrs_fetched) {
fetch_attributes(); fetch_attributes();
}
if (!attributes) if (!attributes) {
return nullptr; return nullptr;
}
return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr()); return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr());
} }
@ -164,8 +170,9 @@ void GDMonoClass::fetch_attributes() {
void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base) { void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base) {
CRASH_COND(!CACHED_CLASS(GodotObject)->is_assignable_from(this)); CRASH_COND(!CACHED_CLASS(GodotObject)->is_assignable_from(this));
if (methods_fetched) if (methods_fetched) {
return; return;
}
void *iter = nullptr; void *iter = nullptr;
MonoMethod *raw_method = nullptr; MonoMethod *raw_method = nullptr;
@ -202,8 +209,9 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base
break; break;
} }
if (native_top == CACHED_CLASS(GodotObject)) if (native_top == CACHED_CLASS(GodotObject)) {
break; break;
}
native_top = native_top->get_parent_class(); native_top = native_top->get_parent_class();
} }
@ -212,8 +220,9 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base
uint32_t flags = mono_method_get_flags(method->mono_method, nullptr); uint32_t flags = mono_method_get_flags(method->mono_method, nullptr);
if (!(flags & MONO_METHOD_ATTR_VIRTUAL)) if (!(flags & MONO_METHOD_ATTR_VIRTUAL)) {
continue; continue;
}
// Virtual method of Godot Object derived type, let's try to find GodotMethod attribute // Virtual method of Godot Object derived type, let's try to find GodotMethod attribute
@ -235,15 +244,17 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base
#endif #endif
MethodKey key = MethodKey(godot_method_name, method->get_parameters_count()); MethodKey key = MethodKey(godot_method_name, method->get_parameters_count());
GDMonoMethod **existing_method = methods.getptr(key); GDMonoMethod **existing_method = methods.getptr(key);
if (existing_method) if (existing_method) {
memdelete(*existing_method); // Must delete old one memdelete(*existing_method); // Must delete old one
}
methods.set(key, method); methods.set(key, method);
break; break;
} }
if (top == CACHED_CLASS(GodotObject)) if (top == CACHED_CLASS(GodotObject)) {
break; break;
}
top = top->get_parent_class(); top = top->get_parent_class();
} }
@ -258,8 +269,9 @@ GDMonoMethod *GDMonoClass::get_fetched_method_unknown_params(const StringName &p
const MethodKey *k = nullptr; const MethodKey *k = nullptr;
while ((k = methods.next(k))) { while ((k = methods.next(k))) {
if (k->name == p_name) if (k->name == p_name) {
return methods.get(*k); return methods.get(*k);
}
} }
return nullptr; return nullptr;
@ -283,11 +295,13 @@ GDMonoMethod *GDMonoClass::get_method(const StringName &p_name, int p_params_cou
GDMonoMethod **match = methods.getptr(key); GDMonoMethod **match = methods.getptr(key);
if (match) if (match) {
return *match; return *match;
}
if (methods_fetched) if (methods_fetched) {
return nullptr; return nullptr;
}
MonoMethod *raw_method = mono_class_get_method_from_name(mono_class, String(p_name).utf8().get_data(), p_params_count); MonoMethod *raw_method = mono_class_get_method_from_name(mono_class, String(p_name).utf8().get_data(), p_params_count);
@ -323,8 +337,9 @@ GDMonoMethod *GDMonoClass::get_method(MonoMethod *p_raw_method, const StringName
GDMonoMethod **match = methods.getptr(key); GDMonoMethod **match = methods.getptr(key);
if (match) if (match) {
return *match; return *match;
}
GDMonoMethod *method = memnew(GDMonoMethod(p_name, p_raw_method)); GDMonoMethod *method = memnew(GDMonoMethod(p_name, p_raw_method));
methods.set(key, method); methods.set(key, method);
@ -337,8 +352,9 @@ GDMonoMethod *GDMonoClass::get_method_with_desc(const String &p_description, boo
MonoMethod *method = mono_method_desc_search_in_class(desc, mono_class); MonoMethod *method = mono_method_desc_search_in_class(desc, mono_class);
mono_method_desc_free(desc); mono_method_desc_free(desc);
if (!method) if (!method) {
return nullptr; return nullptr;
}
ERR_FAIL_COND_V(mono_method_get_class(method) != mono_class, nullptr); ERR_FAIL_COND_V(mono_method_get_class(method) != mono_class, nullptr);
@ -348,11 +364,13 @@ GDMonoMethod *GDMonoClass::get_method_with_desc(const String &p_description, boo
GDMonoField *GDMonoClass::get_field(const StringName &p_name) { GDMonoField *GDMonoClass::get_field(const StringName &p_name) {
Map<StringName, GDMonoField *>::Element *result = fields.find(p_name); Map<StringName, GDMonoField *>::Element *result = fields.find(p_name);
if (result) if (result) {
return result->value(); return result->value();
}
if (fields_fetched) if (fields_fetched) {
return nullptr; return nullptr;
}
MonoClassField *raw_field = mono_class_get_field_from_name(mono_class, String(p_name).utf8().get_data()); MonoClassField *raw_field = mono_class_get_field_from_name(mono_class, String(p_name).utf8().get_data());
@ -367,8 +385,9 @@ GDMonoField *GDMonoClass::get_field(const StringName &p_name) {
} }
const Vector<GDMonoField *> &GDMonoClass::get_all_fields() { const Vector<GDMonoField *> &GDMonoClass::get_all_fields() {
if (fields_fetched) if (fields_fetched) {
return fields_list; return fields_list;
}
void *iter = nullptr; void *iter = nullptr;
MonoClassField *raw_field = nullptr; MonoClassField *raw_field = nullptr;
@ -394,11 +413,13 @@ const Vector<GDMonoField *> &GDMonoClass::get_all_fields() {
GDMonoProperty *GDMonoClass::get_property(const StringName &p_name) { GDMonoProperty *GDMonoClass::get_property(const StringName &p_name) {
Map<StringName, GDMonoProperty *>::Element *result = properties.find(p_name); Map<StringName, GDMonoProperty *>::Element *result = properties.find(p_name);
if (result) if (result) {
return result->value(); return result->value();
}
if (properties_fetched) if (properties_fetched) {
return nullptr; return nullptr;
}
MonoProperty *raw_property = mono_class_get_property_from_name(mono_class, String(p_name).utf8().get_data()); MonoProperty *raw_property = mono_class_get_property_from_name(mono_class, String(p_name).utf8().get_data());
@ -413,8 +434,9 @@ GDMonoProperty *GDMonoClass::get_property(const StringName &p_name) {
} }
const Vector<GDMonoProperty *> &GDMonoClass::get_all_properties() { const Vector<GDMonoProperty *> &GDMonoClass::get_all_properties() {
if (properties_fetched) if (properties_fetched) {
return properties_list; return properties_list;
}
void *iter = nullptr; void *iter = nullptr;
MonoProperty *raw_property = nullptr; MonoProperty *raw_property = nullptr;
@ -438,8 +460,9 @@ const Vector<GDMonoProperty *> &GDMonoClass::get_all_properties() {
} }
const Vector<GDMonoClass *> &GDMonoClass::get_all_delegates() { const Vector<GDMonoClass *> &GDMonoClass::get_all_delegates() {
if (delegates_fetched) if (delegates_fetched) {
return delegates_list; return delegates_list;
}
void *iter = nullptr; void *iter = nullptr;
MonoClass *raw_class = nullptr; MonoClass *raw_class = nullptr;

View File

@ -597,11 +597,13 @@ String GDMonoField::get_string_value(MonoObject *p_object) {
bool GDMonoField::has_attribute(GDMonoClass *p_attr_class) { bool GDMonoField::has_attribute(GDMonoClass *p_attr_class) {
ERR_FAIL_NULL_V(p_attr_class, false); ERR_FAIL_NULL_V(p_attr_class, false);
if (!attrs_fetched) if (!attrs_fetched) {
fetch_attributes(); fetch_attributes();
}
if (!attributes) if (!attributes) {
return false; return false;
}
return mono_custom_attrs_has_attr(attributes, p_attr_class->get_mono_ptr()); return mono_custom_attrs_has_attr(attributes, p_attr_class->get_mono_ptr());
} }
@ -609,11 +611,13 @@ bool GDMonoField::has_attribute(GDMonoClass *p_attr_class) {
MonoObject *GDMonoField::get_attribute(GDMonoClass *p_attr_class) { MonoObject *GDMonoField::get_attribute(GDMonoClass *p_attr_class) {
ERR_FAIL_NULL_V(p_attr_class, nullptr); ERR_FAIL_NULL_V(p_attr_class, nullptr);
if (!attrs_fetched) if (!attrs_fetched) {
fetch_attributes(); fetch_attributes();
}
if (!attributes) if (!attributes) {
return nullptr; return nullptr;
}
return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr()); return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr());
} }

View File

@ -122,9 +122,10 @@ void unhandled_exception(MonoException *p_exc) {
GD_UNREACHABLE(); GD_UNREACHABLE();
} else { } else {
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
GDMonoUtils::debug_send_unhandled_exception_error((MonoException *)p_exc); GDMonoUtils::debug_send_unhandled_exception_error(p_exc);
if (EngineDebugger::is_active()) if (EngineDebugger::is_active()) {
EngineDebugger::get_singleton()->poll_events(false); EngineDebugger::get_singleton()->poll_events(false);
}
#endif #endif
} }
} }

View File

@ -55,8 +55,9 @@ static int get_log_level_id(const char *p_log_level) {
int i = 0; int i = 0;
while (valid_log_levels[i]) { while (valid_log_levels[i]) {
if (!strcmp(valid_log_levels[i], p_log_level)) if (!strcmp(valid_log_levels[i], p_log_level)) {
return i; return i;
}
i++; i++;
} }
@ -115,10 +116,12 @@ void GDMonoLog::_delete_old_log_files(const String &p_logs_dir) {
String current; String current;
while ((current = da->get_next()).length()) { while ((current = da->get_next()).length()) {
if (da->current_is_dir()) if (da->current_is_dir()) {
continue; continue;
if (!current.ends_with(".txt")) }
if (!current.ends_with(".txt")) {
continue; continue;
}
uint64_t modified_time = FileAccess::get_modified_time(da->get_current_dir().plus_file(current)); uint64_t modified_time = FileAccess::get_modified_time(da->get_current_dir().plus_file(current));

View File

@ -72,92 +72,119 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_
case MONO_TYPE_VALUETYPE: { case MONO_TYPE_VALUETYPE: {
GDMonoClass *vtclass = p_type.type_class; GDMonoClass *vtclass = p_type.type_class;
if (vtclass == CACHED_CLASS(Vector2)) if (vtclass == CACHED_CLASS(Vector2)) {
return Variant::VECTOR2; return Variant::VECTOR2;
}
if (vtclass == CACHED_CLASS(Vector2i)) if (vtclass == CACHED_CLASS(Vector2i)) {
return Variant::VECTOR2I; return Variant::VECTOR2I;
}
if (vtclass == CACHED_CLASS(Rect2)) if (vtclass == CACHED_CLASS(Rect2)) {
return Variant::RECT2; return Variant::RECT2;
}
if (vtclass == CACHED_CLASS(Rect2i)) if (vtclass == CACHED_CLASS(Rect2i)) {
return Variant::RECT2I; return Variant::RECT2I;
}
if (vtclass == CACHED_CLASS(Transform2D)) if (vtclass == CACHED_CLASS(Transform2D)) {
return Variant::TRANSFORM2D; return Variant::TRANSFORM2D;
}
if (vtclass == CACHED_CLASS(Vector3)) if (vtclass == CACHED_CLASS(Vector3)) {
return Variant::VECTOR3; return Variant::VECTOR3;
}
if (vtclass == CACHED_CLASS(Vector3i)) if (vtclass == CACHED_CLASS(Vector3i)) {
return Variant::VECTOR3I; return Variant::VECTOR3I;
}
if (vtclass == CACHED_CLASS(Basis)) if (vtclass == CACHED_CLASS(Basis)) {
return Variant::BASIS; return Variant::BASIS;
}
if (vtclass == CACHED_CLASS(Quat)) if (vtclass == CACHED_CLASS(Quat)) {
return Variant::QUAT; return Variant::QUAT;
}
if (vtclass == CACHED_CLASS(Transform)) if (vtclass == CACHED_CLASS(Transform)) {
return Variant::TRANSFORM; return Variant::TRANSFORM;
}
if (vtclass == CACHED_CLASS(AABB)) if (vtclass == CACHED_CLASS(AABB)) {
return Variant::AABB; return Variant::AABB;
}
if (vtclass == CACHED_CLASS(Color)) if (vtclass == CACHED_CLASS(Color)) {
return Variant::COLOR; return Variant::COLOR;
}
if (vtclass == CACHED_CLASS(Plane)) if (vtclass == CACHED_CLASS(Plane)) {
return Variant::PLANE; return Variant::PLANE;
}
if (vtclass == CACHED_CLASS(Callable)) if (vtclass == CACHED_CLASS(Callable)) {
return Variant::CALLABLE; return Variant::CALLABLE;
}
if (vtclass == CACHED_CLASS(SignalInfo)) if (vtclass == CACHED_CLASS(SignalInfo)) {
return Variant::SIGNAL; return Variant::SIGNAL;
}
if (mono_class_is_enum(vtclass->get_mono_ptr())) if (mono_class_is_enum(vtclass->get_mono_ptr())) {
return Variant::INT; return Variant::INT;
}
} break; } break;
case MONO_TYPE_ARRAY: case MONO_TYPE_ARRAY:
case MONO_TYPE_SZARRAY: { case MONO_TYPE_SZARRAY: {
MonoArrayType *array_type = mono_type_get_array_type(p_type.type_class->get_mono_type()); MonoArrayType *array_type = mono_type_get_array_type(p_type.type_class->get_mono_type());
if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) {
return Variant::ARRAY; return Variant::ARRAY;
}
if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) {
return Variant::PACKED_BYTE_ARRAY; return Variant::PACKED_BYTE_ARRAY;
}
if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) {
return Variant::PACKED_INT32_ARRAY; return Variant::PACKED_INT32_ARRAY;
}
if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) {
return Variant::PACKED_INT64_ARRAY; return Variant::PACKED_INT64_ARRAY;
}
if (array_type->eklass == CACHED_CLASS_RAW(float)) if (array_type->eklass == CACHED_CLASS_RAW(float)) {
return Variant::PACKED_FLOAT32_ARRAY; return Variant::PACKED_FLOAT32_ARRAY;
}
if (array_type->eklass == CACHED_CLASS_RAW(double)) if (array_type->eklass == CACHED_CLASS_RAW(double)) {
return Variant::PACKED_FLOAT64_ARRAY; return Variant::PACKED_FLOAT64_ARRAY;
}
if (array_type->eklass == CACHED_CLASS_RAW(String)) if (array_type->eklass == CACHED_CLASS_RAW(String)) {
return Variant::PACKED_STRING_ARRAY; return Variant::PACKED_STRING_ARRAY;
}
if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) {
return Variant::PACKED_VECTOR2_ARRAY; return Variant::PACKED_VECTOR2_ARRAY;
}
if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) {
return Variant::PACKED_VECTOR3_ARRAY; return Variant::PACKED_VECTOR3_ARRAY;
}
if (array_type->eklass == CACHED_CLASS_RAW(Color)) if (array_type->eklass == CACHED_CLASS_RAW(Color)) {
return Variant::PACKED_COLOR_ARRAY; return Variant::PACKED_COLOR_ARRAY;
}
GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass); GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) {
return Variant::ARRAY; return Variant::ARRAY;
}
} break; } break;
case MONO_TYPE_CLASS: { case MONO_TYPE_CLASS: {
@ -201,8 +228,9 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_
} break; } break;
case MONO_TYPE_OBJECT: { case MONO_TYPE_OBJECT: {
if (r_nil_is_variant) if (r_nil_is_variant) {
*r_nil_is_variant = true; *r_nil_is_variant = true;
}
return Variant::NIL; return Variant::NIL;
} break; } break;
@ -244,8 +272,9 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_
} break; } break;
} }
if (r_nil_is_variant) if (r_nil_is_variant) {
*r_nil_is_variant = false; *r_nil_is_variant = false;
}
// Unknown // Unknown
return Variant::NIL; return Variant::NIL;
@ -282,31 +311,6 @@ bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_
return false; return false;
} }
bool try_get_dictionary_key_value_types(const ManagedType &p_dictionary_type, ManagedType &r_key_type, ManagedType &r_value_type) {
switch (p_dictionary_type.type_encoding) {
case MONO_TYPE_GENERICINST: {
MonoReflectionType *dict_reftype = mono_type_get_object(mono_domain_get(), p_dictionary_type.type_class->get_mono_type());
if (GDMonoUtils::Marshal::type_is_generic_dictionary(dict_reftype) ||
GDMonoUtils::Marshal::type_is_system_generic_dictionary(dict_reftype) ||
GDMonoUtils::Marshal::type_is_generic_idictionary(dict_reftype)) {
MonoReflectionType *key_reftype;
MonoReflectionType *value_reftype;
GDMonoUtils::Marshal::dictionary_get_key_value_types(dict_reftype, &key_reftype, &value_reftype);
r_key_type = ManagedType::from_reftype(key_reftype);
r_value_type = ManagedType::from_reftype(value_reftype);
return true;
}
} break;
default: {
} break;
}
return false;
}
String mono_to_utf8_string(MonoString *p_mono_string) { String mono_to_utf8_string(MonoString *p_mono_string) {
MonoError error; MonoError error;
char *utf8 = mono_string_to_utf8_checked(p_mono_string, &error); char *utf8 = mono_string_to_utf8_checked(p_mono_string, &error);
@ -328,8 +332,9 @@ String mono_to_utf16_string(MonoString *p_mono_string) {
int len = mono_string_length(p_mono_string); int len = mono_string_length(p_mono_string);
String ret; String ret;
if (len == 0) if (len == 0) {
return ret; return ret;
}
ret.resize(len + 1); ret.resize(len + 1);
ret.set(len, 0); ret.set(len, 0);
@ -409,8 +414,9 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
} }
case MONO_TYPE_STRING: { case MONO_TYPE_STRING: {
if (p_var->get_type() == Variant::NIL) if (p_var->get_type() == Variant::NIL) {
return nullptr; // Otherwise, Variant -> String would return the string "Null" return nullptr; // Otherwise, Variant -> String would return the string "Null"
}
return (MonoObject *)mono_string_from_godot(p_var->operator String()); return (MonoObject *)mono_string_from_godot(p_var->operator String());
} break; } break;
@ -547,39 +553,50 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
case MONO_TYPE_SZARRAY: { case MONO_TYPE_SZARRAY: {
MonoArrayType *array_type = mono_type_get_array_type(p_type.type_class->get_mono_type()); MonoArrayType *array_type = mono_type_get_array_type(p_type.type_class->get_mono_type());
if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) {
return (MonoObject *)Array_to_mono_array(p_var->operator Array()); return (MonoObject *)Array_to_mono_array(p_var->operator Array());
}
if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) {
return (MonoObject *)PackedByteArray_to_mono_array(p_var->operator PackedByteArray()); return (MonoObject *)PackedByteArray_to_mono_array(p_var->operator PackedByteArray());
}
if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) {
return (MonoObject *)PackedInt32Array_to_mono_array(p_var->operator PackedInt32Array()); return (MonoObject *)PackedInt32Array_to_mono_array(p_var->operator PackedInt32Array());
}
if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) {
return (MonoObject *)PackedInt64Array_to_mono_array(p_var->operator PackedInt64Array()); return (MonoObject *)PackedInt64Array_to_mono_array(p_var->operator PackedInt64Array());
}
if (array_type->eklass == CACHED_CLASS_RAW(float)) if (array_type->eklass == CACHED_CLASS_RAW(float)) {
return (MonoObject *)PackedFloat32Array_to_mono_array(p_var->operator PackedFloat32Array()); return (MonoObject *)PackedFloat32Array_to_mono_array(p_var->operator PackedFloat32Array());
}
if (array_type->eklass == CACHED_CLASS_RAW(double)) if (array_type->eklass == CACHED_CLASS_RAW(double)) {
return (MonoObject *)PackedFloat64Array_to_mono_array(p_var->operator PackedFloat64Array()); return (MonoObject *)PackedFloat64Array_to_mono_array(p_var->operator PackedFloat64Array());
}
if (array_type->eklass == CACHED_CLASS_RAW(String)) if (array_type->eklass == CACHED_CLASS_RAW(String)) {
return (MonoObject *)PackedStringArray_to_mono_array(p_var->operator PackedStringArray()); return (MonoObject *)PackedStringArray_to_mono_array(p_var->operator PackedStringArray());
}
if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) {
return (MonoObject *)PackedVector2Array_to_mono_array(p_var->operator PackedVector2Array()); return (MonoObject *)PackedVector2Array_to_mono_array(p_var->operator PackedVector2Array());
}
if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) {
return (MonoObject *)PackedVector3Array_to_mono_array(p_var->operator PackedVector3Array()); return (MonoObject *)PackedVector3Array_to_mono_array(p_var->operator PackedVector3Array());
}
if (array_type->eklass == CACHED_CLASS_RAW(Color)) if (array_type->eklass == CACHED_CLASS_RAW(Color)) {
return (MonoObject *)PackedColorArray_to_mono_array(p_var->operator PackedColorArray()); return (MonoObject *)PackedColorArray_to_mono_array(p_var->operator PackedColorArray());
}
GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass); GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) {
return (MonoObject *)Array_to_mono_array(p_var->operator Array(), array_type_class); return (MonoObject *)Array_to_mono_array(p_var->operator Array(), array_type_class);
}
ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to a managed array of unmarshallable element type."); ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to a managed array of unmarshallable element type.");
} break; } break;
@ -820,100 +837,128 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
return unbox<double>(p_obj); return unbox<double>(p_obj);
case MONO_TYPE_STRING: { case MONO_TYPE_STRING: {
if (p_obj == nullptr) if (p_obj == nullptr) {
return Variant(); // NIL return Variant(); // NIL
}
return mono_string_to_godot_not_null((MonoString *)p_obj); return mono_string_to_godot_not_null((MonoString *)p_obj);
} break; } break;
case MONO_TYPE_VALUETYPE: { case MONO_TYPE_VALUETYPE: {
GDMonoClass *vtclass = p_type.type_class; GDMonoClass *vtclass = p_type.type_class;
if (vtclass == CACHED_CLASS(Vector2)) if (vtclass == CACHED_CLASS(Vector2)) {
return MARSHALLED_IN(Vector2, unbox_addr<GDMonoMarshal::M_Vector2>(p_obj)); return MARSHALLED_IN(Vector2, unbox_addr<GDMonoMarshal::M_Vector2>(p_obj));
}
if (vtclass == CACHED_CLASS(Vector2i)) if (vtclass == CACHED_CLASS(Vector2i)) {
return MARSHALLED_IN(Vector2i, unbox_addr<GDMonoMarshal::M_Vector2i>(p_obj)); return MARSHALLED_IN(Vector2i, unbox_addr<GDMonoMarshal::M_Vector2i>(p_obj));
}
if (vtclass == CACHED_CLASS(Rect2)) if (vtclass == CACHED_CLASS(Rect2)) {
return MARSHALLED_IN(Rect2, unbox_addr<GDMonoMarshal::M_Rect2>(p_obj)); return MARSHALLED_IN(Rect2, unbox_addr<GDMonoMarshal::M_Rect2>(p_obj));
}
if (vtclass == CACHED_CLASS(Rect2i)) if (vtclass == CACHED_CLASS(Rect2i)) {
return MARSHALLED_IN(Rect2i, unbox_addr<GDMonoMarshal::M_Rect2i>(p_obj)); return MARSHALLED_IN(Rect2i, unbox_addr<GDMonoMarshal::M_Rect2i>(p_obj));
}
if (vtclass == CACHED_CLASS(Transform2D)) if (vtclass == CACHED_CLASS(Transform2D)) {
return MARSHALLED_IN(Transform2D, unbox_addr<GDMonoMarshal::M_Transform2D>(p_obj)); return MARSHALLED_IN(Transform2D, unbox_addr<GDMonoMarshal::M_Transform2D>(p_obj));
}
if (vtclass == CACHED_CLASS(Vector3)) if (vtclass == CACHED_CLASS(Vector3)) {
return MARSHALLED_IN(Vector3, unbox_addr<GDMonoMarshal::M_Vector3>(p_obj)); return MARSHALLED_IN(Vector3, unbox_addr<GDMonoMarshal::M_Vector3>(p_obj));
}
if (vtclass == CACHED_CLASS(Vector3i)) if (vtclass == CACHED_CLASS(Vector3i)) {
return MARSHALLED_IN(Vector3i, unbox_addr<GDMonoMarshal::M_Vector3i>(p_obj)); return MARSHALLED_IN(Vector3i, unbox_addr<GDMonoMarshal::M_Vector3i>(p_obj));
}
if (vtclass == CACHED_CLASS(Basis)) if (vtclass == CACHED_CLASS(Basis)) {
return MARSHALLED_IN(Basis, unbox_addr<GDMonoMarshal::M_Basis>(p_obj)); return MARSHALLED_IN(Basis, unbox_addr<GDMonoMarshal::M_Basis>(p_obj));
}
if (vtclass == CACHED_CLASS(Quat)) if (vtclass == CACHED_CLASS(Quat)) {
return MARSHALLED_IN(Quat, unbox_addr<GDMonoMarshal::M_Quat>(p_obj)); return MARSHALLED_IN(Quat, unbox_addr<GDMonoMarshal::M_Quat>(p_obj));
}
if (vtclass == CACHED_CLASS(Transform)) if (vtclass == CACHED_CLASS(Transform)) {
return MARSHALLED_IN(Transform, unbox_addr<GDMonoMarshal::M_Transform>(p_obj)); return MARSHALLED_IN(Transform, unbox_addr<GDMonoMarshal::M_Transform>(p_obj));
}
if (vtclass == CACHED_CLASS(AABB)) if (vtclass == CACHED_CLASS(AABB)) {
return MARSHALLED_IN(AABB, unbox_addr<GDMonoMarshal::M_AABB>(p_obj)); return MARSHALLED_IN(AABB, unbox_addr<GDMonoMarshal::M_AABB>(p_obj));
}
if (vtclass == CACHED_CLASS(Color)) if (vtclass == CACHED_CLASS(Color)) {
return MARSHALLED_IN(Color, unbox_addr<GDMonoMarshal::M_Color>(p_obj)); return MARSHALLED_IN(Color, unbox_addr<GDMonoMarshal::M_Color>(p_obj));
}
if (vtclass == CACHED_CLASS(Plane)) if (vtclass == CACHED_CLASS(Plane)) {
return MARSHALLED_IN(Plane, unbox_addr<GDMonoMarshal::M_Plane>(p_obj)); return MARSHALLED_IN(Plane, unbox_addr<GDMonoMarshal::M_Plane>(p_obj));
}
if (vtclass == CACHED_CLASS(Callable)) if (vtclass == CACHED_CLASS(Callable)) {
return managed_to_callable(unbox<GDMonoMarshal::M_Callable>(p_obj)); return managed_to_callable(unbox<GDMonoMarshal::M_Callable>(p_obj));
}
if (vtclass == CACHED_CLASS(SignalInfo)) if (vtclass == CACHED_CLASS(SignalInfo)) {
return managed_to_signal_info(unbox<GDMonoMarshal::M_SignalInfo>(p_obj)); return managed_to_signal_info(unbox<GDMonoMarshal::M_SignalInfo>(p_obj));
}
if (mono_class_is_enum(vtclass->get_mono_ptr())) if (mono_class_is_enum(vtclass->get_mono_ptr())) {
return unbox<int32_t>(p_obj); return unbox<int32_t>(p_obj);
}
} break; } break;
case MONO_TYPE_ARRAY: case MONO_TYPE_ARRAY:
case MONO_TYPE_SZARRAY: { case MONO_TYPE_SZARRAY: {
MonoArrayType *array_type = mono_type_get_array_type(p_type.type_class->get_mono_type()); MonoArrayType *array_type = mono_type_get_array_type(p_type.type_class->get_mono_type());
if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) {
return mono_array_to_Array((MonoArray *)p_obj); return mono_array_to_Array((MonoArray *)p_obj);
}
if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) {
return mono_array_to_PackedByteArray((MonoArray *)p_obj); return mono_array_to_PackedByteArray((MonoArray *)p_obj);
}
if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) {
return mono_array_to_PackedInt32Array((MonoArray *)p_obj); return mono_array_to_PackedInt32Array((MonoArray *)p_obj);
}
if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) {
return mono_array_to_PackedInt64Array((MonoArray *)p_obj); return mono_array_to_PackedInt64Array((MonoArray *)p_obj);
}
if (array_type->eklass == CACHED_CLASS_RAW(float)) if (array_type->eklass == CACHED_CLASS_RAW(float)) {
return mono_array_to_PackedFloat32Array((MonoArray *)p_obj); return mono_array_to_PackedFloat32Array((MonoArray *)p_obj);
}
if (array_type->eklass == CACHED_CLASS_RAW(double)) if (array_type->eklass == CACHED_CLASS_RAW(double)) {
return mono_array_to_PackedFloat64Array((MonoArray *)p_obj); return mono_array_to_PackedFloat64Array((MonoArray *)p_obj);
}
if (array_type->eklass == CACHED_CLASS_RAW(String)) if (array_type->eklass == CACHED_CLASS_RAW(String)) {
return mono_array_to_PackedStringArray((MonoArray *)p_obj); return mono_array_to_PackedStringArray((MonoArray *)p_obj);
}
if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) {
return mono_array_to_PackedVector2Array((MonoArray *)p_obj); return mono_array_to_PackedVector2Array((MonoArray *)p_obj);
}
if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) {
return mono_array_to_PackedVector3Array((MonoArray *)p_obj); return mono_array_to_PackedVector3Array((MonoArray *)p_obj);
}
if (array_type->eklass == CACHED_CLASS_RAW(Color)) if (array_type->eklass == CACHED_CLASS_RAW(Color)) {
return mono_array_to_PackedColorArray((MonoArray *)p_obj); return mono_array_to_PackedColorArray((MonoArray *)p_obj);
}
GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass); GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) {
return mono_array_to_Array((MonoArray *)p_obj); return mono_array_to_Array((MonoArray *)p_obj);
}
if (p_fail_with_err) { if (p_fail_with_err) {
ERR_FAIL_V_MSG(Variant(), "Attempted to convert a managed array of unmarshallable element type to Variant."); ERR_FAIL_V_MSG(Variant(), "Attempted to convert a managed array of unmarshallable element type to Variant.");
@ -1012,8 +1057,9 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
} }
Variant mono_object_to_variant(MonoObject *p_obj) { Variant mono_object_to_variant(MonoObject *p_obj) {
if (!p_obj) if (!p_obj) {
return Variant(); return Variant();
}
ManagedType type = ManagedType::from_class(mono_object_get_class(p_obj)); ManagedType type = ManagedType::from_class(mono_object_get_class(p_obj));
@ -1021,15 +1067,17 @@ Variant mono_object_to_variant(MonoObject *p_obj) {
} }
Variant mono_object_to_variant(MonoObject *p_obj, const ManagedType &p_type) { Variant mono_object_to_variant(MonoObject *p_obj, const ManagedType &p_type) {
if (!p_obj) if (!p_obj) {
return Variant(); return Variant();
}
return mono_object_to_variant_impl(p_obj, p_type); return mono_object_to_variant_impl(p_obj, p_type);
} }
Variant mono_object_to_variant_no_err(MonoObject *p_obj, const ManagedType &p_type) { Variant mono_object_to_variant_no_err(MonoObject *p_obj, const ManagedType &p_type) {
if (!p_obj) if (!p_obj) {
return Variant(); return Variant();
}
return mono_object_to_variant_impl(p_obj, p_type, /* fail_with_err: */ false); return mono_object_to_variant_impl(p_obj, p_type, /* fail_with_err: */ false);
} }
@ -1048,8 +1096,9 @@ String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc) {
MonoString *mono_str = GDMonoUtils::object_to_string(p_obj, &exc); MonoString *mono_str = GDMonoUtils::object_to_string(p_obj, &exc);
if (exc) { if (exc) {
if (r_exc) if (r_exc) {
*r_exc = exc; *r_exc = exc;
}
return String(); return String();
} }
@ -1159,8 +1208,9 @@ MonoArray *Array_to_mono_array(const Array &p_array, GDMonoClass *p_array_type_c
Array mono_array_to_Array(MonoArray *p_array) { Array mono_array_to_Array(MonoArray *p_array) {
Array ret; Array ret;
if (!p_array) if (!p_array) {
return ret; return ret;
}
int length = mono_array_length(p_array); int length = mono_array_length(p_array);
ret.resize(length); ret.resize(length);
@ -1178,7 +1228,7 @@ MonoArray *PackedInt32Array_to_mono_array(const PackedInt32Array &p_array) {
MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(int32_t), length); MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(int32_t), length);
int32_t *dst = (int32_t *)mono_array_addr(ret, int32_t, 0); int32_t *dst = mono_array_addr(ret, int32_t, 0);
memcpy(dst, src, length); memcpy(dst, src, length);
return ret; return ret;
@ -1186,13 +1236,14 @@ MonoArray *PackedInt32Array_to_mono_array(const PackedInt32Array &p_array) {
PackedInt32Array mono_array_to_PackedInt32Array(MonoArray *p_array) { PackedInt32Array mono_array_to_PackedInt32Array(MonoArray *p_array) {
PackedInt32Array ret; PackedInt32Array ret;
if (!p_array) if (!p_array) {
return ret; return ret;
}
int length = mono_array_length(p_array); int length = mono_array_length(p_array);
ret.resize(length); ret.resize(length);
int32_t *dst = ret.ptrw(); int32_t *dst = ret.ptrw();
const int32_t *src = (const int32_t *)mono_array_addr(p_array, int32_t, 0); const int32_t *src = mono_array_addr(p_array, int32_t, 0);
memcpy(dst, src, length); memcpy(dst, src, length);
return ret; return ret;
@ -1204,7 +1255,7 @@ MonoArray *PackedInt64Array_to_mono_array(const PackedInt64Array &p_array) {
MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(int64_t), length); MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(int64_t), length);
int64_t *dst = (int64_t *)mono_array_addr(ret, int64_t, 0); int64_t *dst = mono_array_addr(ret, int64_t, 0);
memcpy(dst, src, length); memcpy(dst, src, length);
return ret; return ret;
@ -1212,13 +1263,14 @@ MonoArray *PackedInt64Array_to_mono_array(const PackedInt64Array &p_array) {
PackedInt64Array mono_array_to_PackedInt64Array(MonoArray *p_array) { PackedInt64Array mono_array_to_PackedInt64Array(MonoArray *p_array) {
PackedInt64Array ret; PackedInt64Array ret;
if (!p_array) if (!p_array) {
return ret; return ret;
}
int length = mono_array_length(p_array); int length = mono_array_length(p_array);
ret.resize(length); ret.resize(length);
int64_t *dst = ret.ptrw(); int64_t *dst = ret.ptrw();
const int64_t *src = (const int64_t *)mono_array_addr(p_array, int64_t, 0); const int64_t *src = mono_array_addr(p_array, int64_t, 0);
memcpy(dst, src, length); memcpy(dst, src, length);
return ret; return ret;
@ -1230,7 +1282,7 @@ MonoArray *PackedByteArray_to_mono_array(const PackedByteArray &p_array) {
MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(uint8_t), length); MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(uint8_t), length);
uint8_t *dst = (uint8_t *)mono_array_addr(ret, uint8_t, 0); uint8_t *dst = mono_array_addr(ret, uint8_t, 0);
memcpy(dst, src, length); memcpy(dst, src, length);
return ret; return ret;
@ -1238,13 +1290,14 @@ MonoArray *PackedByteArray_to_mono_array(const PackedByteArray &p_array) {
PackedByteArray mono_array_to_PackedByteArray(MonoArray *p_array) { PackedByteArray mono_array_to_PackedByteArray(MonoArray *p_array) {
PackedByteArray ret; PackedByteArray ret;
if (!p_array) if (!p_array) {
return ret; return ret;
}
int length = mono_array_length(p_array); int length = mono_array_length(p_array);
ret.resize(length); ret.resize(length);
uint8_t *dst = ret.ptrw(); uint8_t *dst = ret.ptrw();
const uint8_t *src = (const uint8_t *)mono_array_addr(p_array, uint8_t, 0); const uint8_t *src = mono_array_addr(p_array, uint8_t, 0);
memcpy(dst, src, length); memcpy(dst, src, length);
return ret; return ret;
@ -1256,7 +1309,7 @@ MonoArray *PackedFloat32Array_to_mono_array(const PackedFloat32Array &p_array) {
MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(float), length); MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(float), length);
float *dst = (float *)mono_array_addr(ret, float, 0); float *dst = mono_array_addr(ret, float, 0);
memcpy(dst, src, length); memcpy(dst, src, length);
return ret; return ret;
@ -1264,13 +1317,14 @@ MonoArray *PackedFloat32Array_to_mono_array(const PackedFloat32Array &p_array) {
PackedFloat32Array mono_array_to_PackedFloat32Array(MonoArray *p_array) { PackedFloat32Array mono_array_to_PackedFloat32Array(MonoArray *p_array) {
PackedFloat32Array ret; PackedFloat32Array ret;
if (!p_array) if (!p_array) {
return ret; return ret;
}
int length = mono_array_length(p_array); int length = mono_array_length(p_array);
ret.resize(length); ret.resize(length);
float *dst = ret.ptrw(); float *dst = ret.ptrw();
const float *src = (const float *)mono_array_addr(p_array, float, 0); const float *src = mono_array_addr(p_array, float, 0);
memcpy(dst, src, length); memcpy(dst, src, length);
return ret; return ret;
@ -1282,7 +1336,7 @@ MonoArray *PackedFloat64Array_to_mono_array(const PackedFloat64Array &p_array) {
MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(double), length); MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(double), length);
double *dst = (double *)mono_array_addr(ret, double, 0); double *dst = mono_array_addr(ret, double, 0);
memcpy(dst, src, length); memcpy(dst, src, length);
return ret; return ret;
@ -1290,13 +1344,14 @@ MonoArray *PackedFloat64Array_to_mono_array(const PackedFloat64Array &p_array) {
PackedFloat64Array mono_array_to_PackedFloat64Array(MonoArray *p_array) { PackedFloat64Array mono_array_to_PackedFloat64Array(MonoArray *p_array) {
PackedFloat64Array ret; PackedFloat64Array ret;
if (!p_array) if (!p_array) {
return ret; return ret;
}
int length = mono_array_length(p_array); int length = mono_array_length(p_array);
ret.resize(length); ret.resize(length);
double *dst = ret.ptrw(); double *dst = ret.ptrw();
const double *src = (const double *)mono_array_addr(p_array, double, 0); const double *src = mono_array_addr(p_array, double, 0);
memcpy(dst, src, length); memcpy(dst, src, length);
return ret; return ret;
@ -1318,8 +1373,9 @@ MonoArray *PackedStringArray_to_mono_array(const PackedStringArray &p_array) {
PackedStringArray mono_array_to_PackedStringArray(MonoArray *p_array) { PackedStringArray mono_array_to_PackedStringArray(MonoArray *p_array) {
PackedStringArray ret; PackedStringArray ret;
if (!p_array) if (!p_array) {
return ret; return ret;
}
int length = mono_array_length(p_array); int length = mono_array_length(p_array);
ret.resize(length); ret.resize(length);
String *w = ret.ptrw(); String *w = ret.ptrw();
@ -1339,7 +1395,7 @@ MonoArray *PackedColorArray_to_mono_array(const PackedColorArray &p_array) {
MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Color), length); MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Color), length);
if constexpr (InteropLayout::MATCHES_Color) { if constexpr (InteropLayout::MATCHES_Color) {
Color *dst = (Color *)mono_array_addr(ret, Color, 0); Color *dst = mono_array_addr(ret, Color, 0);
memcpy(dst, src, length); memcpy(dst, src, length);
} else { } else {
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
@ -1353,14 +1409,15 @@ MonoArray *PackedColorArray_to_mono_array(const PackedColorArray &p_array) {
PackedColorArray mono_array_to_PackedColorArray(MonoArray *p_array) { PackedColorArray mono_array_to_PackedColorArray(MonoArray *p_array) {
PackedColorArray ret; PackedColorArray ret;
if (!p_array) if (!p_array) {
return ret; return ret;
}
int length = mono_array_length(p_array); int length = mono_array_length(p_array);
ret.resize(length); ret.resize(length);
Color *dst = ret.ptrw(); Color *dst = ret.ptrw();
if constexpr (InteropLayout::MATCHES_Color) { if constexpr (InteropLayout::MATCHES_Color) {
const Color *src = (const Color *)mono_array_addr(p_array, Color, 0); const Color *src = mono_array_addr(p_array, Color, 0);
memcpy(dst, src, length); memcpy(dst, src, length);
} else { } else {
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
@ -1378,7 +1435,7 @@ MonoArray *PackedVector2Array_to_mono_array(const PackedVector2Array &p_array) {
MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Vector2), length); MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Vector2), length);
if constexpr (InteropLayout::MATCHES_Vector2) { if constexpr (InteropLayout::MATCHES_Vector2) {
Vector2 *dst = (Vector2 *)mono_array_addr(ret, Vector2, 0); Vector2 *dst = mono_array_addr(ret, Vector2, 0);
memcpy(dst, src, length); memcpy(dst, src, length);
} else { } else {
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
@ -1392,14 +1449,15 @@ MonoArray *PackedVector2Array_to_mono_array(const PackedVector2Array &p_array) {
PackedVector2Array mono_array_to_PackedVector2Array(MonoArray *p_array) { PackedVector2Array mono_array_to_PackedVector2Array(MonoArray *p_array) {
PackedVector2Array ret; PackedVector2Array ret;
if (!p_array) if (!p_array) {
return ret; return ret;
}
int length = mono_array_length(p_array); int length = mono_array_length(p_array);
ret.resize(length); ret.resize(length);
Vector2 *dst = ret.ptrw(); Vector2 *dst = ret.ptrw();
if constexpr (InteropLayout::MATCHES_Vector2) { if constexpr (InteropLayout::MATCHES_Vector2) {
const Vector2 *src = (const Vector2 *)mono_array_addr(p_array, Vector2, 0); const Vector2 *src = mono_array_addr(p_array, Vector2, 0);
memcpy(dst, src, length); memcpy(dst, src, length);
} else { } else {
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
@ -1417,7 +1475,7 @@ MonoArray *PackedVector3Array_to_mono_array(const PackedVector3Array &p_array) {
MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Vector3), length); MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Vector3), length);
if constexpr (InteropLayout::MATCHES_Vector3) { if constexpr (InteropLayout::MATCHES_Vector3) {
Vector3 *dst = (Vector3 *)mono_array_addr(ret, Vector3, 0); Vector3 *dst = mono_array_addr(ret, Vector3, 0);
memcpy(dst, src, length); memcpy(dst, src, length);
} else { } else {
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
@ -1431,14 +1489,15 @@ MonoArray *PackedVector3Array_to_mono_array(const PackedVector3Array &p_array) {
PackedVector3Array mono_array_to_PackedVector3Array(MonoArray *p_array) { PackedVector3Array mono_array_to_PackedVector3Array(MonoArray *p_array) {
PackedVector3Array ret; PackedVector3Array ret;
if (!p_array) if (!p_array) {
return ret; return ret;
}
int length = mono_array_length(p_array); int length = mono_array_length(p_array);
ret.resize(length); ret.resize(length);
Vector3 *dst = ret.ptrw(); Vector3 *dst = ret.ptrw();
if constexpr (InteropLayout::MATCHES_Vector3) { if constexpr (InteropLayout::MATCHES_Vector3) {
const Vector3 *src = (const Vector3 *)mono_array_addr(p_array, Vector3, 0); const Vector3 *src = mono_array_addr(p_array, Vector3, 0);
memcpy(dst, src, length); memcpy(dst, src, length);
} else { } else {
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {

View File

@ -66,7 +66,6 @@ T *unbox_addr(MonoObject *p_obj) {
Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_variant = nullptr); Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_variant = nullptr);
bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_elem_type); bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_elem_type);
bool try_get_dictionary_key_value_types(const ManagedType &p_dictionary_type, ManagedType &r_key_type, ManagedType &r_value_type);
// String // String
@ -74,15 +73,17 @@ String mono_to_utf8_string(MonoString *p_mono_string);
String mono_to_utf16_string(MonoString *p_mono_string); String mono_to_utf16_string(MonoString *p_mono_string);
_FORCE_INLINE_ String mono_string_to_godot_not_null(MonoString *p_mono_string) { _FORCE_INLINE_ String mono_string_to_godot_not_null(MonoString *p_mono_string) {
if (sizeof(CharType) == 2) if constexpr (sizeof(CharType) == 2) {
return mono_to_utf16_string(p_mono_string); return mono_to_utf16_string(p_mono_string);
}
return mono_to_utf8_string(p_mono_string); return mono_to_utf8_string(p_mono_string);
} }
_FORCE_INLINE_ String mono_string_to_godot(MonoString *p_mono_string) { _FORCE_INLINE_ String mono_string_to_godot(MonoString *p_mono_string) {
if (p_mono_string == nullptr) if (p_mono_string == nullptr) {
return String(); return String();
}
return mono_string_to_godot_not_null(p_mono_string); return mono_string_to_godot_not_null(p_mono_string);
} }
@ -96,8 +97,9 @@ _FORCE_INLINE_ MonoString *mono_from_utf16_string(const String &p_string) {
} }
_FORCE_INLINE_ MonoString *mono_string_from_godot(const String &p_string) { _FORCE_INLINE_ MonoString *mono_string_from_godot(const String &p_string) {
if (sizeof(CharType) == 2) if constexpr (sizeof(CharType) == 2) {
return mono_from_utf16_string(p_string); return mono_from_utf16_string(p_string);
}
return mono_from_utf8_string(p_string); return mono_from_utf8_string(p_string);
} }

View File

@ -155,11 +155,13 @@ MonoObject *GDMonoMethod::invoke_raw(MonoObject *p_object, void **p_params, Mono
bool GDMonoMethod::has_attribute(GDMonoClass *p_attr_class) { bool GDMonoMethod::has_attribute(GDMonoClass *p_attr_class) {
ERR_FAIL_NULL_V(p_attr_class, false); ERR_FAIL_NULL_V(p_attr_class, false);
if (!attrs_fetched) if (!attrs_fetched) {
fetch_attributes(); fetch_attributes();
}
if (!attributes) if (!attributes) {
return false; return false;
}
return mono_custom_attrs_has_attr(attributes, p_attr_class->get_mono_ptr()); return mono_custom_attrs_has_attr(attributes, p_attr_class->get_mono_ptr());
} }
@ -167,11 +169,13 @@ bool GDMonoMethod::has_attribute(GDMonoClass *p_attr_class) {
MonoObject *GDMonoMethod::get_attribute(GDMonoClass *p_attr_class) { MonoObject *GDMonoMethod::get_attribute(GDMonoClass *p_attr_class) {
ERR_FAIL_NULL_V(p_attr_class, nullptr); ERR_FAIL_NULL_V(p_attr_class, nullptr);
if (!attrs_fetched) if (!attrs_fetched) {
fetch_attributes(); fetch_attributes();
}
if (!attributes) if (!attributes) {
return nullptr; return nullptr;
}
return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr()); return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr());
} }
@ -250,8 +254,9 @@ const MethodInfo &GDMonoMethod::get_method_info() {
bool nil_is_variant = false; bool nil_is_variant = false;
method_info.return_val = PropertyInfo(GDMonoMarshal::managed_to_variant_type(return_type, &nil_is_variant), ""); method_info.return_val = PropertyInfo(GDMonoMarshal::managed_to_variant_type(return_type, &nil_is_variant), "");
if (method_info.return_val.type == Variant::NIL && nil_is_variant) if (method_info.return_val.type == Variant::NIL && nil_is_variant) {
method_info.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; method_info.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
}
Vector<StringName> names; Vector<StringName> names;
get_parameter_names(names); get_parameter_names(names);
@ -259,8 +264,9 @@ const MethodInfo &GDMonoMethod::get_method_info() {
for (int i = 0; i < params_count; ++i) { for (int i = 0; i < params_count; ++i) {
nil_is_variant = false; nil_is_variant = false;
PropertyInfo arg_info = PropertyInfo(GDMonoMarshal::managed_to_variant_type(param_types[i], &nil_is_variant), names[i]); PropertyInfo arg_info = PropertyInfo(GDMonoMarshal::managed_to_variant_type(param_types[i], &nil_is_variant), names[i]);
if (arg_info.type == Variant::NIL && nil_is_variant) if (arg_info.type == Variant::NIL && nil_is_variant) {
arg_info.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; arg_info.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
}
method_info.arguments.push_back(arg_info); method_info.arguments.push_back(arg_info);
} }

View File

@ -77,15 +77,17 @@ GDMonoProperty::~GDMonoProperty() {
bool GDMonoProperty::is_static() { bool GDMonoProperty::is_static() {
MonoMethod *prop_method = mono_property_get_get_method(mono_property); MonoMethod *prop_method = mono_property_get_get_method(mono_property);
if (prop_method == nullptr) if (prop_method == nullptr) {
prop_method = mono_property_get_set_method(mono_property); prop_method = mono_property_get_set_method(mono_property);
}
return mono_method_get_flags(prop_method, nullptr) & MONO_METHOD_ATTR_STATIC; return mono_method_get_flags(prop_method, nullptr) & MONO_METHOD_ATTR_STATIC;
} }
IMonoClassMember::Visibility GDMonoProperty::get_visibility() { IMonoClassMember::Visibility GDMonoProperty::get_visibility() {
MonoMethod *prop_method = mono_property_get_get_method(mono_property); MonoMethod *prop_method = mono_property_get_get_method(mono_property);
if (prop_method == nullptr) if (prop_method == nullptr) {
prop_method = mono_property_get_set_method(mono_property); prop_method = mono_property_get_set_method(mono_property);
}
switch (mono_method_get_flags(prop_method, nullptr) & MONO_METHOD_ATTR_ACCESS_MASK) { switch (mono_method_get_flags(prop_method, nullptr) & MONO_METHOD_ATTR_ACCESS_MASK) {
case MONO_METHOD_ATTR_PRIVATE: case MONO_METHOD_ATTR_PRIVATE:
@ -106,11 +108,13 @@ IMonoClassMember::Visibility GDMonoProperty::get_visibility() {
bool GDMonoProperty::has_attribute(GDMonoClass *p_attr_class) { bool GDMonoProperty::has_attribute(GDMonoClass *p_attr_class) {
ERR_FAIL_NULL_V(p_attr_class, false); ERR_FAIL_NULL_V(p_attr_class, false);
if (!attrs_fetched) if (!attrs_fetched) {
fetch_attributes(); fetch_attributes();
}
if (!attributes) if (!attributes) {
return false; return false;
}
return mono_custom_attrs_has_attr(attributes, p_attr_class->get_mono_ptr()); return mono_custom_attrs_has_attr(attributes, p_attr_class->get_mono_ptr());
} }
@ -118,11 +122,13 @@ bool GDMonoProperty::has_attribute(GDMonoClass *p_attr_class) {
MonoObject *GDMonoProperty::get_attribute(GDMonoClass *p_attr_class) { MonoObject *GDMonoProperty::get_attribute(GDMonoClass *p_attr_class) {
ERR_FAIL_NULL_V(p_attr_class, nullptr); ERR_FAIL_NULL_V(p_attr_class, nullptr);
if (!attrs_fetched) if (!attrs_fetched) {
fetch_attributes(); fetch_attributes();
}
if (!attributes) if (!attributes) {
return nullptr; return nullptr;
}
return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr()); return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr());
} }

View File

@ -38,7 +38,6 @@
#include "core/os/dir_access.h" #include "core/os/dir_access.h"
#include "core/os/mutex.h" #include "core/os/mutex.h"
#include "core/os/os.h" #include "core/os/os.h"
#include "core/project_settings.h"
#include "core/reference.h" #include "core/reference.h"
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
@ -51,13 +50,13 @@
#include "gd_mono_cache.h" #include "gd_mono_cache.h"
#include "gd_mono_class.h" #include "gd_mono_class.h"
#include "gd_mono_marshal.h" #include "gd_mono_marshal.h"
#include "gd_mono_method_thunk.h"
namespace GDMonoUtils { namespace GDMonoUtils {
MonoObject *unmanaged_get_managed(Object *unmanaged) { MonoObject *unmanaged_get_managed(Object *unmanaged) {
if (!unmanaged) if (!unmanaged) {
return nullptr; return nullptr;
}
if (unmanaged->get_script_instance()) { if (unmanaged->get_script_instance()) {
CSharpInstance *cs_instance = CAST_CSHARP_INSTANCE(unmanaged->get_script_instance()); CSharpInstance *cs_instance = CAST_CSHARP_INSTANCE(unmanaged->get_script_instance());
@ -90,8 +89,9 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) {
MonoObject *target = gchandle.get_target(); MonoObject *target = gchandle.get_target();
if (target) if (target) {
return target; return target;
}
CSharpLanguage::get_singleton()->release_script_gchandle(gchandle); CSharpLanguage::get_singleton()->release_script_gchandle(gchandle);
@ -196,8 +196,9 @@ GDMonoClass *get_object_class(MonoObject *p_object) {
GDMonoClass *type_get_proxy_class(const StringName &p_type) { GDMonoClass *type_get_proxy_class(const StringName &p_type) {
String class_name = p_type; String class_name = p_type;
if (class_name[0] == '_') if (class_name[0] == '_') {
class_name = class_name.substr(1, class_name.length()); class_name = class_name.substr(1, class_name.length());
}
GDMonoClass *klass = GDMono::get_singleton()->get_core_api_assembly()->get_class(BINDINGS_NAMESPACE, class_name); GDMonoClass *klass = GDMono::get_singleton()->get_core_api_assembly()->get_class(BINDINGS_NAMESPACE, class_name);
@ -220,11 +221,14 @@ GDMonoClass *get_class_native_base(GDMonoClass *p_class) {
do { do {
const GDMonoAssembly *assembly = klass->get_assembly(); const GDMonoAssembly *assembly = klass->get_assembly();
if (assembly == GDMono::get_singleton()->get_core_api_assembly())
if (assembly == GDMono::get_singleton()->get_core_api_assembly()) {
return klass; return klass;
}
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
if (assembly == GDMono::get_singleton()->get_editor_api_assembly()) if (assembly == GDMono::get_singleton()->get_editor_api_assembly()) {
return klass; return klass;
}
#endif #endif
} while ((klass = klass->get_parent_class()) != nullptr); } while ((klass = klass->get_parent_class()) != nullptr);
@ -385,14 +389,6 @@ String get_exception_name_and_message(MonoException *p_exc) {
return res; return res;
} }
void set_exception_message(MonoException *p_exc, String message) {
MonoClass *klass = mono_object_get_class((MonoObject *)p_exc);
MonoProperty *prop = mono_class_get_property_from_name(klass, "Message");
MonoString *msg = GDMonoMarshal::mono_string_from_godot(message);
void *params[1] = { msg };
property_set_value(prop, (MonoObject *)p_exc, params, nullptr);
}
void debug_print_unhandled_exception(MonoException *p_exc) { void debug_print_unhandled_exception(MonoException *p_exc) {
print_unhandled_exception(p_exc); print_unhandled_exception(p_exc);
debug_send_unhandled_exception_error(p_exc); debug_send_unhandled_exception_error(p_exc);
@ -410,8 +406,9 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) {
} }
static thread_local bool _recursion_flag_ = false; static thread_local bool _recursion_flag_ = false;
if (_recursion_flag_) if (_recursion_flag_) {
return; return;
}
_recursion_flag_ = true; _recursion_flag_ = true;
SCOPE_EXIT { _recursion_flag_ = false; }; SCOPE_EXIT { _recursion_flag_ = false; };
@ -441,8 +438,9 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) {
Vector<ScriptLanguage::StackInfo> _si; Vector<ScriptLanguage::StackInfo> _si;
if (stack_trace != nullptr) { if (stack_trace != nullptr) {
_si = CSharpLanguage::get_singleton()->stack_trace_get_info(stack_trace); _si = CSharpLanguage::get_singleton()->stack_trace_get_info(stack_trace);
for (int i = _si.size() - 1; i >= 0; i--) for (int i = _si.size() - 1; i >= 0; i--) {
si.insert(0, _si[i]); si.insert(0, _si[i]);
}
} }
exc_msg += (exc_msg.length() > 0 ? " ---> " : "") + GDMonoUtils::get_exception_name_and_message(p_exc); exc_msg += (exc_msg.length() > 0 ? " ---> " : "") + GDMonoUtils::get_exception_name_and_message(p_exc);
@ -452,8 +450,9 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) {
CRASH_COND(inner_exc_prop == nullptr); CRASH_COND(inner_exc_prop == nullptr);
MonoObject *inner_exc = inner_exc_prop->get_value((MonoObject *)p_exc); MonoObject *inner_exc = inner_exc_prop->get_value((MonoObject *)p_exc);
if (inner_exc != nullptr) if (inner_exc != nullptr) {
si.insert(0, separator); si.insert(0, separator);
}
p_exc = (MonoException *)inner_exc; p_exc = (MonoException *)inner_exc;
} }

View File

@ -84,10 +84,6 @@ void detach_current_thread(MonoThread *p_mono_thread);
MonoThread *get_current_thread(); MonoThread *get_current_thread();
bool is_thread_attached(); bool is_thread_attached();
_FORCE_INLINE_ bool is_main_thread() {
return mono_domain_get() != nullptr && mono_thread_get_main() == mono_thread_current();
}
uint32_t new_strong_gchandle(MonoObject *p_object); uint32_t new_strong_gchandle(MonoObject *p_object);
uint32_t new_strong_gchandle_pinned(MonoObject *p_object); uint32_t new_strong_gchandle_pinned(MonoObject *p_object);
uint32_t new_weak_gchandle(MonoObject *p_object); uint32_t new_weak_gchandle(MonoObject *p_object);
@ -115,7 +111,6 @@ String get_type_desc(MonoType *p_type);
String get_type_desc(MonoReflectionType *p_reftype); String get_type_desc(MonoReflectionType *p_reftype);
String get_exception_name_and_message(MonoException *p_exc); String get_exception_name_and_message(MonoException *p_exc);
void set_exception_message(MonoException *p_exc, String message);
void debug_print_unhandled_exception(MonoException *p_exc); void debug_print_unhandled_exception(MonoException *p_exc);
void debug_send_unhandled_exception_error(MonoException *p_exc); void debug_send_unhandled_exception_error(MonoException *p_exc);

View File

@ -62,8 +62,9 @@ void register_mono_types() {
void unregister_mono_types() { void unregister_mono_types() {
ScriptServer::unregister_language(script_language_cs); ScriptServer::unregister_language(script_language_cs);
if (script_language_cs) if (script_language_cs) {
memdelete(script_language_cs); memdelete(script_language_cs);
}
ResourceLoader::remove_resource_format_loader(resource_loader_cs); ResourceLoader::remove_resource_format_loader(resource_loader_cs);
resource_loader_cs.unref(); resource_loader_cs.unref();
@ -71,6 +72,7 @@ void unregister_mono_types() {
ResourceSaver::remove_resource_format_saver(resource_saver_cs); ResourceSaver::remove_resource_format_saver(resource_saver_cs);
resource_saver_cs.unref(); resource_saver_cs.unref();
if (_godotsharp) if (_godotsharp) {
memdelete(_godotsharp); memdelete(_godotsharp);
}
} }

View File

@ -51,18 +51,21 @@ bool SignalAwaiterCallable::compare_equal(const CallableCustom *p_a, const Calla
const SignalAwaiterCallable *a = static_cast<const SignalAwaiterCallable *>(p_a); const SignalAwaiterCallable *a = static_cast<const SignalAwaiterCallable *>(p_a);
const SignalAwaiterCallable *b = static_cast<const SignalAwaiterCallable *>(p_b); const SignalAwaiterCallable *b = static_cast<const SignalAwaiterCallable *>(p_b);
if (a->target_id != b->target_id) if (a->target_id != b->target_id) {
return false; return false;
}
if (a->signal != b->signal) if (a->signal != b->signal) {
return false; return false;
}
return true; return true;
} }
bool SignalAwaiterCallable::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) { bool SignalAwaiterCallable::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) {
if (compare_equal(p_a, p_b)) if (compare_equal(p_a, p_b)) {
return false; return false;
}
return p_a < p_b; return p_a < p_b;
} }
@ -145,18 +148,21 @@ bool EventSignalCallable::compare_equal(const CallableCustom *p_a, const Callabl
const EventSignalCallable *a = static_cast<const EventSignalCallable *>(p_a); const EventSignalCallable *a = static_cast<const EventSignalCallable *>(p_a);
const EventSignalCallable *b = static_cast<const EventSignalCallable *>(p_b); const EventSignalCallable *b = static_cast<const EventSignalCallable *>(p_b);
if (a->owner != b->owner) if (a->owner != b->owner) {
return false; return false;
}
if (a->event_signal != b->event_signal) if (a->event_signal != b->event_signal) {
return false; return false;
}
return true; return true;
} }
bool EventSignalCallable::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) { bool EventSignalCallable::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) {
if (compare_equal(p_a, p_b)) if (compare_equal(p_a, p_b)) {
return false; return false;
}
return p_a < p_b; return p_a < p_b;
} }

View File

@ -50,34 +50,6 @@
namespace path { namespace path {
String find_executable(const String &p_name) {
#ifdef WINDOWS_ENABLED
Vector<String> exts = OS::get_singleton()->get_environment("PATHEXT").split(ENV_PATH_SEP, false);
#endif
Vector<String> env_path = OS::get_singleton()->get_environment("PATH").split(ENV_PATH_SEP, false);
if (env_path.empty())
return String();
for (int i = 0; i < env_path.size(); i++) {
String p = path::join(env_path[i], p_name);
#ifdef WINDOWS_ENABLED
for (int j = 0; j < exts.size(); j++) {
String p2 = p + exts[j].to_lower(); // lowercase to reduce risk of case mismatch warning
if (FileAccess::exists(p2))
return p2;
}
#else
if (FileAccess::exists(p))
return p;
#endif
}
return String();
}
String cwd() { String cwd() {
#ifdef WINDOWS_ENABLED #ifdef WINDOWS_ENABLED
const DWORD expected_size = ::GetCurrentDirectoryW(0, nullptr); const DWORD expected_size = ::GetCurrentDirectoryW(0, nullptr);
@ -90,12 +62,14 @@ String cwd() {
return buffer.simplify_path(); return buffer.simplify_path();
#else #else
char buffer[PATH_MAX]; char buffer[PATH_MAX];
if (::getcwd(buffer, sizeof(buffer)) == nullptr) if (::getcwd(buffer, sizeof(buffer)) == nullptr) {
return "."; return ".";
}
String result; String result;
if (result.parse_utf8(buffer)) if (result.parse_utf8(buffer)) {
return "."; return ".";
}
return result.simplify_path(); return result.simplify_path();
#endif #endif
@ -135,23 +109,26 @@ String realpath(const String &p_path) {
#elif UNIX_ENABLED #elif UNIX_ENABLED
char *resolved_path = ::realpath(p_path.utf8().get_data(), nullptr); char *resolved_path = ::realpath(p_path.utf8().get_data(), nullptr);
if (!resolved_path) if (!resolved_path) {
return p_path; return p_path;
}
String result; String result;
bool parse_ok = result.parse_utf8(resolved_path); bool parse_ok = result.parse_utf8(resolved_path);
::free(resolved_path); ::free(resolved_path);
if (parse_ok) if (parse_ok) {
return p_path; return p_path;
}
return result.simplify_path(); return result.simplify_path();
#endif #endif
} }
String join(const String &p_a, const String &p_b) { String join(const String &p_a, const String &p_b) {
if (p_a.empty()) if (p_a.empty()) {
return p_b; return p_b;
}
const CharType a_last = p_a[p_a.length() - 1]; const CharType a_last = p_a[p_a.length() - 1];
if ((a_last == '/' || a_last == '\\') || if ((a_last == '/' || a_last == '\\') ||
@ -178,8 +155,9 @@ String relative_to_impl(const String &p_path, const String &p_relative_to) {
} else { } else {
String base_dir = p_relative_to.get_base_dir(); String base_dir = p_relative_to.get_base_dir();
if (base_dir.length() <= 2 && (base_dir.empty() || base_dir.ends_with(":"))) if (base_dir.length() <= 2 && (base_dir.empty() || base_dir.ends_with(":"))) {
return p_path; return p_path;
}
return String("..").plus_file(relative_to_impl(p_path, base_dir)); return String("..").plus_file(relative_to_impl(p_path, base_dir));
} }

View File

@ -40,8 +40,6 @@ String join(const String &p_a, const String &p_b);
String join(const String &p_a, const String &p_b, const String &p_c); String join(const String &p_a, const String &p_b, const String &p_c);
String join(const String &p_a, const String &p_b, const String &p_c, const String &p_d); String join(const String &p_a, const String &p_b, const String &p_c, const String &p_d);
String find_executable(const String &p_name);
/// Returns a normalized absolute path to the current working directory /// Returns a normalized absolute path to the current working directory
String cwd(); String cwd();

View File

@ -38,14 +38,16 @@
namespace { namespace {
int sfind(const String &p_text, int p_from) { int sfind(const String &p_text, int p_from) {
if (p_from < 0) if (p_from < 0) {
return -1; return -1;
}
int src_len = 2; int src_len = 2;
int len = p_text.length(); int len = p_text.length();
if (len == 0) if (len == 0) {
return -1; return -1;
}
const CharType *src = p_text.c_str(); const CharType *src = p_text.c_str();
@ -75,8 +77,9 @@ int sfind(const String &p_text, int p_from) {
} }
} }
if (found) if (found) {
return i; return i;
}
} }
return -1; return -1;
@ -85,8 +88,9 @@ int sfind(const String &p_text, int p_from) {
} // namespace } // namespace
String sformat(const String &p_text, const Variant &p1, const Variant &p2, const Variant &p3, const Variant &p4, const Variant &p5) { String sformat(const String &p_text, const Variant &p1, const Variant &p2, const Variant &p3, const Variant &p4, const Variant &p5) {
if (p_text.length() < 2) if (p_text.length() < 2) {
return p_text; return p_text;
}
Array args; Array args;