From b5b3421a476fdd121ff6c9d159a9918ce79759e8 Mon Sep 17 00:00:00 2001 From: Chris Cranford Date: Sat, 6 Jan 2024 22:47:15 -0500 Subject: [PATCH] GH-52 Work with scene node properties & methods --- src/editor/graph/actions/action_menu_filter.h | 2 ++ .../actions/default_action_registrar.cpp | 28 ++++++++++++++++--- src/editor/graph/graph_edit.cpp | 16 ++++++++++- src/editor/graph/graph_node_pin.cpp | 3 ++ src/editor/graph/graph_node_pin.h | 1 + src/script/node.h | 5 ++++ src/script/node_pin.cpp | 5 ++++ src/script/node_pin.h | 4 +++ src/script/nodes/scene/scene_node.cpp | 15 ++++++++++ src/script/nodes/scene/scene_node.h | 1 + 10 files changed, 75 insertions(+), 5 deletions(-) diff --git a/src/editor/graph/actions/action_menu_filter.h b/src/editor/graph/actions/action_menu_filter.h index 414c2b34..d85f763f 100644 --- a/src/editor/graph/actions/action_menu_filter.h +++ b/src/editor/graph/actions/action_menu_filter.h @@ -72,6 +72,8 @@ struct OrchestratorGraphActionFilter /// then the action is filtered out. Vector target_classes; + /// The target object to expressly get context details about + Object* target_object; }; #endif // ORCHESTRATOR_GRAPH_ACTION_MENU_ITEM_FILTER_H diff --git a/src/editor/graph/actions/default_action_registrar.cpp b/src/editor/graph/actions/default_action_registrar.cpp index 8ba50354..d7d006b5 100644 --- a/src/editor/graph/actions/default_action_registrar.cpp +++ b/src/editor/graph/actions/default_action_registrar.cpp @@ -21,6 +21,7 @@ #include "common/variant_utils.h" #include "common/string_utils.h" #include "editor/graph/graph_edit.h" +#include "editor/graph/graph_node_pin.h" #include "editor/graph/graph_node_spawner.h" #include "script/nodes/script_nodes.h" @@ -337,7 +338,11 @@ void OrchestratorDefaultGraphActionRegistrar::_register_graph_items(const Orches return; PackedStringArray classes; - if (!p_context.filter->target_classes.is_empty()) + if (p_context.filter->target_object) + { + classes.push_back(p_context.filter->target_object->get_class()); + } + else if (!p_context.filter->target_classes.is_empty()) { for (String target_class : p_context.filter->target_classes) { @@ -366,7 +371,12 @@ void OrchestratorDefaultGraphActionRegistrar::_register_graph_items(const Orches void OrchestratorDefaultGraphActionRegistrar::_register_class_properties(const OrchestratorGraphActionRegistrarContext& p_context, const StringName& p_class_name) { - TypedArray properties = ClassDB::class_get_property_list(p_class_name, true); + TypedArray properties; + if (p_context.filter->target_object) + properties = p_context.filter->target_object->get_property_list(); + else + properties = ClassDB::class_get_property_list(p_class_name, true); + for (int i = 0; i < properties.size(); i++) { const PropertyInfo pi = DictionaryUtils::to_property(properties[i]); @@ -400,7 +410,12 @@ void OrchestratorDefaultGraphActionRegistrar::_register_class_properties(const O void OrchestratorDefaultGraphActionRegistrar::_register_class_methods(const OrchestratorGraphActionRegistrarContext& p_context, const StringName& p_class_name) { - TypedArray methods = ClassDB::class_get_method_list(p_class_name, true); + TypedArray methods; + if (p_context.filter->target_object) + methods = p_context.filter->target_object->get_method_list(); + else + methods = ClassDB::class_get_method_list(p_class_name, true); + for (int i = 0; i < methods.size(); i++) { const MethodInfo mi = DictionaryUtils::to_method(methods[i]); @@ -428,7 +443,12 @@ void OrchestratorDefaultGraphActionRegistrar::_register_class_methods(const Orch void OrchestratorDefaultGraphActionRegistrar::_register_class_signals(const OrchestratorGraphActionRegistrarContext& p_context, const StringName& p_class_name) { - TypedArray signals = ClassDB::class_get_signal_list(p_class_name, true); + TypedArray signals; + if (p_context.filter->target_object) + signals = p_context.filter->target_object->get_signal_list(); + else + signals = ClassDB::class_get_signal_list(p_class_name, true); + for (int i = 0; i < signals.size(); i++) { const MethodInfo si = DictionaryUtils::to_method(signals[i]); diff --git a/src/editor/graph/graph_edit.cpp b/src/editor/graph/graph_edit.cpp index e10edb27..69f59173 100644 --- a/src/editor/graph/graph_edit.cpp +++ b/src/editor/graph/graph_edit.cpp @@ -750,6 +750,13 @@ void OrchestratorGraphEdit::_on_attempt_connection_from_empty(const StringName& filter.context.pins.push_back(pin); ResolvedType resolved_type = pin->resolve_type(); + if (resolved_type.object) + { + // When a resolved object isp provided, it takes precedence + filter.target_classes.push_back(resolved_type.object->get_class()); + filter.target_object = resolved_type.object; + filter.context.pins.clear(); + } if (resolved_type.is_class_type()) { filter.target_classes.push_back(resolved_type.class_name); @@ -774,7 +781,14 @@ void OrchestratorGraphEdit::_on_attempt_connection_to_empty(const StringName& p_ filter.context.pins.push_back(pin); ResolvedType resolved_type = pin->resolve_type(); - if (resolved_type.is_class_type()) + if (resolved_type.object) + { + // When a resolved object is provided, it takes precedence + filter.target_classes.push_back(resolved_type.object->get_class()); + filter.target_object = resolved_type.object; + filter.context.pins.clear(); + } + else if (resolved_type.is_class_type()) { filter.target_classes.push_back(resolved_type.class_name); filter.context.pins.clear(); diff --git a/src/editor/graph/graph_node_pin.cpp b/src/editor/graph/graph_node_pin.cpp index 11ee8e71..21486177 100644 --- a/src/editor/graph/graph_node_pin.cpp +++ b/src/editor/graph/graph_node_pin.cpp @@ -136,6 +136,9 @@ ResolvedType OrchestratorGraphNodePin::resolve_type() const else resolved_type.class_name = "Object"; + // Primarily used by SceneNode to get scene attributes about the target + resolved_type.object = _pin->resolve_target(); + return resolved_type; } diff --git a/src/editor/graph/graph_node_pin.h b/src/editor/graph/graph_node_pin.h index 03520663..f4732c5f 100644 --- a/src/editor/graph/graph_node_pin.h +++ b/src/editor/graph/graph_node_pin.h @@ -37,6 +37,7 @@ struct ResolvedType { Variant::Type type{ Variant::NIL }; StringName class_name; + Object* object; _FORCE_INLINE_ bool is_non_object_type() const { return type != Variant::NIL && type != Variant::OBJECT; } _FORCE_INLINE_ bool is_class_type() const { return !class_name.is_empty(); } diff --git a/src/script/node.h b/src/script/node.h index 092056a8..67c35dd7 100644 --- a/src/script/node.h +++ b/src/script/node.h @@ -299,6 +299,11 @@ class OScriptNode : public Resource /// @return the resolved class type virtual StringName resolve_type_class(const Ref& p_pin) const { return ""; } + /// Resolves the target object of the specified pin + /// @param p_pin the pin + /// @return the resolved target object + virtual Object* resolve_target(const Ref& p_pin) const { return nullptr; } + /// Create a pin associated with this node. /// @param p_direction the pin direction, input or output /// @param p_name the pin name diff --git a/src/script/node_pin.cpp b/src/script/node_pin.cpp index 10a57f25..d929569d 100644 --- a/src/script/node_pin.cpp +++ b/src/script/node_pin.cpp @@ -534,4 +534,9 @@ bool OScriptNodePin::has_any_connections() const Vector> OScriptNodePin::get_connections() const { return get_owning_node()->get_owning_script()->get_connections(this); +} + +Object* OScriptNodePin::resolve_target() +{ + return get_owning_node()->resolve_target(this); } \ No newline at end of file diff --git a/src/script/node_pin.h b/src/script/node_pin.h index 257ba628..7e5b0e2b 100644 --- a/src/script/node_pin.h +++ b/src/script/node_pin.h @@ -245,6 +245,10 @@ class OScriptNodePin : public Resource /// Return whether this pin acts as an execution pin. /// @return true if the pin is a control flow, execution pin, false otherwise _FORCE_INLINE_ bool is_execution() const { return get_flags().has_flag(OScriptNodePin::Flags::EXECUTION); } + + /// Attempts to resolve the target object of this pin. + /// @return the target object of the pin or {@code nullptr} if there is no target. + Object* resolve_target(); }; VARIANT_BITFIELD_CAST(OScriptNodePin::Flags) diff --git a/src/script/nodes/scene/scene_node.cpp b/src/script/nodes/scene/scene_node.cpp index f780d6c3..92410476 100644 --- a/src/script/nodes/scene/scene_node.cpp +++ b/src/script/nodes/scene/scene_node.cpp @@ -109,6 +109,21 @@ String OScriptNodeSceneNode::get_icon() const return "NodeInfo"; } +Object* OScriptNodeSceneNode::resolve_target(const Ref& p_pin) const +{ + if (_is_in_editor() && p_pin.is_valid() && p_pin->is_output() && !p_pin->is_execution()) + { + SceneTree* st = Object::cast_to(Engine::get_singleton()->get_main_loop()); + if (st && st->get_edited_scene_root()) + { + Node* root = st->get_edited_scene_root(); + if (root) + return root->get_node_or_null(_node_path); + } + } + return super::resolve_target(p_pin); +} + OScriptNodeInstance* OScriptNodeSceneNode::instantiate(OScriptInstance* p_instance) { OScriptNodeSceneNodeInstance* i = memnew(OScriptNodeSceneNodeInstance); diff --git a/src/script/nodes/scene/scene_node.h b/src/script/nodes/scene/scene_node.h index 8460e33c..d201ac9e 100644 --- a/src/script/nodes/scene/scene_node.h +++ b/src/script/nodes/scene/scene_node.h @@ -41,6 +41,7 @@ class OScriptNodeSceneNode : public OScriptNode String get_node_title() const override; String get_node_title_color_name() const override { return "scene"; } String get_icon() const override; + Object* resolve_target(const Ref& p_pin) const override; OScriptNodeInstance* instantiate(OScriptInstance* p_instance) override; void initialize(const OScriptNodeInitContext& p_context) override; //~ End OScriptNode Interface