diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2020-06-12 13:16:14 +0200 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2020-06-12 14:30:18 +0200 |
commit | b3bc5aafc5dbe6559534bb1e19093e719afbf52c (patch) | |
tree | 850db91f87f2bd497c3fb0c662d7d3809a53c6fb | |
parent | 84abf5a979648081a9076ec6b342f5f9d33093d4 (diff) |
Object: Add usage hint to instantiate Object properties in editor
Fixes #36372 as Path2D/Path3D's `curve` property no longer uses a Curve
instance as default value, but instead it gets a (unique) default Curve
instance when created through the editor (CreateDialog).
ClassDB gets a sanity check to ensure that we don't do the same mistake
for other properties in the future, but instead use the dedicated
property usage hint.
Fixes #36372.
Fixes #36650.
Supersedes #36644 and #36656.
Co-authored-by: Thakee Nathees <thakeenathees@gmail.com>
Co-authored-by: simpuid <utkarsh.email@yahoo.com>
-rw-r--r-- | core/class_db.cpp | 18 | ||||
-rw-r--r-- | core/object.h | 1 | ||||
-rw-r--r-- | editor/create_dialog.cpp | 49 | ||||
-rw-r--r-- | scene/2d/path_2d.cpp | 6 | ||||
-rw-r--r-- | scene/2d/path_2d.h | 2 | ||||
-rw-r--r-- | scene/3d/path_3d.cpp | 6 | ||||
-rw-r--r-- | scene/3d/path_3d.h | 2 |
7 files changed, 54 insertions, 30 deletions
diff --git a/core/class_db.cpp b/core/class_db.cpp index eed9ec17cb..05c9850c39 100644 --- a/core/class_db.cpp +++ b/core/class_db.cpp @@ -1386,7 +1386,23 @@ Variant ClassDB::class_get_default_property_value(const StringName &p_class, con if (r_valid != nullptr) { *r_valid = true; } - return default_values[p_class][p_property]; + + Variant var = default_values[p_class][p_property]; + +#ifdef DEBUG_ENABLED + // Some properties may have an instantiated Object as default value, + // (like Path2D's `curve` used to have), but that's not a good practice. + // Instead, those properties should use PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT + // to be auto-instantiated when created in the editor. + if (var.get_type() == Variant::OBJECT) { + Object *obj = var.get_validated_object(); + if (obj) { + WARN_PRINT(vformat("Instantiated %s used as default value for %s's \"%s\" property.", obj->get_class(), p_class, p_property)); + } + } +#endif + + return var; } RWLock *ClassDB::lock = nullptr; diff --git a/core/object.h b/core/object.h index 95662f6208..5b46a0f93a 100644 --- a/core/object.h +++ b/core/object.h @@ -124,6 +124,7 @@ enum PropertyUsageFlags { PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT = 1 << 24, PROPERTY_USAGE_KEYING_INCREMENTS = 1 << 25, // Used in inspector to increment property when keyed in animation player PROPERTY_USAGE_DEFERRED_SET_RESOURCE = 1 << 26, // when loading, the resource for this property can be set at the end of loading + PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT = 1 << 27, // For Object properties, instantiate them when creating in editor. PROPERTY_USAGE_DEFAULT = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK, PROPERTY_USAGE_DEFAULT_INTL = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK | PROPERTY_USAGE_INTERNATIONALIZED, diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index 4bd7371c21..73468f8ce0 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -513,30 +513,45 @@ String CreateDialog::get_selected_type() { Object *CreateDialog::instance_selected() { TreeItem *selected = search_options->get_selected(); - if (selected) { - Variant md = selected->get_metadata(0); + if (!selected) { + return nullptr; + } - String custom; - if (md.get_type() != Variant::NIL) { - custom = md; - } + Variant md = selected->get_metadata(0); + String custom; + if (md.get_type() != Variant::NIL) { + custom = md; + } - if (custom != String()) { - if (ScriptServer::is_global_class(custom)) { - Object *obj = EditorNode::get_editor_data().script_class_instance(custom); - Node *n = Object::cast_to<Node>(obj); - if (n) { - n->set_name(custom); - } - return obj; + Object *obj = nullptr; + + if (!custom.empty()) { + if (ScriptServer::is_global_class(custom)) { + obj = EditorNode::get_editor_data().script_class_instance(custom); + Node *n = Object::cast_to<Node>(obj); + if (n) { + n->set_name(custom); } - return EditorNode::get_editor_data().instance_custom_type(selected->get_text(0), custom); + obj = n; } else { - return ClassDB::instance(selected->get_text(0)); + obj = EditorNode::get_editor_data().instance_custom_type(selected->get_text(0), custom); + } + } else { + obj = ClassDB::instance(selected->get_text(0)); + } + + // Check if any Object-type property should be instantiated. + List<PropertyInfo> pinfo; + obj->get_property_list(&pinfo); + + for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { + if (E->get().type == Variant::OBJECT && E->get().usage & PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT) { + Object *prop = ClassDB::instance(E->get().class_name); + obj->set(E->get().name, prop); } } - return nullptr; + return obj; } void CreateDialog::_item_selected() { diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index 00e9af3bb7..f2f549e851 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -149,11 +149,7 @@ void Path2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_curve", "curve"), &Path2D::set_curve); ClassDB::bind_method(D_METHOD("get_curve"), &Path2D::get_curve); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve2D"), "set_curve", "get_curve"); -} - -Path2D::Path2D() { - set_curve(Ref<Curve2D>(memnew(Curve2D))); //create one by default + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT), "set_curve", "get_curve"); } ///////////////////////////////////////////////////////////////////////////////// diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h index 288ef698e7..38fcca0323 100644 --- a/scene/2d/path_2d.h +++ b/scene/2d/path_2d.h @@ -55,7 +55,7 @@ public: void set_curve(const Ref<Curve2D> &p_curve); Ref<Curve2D> get_curve() const; - Path2D(); + Path2D() {} }; class PathFollow2D : public Node2D { diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp index dcfdf8efcf..40d988ff9f 100644 --- a/scene/3d/path_3d.cpp +++ b/scene/3d/path_3d.cpp @@ -77,15 +77,11 @@ void Path3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_curve", "curve"), &Path3D::set_curve); ClassDB::bind_method(D_METHOD("get_curve"), &Path3D::get_curve); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve3D"), "set_curve", "get_curve"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve3D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT), "set_curve", "get_curve"); ADD_SIGNAL(MethodInfo("curve_changed")); } -Path3D::Path3D() { - set_curve(Ref<Curve3D>(memnew(Curve3D))); //create one by default -} - ////////////// void PathFollow3D::_update_transform() { diff --git a/scene/3d/path_3d.h b/scene/3d/path_3d.h index 5a33016bc6..7f227a8a6f 100644 --- a/scene/3d/path_3d.h +++ b/scene/3d/path_3d.h @@ -49,7 +49,7 @@ public: void set_curve(const Ref<Curve3D> &p_curve); Ref<Curve3D> get_curve() const; - Path3D(); + Path3D() {} }; class PathFollow3D : public Node3D { |