diff options
author | reduz <reduzio@gmail.com> | 2022-06-19 00:42:02 +0200 |
---|---|---|
committer | reduz <reduzio@gmail.com> | 2022-06-25 15:50:15 +0200 |
commit | b7c41f9ba1afe892af465b56cd942b83e1a19b13 (patch) | |
tree | 4704fff413b5593bed54ccc483088e7cb7a357a0 /scene/resources/resource_format_text.cpp | |
parent | c32285733d4f235249c1031ee64d19b751e4d7df (diff) | |
download | redot-engine-b7c41f9ba1afe892af465b56cd942b83e1a19b13.tar.gz |
Add ability to export Node pointers as NodePaths
This PR implements:
* A new hint: PROPERTY_HINT_NODE_TYPE for variant type OBJECT, which can take specific node types as hint string.
* The editor will show it as a node path, but will set it as a pointer to a node from the current scene if you select a path.
* When scene is saved, the node path is saved, then restored as a pointer.
NOTE: This is a proof of concept and this approach will most likely not work. The reason if that, if the node referenced is deleted, then when trying to edit this the node will become invalid.
Potential workarounds: Since this uses the Variant API, it should obtain the pointer from the Variant object ID. Yet, this would either only really work in GDScript or it would need to be implemented with workarounds in every language.
Alternative ways to make this work: Nodes could export an additional property with a node path (like for which_node, it could be which_node_path).
Another alternative: Path editing could happen as a hidden metadata (ignoring the pointer).
Diffstat (limited to 'scene/resources/resource_format_text.cpp')
-rw-r--r-- | scene/resources/resource_format_text.cpp | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index dba53338eb..217b7d6d1a 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -212,6 +212,15 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars type = SceneState::TYPE_INSTANCED; //no type? assume this was instantiated } + HashSet<StringName> path_properties; + + if (next_tag.fields.has("node_paths")) { + Vector<String> paths = next_tag.fields["node_paths"]; + for (int i = 0; i < paths.size(); i++) { + path_properties.insert(paths[i]); + } + } + if (next_tag.fields.has("instance")) { instance = packed_scene->get_state()->add_value(next_tag.fields["instance"]); @@ -276,9 +285,10 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars } if (!assign.is_empty()) { - int nameidx = packed_scene->get_state()->add_name(assign); + StringName assign_name = assign; + int nameidx = packed_scene->get_state()->add_name(assign_name); int valueidx = packed_scene->get_state()->add_value(value); - packed_scene->get_state()->add_node_property(node_id, nameidx, valueidx); + packed_scene->get_state()->add_node_property(node_id, nameidx, valueidx, path_properties.has(assign_name)); //it's assignment } else if (!next_tag.name.is_empty()) { break; @@ -1941,6 +1951,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const Ref<Reso Ref<PackedScene> instance = state->get_node_instance(i); String instance_placeholder = state->get_node_instance_placeholder(i); Vector<StringName> groups = state->get_node_groups(i); + Vector<String> deferred_node_paths = state->get_node_deferred_nodepath_properties(i); String header = "[node"; header += " name=\"" + String(name).c_escape() + "\""; @@ -1957,6 +1968,10 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const Ref<Reso header += " index=\"" + itos(index) + "\""; } + if (deferred_node_paths.size()) { + header += " node_paths=" + Variant(deferred_node_paths).get_construct_string(); + } + if (groups.size()) { // Write all groups on the same line as they're part of a section header. // This improves readability while not impacting VCS friendliness too much, |