Skip to content

Commit

Permalink
GH-283 Support method chaining
Browse files Browse the repository at this point in the history
  • Loading branch information
Naros committed Apr 24, 2024
1 parent 7659bfc commit 57ce555
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 8 deletions.
45 changes: 37 additions & 8 deletions src/script/nodes/functions/call_function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ class OScriptNodeCallFunctionInstance : public OScriptNodeInstance
Object* _owner{ nullptr };
int _argument_count{ 0 };
int _argument_offset{ 2 };
bool _pure = false;
bool _pure{ false };
bool _chained{ false };
Array _args;

int _do_pure(OScriptNodeExecutionContext& p_context) const
Expand Down Expand Up @@ -139,10 +140,14 @@ class OScriptNodeCallFunctionInstance : public OScriptNodeInstance
{
Variant result = instance->callv(_function_name, _args);
p_context.set_output(0, result);
if (_chained)
p_context.set_output(1, p_context.get_input(0));
}
else
{
instance->callv(_function_name, _args);
if (_chained)
p_context.set_output(0, p_context.get_input(0));
}
return 0;
}
Expand All @@ -161,22 +166,22 @@ void OScriptNodeCallFunction::_bind_methods()

void OScriptNodeCallFunction::_get_property_list(List<PropertyInfo>* r_list) const
{
int32_t read_only_serialize = PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_READ_ONLY;
int32_t read_only_editor = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_READ_ONLY;

r_list->push_back(PropertyInfo(Variant::STRING, "guid", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
r_list->push_back(PropertyInfo(Variant::STRING, "function_name", PROPERTY_HINT_NONE, "", read_only_editor));
r_list->push_back(PropertyInfo(Variant::STRING_NAME, "target_class_name", PROPERTY_HINT_NONE, "", read_only_serialize));
r_list->push_back(PropertyInfo(Variant::INT, "target_type", PROPERTY_HINT_NONE, "", read_only_serialize));
r_list->push_back(PropertyInfo(Variant::STRING, "function_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
r_list->push_back(PropertyInfo(Variant::STRING_NAME, "target_class_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
r_list->push_back(PropertyInfo(Variant::INT, "target_type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));

const String flags = "Pure,Const,Is Bead,Is Self,Virtual,VarArg,Static,Object Core,Editor";
r_list->push_back(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, flags, read_only_serialize));
r_list->push_back(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, flags, PROPERTY_USAGE_STORAGE));

if (_is_method_info_serialized())
r_list->push_back(PropertyInfo(Variant::DICTIONARY, "method", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));

if (_reference.method.flags & METHOD_FLAG_VARARG)
r_list->push_back(PropertyInfo(Variant::INT, "variable_arg_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));

if (_chainable)
r_list->push_back(PropertyInfo(Variant::BOOL, "chain"));
}

bool OScriptNodeCallFunction::_get(const StringName& p_name, Variant& r_value) const
Expand Down Expand Up @@ -216,6 +221,11 @@ bool OScriptNodeCallFunction::_get(const StringName& p_name, Variant& r_value) c
r_value = _vararg_count;
return true;
}
else if (p_name.match("chain"))
{
r_value = _chain;
return true;
}
return false;
}

Expand Down Expand Up @@ -253,6 +263,12 @@ bool OScriptNodeCallFunction::_set(const StringName& p_name, const Variant& p_va
_notify_pins_changed();
return true;
}
else if (p_name.match("chain"))
{
_chain = p_value;
_notify_pins_changed();
return true;
}
return false;
}

Expand All @@ -264,6 +280,7 @@ void OScriptNodeCallFunction::_create_pins_for_method(const MethodInfo& p_method
create_pin(PD_Output, "ExecOut")->set_flags(OScriptNodePin::Flags::EXECUTION);
}

_chainable = false;
if (get_argument_offset() != 0)
{
Variant::Type target_type = _reference.target_type != Variant::NIL ? _reference.target_type : Variant::OBJECT;
Expand All @@ -275,6 +292,9 @@ void OScriptNodeCallFunction::_create_pins_for_method(const MethodInfo& p_method
target->set_target_class(get_owning_script()->get_base_type());
else
target->set_target_class("Object");

_chainable = true;
notify_property_list_changed();
}
}

Expand Down Expand Up @@ -326,6 +346,14 @@ void OScriptNodeCallFunction::_create_pins_for_method(const MethodInfo& p_method
rv->set_flags(OScriptNodePin::Flags::DATA);
rv->set_target_class(p_method.return_val.class_name);
}

if (_chainable && _chain)
{
Ref<OScriptNodePin> chain = create_pin(PD_Output, "return_target", Variant::OBJECT);
chain->set_flags(OScriptNodePin::Flags::DATA);
chain->set_label("Target");
chain->set_target_class(find_pin("target", PD_Input)->get_target_class());
}
}

bool OScriptNodeCallFunction::_has_execution_pins(const MethodInfo& p_method) const
Expand Down Expand Up @@ -412,6 +440,7 @@ OScriptNodeInstance* OScriptNodeCallFunction::instantiate(OScriptInstance* p_ins
i->_reference = _reference;
i->_function_name = _reference.name;
i->_pure = _function_flags.has_flag(FF_PURE);
i->_chained = _chain;
return i;
}

Expand Down
2 changes: 2 additions & 0 deletions src/script/nodes/functions/call_function.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ class OScriptNodeCallFunction : public OScriptNode
BitField<FunctionFlags> _function_flags{ FF_NONE }; //! Function flags
OScriptFunctionReference _reference; //! Function reference
int _vararg_count{ 0 }; //! Variable argument count
bool _chain{ false }; //! If the node should chain function calls
bool _chainable{ false }; //! Whether the node is chainable

//~ Begin Wrapped Interface
void _get_property_list(List<PropertyInfo>* r_list) const;
Expand Down

0 comments on commit 57ce555

Please sign in to comment.