Merge pull request #38774 from pepegadeveloper123/mono_inherited_scene_bug_3.2
Mono inherited scene bug 3.2
This commit is contained in:
commit
21180675c9
|
@ -2315,58 +2315,69 @@ void CSharpScript::_update_member_info_no_exports() {
|
||||||
bool CSharpScript::_update_exports() {
|
bool CSharpScript::_update_exports() {
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
if (!Engine::get_singleton()->is_editor_hint())
|
bool is_editor = Engine::get_singleton()->is_editor_hint();
|
||||||
return false;
|
if (is_editor)
|
||||||
|
placeholder_fallback_enabled = true; // until proven otherwise
|
||||||
placeholder_fallback_enabled = true; // until proven otherwise
|
#endif
|
||||||
|
|
||||||
if (!valid)
|
if (!valid)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
|
||||||
if (exports_invalidated) {
|
#ifdef TOOLS_ENABLED
|
||||||
|
if (!is_editor || exports_invalidated)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
GD_MONO_SCOPE_THREAD_ATTACH;
|
GD_MONO_SCOPE_THREAD_ATTACH;
|
||||||
|
|
||||||
exports_invalidated = false;
|
|
||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
||||||
member_info.clear();
|
member_info.clear();
|
||||||
exported_members_cache.clear();
|
|
||||||
exported_members_defval_cache.clear();
|
|
||||||
|
|
||||||
// Here we create a temporary managed instance of the class to get the initial values
|
#ifdef TOOLS_ENABLED
|
||||||
|
MonoObject *tmp_object = nullptr;
|
||||||
|
Object *tmp_native = nullptr;
|
||||||
|
uint32_t tmp_pinned_gchandle = 0;
|
||||||
|
|
||||||
MonoObject *tmp_object = mono_object_new(mono_domain_get(), script_class->get_mono_ptr());
|
if (is_editor) {
|
||||||
|
exports_invalidated = false;
|
||||||
|
|
||||||
if (!tmp_object) {
|
exported_members_cache.clear();
|
||||||
ERR_PRINT("Failed to allocate temporary MonoObject.");
|
exported_members_defval_cache.clear();
|
||||||
return false;
|
|
||||||
}
|
// Here we create a temporary managed instance of the class to get the initial values
|
||||||
|
tmp_object = mono_object_new(mono_domain_get(), script_class->get_mono_ptr());
|
||||||
uint32_t tmp_pinned_gchandle = MonoGCHandle::new_strong_handle_pinned(tmp_object); // pin it (not sure if needed)
|
|
||||||
|
if (!tmp_object) {
|
||||||
GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), 0);
|
ERR_PRINT("Failed to allocate temporary MonoObject.");
|
||||||
|
return false;
|
||||||
ERR_FAIL_NULL_V_MSG(ctor, NULL,
|
}
|
||||||
"Cannot construct temporary MonoObject because the class does not define a parameterless constructor: '" + get_path() + "'.");
|
|
||||||
|
tmp_pinned_gchandle = MonoGCHandle::new_strong_handle_pinned(tmp_object); // pin it (not sure if needed)
|
||||||
MonoException *ctor_exc = NULL;
|
|
||||||
ctor->invoke(tmp_object, NULL, &ctor_exc);
|
GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), 0);
|
||||||
|
|
||||||
Object *tmp_native = GDMonoMarshal::unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(tmp_object));
|
ERR_FAIL_NULL_V_MSG(ctor, NULL,
|
||||||
|
"Cannot construct temporary MonoObject because the class does not define a parameterless constructor: '" + get_path() + "'.");
|
||||||
if (ctor_exc) {
|
|
||||||
// TODO: Should we free 'tmp_native' if the exception was thrown after its creation?
|
MonoException *ctor_exc = NULL;
|
||||||
|
ctor->invoke(tmp_object, NULL, &ctor_exc);
|
||||||
MonoGCHandle::free_handle(tmp_pinned_gchandle);
|
|
||||||
tmp_object = NULL;
|
tmp_native = GDMonoMarshal::unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(tmp_object));
|
||||||
|
|
||||||
ERR_PRINT("Exception thrown from constructor of temporary MonoObject:");
|
if (ctor_exc) {
|
||||||
GDMonoUtils::debug_print_unhandled_exception(ctor_exc);
|
// TODO: Should we free 'tmp_native' if the exception was thrown after its creation?
|
||||||
return false;
|
|
||||||
|
MonoGCHandle::free_handle(tmp_pinned_gchandle);
|
||||||
|
tmp_object = NULL;
|
||||||
|
|
||||||
|
ERR_PRINT("Exception thrown from constructor of temporary MonoObject:");
|
||||||
|
GDMonoUtils::debug_print_unhandled_exception(ctor_exc);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
GDMonoClass *top = script_class;
|
GDMonoClass *top = script_class;
|
||||||
|
|
||||||
|
@ -2382,16 +2393,16 @@ bool CSharpScript::_update_exports() {
|
||||||
if (_get_member_export(field, /* inspect export: */ true, prop_info, exported)) {
|
if (_get_member_export(field, /* inspect export: */ true, prop_info, exported)) {
|
||||||
StringName member_name = field->get_name();
|
StringName member_name = field->get_name();
|
||||||
|
|
||||||
if (exported) {
|
member_info[member_name] = prop_info;
|
||||||
member_info[member_name] = prop_info;
|
#ifdef TOOLS_ENABLED
|
||||||
|
if (is_editor && exported) {
|
||||||
exported_members_cache.push_front(prop_info);
|
exported_members_cache.push_front(prop_info);
|
||||||
|
|
||||||
if (tmp_object) {
|
if (tmp_object) {
|
||||||
exported_members_defval_cache[member_name] = GDMonoMarshal::mono_object_to_variant(field->get_value(tmp_object));
|
exported_members_defval_cache[member_name] = GDMonoMarshal::mono_object_to_variant(field->get_value(tmp_object));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
member_info[member_name] = prop_info;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2403,8 +2414,9 @@ bool CSharpScript::_update_exports() {
|
||||||
if (_get_member_export(property, /* inspect export: */ true, prop_info, exported)) {
|
if (_get_member_export(property, /* inspect export: */ true, prop_info, exported)) {
|
||||||
StringName member_name = property->get_name();
|
StringName member_name = property->get_name();
|
||||||
|
|
||||||
if (exported) {
|
member_info[member_name] = prop_info;
|
||||||
member_info[member_name] = prop_info;
|
#ifdef TOOLS_ENABLED
|
||||||
|
if (is_editor && exported) {
|
||||||
exported_members_cache.push_front(prop_info);
|
exported_members_cache.push_front(prop_info);
|
||||||
|
|
||||||
if (tmp_object) {
|
if (tmp_object) {
|
||||||
|
@ -2417,57 +2429,62 @@ bool CSharpScript::_update_exports() {
|
||||||
exported_members_defval_cache[member_name] = GDMonoMarshal::mono_object_to_variant(ret);
|
exported_members_defval_cache[member_name] = GDMonoMarshal::mono_object_to_variant(ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
member_info[member_name] = prop_info;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
top = top->get_parent_class();
|
top = top->get_parent_class();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Need to check this here, before disposal
|
#ifdef TOOLS_ENABLED
|
||||||
bool base_ref = Object::cast_to<Reference>(tmp_native) != NULL;
|
if (is_editor) {
|
||||||
|
// Need to check this here, before disposal
|
||||||
|
bool base_ref = Object::cast_to<Reference>(tmp_native) != NULL;
|
||||||
|
|
||||||
// Dispose the temporary managed instance
|
// Dispose the temporary managed instance
|
||||||
|
|
||||||
MonoException *exc = NULL;
|
MonoException *exc = NULL;
|
||||||
GDMonoUtils::dispose(tmp_object, &exc);
|
GDMonoUtils::dispose(tmp_object, &exc);
|
||||||
|
|
||||||
if (exc) {
|
if (exc) {
|
||||||
ERR_PRINT("Exception thrown from method Dispose() of temporary MonoObject:");
|
ERR_PRINT("Exception thrown from method Dispose() of temporary MonoObject:");
|
||||||
GDMonoUtils::debug_print_unhandled_exception(exc);
|
GDMonoUtils::debug_print_unhandled_exception(exc);
|
||||||
|
}
|
||||||
|
|
||||||
|
MonoGCHandle::free_handle(tmp_pinned_gchandle);
|
||||||
|
tmp_object = NULL;
|
||||||
|
|
||||||
|
if (tmp_native && !base_ref) {
|
||||||
|
Node *node = Object::cast_to<Node>(tmp_native);
|
||||||
|
if (node && node->is_inside_tree()) {
|
||||||
|
ERR_PRINTS("Temporary instance was added to the scene tree.");
|
||||||
|
} else {
|
||||||
|
memdelete(tmp_native);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
MonoGCHandle::free_handle(tmp_pinned_gchandle);
|
#ifdef TOOLS_ENABLED
|
||||||
tmp_object = NULL;
|
if (is_editor) {
|
||||||
|
placeholder_fallback_enabled = false;
|
||||||
|
|
||||||
if (tmp_native && !base_ref) {
|
if (placeholders.size()) {
|
||||||
Node *node = Object::cast_to<Node>(tmp_native);
|
// Update placeholders if any
|
||||||
if (node && node->is_inside_tree()) {
|
Map<StringName, Variant> values;
|
||||||
ERR_PRINTS("Temporary instance was added to the scene tree.");
|
List<PropertyInfo> propnames;
|
||||||
} else {
|
_update_exports_values(values, propnames);
|
||||||
memdelete(tmp_native);
|
|
||||||
|
for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) {
|
||||||
|
E->get()->update(propnames, values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
placeholder_fallback_enabled = false;
|
|
||||||
|
|
||||||
if (placeholders.size()) {
|
|
||||||
// Update placeholders if any
|
|
||||||
Map<StringName, Variant> values;
|
|
||||||
List<PropertyInfo> propnames;
|
|
||||||
_update_exports_values(values, propnames);
|
|
||||||
|
|
||||||
for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) {
|
|
||||||
E->get()->update(propnames, values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return changed;
|
return changed;
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSharpScript::load_script_signals(GDMonoClass *p_class, GDMonoClass *p_native_class) {
|
void CSharpScript::load_script_signals(GDMonoClass *p_class, GDMonoClass *p_native_class) {
|
||||||
|
@ -2538,7 +2555,6 @@ bool CSharpScript::_get_signal(GDMonoClass *p_class, GDMonoClass *p_delegate, Ve
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
|
||||||
/**
|
/**
|
||||||
* Returns false if there was an error, otherwise true.
|
* Returns false if there was an error, otherwise true.
|
||||||
* If there was an error, r_prop_info and r_exported are not assigned any value.
|
* If there was an error, r_prop_info and r_exported are not assigned any value.
|
||||||
|
@ -2552,8 +2568,10 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
|
||||||
(m_member->get_enclosing_class()->get_full_name() + "." + (String)m_member->get_name())
|
(m_member->get_enclosing_class()->get_full_name() + "." + (String)m_member->get_name())
|
||||||
|
|
||||||
if (p_member->is_static()) {
|
if (p_member->is_static()) {
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
if (p_member->has_attribute(CACHED_CLASS(ExportAttribute)))
|
if (p_member->has_attribute(CACHED_CLASS(ExportAttribute)))
|
||||||
ERR_PRINTS("Cannot export member because it is static: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
|
ERR_PRINTS("Cannot export member because it is static: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2575,13 +2593,17 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
|
||||||
if (p_member->get_member_type() == IMonoClassMember::MEMBER_TYPE_PROPERTY) {
|
if (p_member->get_member_type() == IMonoClassMember::MEMBER_TYPE_PROPERTY) {
|
||||||
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
|
||||||
if (exported)
|
if (exported)
|
||||||
ERR_PRINTS("Read-only property cannot be exported: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
|
ERR_PRINTS("Read-only property cannot be exported: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!property->has_setter()) {
|
if (!property->has_setter()) {
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
if (exported)
|
if (exported)
|
||||||
ERR_PRINTS("Write-only property (without getter) cannot be exported: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
|
ERR_PRINTS("Write-only property (without getter) cannot be exported: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2600,10 +2622,13 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
|
||||||
String hint_string;
|
String hint_string;
|
||||||
|
|
||||||
if (variant_type == Variant::NIL) {
|
if (variant_type == Variant::NIL) {
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
ERR_PRINTS("Unknown exported member type: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
|
ERR_PRINTS("Unknown exported member type: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
int hint_res = _try_get_member_export_hint(p_member, type, variant_type, /* allow_generics: */ true, hint, hint_string);
|
int hint_res = _try_get_member_export_hint(p_member, type, variant_type, /* allow_generics: */ true, hint, hint_string);
|
||||||
|
|
||||||
ERR_FAIL_COND_V_MSG(hint_res == -1, false,
|
ERR_FAIL_COND_V_MSG(hint_res == -1, false,
|
||||||
|
@ -2614,6 +2639,7 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
|
||||||
hint = PropertyHint(CACHED_FIELD(ExportAttribute, hint)->get_int_value(attr));
|
hint = PropertyHint(CACHED_FIELD(ExportAttribute, hint)->get_int_value(attr));
|
||||||
hint_string = CACHED_FIELD(ExportAttribute, hintString)->get_string_value(attr);
|
hint_string = CACHED_FIELD(ExportAttribute, hintString)->get_string_value(attr);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
r_prop_info = PropertyInfo(variant_type, (String)p_member->get_name(), hint, hint_string, PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE);
|
r_prop_info = PropertyInfo(variant_type, (String)p_member->get_name(), hint, hint_string, PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE);
|
||||||
r_exported = true;
|
r_exported = true;
|
||||||
|
@ -2623,6 +2649,7 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
|
||||||
#undef MEMBER_FULL_QUALIFIED_NAME
|
#undef MEMBER_FULL_QUALIFIED_NAME
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, ManagedType p_type, Variant::Type p_variant_type, bool p_allow_generics, PropertyHint &r_hint, String &r_hint_string) {
|
int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, ManagedType p_type, Variant::Type p_variant_type, bool p_allow_generics, PropertyHint &r_hint, String &r_hint_string) {
|
||||||
|
|
||||||
GD_MONO_ASSERT_THREAD_ATTACHED;
|
GD_MONO_ASSERT_THREAD_ATTACHED;
|
||||||
|
|
|
@ -133,8 +133,8 @@ class CSharpScript : public Script {
|
||||||
bool _get_signal(GDMonoClass *p_class, GDMonoClass *p_delegate, Vector<Argument> ¶ms);
|
bool _get_signal(GDMonoClass *p_class, GDMonoClass *p_delegate, Vector<Argument> ¶ms);
|
||||||
|
|
||||||
bool _update_exports();
|
bool _update_exports();
|
||||||
#ifdef TOOLS_ENABLED
|
|
||||||
bool _get_member_export(IMonoClassMember *p_member, bool p_inspect_export, PropertyInfo &r_prop_info, bool &r_exported);
|
bool _get_member_export(IMonoClassMember *p_member, bool p_inspect_export, PropertyInfo &r_prop_info, bool &r_exported);
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
static int _try_get_member_export_hint(IMonoClassMember *p_member, ManagedType p_type, Variant::Type p_variant_type, bool p_allow_generics, PropertyHint &r_hint, String &r_hint_string);
|
static int _try_get_member_export_hint(IMonoClassMember *p_member, ManagedType p_type, Variant::Type p_variant_type, bool p_allow_generics, PropertyHint &r_hint, String &r_hint_string);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue