Skip to content

Commit

Permalink
VaheraGH-360 Select action names from drop-down list
Browse files Browse the repository at this point in the history
  • Loading branch information
Naros committed May 27, 2024
1 parent 1b73261 commit 3f2f461
Show file tree
Hide file tree
Showing 12 changed files with 221 additions and 7 deletions.
1 change: 1 addition & 0 deletions src/editor/editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ void register_editor_classes()
ORCHESTRATOR_REGISTER_INTERNAL_CLASS(OrchestratorGraphNodePinEnum)
ORCHESTRATOR_REGISTER_INTERNAL_CLASS(OrchestratorGraphNodePinExec)
ORCHESTRATOR_REGISTER_INTERNAL_CLASS(OrchestratorGraphNodePinFile)
ORCHESTRATOR_REGISTER_INTERNAL_CLASS(OrchestratorGraphNodePinInputAction)
ORCHESTRATOR_REGISTER_INTERNAL_CLASS(OrchestratorGraphNodePinNodePath)
ORCHESTRATOR_REGISTER_INTERNAL_CLASS(OrchestratorGraphNodePinNumeric)
ORCHESTRATOR_REGISTER_INTERNAL_CLASS(OrchestratorGraphNodePinObject)
Expand Down
2 changes: 1 addition & 1 deletion src/editor/graph/graph_edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@
#include "common/name_utils.h"
#include "common/scene_utils.h"
#include "common/version.h"
#include "editor/graph/factories/graph_node_factory.h"
#include "editor/graph/graph_knot.h"
#include "editor/graph/graph_node_pin.h"
#include "editor/graph/graph_node_spawner.h"
#include "editor/graph/nodes/graph_node_comment.h"
#include "nodes/graph_node_factory.h"
#include "plugin/plugin.h"
#include "plugin/settings.h"
#include "script/language.h"
Expand Down
2 changes: 1 addition & 1 deletion src/editor/graph/nodes/graph_node_default.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#include "graph_node_default.h"

#include "common/scene_utils.h"
#include "editor/graph/factories/graph_node_pin_factory.h"
#include "editor/graph/pins/graph_node_pin_factory.h"

#include <godot_cpp/classes/h_box_container.hpp>
#include <godot_cpp/classes/v_box_container.hpp>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
//
#include "graph_node_factory.h"

#include "editor/graph/nodes/graph_node_default.h"
#include "editor/graph/nodes/graph_node_comment.h"
#include "editor/graph/nodes/graph_node_default.h"

OrchestratorGraphNode* OrchestratorGraphNodeFactory::create_node(OrchestratorGraphEdit* p_graph, const Ref<OScriptNode>& p_node)
{
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,40 @@
#include "graph_node_pin_factory.h"

#include "editor/graph/pins/graph_node_pins.h"
#include "script/nodes/functions/call_function.h"
#include "script/nodes/functions/call_member_function.h"

OrchestratorGraphNodePin* OrchestratorGraphNodePinFactory::create_pin(OrchestratorGraphNode* p_node, Ref<OScriptNodePin> p_pin)
#include <godot_cpp/classes/input.hpp>

OrchestratorGraphNodePin* OrchestratorGraphNodePinFactory::_resolve_string_based_pin(OrchestratorGraphNode* p_node, const Ref<OScriptNodePin>& p_pin)
{
static PackedStringArray input_event_names = Array::make("is_action_pressed", "is_action_released",
"is_action", "get_action_strength");

static PackedStringArray input_names = Array::make("action_press", "action_release", "get_action_raw_strength",
"get_action_strength", "is_action_just_pressed", "is_action_just_released", "is_action_pressed");

if (OScriptNodeCallMemberFunction* cmf = Object::cast_to<OScriptNodeCallMemberFunction>(p_pin->get_owning_node()))
{
const String target_class_name = cmf->get_target_class();
if (InputEvent::get_class_static().match(target_class_name))
{
const MethodInfo& mi = cmf->get_function();
if (input_event_names.has(mi.name) && p_pin->get_pin_name().match("action"))
return memnew(OrchestratorGraphNodePinInputAction(p_node, p_pin));
}
else if (Input::get_class_static().match(target_class_name))
{
const MethodInfo& mi = cmf->get_function();
if (input_names.has(mi.name) && p_pin->get_pin_name().match("action"))
return memnew(OrchestratorGraphNodePinInputAction(p_node, p_pin));
}
}

return memnew(OrchestratorGraphNodePinString(p_node, p_pin));
}

OrchestratorGraphNodePin* OrchestratorGraphNodePinFactory::create_pin(OrchestratorGraphNode* p_node, const Ref<OScriptNodePin>& p_pin)
{
if (p_pin->get_flags().has_flag(OScriptNodePin::Flags::EXECUTION))
return memnew(OrchestratorGraphNodePinExec(p_node, p_pin));
Expand All @@ -36,7 +68,7 @@ OrchestratorGraphNodePin* OrchestratorGraphNodePinFactory::create_pin(Orchestrat
{
case Variant::STRING:
case Variant::STRING_NAME:
return memnew(OrchestratorGraphNodePinString(p_node, p_pin));
return _resolve_string_based_pin(p_node, p_pin);

case Variant::FLOAT:
case Variant::INT:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,18 @@ class OrchestratorGraphNodePinFactory
// Intentionally private
OrchestratorGraphNodePinFactory() = default;

/// Resolves the string-based pin type
/// @param p_node the graph node that will own the pin
/// @param p_pin the pin to create a rendering widget for
static OrchestratorGraphNodePin* _resolve_string_based_pin(OrchestratorGraphNode* p_node, const Ref<OScriptNodePin>& p_pin);

public:

/// Creates the appropriate OrchestratorGraphNodePin implementation for the given node and pin.
/// @param p_node the graph node that will own the pin
/// @param p_pin the orchestration script pin reference
/// @return the orchestration graph node pin instance, never null
static OrchestratorGraphNodePin* create_pin(OrchestratorGraphNode* p_node, Ref<OScriptNodePin> p_pin);
static OrchestratorGraphNodePin* create_pin(OrchestratorGraphNode* p_node, const Ref<OScriptNodePin>& p_pin);
};

#endif // ORCHESTRATOR_GRAPH_NODE_PIN_FACTORY_H
93 changes: 93 additions & 0 deletions src/editor/graph/pins/graph_node_pin_input_action.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// This file is part of the Godot Orchestrator project.
//
// Copyright (c) 2023-present Vahera Studios LLC and its contributors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "graph_node_pin_input_action.h"

#include "common/callable_lambda.h"

#include <godot_cpp/classes/config_file.hpp>
#include <godot_cpp/classes/input.hpp>
#include <godot_cpp/classes/input_map.hpp>
#include <godot_cpp/classes/option_button.hpp>
#include <godot_cpp/classes/project_settings.hpp>

void OrchestratorGraphNodePinInputAction::_populate_action_list()
{
_button->clear();

String default_value = _pin->get_effective_default_value();
bool found = false;

Ref<ConfigFile> project(memnew(ConfigFile));
if (project->load("res://project.godot") == OK)
{
const PackedStringArray custom_action_names = project->get_section_keys("input");
for (const String& custom_action_name : custom_action_names)
{
_button->add_item(custom_action_name);
if (custom_action_name.match(default_value))
{
_button->select(_button->get_item_count() - 1);
found = true;
}
}
}

const TypedArray<StringName> action_names = InputMap::get_singleton()->get_actions();
for (int i = 0; i < action_names.size(); i++)
{
const StringName& action_name = action_names[i];
if (action_name.begins_with("spatial_editor/"))
continue;

_button->add_item(action_name);
if (action_name.match(default_value))
{
_button->select(_button->get_item_count() - 1);
found = true;
}
}

if (!found)
_pin->set_default_value(Variant());
}

Control* OrchestratorGraphNodePinInputAction::_get_default_value_widget()
{
_button = memnew(OptionButton);
_button->set_allow_reselect(true);
_button->get_popup()->set_max_size(Vector2(32768, 400));
_button->set_tooltip_text("Actions defined in Project Settings: Input Map");

_button->connect("item_selected", callable_mp_lambda(this, [&](int index) {
const String action_name = _button->get_item_text(index);
_pin->set_default_value(action_name);
_button->release_focus();
}));

ProjectSettings::get_singleton()->connect("settings_changed", callable_mp_lambda(this, [&]() {
_populate_action_list();
}));

_populate_action_list();

return _button;
}

OrchestratorGraphNodePinInputAction::OrchestratorGraphNodePinInputAction(OrchestratorGraphNode* p_node, const Ref<OScriptNodePin>& p_pin)
: OrchestratorGraphNodePin(p_node, p_pin)
{
}
50 changes: 50 additions & 0 deletions src/editor/graph/pins/graph_node_pin_input_action.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// This file is part of the Godot Orchestrator project.
//
// Copyright (c) 2023-present Vahera Studios LLC and its contributors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef ORCHESTRATOR_GRAPH_NODE_PIN_INPUT_ACTION_H
#define ORCHESTRATOR_GRAPH_NODE_PIN_INPUT_ACTION_H

#include "editor/graph/graph_node_pin.h"

#include <godot_cpp/classes/option_button.hpp>

/// Pin input widget for selecting input actions from a drop-down list
class OrchestratorGraphNodePinInputAction : public OrchestratorGraphNodePin
{
GDCLASS(OrchestratorGraphNodePinInputAction, OrchestratorGraphNodePin);
static void _bind_methods() {}

protected:
OptionButton* _button{ nullptr };

//~ Begin OrchestratorGraphNodePin Interface
Control* _get_default_value_widget() override;
//~ End OrchestratorGraphNodePin Interface

/// Populates the button's action list
void _populate_action_list();

// Default constructor
OrchestratorGraphNodePinInputAction() = default;

public:
/// Constructs the input action pin
/// @param p_node the graph node
/// @param p_pin the script node pin
OrchestratorGraphNodePinInputAction(OrchestratorGraphNode* p_node, const Ref<OScriptNodePin>& p_pin);
};

#endif // ORCHESTRATOR_GRAPH_NODE_PIN_INPUT_ACTION_H
1 change: 1 addition & 0 deletions src/editor/graph/pins/graph_node_pins.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "editor/graph/pins/graph_node_pin_enum.h"
#include "editor/graph/pins/graph_node_pin_exec.h"
#include "editor/graph/pins/graph_node_pin_file.h"
#include "editor/graph/pins/graph_node_pin_input_action.h"
#include "editor/graph/pins/graph_node_pin_node_path.h"
#include "editor/graph/pins/graph_node_pin_numeric.h"
#include "editor/graph/pins/graph_node_pin_object.h"
Expand Down
23 changes: 22 additions & 1 deletion src/script/nodes/functions/call_member_function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include "call_member_function.h"

#include "common/dictionary_utils.h"
#include "common/method_utils.h"
#include "common/variant_utils.h"
#include "common/version.h"

Expand Down Expand Up @@ -94,3 +93,25 @@ void OScriptNodeCallMemberFunction::initialize(const OScriptNodeInitContext& p_c

super::initialize(p_context);
}

void OScriptNodeCallMemberFunction::on_pin_connected(const Ref<OScriptNodePin>& p_pin)
{
if (p_pin->get_pin_name().match("target"))
{
_function_flags = int64_t(_function_flags) & ~FF_IS_SELF;

const Ref<OScriptNodePin> supplier = p_pin->get_connections()[0];
const String target_class = supplier->get_owning_node()->resolve_type_class(supplier);
_reference.target_class_name = target_class;
}
}

void OScriptNodeCallMemberFunction::on_pin_disconnected(const Ref<OScriptNodePin>& p_pin)
{
if (p_pin->get_pin_name().match("target"))
{
_function_flags.set_flag(FF_IS_SELF);
_reference.target_class_name = get_owning_script()->get_base_type();
}
reconstruct_node();
}
11 changes: 11 additions & 0 deletions src/script/nodes/functions/call_member_function.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,18 @@ class OScriptNodeCallMemberFunction : public OScriptNodeCallFunction
String get_node_title_color_name() const override { return "function_call"; }
String get_help_topic() const override;
void initialize(const OScriptNodeInitContext& p_context) override;
void on_pin_connected(const Ref<OScriptNodePin>& p_pin) override;
void on_pin_disconnected(const Ref<OScriptNodePin>& p_pin) override;
//~ End OScriptNode Interface

/// Get the target function class
/// @return the target function class
String get_target_class() const { return _reference.target_class_name; }

/// Get the Godot function reference
/// @return the function reference
const MethodInfo& get_function() const { return _reference.method; }

};

#endif // ORCHESTRATOR_SCRIPT_NODE_CALL_MEMBER_FUNCTION_H

0 comments on commit 3f2f461

Please sign in to comment.