diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2022-08-24 12:05:37 +0200 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2022-08-24 12:08:17 +0200 |
commit | b1f392c25e214b331f87737d9e27aad30e95f201 (patch) | |
tree | 2a9b5071d74546fd23c28a3736f13e878f4c8bcc | |
parent | 0626ce50cfd35d1eb81c6c9627f8540be9636b4b (diff) |
Remove VisualScript module for 4.0
As announced in https://godotengine.org/article/godot-4-will-discontinue-visual-scripting,
Godot maintainers have agreed to discontinue the current implementation of
our VisualScript language.
The way it had been designed was not user-friendly enough and we did not
succeed in improving its usability to actually make it a good low-code
solution for users who need one.
So we prefer to remove it for Godot 4.0 and leave the door open for new,
innovative ideas around visual scripting, to be developed as plugins or
extensions now that Godot provides sufficient functionality for this
(notably via GDExtension and the godot-cpp C++ bindings).
The current module has been moved to a dedicated repository (with full Git
history extracted with `git filter-branch`):
https://github.com/godotengine/godot-visual-script
It can still be compiled as a C++ module (for now, but will likely require
work to be kept in sync with the engine repository), but our hope is that
contributors will port it to GDExtension (which is quite compatibile with
the existing C++ module code when using the godot-cpp C++ bindings).
77 files changed, 5 insertions, 25444 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 49355d2782..e5565e72ed 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -74,10 +74,10 @@ if your ZIP file isn't accepted by GitHub because it's too large. We recommend always attaching a minimal reproduction project, even if the issue may seem simple to reproduce manually. -**Note for C# users:** If your issue is not Mono-specific, please upload a -minimal reproduction project written in GDScript or VisualScript. +**Note for C# users:** If your issue is not .NET-specific, please upload a +minimal reproduction project written in GDScript. This will make it easier for contributors to reproduce the issue -locally as not everyone has a Mono setup available. +locally as not everyone has a .NET setup available. **If you've been asked by a maintainer to upload a minimal reproduction project, you *must* do so within 7 days.** Otherwise, your bug report will be closed as diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index 722177c9e8..5b08954875 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -1303,10 +1303,8 @@ <member name="TranslationServer" type="TranslationServer" setter="" getter=""> The [TranslationServer] singleton. </member> - <member name="VisualScriptCustomNodes" type="VisualScriptCustomNodes" setter="" getter=""> - The [VisualScriptCustomNodes] singleton. - </member> <member name="WorkerThreadPool" type="WorkerThreadPool" setter="" getter=""> + The [WorkerThreadPool] singleton. </member> <member name="XRServer" type="XRServer" setter="" getter=""> The [XRServer] singleton. diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml index 5f9b6f7206..3c71a02a21 100644 --- a/doc/classes/Object.xml +++ b/doc/classes/Object.xml @@ -5,7 +5,7 @@ </brief_description> <description> Every class which is not a built-in type inherits from this class. - You can construct Objects from scripting languages, using [code]Object.new()[/code] in GDScript, [code]new Object[/code] in C#, or the "Construct Object" node in VisualScript. + You can construct Objects from scripting languages, using [code]Object.new()[/code] in GDScript, or [code]new Object[/code] in C#. Objects do not manage memory. If a class inherits from Object, you will have to delete instances of it manually. To do so, call the [method free] method from your script or delete the instance from C++. Some classes that extend Object add memory management. This is the case of [RefCounted], which counts references and deletes itself automatically when no longer referenced. [Node], another fundamental type, deletes all its children when freed from memory. Objects export properties, which are mainly useful for storage and editing, but not really so much in programming. Properties are exported in [method _get_property_list] and handled in [method _get] and [method _set]. However, scripting languages and C++ have simpler means to export them. diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 0cee71b613..a2e202b218 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -464,9 +464,6 @@ <member name="debug/settings/stdout/verbose_stdout" type="bool" setter="" getter="" default="false"> Print more information to standard output when running. It displays information such as memory leaks, which scenes and resources are being loaded, etc. This can also be enabled using the [code]--verbose[/code] or [code]-v[/code] command line argument, even on an exported project. See also [method OS.is_stdout_verbose] and [method @GlobalScope.print_verbose]. </member> - <member name="debug/settings/visual_script/max_call_stack" type="int" setter="" getter="" default="1024"> - Maximum call stack in visual scripting, to avoid infinite recursion. - </member> <member name="debug/shapes/collision/contact_color" type="Color" setter="" getter="" default="Color(1, 0.2, 0.1, 0.8)"> Color of the contact points between collision shapes, visible when "Visible Collision Shapes" is enabled in the Debug menu. </member> diff --git a/doc/classes/Variant.xml b/doc/classes/Variant.xml index 0d6fcd0ef5..6b384d6a77 100644 --- a/doc/classes/Variant.xml +++ b/doc/classes/Variant.xml @@ -23,7 +23,6 @@ [/codeblocks] Godot tracks all scripting API variables within Variants. Without even realizing it, you use Variants all the time. When a particular language enforces its own rules for keeping data typed, then that language is applying its own custom logic over the base Variant scripting API. - GDScript automatically wrap values in them. It keeps all data in plain Variants by default and then optionally enforces custom static typing rules on variable types. - - VisualScript tracks properties inside Variants as well, but it also uses static typing. The GUI interface enforces that properties have a particular type that doesn't change over time. - C# is statically typed, but uses the Mono [code]object[/code] type in place of Godot's Variant class when it needs to represent a dynamic value. [code]object[/code] is the Mono runtime's equivalent of the same concept. The global [method @GlobalScope.typeof] function returns the enumerated value of the Variant type stored in the current variable (see [enum Variant.Type]). [codeblocks] diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index de1776c0ea..a0c9ddb14b 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -49,7 +49,6 @@ #include "editor/find_in_files.h" #include "editor/node_dock.h" #include "editor/plugins/shader_editor_plugin.h" -#include "modules/visual_script/editor/visual_script_editor.h" #include "scene/main/window.h" #include "scene/scene_string_names.h" #include "script_text_editor.h" diff --git a/modules/visual_script/SCsub b/modules/visual_script/SCsub deleted file mode 100644 index b91cceae09..0000000000 --- a/modules/visual_script/SCsub +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python - -Import("env") -Import("env_modules") - -env_vs = env_modules.Clone() - -env_vs.add_source_files(env.modules_sources, "*.cpp") - -if env["tools"]: - env_vs.add_source_files(env.modules_sources, "editor/*.cpp") diff --git a/modules/visual_script/config.py b/modules/visual_script/config.py deleted file mode 100644 index e8990c43c8..0000000000 --- a/modules/visual_script/config.py +++ /dev/null @@ -1,63 +0,0 @@ -def can_build(env, platform): - return True - - -def configure(env): - pass - - -def get_doc_classes(): - return [ - "VisualScriptBasicTypeConstant", - "VisualScriptBuiltinFunc", - "VisualScriptClassConstant", - "VisualScriptComment", - "VisualScriptComposeArray", - "VisualScriptCondition", - "VisualScriptConstant", - "VisualScriptConstructor", - "VisualScriptCustomNode", - "VisualScriptCustomNodes", - "VisualScriptDeconstruct", - "VisualScriptEditor", - "VisualScriptEmitSignal", - "VisualScriptEngineSingleton", - "VisualScriptExpression", - "VisualScriptFunctionCall", - "VisualScriptFunctionState", - "VisualScriptFunction", - "VisualScriptGlobalConstant", - "VisualScriptIndexGet", - "VisualScriptIndexSet", - "VisualScriptInputAction", - "VisualScriptIterator", - "VisualScriptLists", - "VisualScriptLocalVarSet", - "VisualScriptLocalVar", - "VisualScriptMathConstant", - "VisualScriptNode", - "VisualScriptOperator", - "VisualScriptPreload", - "VisualScriptPropertyGet", - "VisualScriptPropertySet", - "VisualScriptResourcePath", - "VisualScriptReturn", - "VisualScriptSceneNode", - "VisualScriptSceneTree", - "VisualScriptSelect", - "VisualScriptSelf", - "VisualScriptSequence", - "VisualScriptSubCall", - "VisualScriptSwitch", - "VisualScriptTypeCast", - "VisualScriptVariableGet", - "VisualScriptVariableSet", - "VisualScriptWhile", - "VisualScript", - "VisualScriptYieldSignal", - "VisualScriptYield", - ] - - -def get_doc_path(): - return "doc_classes" diff --git a/modules/visual_script/doc_classes/VisualScript.xml b/modules/visual_script/doc_classes/VisualScript.xml deleted file mode 100644 index ff6b7a8b5f..0000000000 --- a/modules/visual_script/doc_classes/VisualScript.xml +++ /dev/null @@ -1,357 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScript" inherits="Script" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A script implemented in the Visual Script programming environment. - </brief_description> - <description> - A script implemented in the Visual Script programming environment. The script extends the functionality of all objects that instance it. - [method Object.set_script] extends an existing object, if that object's class matches one of the script's base classes. - You are most likely to use this class via the Visual Script editor or when writing plugins for it. - </description> - <tutorials> - <link title="VisualScript documentation index">$DOCS_URL/tutorials/scripting/visual_script/index.html</link> - </tutorials> - <methods> - <method name="add_custom_signal"> - <return type="void" /> - <param index="0" name="name" type="StringName" /> - <description> - Add a custom signal with the specified name to the VisualScript. - </description> - </method> - <method name="add_function"> - <return type="void" /> - <param index="0" name="name" type="StringName" /> - <param index="1" name="func_node_id" type="int" /> - <description> - Add a function with the specified name to the VisualScript, and assign the root [VisualScriptFunction] node's id as [code]func_node_id[/code]. - </description> - </method> - <method name="add_node"> - <return type="void" /> - <param index="0" name="id" type="int" /> - <param index="1" name="node" type="VisualScriptNode" /> - <param index="2" name="position" type="Vector2" default="Vector2(0, 0)" /> - <description> - Add a node to the VisualScript. - </description> - </method> - <method name="add_variable"> - <return type="void" /> - <param index="0" name="name" type="StringName" /> - <param index="1" name="default_value" type="Variant" default="null" /> - <param index="2" name="export" type="bool" default="false" /> - <description> - Add a variable to the VisualScript, optionally giving it a default value or marking it as exported. - </description> - </method> - <method name="custom_signal_add_argument"> - <return type="void" /> - <param index="0" name="name" type="StringName" /> - <param index="1" name="type" type="int" enum="Variant.Type" /> - <param index="2" name="argname" type="String" /> - <param index="3" name="index" type="int" default="-1" /> - <description> - Add an argument to a custom signal added with [method add_custom_signal]. - </description> - </method> - <method name="custom_signal_get_argument_count" qualifiers="const"> - <return type="int" /> - <param index="0" name="name" type="StringName" /> - <description> - Get the count of a custom signal's arguments. - </description> - </method> - <method name="custom_signal_get_argument_name" qualifiers="const"> - <return type="String" /> - <param index="0" name="name" type="StringName" /> - <param index="1" name="argidx" type="int" /> - <description> - Get the name of a custom signal's argument. - </description> - </method> - <method name="custom_signal_get_argument_type" qualifiers="const"> - <return type="int" enum="Variant.Type" /> - <param index="0" name="name" type="StringName" /> - <param index="1" name="argidx" type="int" /> - <description> - Get the type of a custom signal's argument. - </description> - </method> - <method name="custom_signal_remove_argument"> - <return type="void" /> - <param index="0" name="name" type="StringName" /> - <param index="1" name="argidx" type="int" /> - <description> - Remove a specific custom signal's argument. - </description> - </method> - <method name="custom_signal_set_argument_name"> - <return type="void" /> - <param index="0" name="name" type="StringName" /> - <param index="1" name="argidx" type="int" /> - <param index="2" name="argname" type="String" /> - <description> - Rename a custom signal's argument. - </description> - </method> - <method name="custom_signal_set_argument_type"> - <return type="void" /> - <param index="0" name="name" type="StringName" /> - <param index="1" name="argidx" type="int" /> - <param index="2" name="type" type="int" enum="Variant.Type" /> - <description> - Change the type of a custom signal's argument. - </description> - </method> - <method name="custom_signal_swap_argument"> - <return type="void" /> - <param index="0" name="name" type="StringName" /> - <param index="1" name="argidx" type="int" /> - <param index="2" name="withidx" type="int" /> - <description> - Swap two of the arguments of a custom signal. - </description> - </method> - <method name="data_connect"> - <return type="void" /> - <param index="0" name="from_node" type="int" /> - <param index="1" name="from_port" type="int" /> - <param index="2" name="to_node" type="int" /> - <param index="3" name="to_port" type="int" /> - <description> - Connect two data ports. The value of [code]from_node[/code]'s [code]from_port[/code] would be fed into [code]to_node[/code]'s [code]to_port[/code]. - </description> - </method> - <method name="data_disconnect"> - <return type="void" /> - <param index="0" name="from_node" type="int" /> - <param index="1" name="from_port" type="int" /> - <param index="2" name="to_node" type="int" /> - <param index="3" name="to_port" type="int" /> - <description> - Disconnect two data ports previously connected with [method data_connect]. - </description> - </method> - <method name="get_function_node_id" qualifiers="const"> - <return type="int" /> - <param index="0" name="name" type="StringName" /> - <description> - Returns the id of a function's entry point node. - </description> - </method> - <method name="get_node" qualifiers="const"> - <return type="VisualScriptNode" /> - <param index="0" name="id" type="int" /> - <description> - Returns a node given its id. - </description> - </method> - <method name="get_node_position" qualifiers="const"> - <return type="Vector2" /> - <param index="0" name="id" type="int" /> - <description> - Returns a node's position in pixels. - </description> - </method> - <method name="get_scroll" qualifiers="const"> - <return type="Vector2" /> - <description> - Returns the current position of the center of the screen. - </description> - </method> - <method name="get_variable_default_value" qualifiers="const"> - <return type="Variant" /> - <param index="0" name="name" type="StringName" /> - <description> - Returns the default (initial) value of a variable. - </description> - </method> - <method name="get_variable_export" qualifiers="const"> - <return type="bool" /> - <param index="0" name="name" type="StringName" /> - <description> - Returns whether a variable is exported. - </description> - </method> - <method name="get_variable_info" qualifiers="const"> - <return type="Dictionary" /> - <param index="0" name="name" type="StringName" /> - <description> - Returns the information for a given variable as a dictionary. The information includes its name, type, hint and usage. - </description> - </method> - <method name="has_custom_signal" qualifiers="const"> - <return type="bool" /> - <param index="0" name="name" type="StringName" /> - <description> - Returns whether a signal exists with the specified name. - </description> - </method> - <method name="has_data_connection" qualifiers="const"> - <return type="bool" /> - <param index="0" name="from_node" type="int" /> - <param index="1" name="from_port" type="int" /> - <param index="2" name="to_node" type="int" /> - <param index="3" name="to_port" type="int" /> - <description> - Returns whether the specified data ports are connected. - </description> - </method> - <method name="has_function" qualifiers="const"> - <return type="bool" /> - <param index="0" name="name" type="StringName" /> - <description> - Returns whether a function exists with the specified name. - </description> - </method> - <method name="has_node" qualifiers="const"> - <return type="bool" /> - <param index="0" name="id" type="int" /> - <description> - Returns whether a node exists with the given id. - </description> - </method> - <method name="has_sequence_connection" qualifiers="const"> - <return type="bool" /> - <param index="0" name="from_node" type="int" /> - <param index="1" name="from_output" type="int" /> - <param index="2" name="to_node" type="int" /> - <description> - Returns whether the specified sequence ports are connected. - </description> - </method> - <method name="has_variable" qualifiers="const"> - <return type="bool" /> - <param index="0" name="name" type="StringName" /> - <description> - Returns whether a variable exists with the specified name. - </description> - </method> - <method name="remove_custom_signal"> - <return type="void" /> - <param index="0" name="name" type="StringName" /> - <description> - Remove a custom signal with the given name. - </description> - </method> - <method name="remove_function"> - <return type="void" /> - <param index="0" name="name" type="StringName" /> - <description> - Remove a specific function and its nodes from the script. - </description> - </method> - <method name="remove_node"> - <return type="void" /> - <param index="0" name="id" type="int" /> - <description> - Remove the node with the specified id. - </description> - </method> - <method name="remove_variable"> - <return type="void" /> - <param index="0" name="name" type="StringName" /> - <description> - Remove a variable with the given name. - </description> - </method> - <method name="rename_custom_signal"> - <return type="void" /> - <param index="0" name="name" type="StringName" /> - <param index="1" name="new_name" type="StringName" /> - <description> - Change the name of a custom signal. - </description> - </method> - <method name="rename_function"> - <return type="void" /> - <param index="0" name="name" type="StringName" /> - <param index="1" name="new_name" type="StringName" /> - <description> - Change the name of a function. - </description> - </method> - <method name="rename_variable"> - <return type="void" /> - <param index="0" name="name" type="StringName" /> - <param index="1" name="new_name" type="StringName" /> - <description> - Change the name of a variable. - </description> - </method> - <method name="sequence_connect"> - <return type="void" /> - <param index="0" name="from_node" type="int" /> - <param index="1" name="from_output" type="int" /> - <param index="2" name="to_node" type="int" /> - <description> - Connect two sequence ports. The execution will flow from of [code]from_node[/code]'s [code]from_output[/code] into [code]to_node[/code]. - Unlike [method data_connect], there isn't a [code]to_port[/code], since the target node can have only one sequence port. - </description> - </method> - <method name="sequence_disconnect"> - <return type="void" /> - <param index="0" name="from_node" type="int" /> - <param index="1" name="from_output" type="int" /> - <param index="2" name="to_node" type="int" /> - <description> - Disconnect two sequence ports previously connected with [method sequence_connect]. - </description> - </method> - <method name="set_instance_base_type"> - <return type="void" /> - <param index="0" name="type" type="StringName" /> - <description> - Set the base type of the script. - </description> - </method> - <method name="set_node_position"> - <return type="void" /> - <param index="0" name="id" type="int" /> - <param index="1" name="position" type="Vector2" /> - <description> - Set the node position in the VisualScript graph. - </description> - </method> - <method name="set_scroll"> - <return type="void" /> - <param index="0" name="offset" type="Vector2" /> - <description> - Set the screen center to the given position. - </description> - </method> - <method name="set_variable_default_value"> - <return type="void" /> - <param index="0" name="name" type="StringName" /> - <param index="1" name="value" type="Variant" /> - <description> - Change the default (initial) value of a variable. - </description> - </method> - <method name="set_variable_export"> - <return type="void" /> - <param index="0" name="name" type="StringName" /> - <param index="1" name="enable" type="bool" /> - <description> - Change whether a variable is exported. - </description> - </method> - <method name="set_variable_info"> - <return type="void" /> - <param index="0" name="name" type="StringName" /> - <param index="1" name="value" type="Dictionary" /> - <description> - Set a variable's info, using the same format as [method get_variable_info]. - </description> - </method> - </methods> - <signals> - <signal name="node_ports_changed"> - <param index="0" name="id" type="int" /> - <description> - Emitted when the ports of a node are changed. - </description> - </signal> - </signals> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml b/modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml deleted file mode 100644 index 0ed66f44e1..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptBasicTypeConstant" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A Visual Script node representing a constant from the base types. - </brief_description> - <description> - A Visual Script node representing a constant from base types, such as [constant Vector3.AXIS_X]. - </description> - <tutorials> - </tutorials> - <members> - <member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" enum="Variant.Type" default="0"> - The type to get the constant from. - </member> - <member name="constant" type="StringName" setter="set_basic_type_constant" getter="get_basic_type_constant"> - The name of the constant to return. - </member> - </members> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml deleted file mode 100644 index 647b627d25..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml +++ /dev/null @@ -1,221 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptBuiltinFunc" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A Visual Script node used to call built-in functions. - </brief_description> - <description> - A built-in function used inside a [VisualScript]. It is usually a math function or an utility function. - See also [@GDScript], for the same functions in the GDScript language. - </description> - <tutorials> - </tutorials> - <members> - <member name="function" type="int" setter="set_func" getter="get_func" enum="VisualScriptBuiltinFunc.BuiltinFunc" default="0"> - The function to be executed. - </member> - </members> - <constants> - <constant name="MATH_SIN" value="0" enum="BuiltinFunc"> - Returns the sine of the input. - </constant> - <constant name="MATH_COS" value="1" enum="BuiltinFunc"> - Returns the cosine of the input. - </constant> - <constant name="MATH_TAN" value="2" enum="BuiltinFunc"> - Returns the tangent of the input. - </constant> - <constant name="MATH_SINH" value="3" enum="BuiltinFunc"> - Returns the hyperbolic sine of the input. - </constant> - <constant name="MATH_COSH" value="4" enum="BuiltinFunc"> - Returns the hyperbolic cosine of the input. - </constant> - <constant name="MATH_TANH" value="5" enum="BuiltinFunc"> - Returns the hyperbolic tangent of the input. - </constant> - <constant name="MATH_ASIN" value="6" enum="BuiltinFunc"> - Returns the arc sine of the input. - </constant> - <constant name="MATH_ACOS" value="7" enum="BuiltinFunc"> - Returns the arc cosine of the input. - </constant> - <constant name="MATH_ATAN" value="8" enum="BuiltinFunc"> - Returns the arc tangent of the input. - </constant> - <constant name="MATH_ATAN2" value="9" enum="BuiltinFunc"> - Returns the arc tangent of the input, using the signs of both parameters to determine the exact angle. - </constant> - <constant name="MATH_SQRT" value="10" enum="BuiltinFunc"> - Returns the square root of the input. - </constant> - <constant name="MATH_FMOD" value="11" enum="BuiltinFunc"> - Returns the remainder of one input divided by the other, using floating-point numbers. - </constant> - <constant name="MATH_FPOSMOD" value="12" enum="BuiltinFunc"> - Returns the positive remainder of one input divided by the other, using floating-point numbers. - </constant> - <constant name="MATH_FLOOR" value="13" enum="BuiltinFunc"> - Returns the input rounded down. - </constant> - <constant name="MATH_CEIL" value="14" enum="BuiltinFunc"> - Returns the input rounded up. - </constant> - <constant name="MATH_ROUND" value="15" enum="BuiltinFunc"> - Returns the input rounded to the nearest integer. - </constant> - <constant name="MATH_ABS" value="16" enum="BuiltinFunc"> - Returns the absolute value of the input. - </constant> - <constant name="MATH_SIGN" value="17" enum="BuiltinFunc"> - Returns the sign of the input, turning it into 1, -1, or 0. Useful to determine if the input is positive or negative. - </constant> - <constant name="MATH_POW" value="18" enum="BuiltinFunc"> - Returns the input raised to a given power. - </constant> - <constant name="MATH_LOG" value="19" enum="BuiltinFunc"> - Returns the natural logarithm of the input. Note that this is not the typical base-10 logarithm function calculators use. - </constant> - <constant name="MATH_EXP" value="20" enum="BuiltinFunc"> - Returns the mathematical constant [b]e[/b] raised to the specified power of the input. [b]e[/b] has an approximate value of 2.71828. - </constant> - <constant name="MATH_ISNAN" value="21" enum="BuiltinFunc"> - Returns whether the input is NaN (Not a Number) or not. NaN is usually produced by dividing 0 by 0, though other ways exist. - </constant> - <constant name="MATH_ISINF" value="22" enum="BuiltinFunc"> - Returns whether the input is an infinite floating-point number or not. Infinity is usually produced by dividing a number by 0, though other ways exist. - </constant> - <constant name="MATH_EASE" value="23" enum="BuiltinFunc"> - Easing function, based on exponent. 0 is constant, 1 is linear, 0 to 1 is ease-in, 1+ is ease out. Negative values are in-out/out in. - </constant> - <constant name="MATH_STEP_DECIMALS" value="24" enum="BuiltinFunc"> - Returns the number of digit places after the decimal that the first non-zero digit occurs. - </constant> - <constant name="MATH_SNAPPED" value="25" enum="BuiltinFunc"> - Returns the input snapped to a given step. - </constant> - <constant name="MATH_LERP" value="26" enum="BuiltinFunc"> - Returns a number linearly interpolated between the first two inputs, based on the third input. Uses the formula [code]a + (a - b) * t[/code]. - </constant> - <constant name="MATH_CUBIC_INTERPOLATE" value="27" enum="BuiltinFunc"> - </constant> - <constant name="MATH_INVERSE_LERP" value="28" enum="BuiltinFunc"> - </constant> - <constant name="MATH_RANGE_LERP" value="29" enum="BuiltinFunc"> - </constant> - <constant name="MATH_MOVE_TOWARD" value="30" enum="BuiltinFunc"> - Moves the number toward a value, based on the third input. - </constant> - <constant name="MATH_RANDOMIZE" value="31" enum="BuiltinFunc"> - Randomize the seed (or the internal state) of the random number generator. Current implementation reseeds using a number based on time. - </constant> - <constant name="MATH_RANDI" value="32" enum="BuiltinFunc"> - Returns a random 32 bits integer value. To obtain a random value between 0 to N (where N is smaller than 2^32 - 1), you can use it with the remainder function. - </constant> - <constant name="MATH_RANDF" value="33" enum="BuiltinFunc"> - Returns a random floating-point value between 0 and 1. To obtain a random value between 0 to N, you can use it with multiplication. - </constant> - <constant name="MATH_RANDI_RANGE" value="34" enum="BuiltinFunc"> - Returns a random 32-bit integer value between the two inputs. - </constant> - <constant name="MATH_RANDF_RANGE" value="35" enum="BuiltinFunc"> - Returns a random floating-point value between the two inputs. - </constant> - <constant name="MATH_RANDFN" value="36" enum="BuiltinFunc"> - Returns a normally-distributed pseudo-random number, using Box-Muller transform with the specified mean and a standard deviation. This is also called Gaussian distribution. - </constant> - <constant name="MATH_SEED" value="37" enum="BuiltinFunc"> - Set the seed for the random number generator. - </constant> - <constant name="MATH_RANDSEED" value="38" enum="BuiltinFunc"> - Returns a random value from the given seed, along with the new seed. - </constant> - <constant name="MATH_DEG2RAD" value="39" enum="BuiltinFunc"> - Convert the input from degrees to radians. - </constant> - <constant name="MATH_RAD2DEG" value="40" enum="BuiltinFunc"> - Convert the input from radians to degrees. - </constant> - <constant name="MATH_LINEAR2DB" value="41" enum="BuiltinFunc"> - Convert the input from linear volume to decibel volume. - </constant> - <constant name="MATH_DB2LINEAR" value="42" enum="BuiltinFunc"> - Convert the input from decibel volume to linear volume. - </constant> - <constant name="MATH_WRAP" value="43" enum="BuiltinFunc"> - </constant> - <constant name="MATH_WRAPF" value="44" enum="BuiltinFunc"> - </constant> - <constant name="MATH_PINGPONG" value="45" enum="BuiltinFunc"> - Returns the [code]value[/code] wrapped between [code]0[/code] and the [code]length[/code]. If the limit is reached, the next value the function returned is decreased to the [code]0[/code] side or increased to the [code]length[/code] side (like a triangle wave). If [code]length[/code] is less than zero, it becomes positive. - </constant> - <constant name="LOGIC_MAX" value="46" enum="BuiltinFunc"> - Returns the greater of the two numbers, also known as their maximum. - </constant> - <constant name="LOGIC_MIN" value="47" enum="BuiltinFunc"> - Returns the lesser of the two numbers, also known as their minimum. - </constant> - <constant name="LOGIC_CLAMP" value="48" enum="BuiltinFunc"> - Returns the input clamped inside the given range, ensuring the result is never outside it. Equivalent to [code]min(max(input, range_low), range_high)[/code]. - </constant> - <constant name="LOGIC_NEAREST_PO2" value="49" enum="BuiltinFunc"> - Returns the nearest power of 2 to the input. - </constant> - <constant name="OBJ_WEAKREF" value="50" enum="BuiltinFunc"> - Create a [WeakRef] from the input. - </constant> - <constant name="TYPE_CONVERT" value="51" enum="BuiltinFunc"> - Convert between types. - </constant> - <constant name="TYPE_OF" value="52" enum="BuiltinFunc"> - Returns the type of the input as an integer. Check [enum Variant.Type] for the integers that might be returned. - </constant> - <constant name="TYPE_EXISTS" value="53" enum="BuiltinFunc"> - Checks if a type is registered in the [ClassDB]. - </constant> - <constant name="TEXT_CHAR" value="54" enum="BuiltinFunc"> - Returns a character with the given ascii value. - </constant> - <constant name="TEXT_STR" value="55" enum="BuiltinFunc"> - Convert the input to a string. - </constant> - <constant name="TEXT_PRINT" value="56" enum="BuiltinFunc"> - Print the given string to the output window. - </constant> - <constant name="TEXT_PRINTERR" value="57" enum="BuiltinFunc"> - Print the given string to the standard error output. - </constant> - <constant name="TEXT_PRINTRAW" value="58" enum="BuiltinFunc"> - Print the given string to the standard output, without adding a newline. - </constant> - <constant name="TEXT_PRINT_VERBOSE" value="59" enum="BuiltinFunc"> - </constant> - <constant name="VAR_TO_STR" value="60" enum="BuiltinFunc"> - Serialize a [Variant] to a string. - </constant> - <constant name="STR_TO_VAR" value="61" enum="BuiltinFunc"> - Deserialize a [Variant] from a string serialized using [constant VAR_TO_STR]. - </constant> - <constant name="VAR_TO_BYTES" value="62" enum="BuiltinFunc"> - Serialize a [Variant] to a [PackedByteArray]. - </constant> - <constant name="BYTES_TO_VAR" value="63" enum="BuiltinFunc"> - Deserialize a [Variant] from a [PackedByteArray] serialized using [constant VAR_TO_BYTES]. - </constant> - <constant name="MATH_SMOOTHSTEP" value="64" enum="BuiltinFunc"> - Returns a number smoothly interpolated between the first two inputs, based on the third input. Similar to [constant MATH_LERP], but interpolates faster at the beginning and slower at the end. Using Hermite interpolation formula: - [codeblock] - var t = clamp((weight - from) / (to - from), 0.0, 1.0) - return t * t * (3.0 - 2.0 * t) - [/codeblock] - </constant> - <constant name="MATH_POSMOD" value="65" enum="BuiltinFunc"> - </constant> - <constant name="MATH_LERP_ANGLE" value="66" enum="BuiltinFunc"> - </constant> - <constant name="TEXT_ORD" value="67" enum="BuiltinFunc"> - </constant> - <constant name="FUNC_MAX" value="68" enum="BuiltinFunc"> - Represents the size of the [enum BuiltinFunc] enum. - </constant> - </constants> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptClassConstant.xml b/modules/visual_script/doc_classes/VisualScriptClassConstant.xml deleted file mode 100644 index 2509084f0e..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptClassConstant.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptClassConstant" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - Gets a constant from a given class. - </brief_description> - <description> - This node returns a constant from a given class, such as [constant TYPE_INT]. See the given class' documentation for available constants. - [b]Input Ports:[/b] - none - [b]Output Ports:[/b] - - Data (variant): [code]value[/code] - </description> - <tutorials> - </tutorials> - <members> - <member name="base_type" type="StringName" setter="set_base_type" getter="get_base_type" default="&"Object""> - The constant's parent class. - </member> - <member name="constant" type="StringName" setter="set_class_constant" getter="get_class_constant" default="&"""> - The constant to return. See the given class for its available constants. - </member> - </members> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptComment.xml b/modules/visual_script/doc_classes/VisualScriptComment.xml deleted file mode 100644 index cf4b57ca19..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptComment.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptComment" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A Visual Script node used to annotate the script. - </brief_description> - <description> - A Visual Script node used to display annotations in the script, so that code may be documented. - Comment nodes can be resized so they encompass a group of nodes. - </description> - <tutorials> - </tutorials> - <members> - <member name="description" type="String" setter="set_description" getter="get_description" default=""""> - The text inside the comment node. - </member> - <member name="size" type="Vector2" setter="set_size" getter="get_size" default="Vector2(150, 150)"> - The comment node's size (in pixels). - </member> - <member name="title" type="String" setter="set_title" getter="get_title" default=""Comment""> - The comment node's title. - </member> - </members> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptComposeArray.xml b/modules/visual_script/doc_classes/VisualScriptComposeArray.xml deleted file mode 100644 index ea73867c4b..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptComposeArray.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptComposeArray" inherits="VisualScriptLists" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A Visual Script Node used to create array from a list of items. - </brief_description> - <description> - A Visual Script Node used to compose array from the list of elements provided with custom in-graph UI hard coded in the VisualScript Editor. - </description> - <tutorials> - </tutorials> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptCondition.xml b/modules/visual_script/doc_classes/VisualScriptCondition.xml deleted file mode 100644 index a29388569f..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptCondition.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptCondition" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A Visual Script node which branches the flow. - </brief_description> - <description> - A Visual Script node that checks a [bool] input port. If [code]true[/code], it will exit via the "true" sequence port. If [code]false[/code], it will exit via the "false" sequence port. After exiting either, it exits via the "done" port. Sequence ports may be left disconnected. - [b]Input Ports:[/b] - - Sequence: [code]if (cond) is[/code] - - Data (boolean): [code]cond[/code] - [b]Output Ports:[/b] - - Sequence: [code]true[/code] - - Sequence: [code]false[/code] - - Sequence: [code]done[/code] - </description> - <tutorials> - </tutorials> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptConstant.xml b/modules/visual_script/doc_classes/VisualScriptConstant.xml deleted file mode 100644 index 645ede9001..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptConstant.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptConstant" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - Gets a contant's value. - </brief_description> - <description> - This node returns a constant's value. - [b]Input Ports:[/b] - none - [b]Output Ports:[/b] - - Data (variant): [code]get[/code] - </description> - <tutorials> - </tutorials> - <members> - <member name="type" type="int" setter="set_constant_type" getter="get_constant_type" enum="Variant.Type" default="0"> - The constant's type. - </member> - <member name="value" type="Variant" setter="set_constant_value" getter="get_constant_value"> - The constant's value. - </member> - </members> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptConstructor.xml b/modules/visual_script/doc_classes/VisualScriptConstructor.xml deleted file mode 100644 index a003f21ab9..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptConstructor.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptConstructor" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A Visual Script node which calls a base type constructor. - </brief_description> - <description> - A Visual Script node which calls a base type constructor. It can be used for type conversion as well. - </description> - <tutorials> - </tutorials> - <methods> - <method name="get_constructor" qualifiers="const"> - <return type="Dictionary" /> - <description> - </description> - </method> - <method name="get_constructor_type" qualifiers="const"> - <return type="int" enum="Variant.Type" /> - <description> - </description> - </method> - <method name="set_constructor"> - <return type="void" /> - <param index="0" name="constructor" type="Dictionary" /> - <description> - </description> - </method> - <method name="set_constructor_type"> - <return type="void" /> - <param index="0" name="type" type="int" enum="Variant.Type" /> - <description> - </description> - </method> - </methods> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptCustomNode.xml b/modules/visual_script/doc_classes/VisualScriptCustomNode.xml deleted file mode 100644 index 6e522b2f84..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptCustomNode.xml +++ /dev/null @@ -1,166 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptCustomNode" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A scripted Visual Script node. - </brief_description> - <description> - A custom Visual Script node which can be scripted in powerful ways. - </description> - <tutorials> - </tutorials> - <methods> - <method name="_get_caption" qualifiers="virtual const"> - <return type="String" /> - <description> - Returns the node's title. - </description> - </method> - <method name="_get_category" qualifiers="virtual const"> - <return type="String" /> - <description> - Returns the node's category. - </description> - </method> - <method name="_get_input_value_port_count" qualifiers="virtual const"> - <return type="int" /> - <description> - Returns the count of input value ports. - </description> - </method> - <method name="_get_input_value_port_hint" qualifiers="virtual const"> - <return type="int" /> - <param index="0" name="input_idx" type="int" /> - <description> - Returns the specified input port's hint. See the [enum @GlobalScope.PropertyHint] hints. - </description> - </method> - <method name="_get_input_value_port_hint_string" qualifiers="virtual const"> - <return type="String" /> - <param index="0" name="input_idx" type="int" /> - <description> - Returns the specified input port's hint string. - </description> - </method> - <method name="_get_input_value_port_name" qualifiers="virtual const"> - <return type="String" /> - <param index="0" name="input_idx" type="int" /> - <description> - Returns the specified input port's name. - </description> - </method> - <method name="_get_input_value_port_type" qualifiers="virtual const"> - <return type="int" /> - <param index="0" name="input_idx" type="int" /> - <description> - Returns the specified input port's type. See the [enum Variant.Type] values. - </description> - </method> - <method name="_get_output_sequence_port_count" qualifiers="virtual const"> - <return type="int" /> - <description> - Returns the amount of output [b]sequence[/b] ports. - </description> - </method> - <method name="_get_output_sequence_port_text" qualifiers="virtual const"> - <return type="String" /> - <param index="0" name="seq_idx" type="int" /> - <description> - Returns the specified [b]sequence[/b] output's name. - </description> - </method> - <method name="_get_output_value_port_count" qualifiers="virtual const"> - <return type="int" /> - <description> - Returns the amount of output value ports. - </description> - </method> - <method name="_get_output_value_port_hint" qualifiers="virtual const"> - <return type="int" /> - <param index="0" name="output_idx" type="int" /> - <description> - Returns the specified output port's hint. See the [enum @GlobalScope.PropertyHint] hints. - </description> - </method> - <method name="_get_output_value_port_hint_string" qualifiers="virtual const"> - <return type="String" /> - <param index="0" name="output_idx" type="int" /> - <description> - Returns the specified output port's hint string. - </description> - </method> - <method name="_get_output_value_port_name" qualifiers="virtual const"> - <return type="String" /> - <param index="0" name="output_idx" type="int" /> - <description> - Returns the specified output port's name. - </description> - </method> - <method name="_get_output_value_port_type" qualifiers="virtual const"> - <return type="int" /> - <param index="0" name="output_idx" type="int" /> - <description> - Returns the specified output port's type. See the [enum Variant.Type] values. - </description> - </method> - <method name="_get_text" qualifiers="virtual const"> - <return type="String" /> - <description> - Returns the custom node's text, which is shown right next to the input [b]sequence[/b] port (if there is none, on the place that is usually taken by it). - </description> - </method> - <method name="_get_working_memory_size" qualifiers="virtual const"> - <return type="int" /> - <description> - Returns the size of the custom node's working memory. See [method _step] for more details. - </description> - </method> - <method name="_has_input_sequence_port" qualifiers="virtual const"> - <return type="bool" /> - <description> - Returns whether the custom node has an input [b]sequence[/b] port. - </description> - </method> - <method name="_step" qualifiers="virtual const"> - <return type="Variant" /> - <param index="0" name="inputs" type="Array" /> - <param index="1" name="outputs" type="Array" /> - <param index="2" name="start_mode" type="int" /> - <param index="3" name="working_mem" type="Array" /> - <description> - Execute the custom node's logic, returning the index of the output sequence port to use or a [String] when there is an error. - The [code]inputs[/code] array contains the values of the input ports. - [code]outputs[/code] is an array whose indices should be set to the respective outputs. - The [code]start_mode[/code] is usually [constant START_MODE_BEGIN_SEQUENCE], unless you have used the [code]STEP_*[/code] constants. - [code]working_mem[/code] is an array which can be used to persist information between runs of the custom node. The size needs to be predefined using [method _get_working_memory_size]. - When returning, you can mask the returned value with one of the [code]STEP_*[/code] constants. - </description> - </method> - </methods> - <constants> - <constant name="START_MODE_BEGIN_SEQUENCE" value="0" enum="StartMode"> - The start mode used the first time when [method _step] is called. - </constant> - <constant name="START_MODE_CONTINUE_SEQUENCE" value="1" enum="StartMode"> - The start mode used when [method _step] is called after coming back from a [constant STEP_PUSH_STACK_BIT]. - </constant> - <constant name="START_MODE_RESUME_YIELD" value="2" enum="StartMode"> - The start mode used when [method _step] is called after resuming from [constant STEP_YIELD_BIT]. - </constant> - <constant name="STEP_PUSH_STACK_BIT" value="16777216"> - Hint used by [method _step] to tell that control should return to it when there is no other node left to execute. - This is used by [VisualScriptCondition] to redirect the sequence to the "Done" port after the [code]true[/code]/[code]false[/code] branch has finished execution. - </constant> - <constant name="STEP_GO_BACK_BIT" value="33554432"> - Hint used by [method _step] to tell that control should return back, either hitting a previous [constant STEP_PUSH_STACK_BIT] or exiting the function. - </constant> - <constant name="STEP_NO_ADVANCE_BIT" value="67108864"> - </constant> - <constant name="STEP_EXIT_FUNCTION_BIT" value="134217728"> - Hint used by [method _step] to tell that control should stop and exit the function. - </constant> - <constant name="STEP_YIELD_BIT" value="268435456"> - Hint used by [method _step] to tell that the function should be yielded. - Using this requires you to have at least one working memory slot, which is used for the [VisualScriptFunctionState]. - </constant> - </constants> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptCustomNodes.xml b/modules/visual_script/doc_classes/VisualScriptCustomNodes.xml deleted file mode 100644 index 48d7975051..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptCustomNodes.xml +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptCustomNodes" inherits="Object" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - Manages custom nodes for the Visual Script editor. - </brief_description> - <description> - This singleton can be used to manage (i.e., add or remove) custom nodes for the Visual Script editor. - </description> - <tutorials> - </tutorials> - <methods> - <method name="add_custom_node"> - <return type="void" /> - <param index="0" name="name" type="String" /> - <param index="1" name="category" type="String" /> - <param index="2" name="script" type="Script" /> - <description> - Add a custom Visual Script node to the editor. It'll be placed under "Custom Nodes" with the [code]category[/code] as the parameter. - </description> - </method> - <method name="remove_custom_node"> - <return type="void" /> - <param index="0" name="name" type="String" /> - <param index="1" name="category" type="String" /> - <description> - Remove a custom Visual Script node from the editor. Custom nodes already placed on scripts won't be removed. - </description> - </method> - </methods> - <signals> - <signal name="custom_nodes_updated"> - <description> - Emitted when a custom Visual Script node is added or removed. - </description> - </signal> - </signals> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptDeconstruct.xml b/modules/visual_script/doc_classes/VisualScriptDeconstruct.xml deleted file mode 100644 index b544fd9d90..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptDeconstruct.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptDeconstruct" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A Visual Script node which deconstructs a base type instance into its parts. - </brief_description> - <description> - A Visual Script node which deconstructs a base type instance into its parts. - </description> - <tutorials> - </tutorials> - <members> - <member name="type" type="int" setter="set_deconstruct_type" getter="get_deconstruct_type" enum="Variant.Type" default="0"> - The type to deconstruct. - </member> - </members> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptEmitSignal.xml b/modules/visual_script/doc_classes/VisualScriptEmitSignal.xml deleted file mode 100644 index c0cefa0ab7..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptEmitSignal.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptEmitSignal" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - Emits a specified signal. - </brief_description> - <description> - Emits a specified signal when it is executed. - [b]Input Ports:[/b] - - Sequence: [code]emit[/code] - [b]Output Ports:[/b] - - Sequence - </description> - <tutorials> - </tutorials> - <members> - <member name="signal" type="StringName" setter="set_signal" getter="get_signal" default="&"""> - The signal to emit. - </member> - </members> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptEngineSingleton.xml b/modules/visual_script/doc_classes/VisualScriptEngineSingleton.xml deleted file mode 100644 index f60a048845..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptEngineSingleton.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptEngineSingleton" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A Visual Script node returning a singleton from [@GlobalScope]. - </brief_description> - <description> - A Visual Script node returning a singleton from [@GlobalScope]. - </description> - <tutorials> - </tutorials> - <members> - <member name="constant" type="String" setter="set_singleton" getter="get_singleton" default=""""> - The singleton's name. - </member> - </members> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptExpression.xml b/modules/visual_script/doc_classes/VisualScriptExpression.xml deleted file mode 100644 index 14750e7c8d..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptExpression.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptExpression" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A Visual Script node that can execute a custom expression. - </brief_description> - <description> - A Visual Script node that can execute a custom expression. Values can be provided for the input and the expression result can be retrieved from the output. - </description> - <tutorials> - </tutorials> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptFunction.xml b/modules/visual_script/doc_classes/VisualScriptFunction.xml deleted file mode 100644 index 74d9f194eb..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptFunction.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptFunction" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A Visual Script node representing a function. - </brief_description> - <description> - [VisualScriptFunction] represents a function header. It is the starting point for the function body and can be used to tweak the function's properties (e.g. RPC mode). - </description> - <tutorials> - </tutorials> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptFunctionCall.xml b/modules/visual_script/doc_classes/VisualScriptFunctionCall.xml deleted file mode 100644 index 543263ff8e..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptFunctionCall.xml +++ /dev/null @@ -1,75 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptFunctionCall" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A Visual Script node for calling a function. - </brief_description> - <description> - [VisualScriptFunctionCall] is created when you add or drag and drop a function onto the Visual Script graph. It allows to tweak parameters of the call, e.g. what object the function is called on. - </description> - <tutorials> - </tutorials> - <members> - <member name="base_script" type="String" setter="set_base_script" getter="get_base_script"> - The script to be used when [member call_mode] is set to [constant CALL_MODE_INSTANCE]. - </member> - <member name="base_type" type="StringName" setter="set_base_type" getter="get_base_type" default="&"Object""> - The base type to be used when [member call_mode] is set to [constant CALL_MODE_INSTANCE]. - </member> - <member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" enum="Variant.Type"> - The type to be used when [member call_mode] is set to [constant CALL_MODE_BASIC_TYPE]. - </member> - <member name="call_mode" type="int" setter="set_call_mode" getter="get_call_mode" enum="VisualScriptFunctionCall.CallMode" default="0"> - [code]call_mode[/code] determines the target object on which the method will be called. See [enum CallMode] for options. - </member> - <member name="function" type="StringName" setter="set_function" getter="get_function" default="&"""> - The name of the function to be called. - </member> - <member name="node_path" type="NodePath" setter="set_base_path" getter="get_base_path"> - The node path to use when [member call_mode] is set to [constant CALL_MODE_NODE_PATH]. - </member> - <member name="rpc_call_mode" type="int" setter="set_rpc_call_mode" getter="get_rpc_call_mode" enum="VisualScriptFunctionCall.RPCCallMode" default="0"> - The mode for RPC calls. See [method Node.rpc] for more details and [enum RPCCallMode] for available options. - </member> - <member name="singleton" type="StringName" setter="set_singleton" getter="get_singleton"> - The singleton to call the method on. Used when [member call_mode] is set to [constant CALL_MODE_SINGLETON]. - </member> - <member name="use_default_args" type="int" setter="set_use_default_args" getter="get_use_default_args"> - Number of default arguments that will be used when calling the function. Can't be higher than the number of available default arguments in the method's declaration. - </member> - <member name="validate" type="bool" setter="set_validate" getter="get_validate" default="true"> - If [code]false[/code], call errors (e.g. wrong number of arguments) will be ignored. - </member> - </members> - <constants> - <constant name="CALL_MODE_SELF" value="0" enum="CallMode"> - The method will be called on this [Object]. - </constant> - <constant name="CALL_MODE_NODE_PATH" value="1" enum="CallMode"> - The method will be called on the given [Node] in the scene tree. - </constant> - <constant name="CALL_MODE_INSTANCE" value="2" enum="CallMode"> - The method will be called on an instanced node with the given type and script. - </constant> - <constant name="CALL_MODE_BASIC_TYPE" value="3" enum="CallMode"> - The method will be called on a GDScript basic type (e.g. [Vector2]). - </constant> - <constant name="CALL_MODE_SINGLETON" value="4" enum="CallMode"> - The method will be called on a singleton. - </constant> - <constant name="RPC_DISABLED" value="0" enum="RPCCallMode"> - The method will be called locally. - </constant> - <constant name="RPC_RELIABLE" value="1" enum="RPCCallMode"> - The method will be called remotely. - </constant> - <constant name="RPC_UNRELIABLE" value="2" enum="RPCCallMode"> - The method will be called remotely using an unreliable protocol. - </constant> - <constant name="RPC_RELIABLE_TO_ID" value="3" enum="RPCCallMode"> - The method will be called remotely for the given peer. - </constant> - <constant name="RPC_UNRELIABLE_TO_ID" value="4" enum="RPCCallMode"> - The method will be called remotely for the given peer, using an unreliable protocol. - </constant> - </constants> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptFunctionState.xml b/modules/visual_script/doc_classes/VisualScriptFunctionState.xml deleted file mode 100644 index 03fef9c13b..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptFunctionState.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptFunctionState" inherits="RefCounted" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A Visual Script node representing a function state. - </brief_description> - <description> - [VisualScriptFunctionState] is returned from [VisualScriptYield] and can be used to resume a paused function call. - </description> - <tutorials> - </tutorials> - <methods> - <method name="connect_to_signal"> - <return type="void" /> - <param index="0" name="obj" type="Object" /> - <param index="1" name="signals" type="String" /> - <param index="2" name="args" type="Array" /> - <description> - Connects this [VisualScriptFunctionState] to a signal in the given object to automatically resume when it's emitted. - </description> - </method> - <method name="is_valid" qualifiers="const"> - <return type="bool" /> - <description> - Returns whether the function state is valid. - </description> - </method> - <method name="resume"> - <return type="Variant" /> - <param index="0" name="args" type="Array" default="[]" /> - <description> - Resumes the function to run from the point it was yielded. - </description> - </method> - </methods> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptGlobalConstant.xml b/modules/visual_script/doc_classes/VisualScriptGlobalConstant.xml deleted file mode 100644 index 42ada99257..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptGlobalConstant.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptGlobalConstant" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A Visual Script node returning a constant from [@GlobalScope]. - </brief_description> - <description> - A Visual Script node returning a constant from [@GlobalScope]. - </description> - <tutorials> - </tutorials> - <members> - <member name="constant" type="int" setter="set_global_constant" getter="get_global_constant" default="0"> - The constant to be used. - </member> - </members> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptIndexGet.xml b/modules/visual_script/doc_classes/VisualScriptIndexGet.xml deleted file mode 100644 index 8828bf9039..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptIndexGet.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptIndexGet" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A Visual Script node for getting a value from an array or a dictionary. - </brief_description> - <description> - [VisualScriptIndexGet] will return the value stored in an array or a dictionary under the given index. - </description> - <tutorials> - </tutorials> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptIndexSet.xml b/modules/visual_script/doc_classes/VisualScriptIndexSet.xml deleted file mode 100644 index 5c81dcd339..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptIndexSet.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptIndexSet" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A Visual Script node for setting a value in an array or a dictionary. - </brief_description> - <description> - [VisualScriptIndexSet] will set the value stored in an array or a dictionary under the given index to the provided new value. - </description> - <tutorials> - </tutorials> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptInputAction.xml b/modules/visual_script/doc_classes/VisualScriptInputAction.xml deleted file mode 100644 index 51c2eaf353..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptInputAction.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptInputAction" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A Visual Script node returning a state of an action. - </brief_description> - <description> - [VisualScriptInputAction] can be used to check if an action is pressed or released. - </description> - <tutorials> - </tutorials> - <members> - <member name="action" type="StringName" setter="set_action_name" getter="get_action_name" default="&"""> - Name of the action. - </member> - <member name="mode" type="int" setter="set_action_mode" getter="get_action_mode" enum="VisualScriptInputAction.Mode" default="0"> - State of the action to check. See [enum Mode] for options. - </member> - </members> - <constants> - <constant name="MODE_PRESSED" value="0" enum="Mode"> - [code]True[/code] if action is pressed. - </constant> - <constant name="MODE_RELEASED" value="1" enum="Mode"> - [code]True[/code] if action is released (i.e. not pressed). - </constant> - <constant name="MODE_JUST_PRESSED" value="2" enum="Mode"> - [code]True[/code] on the frame the action was pressed. - </constant> - <constant name="MODE_JUST_RELEASED" value="3" enum="Mode"> - [code]True[/code] on the frame the action was released. - </constant> - </constants> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptIterator.xml b/modules/visual_script/doc_classes/VisualScriptIterator.xml deleted file mode 100644 index ef6846deba..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptIterator.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptIterator" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - Steps through items in a given input. - </brief_description> - <description> - This node steps through each item in a given input. Input can be any sequence data type, such as an [Array] or [String]. When each item has been processed, execution passed out the [code]exit[/code] Sequence port. - [b]Input Ports:[/b] - - Sequence: [code]for (elem) in (input)[/code] - - Data (variant): [code]input[/code] - [b]Output Ports:[/b] - - Sequence: [code]each[/code] - - Sequence: [code]exit[/code] - - Data (variant): [code]elem[/code] - </description> - <tutorials> - </tutorials> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptLists.xml b/modules/visual_script/doc_classes/VisualScriptLists.xml deleted file mode 100644 index 607965bf71..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptLists.xml +++ /dev/null @@ -1,77 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptLists" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A Visual Script virtual class for in-graph editable nodes. - </brief_description> - <description> - A Visual Script virtual class that defines the shape and the default behavior of the nodes that have to be in-graph editable nodes. - </description> - <tutorials> - </tutorials> - <methods> - <method name="add_input_data_port"> - <return type="void" /> - <param index="0" name="type" type="int" enum="Variant.Type" /> - <param index="1" name="name" type="String" /> - <param index="2" name="index" type="int" /> - <description> - Adds an input port to the Visual Script node. - </description> - </method> - <method name="add_output_data_port"> - <return type="void" /> - <param index="0" name="type" type="int" enum="Variant.Type" /> - <param index="1" name="name" type="String" /> - <param index="2" name="index" type="int" /> - <description> - Adds an output port to the Visual Script node. - </description> - </method> - <method name="remove_input_data_port"> - <return type="void" /> - <param index="0" name="index" type="int" /> - <description> - Removes an input port from the Visual Script node. - </description> - </method> - <method name="remove_output_data_port"> - <return type="void" /> - <param index="0" name="index" type="int" /> - <description> - Removes an output port from the Visual Script node. - </description> - </method> - <method name="set_input_data_port_name"> - <return type="void" /> - <param index="0" name="index" type="int" /> - <param index="1" name="name" type="String" /> - <description> - Sets the name of an input port. - </description> - </method> - <method name="set_input_data_port_type"> - <return type="void" /> - <param index="0" name="index" type="int" /> - <param index="1" name="type" type="int" enum="Variant.Type" /> - <description> - Sets the type of an input port. - </description> - </method> - <method name="set_output_data_port_name"> - <return type="void" /> - <param index="0" name="index" type="int" /> - <param index="1" name="name" type="String" /> - <description> - Sets the name of an output port. - </description> - </method> - <method name="set_output_data_port_type"> - <return type="void" /> - <param index="0" name="index" type="int" /> - <param index="1" name="type" type="int" enum="Variant.Type" /> - <description> - Sets the type of an output port. - </description> - </method> - </methods> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptLocalVar.xml b/modules/visual_script/doc_classes/VisualScriptLocalVar.xml deleted file mode 100644 index dbf9049f0a..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptLocalVar.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptLocalVar" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - Gets a local variable's value. - </brief_description> - <description> - Returns a local variable's value. "Var Name" must be supplied, with an optional type. - [b]Input Ports:[/b] - none - [b]Output Ports:[/b] - - Data (variant): [code]get[/code] - </description> - <tutorials> - </tutorials> - <members> - <member name="type" type="int" setter="set_var_type" getter="get_var_type" enum="Variant.Type" default="0"> - The local variable's type. - </member> - <member name="var_name" type="StringName" setter="set_var_name" getter="get_var_name" default="&"new_local""> - The local variable's name. - </member> - </members> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptLocalVarSet.xml b/modules/visual_script/doc_classes/VisualScriptLocalVarSet.xml deleted file mode 100644 index 1ae4e20f97..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptLocalVarSet.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptLocalVarSet" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - Changes a local variable's value. - </brief_description> - <description> - Changes a local variable's value to the given input. The new value is also provided on an output Data port. - [b]Input Ports:[/b] - - Sequence - - Data (variant): [code]set[/code] - [b]Output Ports:[/b] - - Sequence - - Data (variant): [code]get[/code] - </description> - <tutorials> - </tutorials> - <members> - <member name="type" type="int" setter="set_var_type" getter="get_var_type" enum="Variant.Type" default="0"> - The local variable's type. - </member> - <member name="var_name" type="StringName" setter="set_var_name" getter="get_var_name" default="&"new_local""> - The local variable's name. - </member> - </members> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptMathConstant.xml b/modules/visual_script/doc_classes/VisualScriptMathConstant.xml deleted file mode 100644 index 01c36e763b..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptMathConstant.xml +++ /dev/null @@ -1,49 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptMathConstant" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - Commonly used mathematical constants. - </brief_description> - <description> - Provides common math constants, such as Pi, on an output Data port. - [b]Input Ports:[/b] - none - [b]Output Ports:[/b] - - Data (variant): [code]get[/code] - </description> - <tutorials> - </tutorials> - <members> - <member name="constant" type="int" setter="set_math_constant" getter="get_math_constant" enum="VisualScriptMathConstant.MathConstant" default="0"> - The math constant. - </member> - </members> - <constants> - <constant name="MATH_CONSTANT_ONE" value="0" enum="MathConstant"> - Unity: [code]1[/code]. - </constant> - <constant name="MATH_CONSTANT_PI" value="1" enum="MathConstant"> - Pi: [code]3.141593[/code]. - </constant> - <constant name="MATH_CONSTANT_HALF_PI" value="2" enum="MathConstant"> - Pi divided by two: [code]1.570796[/code]. - </constant> - <constant name="MATH_CONSTANT_TAU" value="3" enum="MathConstant"> - Tau: [code]6.283185[/code]. - </constant> - <constant name="MATH_CONSTANT_E" value="4" enum="MathConstant"> - Mathematical constant [code]e[/code], the natural log base: [code]2.718282[/code]. - </constant> - <constant name="MATH_CONSTANT_SQRT2" value="5" enum="MathConstant"> - Square root of two: [code]1.414214[/code]. - </constant> - <constant name="MATH_CONSTANT_INF" value="6" enum="MathConstant"> - Infinity: [code]inf[/code]. - </constant> - <constant name="MATH_CONSTANT_NAN" value="7" enum="MathConstant"> - Not a number: [code]nan[/code]. - </constant> - <constant name="MATH_CONSTANT_MAX" value="8" enum="MathConstant"> - Represents the size of the [enum MathConstant] enum. - </constant> - </constants> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptNode.xml b/modules/visual_script/doc_classes/VisualScriptNode.xml deleted file mode 100644 index 97c4f8ce76..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptNode.xml +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptNode" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A node which is part of a [VisualScript]. - </brief_description> - <description> - A node which is part of a [VisualScript]. Not to be confused with [Node], which is a part of a [SceneTree]. - </description> - <tutorials> - </tutorials> - <methods> - <method name="get_default_input_value" qualifiers="const"> - <return type="Variant" /> - <param index="0" name="port_idx" type="int" /> - <description> - Returns the default value of a given port. The default value is used when nothing is connected to the port. - </description> - </method> - <method name="get_visual_script" qualifiers="const"> - <return type="VisualScript" /> - <description> - Returns the [VisualScript] instance the node is bound to. - </description> - </method> - <method name="ports_changed_notify"> - <return type="void" /> - <description> - Notify that the node's ports have changed. Usually used in conjunction with [VisualScriptCustomNode] . - </description> - </method> - <method name="set_default_input_value"> - <return type="void" /> - <param index="0" name="port_idx" type="int" /> - <param index="1" name="value" type="Variant" /> - <description> - Change the default value of a given port. - </description> - </method> - </methods> - <signals> - <signal name="ports_changed"> - <description> - Emitted when the available input/output ports are changed. - </description> - </signal> - </signals> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptOperator.xml b/modules/visual_script/doc_classes/VisualScriptOperator.xml deleted file mode 100644 index 47ca6ddb90..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptOperator.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptOperator" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A Visual Script node that performs an operation on two values. - </brief_description> - <description> - [b]Input Ports:[/b] - - Data (variant): [code]A[/code] - - Data (variant): [code]B[/code] - [b]Output Ports:[/b] - - Data (variant): [code]result[/code] - </description> - <tutorials> - </tutorials> - <members> - <member name="operator" type="int" setter="set_operator" getter="get_operator" enum="Variant.Operator" default="6"> - The operation to be performed. See [enum Variant.Operator] for available options. - </member> - <member name="type" type="int" setter="set_typed" getter="get_typed" enum="Variant.Type" default="0"> - The type of the values for this operation. See [enum Variant.Type] for available options. - </member> - </members> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptPreload.xml b/modules/visual_script/doc_classes/VisualScriptPreload.xml deleted file mode 100644 index 146d6cd9c3..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptPreload.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptPreload" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - Creates a new [Resource] or loads one from the filesystem. - </brief_description> - <description> - Creates a new [Resource] or loads one from the filesystem. - [b]Input Ports:[/b] - none - [b]Output Ports:[/b] - - Data (object): [code]res[/code] - </description> - <tutorials> - </tutorials> - <members> - <member name="resource" type="Resource" setter="set_preload" getter="get_preload"> - The [Resource] to load. - </member> - </members> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml b/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml deleted file mode 100644 index 77cd6393a9..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptPropertyGet.xml +++ /dev/null @@ -1,48 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptPropertyGet" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A Visual Script node returning a value of a property from an [Object]. - </brief_description> - <description> - [VisualScriptPropertyGet] can return a value of any property from the current object or other objects. - </description> - <tutorials> - </tutorials> - <members> - <member name="base_script" type="String" setter="set_base_script" getter="get_base_script"> - The script to be used when [member set_mode] is set to [constant CALL_MODE_INSTANCE]. - </member> - <member name="base_type" type="StringName" setter="set_base_type" getter="get_base_type" default="&"Object""> - The base type to be used when [member set_mode] is set to [constant CALL_MODE_INSTANCE]. - </member> - <member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" enum="Variant.Type"> - The type to be used when [member set_mode] is set to [constant CALL_MODE_BASIC_TYPE]. - </member> - <member name="index" type="StringName" setter="set_index" getter="get_index"> - The indexed name of the property to retrieve. See [method Object.get_indexed] for details. - </member> - <member name="node_path" type="NodePath" setter="set_base_path" getter="get_base_path"> - The node path to use when [member set_mode] is set to [constant CALL_MODE_NODE_PATH]. - </member> - <member name="property" type="StringName" setter="set_property" getter="get_property" default="&"""> - The name of the property to retrieve. Changing this will clear [member index]. - </member> - <member name="set_mode" type="int" setter="set_call_mode" getter="get_call_mode" enum="VisualScriptPropertyGet.CallMode" default="0"> - [code]set_mode[/code] determines the target object from which the property will be retrieved. See [enum CallMode] for options. - </member> - </members> - <constants> - <constant name="CALL_MODE_SELF" value="0" enum="CallMode"> - The property will be retrieved from this [Object]. - </constant> - <constant name="CALL_MODE_NODE_PATH" value="1" enum="CallMode"> - The property will be retrieved from the given [Node] in the scene tree. - </constant> - <constant name="CALL_MODE_INSTANCE" value="2" enum="CallMode"> - The property will be retrieved from an instanced node with the given type and script. - </constant> - <constant name="CALL_MODE_BASIC_TYPE" value="3" enum="CallMode"> - The property will be retrieved from a GDScript basic type (e.g. [Vector2]). - </constant> - </constants> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptPropertySet.xml b/modules/visual_script/doc_classes/VisualScriptPropertySet.xml deleted file mode 100644 index 6cffa328c7..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptPropertySet.xml +++ /dev/null @@ -1,84 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptPropertySet" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A Visual Script node that sets a property of an [Object]. - </brief_description> - <description> - [VisualScriptPropertySet] can set the value of any property from the current object or other objects. - </description> - <tutorials> - </tutorials> - <members> - <member name="assign_op" type="int" setter="set_assign_op" getter="get_assign_op" enum="VisualScriptPropertySet.AssignOp" default="0"> - The additional operation to perform when assigning. See [enum AssignOp] for options. - </member> - <member name="base_script" type="String" setter="set_base_script" getter="get_base_script"> - The script to be used when [member set_mode] is set to [constant CALL_MODE_INSTANCE]. - </member> - <member name="base_type" type="StringName" setter="set_base_type" getter="get_base_type" default="&"Object""> - The base type to be used when [member set_mode] is set to [constant CALL_MODE_INSTANCE]. - </member> - <member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" enum="Variant.Type"> - The type to be used when [member set_mode] is set to [constant CALL_MODE_BASIC_TYPE]. - </member> - <member name="index" type="StringName" setter="set_index" getter="get_index"> - The indexed name of the property to set. See [method Object.set_indexed] for details. - </member> - <member name="node_path" type="NodePath" setter="set_base_path" getter="get_base_path"> - The node path to use when [member set_mode] is set to [constant CALL_MODE_NODE_PATH]. - </member> - <member name="property" type="StringName" setter="set_property" getter="get_property" default="&"""> - The name of the property to set. Changing this will clear [member index]. - </member> - <member name="set_mode" type="int" setter="set_call_mode" getter="get_call_mode" enum="VisualScriptPropertySet.CallMode" default="0"> - [code]set_mode[/code] determines the target object on which the property will be set. See [enum CallMode] for options. - </member> - </members> - <constants> - <constant name="CALL_MODE_SELF" value="0" enum="CallMode"> - The property will be set on this [Object]. - </constant> - <constant name="CALL_MODE_NODE_PATH" value="1" enum="CallMode"> - The property will be set on the given [Node] in the scene tree. - </constant> - <constant name="CALL_MODE_INSTANCE" value="2" enum="CallMode"> - The property will be set on an instanced node with the given type and script. - </constant> - <constant name="CALL_MODE_BASIC_TYPE" value="3" enum="CallMode"> - The property will be set on a GDScript basic type (e.g. [Vector2]). - </constant> - <constant name="ASSIGN_OP_NONE" value="0" enum="AssignOp"> - The property will be assigned regularly. - </constant> - <constant name="ASSIGN_OP_ADD" value="1" enum="AssignOp"> - The value will be added to the property. Equivalent of doing [code]+=[/code]. - </constant> - <constant name="ASSIGN_OP_SUB" value="2" enum="AssignOp"> - The value will be subtracted from the property. Equivalent of doing [code]-=[/code]. - </constant> - <constant name="ASSIGN_OP_MUL" value="3" enum="AssignOp"> - The property will be multiplied by the value. Equivalent of doing [code]*=[/code]. - </constant> - <constant name="ASSIGN_OP_DIV" value="4" enum="AssignOp"> - The property will be divided by the value. Equivalent of doing [code]/=[/code]. - </constant> - <constant name="ASSIGN_OP_MOD" value="5" enum="AssignOp"> - A modulo operation will be performed on the property and the value. Equivalent of doing [code]%=[/code]. - </constant> - <constant name="ASSIGN_OP_SHIFT_LEFT" value="6" enum="AssignOp"> - The property will be binarly shifted to the left by the given value. Equivalent of doing [code]<<[/code]. - </constant> - <constant name="ASSIGN_OP_SHIFT_RIGHT" value="7" enum="AssignOp"> - The property will be binarly shifted to the right by the given value. Equivalent of doing [code]>>[/code]. - </constant> - <constant name="ASSIGN_OP_BIT_AND" value="8" enum="AssignOp"> - A binary [code]AND[/code] operation will be performed on the property. Equivalent of doing [code]&=[/code]. - </constant> - <constant name="ASSIGN_OP_BIT_OR" value="9" enum="AssignOp"> - A binary [code]OR[/code] operation will be performed on the property. Equivalent of doing [code]|=[/code]. - </constant> - <constant name="ASSIGN_OP_BIT_XOR" value="10" enum="AssignOp"> - A binary [code]XOR[/code] operation will be performed on the property. Equivalent of doing [code]^=[/code]. - </constant> - </constants> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptResourcePath.xml b/modules/visual_script/doc_classes/VisualScriptResourcePath.xml deleted file mode 100644 index 6ca8260ade..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptResourcePath.xml +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptResourcePath" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - </brief_description> - <description> - </description> - <tutorials> - </tutorials> - <members> - <member name="path" type="String" setter="set_resource_path" getter="get_resource_path" default=""""> - </member> - </members> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptReturn.xml b/modules/visual_script/doc_classes/VisualScriptReturn.xml deleted file mode 100644 index 1d59392782..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptReturn.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptReturn" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - Exits a function and returns an optional value. - </brief_description> - <description> - Ends the execution of a function and returns control to the calling function. Optionally, it can return a [Variant] value. - [b]Input Ports:[/b] - - Sequence - - Data (variant): [code]result[/code] (optional) - [b]Output Ports:[/b] - none - </description> - <tutorials> - </tutorials> - <members> - <member name="return_enabled" type="bool" setter="set_enable_return_value" getter="is_return_value_enabled" default="false"> - If [code]true[/code], the [code]return[/code] input port is available. - </member> - <member name="return_type" type="int" setter="set_return_type" getter="get_return_type" enum="Variant.Type" default="0"> - The return value's data type. - </member> - </members> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptSceneNode.xml b/modules/visual_script/doc_classes/VisualScriptSceneNode.xml deleted file mode 100644 index a769d11d94..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptSceneNode.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptSceneNode" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - Node reference. - </brief_description> - <description> - A direct reference to a node. - [b]Input Ports:[/b] - none - [b]Output Ports:[/b] - - Data: [code]node[/code] (obj) - </description> - <tutorials> - </tutorials> - <members> - <member name="node_path" type="NodePath" setter="set_node_path" getter="get_node_path" default="NodePath(".")"> - The node's path in the scene tree. - </member> - </members> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptSceneTree.xml b/modules/visual_script/doc_classes/VisualScriptSceneTree.xml deleted file mode 100644 index 84ab90892f..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptSceneTree.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptSceneTree" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A Visual Script node for accessing [SceneTree] methods. - </brief_description> - <description> - A Visual Script node for accessing [SceneTree] methods. - </description> - <tutorials> - </tutorials> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptSelect.xml b/modules/visual_script/doc_classes/VisualScriptSelect.xml deleted file mode 100644 index 1aa916f779..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptSelect.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptSelect" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - Chooses between two input values. - </brief_description> - <description> - Chooses between two input values based on a Boolean condition. - [b]Input Ports:[/b] - - Data (boolean): [code]cond[/code] - - Data (variant): [code]a[/code] - - Data (variant): [code]b[/code] - [b]Output Ports:[/b] - - Data (variant): [code]out[/code] - </description> - <tutorials> - </tutorials> - <members> - <member name="type" type="int" setter="set_typed" getter="get_typed" enum="Variant.Type" default="0"> - The input variables' type. - </member> - </members> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptSelf.xml b/modules/visual_script/doc_classes/VisualScriptSelf.xml deleted file mode 100644 index 8cc59dbccd..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptSelf.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptSelf" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - Outputs a reference to the current instance. - </brief_description> - <description> - Provides a reference to the node running the visual script. - [b]Input Ports:[/b] - none - [b]Output Ports:[/b] - - Data (object): [code]instance[/code] - </description> - <tutorials> - </tutorials> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptSequence.xml b/modules/visual_script/doc_classes/VisualScriptSequence.xml deleted file mode 100644 index 9adbc30e0d..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptSequence.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptSequence" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - Executes a series of Sequence ports. - </brief_description> - <description> - Steps through a series of one or more output Sequence ports. The [code]current[/code] data port outputs the currently executing item. - [b]Input Ports:[/b] - - Sequence: [code]in order[/code] - [b]Output Ports:[/b] - - Sequence: [code]1[/code] - - Sequence: [code]2 - n[/code] (optional) - - Data (int): [code]current[/code] - </description> - <tutorials> - </tutorials> - <members> - <member name="steps" type="int" setter="set_steps" getter="get_steps" default="1"> - The number of steps in the sequence. - </member> - </members> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptSubCall.xml b/modules/visual_script/doc_classes/VisualScriptSubCall.xml deleted file mode 100644 index 535e89fc82..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptSubCall.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptSubCall" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - Calls a method called [code]_subcall[/code] in this object. - </brief_description> - <description> - [VisualScriptSubCall] will call method named [code]_subcall[/code] in the current script. It will fail if the method doesn't exist or the provided arguments are wrong. - </description> - <tutorials> - </tutorials> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptSwitch.xml b/modules/visual_script/doc_classes/VisualScriptSwitch.xml deleted file mode 100644 index 7befe89f50..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptSwitch.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptSwitch" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - Branches program flow based on a given input's value. - </brief_description> - <description> - Branches the flow based on an input's value. Use [b]Case Count[/b] in the Inspector to set the number of branches and each comparison's optional type. - [b]Input Ports:[/b] - - Sequence: [code]'input' is[/code] - - Data (variant): [code]=[/code] - - Data (variant): [code]=[/code] (optional) - - Data (variant): [code]input[/code] - [b]Output Ports:[/b] - - Sequence - - Sequence (optional) - - Sequence: [code]done[/code] - </description> - <tutorials> - </tutorials> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptTypeCast.xml b/modules/visual_script/doc_classes/VisualScriptTypeCast.xml deleted file mode 100644 index ec84a75601..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptTypeCast.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptTypeCast" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A Visual Script node that casts the given value to another type. - </brief_description> - <description> - [VisualScriptTypeCast] will perform a type conversion to an [Object]-derived type. - </description> - <tutorials> - </tutorials> - <members> - <member name="base_script" type="String" setter="set_base_script" getter="get_base_script" default=""""> - The target script class to be converted to. If none, only the [member base_type] will be used. - </member> - <member name="base_type" type="StringName" setter="set_base_type" getter="get_base_type" default="&"Object""> - The target type to be converted to. - </member> - </members> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptVariableGet.xml b/modules/visual_script/doc_classes/VisualScriptVariableGet.xml deleted file mode 100644 index 8d99b4b9d0..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptVariableGet.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptVariableGet" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - Gets a variable's value. - </brief_description> - <description> - Returns a variable's value. "Var Name" must be supplied, with an optional type. - [b]Input Ports:[/b] - none - [b]Output Ports:[/b] - - Data (variant): [code]value[/code] - </description> - <tutorials> - </tutorials> - <members> - <member name="var_name" type="StringName" setter="set_variable" getter="get_variable" default="&"""> - The variable's name. - </member> - </members> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptVariableSet.xml b/modules/visual_script/doc_classes/VisualScriptVariableSet.xml deleted file mode 100644 index 4f568cc0f6..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptVariableSet.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptVariableSet" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - Changes a variable's value. - </brief_description> - <description> - Changes a variable's value to the given input. - [b]Input Ports:[/b] - - Sequence - - Data (variant): [code]set[/code] - [b]Output Ports:[/b] - - Sequence - </description> - <tutorials> - </tutorials> - <members> - <member name="var_name" type="StringName" setter="set_variable" getter="get_variable" default="&"""> - The variable's name. - </member> - </members> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptWhile.xml b/modules/visual_script/doc_classes/VisualScriptWhile.xml deleted file mode 100644 index 4e7cccef17..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptWhile.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptWhile" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - Conditional loop. - </brief_description> - <description> - Loops while a condition is [code]true[/code]. Execution continues out the [code]exit[/code] Sequence port when the loop terminates. - [b]Input Ports:[/b] - - Sequence: [code]while(cond)[/code] - - Data (bool): [code]cond[/code] - [b]Output Ports:[/b] - - Sequence: [code]repeat[/code] - - Sequence: [code]exit[/code] - </description> - <tutorials> - </tutorials> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptYield.xml b/modules/visual_script/doc_classes/VisualScriptYield.xml deleted file mode 100644 index ec757a3ac4..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptYield.xml +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptYield" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A Visual Script node used to pause a function execution. - </brief_description> - <description> - [VisualScriptYield] will pause the function call and return [VisualScriptFunctionState], which can be used to resume the function. - </description> - <tutorials> - </tutorials> - <members> - <member name="mode" type="int" setter="set_yield_mode" getter="get_yield_mode" enum="VisualScriptYield.YieldMode" default="1"> - The mode to use for yielding. See [enum YieldMode] for available options. - </member> - <member name="wait_time" type="float" setter="set_wait_time" getter="get_wait_time"> - The time to wait when [member mode] is set to [constant YIELD_WAIT]. - </member> - </members> - <constants> - <constant name="YIELD_FRAME" value="1" enum="YieldMode"> - Yields during an idle frame. - </constant> - <constant name="YIELD_PHYSICS_FRAME" value="2" enum="YieldMode"> - Yields during a physics frame. - </constant> - <constant name="YIELD_WAIT" value="3" enum="YieldMode"> - Yields a function and waits the given time. - </constant> - </constants> -</class> diff --git a/modules/visual_script/doc_classes/VisualScriptYieldSignal.xml b/modules/visual_script/doc_classes/VisualScriptYieldSignal.xml deleted file mode 100644 index c3f4bc49c5..0000000000 --- a/modules/visual_script/doc_classes/VisualScriptYieldSignal.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptYieldSignal" inherits="VisualScriptNode" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> - <brief_description> - A Visual Script node yielding for a signal. - </brief_description> - <description> - [VisualScriptYieldSignal] will pause the function execution until the provided signal is emitted. - </description> - <tutorials> - </tutorials> - <members> - <member name="base_type" type="StringName" setter="set_base_type" getter="get_base_type" default="&"Object""> - The base type to be used when [member call_mode] is set to [constant CALL_MODE_INSTANCE]. - </member> - <member name="call_mode" type="int" setter="set_call_mode" getter="get_call_mode" enum="VisualScriptYieldSignal.CallMode" default="0"> - [code]call_mode[/code] determines the target object to wait for the signal emission. See [enum CallMode] for options. - </member> - <member name="node_path" type="NodePath" setter="set_base_path" getter="get_base_path"> - The node path to use when [member call_mode] is set to [constant CALL_MODE_NODE_PATH]. - </member> - <member name="signal" type="StringName" setter="set_signal" getter="get_signal" default="&"""> - The signal name to be waited for. - </member> - </members> - <constants> - <constant name="CALL_MODE_SELF" value="0" enum="CallMode"> - A signal from this [Object] will be used. - </constant> - <constant name="CALL_MODE_NODE_PATH" value="1" enum="CallMode"> - A signal from the given [Node] in the scene tree will be used. - </constant> - <constant name="CALL_MODE_INSTANCE" value="2" enum="CallMode"> - A signal from an instanced node with the given type will be used. - </constant> - </constants> -</class> diff --git a/modules/visual_script/editor/visual_script_editor.cpp b/modules/visual_script/editor/visual_script_editor.cpp deleted file mode 100644 index fec48d1807..0000000000 --- a/modules/visual_script/editor/visual_script_editor.cpp +++ /dev/null @@ -1,4976 +0,0 @@ -/*************************************************************************/ -/* visual_script_editor.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "visual_script_editor.h" - -#include "../visual_script_expression.h" -#include "../visual_script_flow_control.h" -#include "../visual_script_func_nodes.h" -#include "../visual_script_nodes.h" -#include "core/input/input.h" -#include "core/object/class_db.h" -#include "core/object/script_language.h" -#include "core/os/keyboard.h" -#include "core/variant/variant.h" -#include "editor/editor_node.h" -#include "editor/editor_resource_preview.h" -#include "editor/editor_scale.h" -#include "editor/editor_settings.h" -#include "editor/editor_undo_redo_manager.h" -#include "scene/gui/check_button.h" -#include "scene/gui/graph_edit.h" -#include "scene/gui/separator.h" -#include "scene/gui/view_panner.h" -#include "scene/main/window.h" - -#ifdef TOOLS_ENABLED - -void VisualScriptEditedProperty::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_edited_property", "value"), &VisualScriptEditedProperty::set_edited_property); - ClassDB::bind_method(D_METHOD("get_edited_property"), &VisualScriptEditedProperty::get_edited_property); - - ADD_PROPERTY(PropertyInfo(Variant::NIL, "edited_property", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "set_edited_property", "get_edited_property"); -} - -void VisualScriptEditedProperty::set_edited_property(Variant p_variant) { - edited_property = p_variant; -} - -Variant VisualScriptEditedProperty::get_edited_property() const { - return edited_property; -} - -///////////////// - -class VisualScriptEditorSignalEdit : public Object { - GDCLASS(VisualScriptEditorSignalEdit, Object); - - StringName sig; - -public: - Ref<EditorUndoRedoManager> undo_redo; - Ref<VisualScript> script; - -protected: - static void _bind_methods() { - ClassDB::bind_method("_sig_changed", &VisualScriptEditorSignalEdit::_sig_changed); - ADD_SIGNAL(MethodInfo("changed")); - } - - void _sig_changed() { - notify_property_list_changed(); - emit_signal(SNAME("changed")); - } - - bool _set(const StringName &p_name, const Variant &p_value) { - if (sig == StringName()) { - return false; - } - - if (p_name == "argument_count") { - int new_argc = p_value; - int argc = script->custom_signal_get_argument_count(sig); - if (argc == new_argc) { - return true; - } - - undo_redo->create_action(TTR("Change Signal Arguments")); - - if (new_argc < argc) { - for (int i = new_argc; i < argc; i++) { - undo_redo->add_do_method(script.ptr(), "custom_signal_remove_argument", sig, new_argc); - undo_redo->add_undo_method(script.ptr(), "custom_signal_add_argument", sig, script->custom_signal_get_argument_name(sig, i), script->custom_signal_get_argument_type(sig, i), -1); - } - } else if (new_argc > argc) { - for (int i = argc; i < new_argc; i++) { - undo_redo->add_do_method(script.ptr(), "custom_signal_add_argument", sig, Variant::NIL, "arg" + itos(i + 1), -1); - undo_redo->add_undo_method(script.ptr(), "custom_signal_remove_argument", sig, argc); - } - } - - undo_redo->add_do_method(this, "_sig_changed"); - undo_redo->add_undo_method(this, "_sig_changed"); - - undo_redo->commit_action(); - - return true; - } - if (String(p_name).begins_with("argument/")) { - int idx = String(p_name).get_slice("/", 1).to_int() - 1; - ERR_FAIL_INDEX_V(idx, script->custom_signal_get_argument_count(sig), false); - String what = String(p_name).get_slice("/", 2); - if (what == "type") { - int old_type = script->custom_signal_get_argument_type(sig, idx); - int new_type = p_value; - undo_redo->create_action(TTR("Change Argument Type")); - undo_redo->add_do_method(script.ptr(), "custom_signal_set_argument_type", sig, idx, new_type); - undo_redo->add_undo_method(script.ptr(), "custom_signal_set_argument_type", sig, idx, old_type); - undo_redo->commit_action(); - - return true; - } - - if (what == "name") { - String old_name = script->custom_signal_get_argument_name(sig, idx); - String new_name = p_value; - undo_redo->create_action(TTR("Change Argument name")); - undo_redo->add_do_method(script.ptr(), "custom_signal_set_argument_name", sig, idx, new_name); - undo_redo->add_undo_method(script.ptr(), "custom_signal_set_argument_name", sig, idx, old_name); - undo_redo->commit_action(); - return true; - } - } - - return false; - } - - bool _get(const StringName &p_name, Variant &r_ret) const { - if (sig == StringName()) { - return false; - } - - if (p_name == "argument_count") { - r_ret = script->custom_signal_get_argument_count(sig); - return true; - } - if (String(p_name).begins_with("argument/")) { - int idx = String(p_name).get_slice("/", 1).to_int() - 1; - ERR_FAIL_INDEX_V(idx, script->custom_signal_get_argument_count(sig), false); - String what = String(p_name).get_slice("/", 2); - if (what == "type") { - r_ret = script->custom_signal_get_argument_type(sig, idx); - return true; - } - if (what == "name") { - r_ret = script->custom_signal_get_argument_name(sig, idx); - return true; - } - } - - return false; - } - void _get_property_list(List<PropertyInfo> *p_list) const { - if (sig == StringName()) { - return; - } - - p_list->push_back(PropertyInfo(Variant::INT, "argument_count", PROPERTY_HINT_RANGE, "0,256")); - String argt = "Variant"; - for (int i = 1; i < Variant::VARIANT_MAX; i++) { - argt += "," + Variant::get_type_name(Variant::Type(i)); - } - - for (int i = 0; i < script->custom_signal_get_argument_count(sig); i++) { - p_list->push_back(PropertyInfo(Variant::INT, "argument/" + itos(i + 1) + "/type", PROPERTY_HINT_ENUM, argt)); - p_list->push_back(PropertyInfo(Variant::STRING, "argument/" + itos(i + 1) + "/name")); - } - } - -public: - void edit(const StringName &p_sig) { - sig = p_sig; - notify_property_list_changed(); - } -}; - -class VisualScriptEditorVariableEdit : public Object { - GDCLASS(VisualScriptEditorVariableEdit, Object); - - StringName var; - -public: - Ref<EditorUndoRedoManager> undo_redo; - Ref<VisualScript> script; - -protected: - static void _bind_methods() { - ClassDB::bind_method("_var_changed", &VisualScriptEditorVariableEdit::_var_changed); - ClassDB::bind_method("_var_value_changed", &VisualScriptEditorVariableEdit::_var_value_changed); - ADD_SIGNAL(MethodInfo("changed")); - } - - void _var_changed() { - notify_property_list_changed(); - emit_signal(SNAME("changed")); - } - void _var_value_changed() { - emit_signal(SNAME("changed")); - } - - bool _set(const StringName &p_name, const Variant &p_value) { - if (var == StringName()) { - return false; - } - - if (String(p_name) == "value") { - undo_redo->create_action(TTR("Set Variable Default Value")); - Variant current = script->get_variable_default_value(var); - undo_redo->add_do_method(script.ptr(), "set_variable_default_value", var, p_value); - undo_redo->add_undo_method(script.ptr(), "set_variable_default_value", var, current); - undo_redo->add_do_method(this, "_var_value_changed"); - undo_redo->add_undo_method(this, "_var_value_changed"); - undo_redo->commit_action(); - return true; - } - - Dictionary d = script->call("get_variable_info", var); - - if (String(p_name) == "type") { - Dictionary dc = d.duplicate(); - dc["type"] = p_value; - undo_redo->create_action(TTR("Set Variable Type")); - undo_redo->add_do_method(script.ptr(), "set_variable_info", var, dc); - undo_redo->add_undo_method(script.ptr(), "set_variable_info", var, d); - - // Setting the default value. - Variant::Type type = (Variant::Type)(int)p_value; - if (type != Variant::NIL) { - Variant default_value; - Callable::CallError ce; - Variant::construct(type, default_value, nullptr, 0, ce); - if (ce.error == Callable::CallError::CALL_OK) { - undo_redo->add_do_method(script.ptr(), "set_variable_default_value", var, default_value); - undo_redo->add_undo_method(script.ptr(), "set_variable_default_value", var, dc["value"]); - } - } - - undo_redo->add_do_method(this, "_var_changed"); - undo_redo->add_undo_method(this, "_var_changed"); - undo_redo->commit_action(); - return true; - } - - if (String(p_name) == "hint") { - Dictionary dc = d.duplicate(); - dc["hint"] = p_value; - undo_redo->create_action(TTR("Set Variable Type")); - undo_redo->add_do_method(script.ptr(), "set_variable_info", var, dc); - undo_redo->add_undo_method(script.ptr(), "set_variable_info", var, d); - undo_redo->add_do_method(this, "_var_changed"); - undo_redo->add_undo_method(this, "_var_changed"); - undo_redo->commit_action(); - return true; - } - - if (String(p_name) == "hint_string") { - Dictionary dc = d.duplicate(); - dc["hint_string"] = p_value; - undo_redo->create_action(TTR("Set Variable Type")); - undo_redo->add_do_method(script.ptr(), "set_variable_info", var, dc); - undo_redo->add_undo_method(script.ptr(), "set_variable_info", var, d); - undo_redo->add_do_method(this, "_var_changed"); - undo_redo->add_undo_method(this, "_var_changed"); - undo_redo->commit_action(); - return true; - } - - if (String(p_name) == "export") { - script->set_variable_export(var, p_value); - InspectorDock::get_inspector_singleton()->update_tree(); - return true; - } - - return false; - } - - bool _get(const StringName &p_name, Variant &r_ret) const { - if (var == StringName()) { - return false; - } - - if (String(p_name) == "value") { - r_ret = script->get_variable_default_value(var); - return true; - } - - PropertyInfo pinfo = script->get_variable_info(var); - - if (String(p_name) == "type") { - r_ret = pinfo.type; - return true; - } - if (String(p_name) == "hint") { - r_ret = pinfo.hint; - return true; - } - if (String(p_name) == "hint_string") { - r_ret = pinfo.hint_string; - return true; - } - - if (String(p_name) == "export") { - r_ret = script->get_variable_export(var); - return true; - } - - return false; - } - void _get_property_list(List<PropertyInfo> *p_list) const { - if (var == StringName()) { - return; - } - - String argt = "Variant"; - for (int i = 1; i < Variant::VARIANT_MAX; i++) { - argt += "," + Variant::get_type_name(Variant::Type(i)); - } - p_list->push_back(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt)); - p_list->push_back(PropertyInfo(script->get_variable_info(var).type, "value", script->get_variable_info(var).hint, script->get_variable_info(var).hint_string, PROPERTY_USAGE_DEFAULT)); - // Update this when PropertyHint changes. - p_list->push_back(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,ExpRange,Enum,ExpEasing,Length,SpriteFrame,KeyAccel,Flags,Layers2dRender,Layers2dPhysics,Layer3dRender,Layer3dPhysics,File,Dir,GlobalFile,GlobalDir,ResourceType,MultilineText,PlaceholderText,ColorNoAlpha,ImageCompressLossy,ImageCompressLossLess,ObjectId,String,NodePathToEditedNode,MethodOfVariantType,MethodOfBaseType,MethodOfInstance,MethodOfScript,PropertyOfVariantType,PropertyOfBaseType,PropertyOfInstance,PropertyOfScript,ObjectTooBig,NodePathValidTypes")); - p_list->push_back(PropertyInfo(Variant::STRING, "hint_string")); - p_list->push_back(PropertyInfo(Variant::BOOL, "export")); - } - -public: - void edit(const StringName &p_var) { - var = p_var; - notify_property_list_changed(); - } -}; - -static Color _color_from_type(Variant::Type p_type, bool dark_theme = true) { - Color color; - if (dark_theme) { - switch (p_type) { - case Variant::NIL: - color = Color(0.41, 0.93, 0.74); - break; - - case Variant::BOOL: - color = Color(0.55, 0.65, 0.94); - break; - case Variant::INT: - color = Color(0.49, 0.78, 0.94); - break; - case Variant::FLOAT: - color = Color(0.38, 0.85, 0.96); - break; - case Variant::STRING: - color = Color(0.42, 0.65, 0.93); - break; - - case Variant::VECTOR2: - color = Color(0.74, 0.57, 0.95); - break; - case Variant::VECTOR2I: - color = Color(0.74, 0.57, 0.95); - break; - case Variant::RECT2: - color = Color(0.95, 0.57, 0.65); - break; - case Variant::RECT2I: - color = Color(0.95, 0.57, 0.65); - break; - case Variant::VECTOR3: - color = Color(0.84, 0.49, 0.93); - break; - case Variant::VECTOR3I: - color = Color(0.84, 0.49, 0.93); - break; - case Variant::VECTOR4: - color = Color(0.84, 0.49, 0.94); - break; - case Variant::VECTOR4I: - color = Color(0.84, 0.49, 0.94); - break; - case Variant::TRANSFORM2D: - color = Color(0.77, 0.93, 0.41); - break; - case Variant::PLANE: - color = Color(0.97, 0.44, 0.44); - break; - case Variant::QUATERNION: - color = Color(0.93, 0.41, 0.64); - break; - case Variant::AABB: - color = Color(0.93, 0.47, 0.57); - break; - case Variant::BASIS: - color = Color(0.89, 0.93, 0.41); - break; - case Variant::TRANSFORM3D: - color = Color(0.96, 0.66, 0.43); - break; - - case Variant::COLOR: - color = Color(0.62, 1.0, 0.44); - break; - case Variant::NODE_PATH: - color = Color(0.41, 0.58, 0.93); - break; - case Variant::RID: - color = Color(0.41, 0.93, 0.6); - break; - case Variant::OBJECT: - color = Color(0.47, 0.95, 0.91); - break; - case Variant::DICTIONARY: - color = Color(0.47, 0.93, 0.69); - break; - - case Variant::ARRAY: - color = Color(0.88, 0.88, 0.88); - break; - case Variant::PACKED_BYTE_ARRAY: - color = Color(0.67, 0.96, 0.78); - break; - case Variant::PACKED_INT32_ARRAY: - color = Color(0.69, 0.86, 0.96); - break; - case Variant::PACKED_FLOAT32_ARRAY: - color = Color(0.59, 0.91, 0.97); - break; - case Variant::PACKED_INT64_ARRAY: - color = Color(0.69, 0.86, 0.96); - break; - case Variant::PACKED_FLOAT64_ARRAY: - color = Color(0.59, 0.91, 0.97); - break; - case Variant::PACKED_STRING_ARRAY: - color = Color(0.62, 0.77, 0.95); - break; - case Variant::PACKED_VECTOR2_ARRAY: - color = Color(0.82, 0.7, 0.96); - break; - case Variant::PACKED_VECTOR3_ARRAY: - color = Color(0.87, 0.61, 0.95); - break; - case Variant::PACKED_COLOR_ARRAY: - color = Color(0.91, 1.0, 0.59); - break; - - default: - color.set_hsv(p_type / float(Variant::VARIANT_MAX), 0.7, 0.7); - } - } else { - switch (p_type) { - case Variant::NIL: - color = Color(0.15, 0.89, 0.63); - break; - - case Variant::BOOL: - color = Color(0.43, 0.56, 0.92); - break; - case Variant::INT: - color = Color(0.31, 0.7, 0.91); - break; - case Variant::FLOAT: - color = Color(0.15, 0.8, 0.94); - break; - case Variant::STRING: - color = Color(0.27, 0.56, 0.91); - break; - - case Variant::VECTOR2: - color = Color(0.68, 0.46, 0.93); - break; - case Variant::VECTOR2I: - color = Color(0.68, 0.46, 0.93); - break; - case Variant::RECT2: - color = Color(0.93, 0.46, 0.56); - break; - case Variant::RECT2I: - color = Color(0.93, 0.46, 0.56); - break; - case Variant::VECTOR3: - color = Color(0.86, 0.42, 0.93); - break; - case Variant::VECTOR3I: - color = Color(0.86, 0.42, 0.93); - break; - case Variant::TRANSFORM2D: - color = Color(0.59, 0.81, 0.1); - break; - case Variant::PLANE: - color = Color(0.97, 0.44, 0.44); - break; - case Variant::QUATERNION: - color = Color(0.93, 0.41, 0.64); - break; - case Variant::AABB: - color = Color(0.93, 0.47, 0.57); - break; - case Variant::BASIS: - color = Color(0.7, 0.73, 0.1); - break; - case Variant::TRANSFORM3D: - color = Color(0.96, 0.56, 0.28); - break; - - case Variant::COLOR: - color = Color(0.24, 0.75, 0.0); - break; - case Variant::NODE_PATH: - color = Color(0.41, 0.58, 0.93); - break; - case Variant::RID: - color = Color(0.17, 0.9, 0.45); - break; - case Variant::OBJECT: - color = Color(0.07, 0.84, 0.76); - break; - case Variant::DICTIONARY: - color = Color(0.34, 0.91, 0.62); - break; - - case Variant::ARRAY: - color = Color(0.45, 0.45, 0.45); - break; - case Variant::PACKED_BYTE_ARRAY: - color = Color(0.38, 0.92, 0.6); - break; - case Variant::PACKED_INT32_ARRAY: - color = Color(0.38, 0.73, 0.92); - break; - case Variant::PACKED_FLOAT32_ARRAY: - color = Color(0.25, 0.83, 0.95); - break; - case Variant::PACKED_INT64_ARRAY: - color = Color(0.38, 0.73, 0.92); - break; - case Variant::PACKED_FLOAT64_ARRAY: - color = Color(0.25, 0.83, 0.95); - break; - case Variant::PACKED_STRING_ARRAY: - color = Color(0.38, 0.62, 0.92); - break; - case Variant::PACKED_VECTOR2_ARRAY: - color = Color(0.62, 0.36, 0.92); - break; - case Variant::PACKED_VECTOR3_ARRAY: - color = Color(0.79, 0.35, 0.92); - break; - case Variant::PACKED_COLOR_ARRAY: - color = Color(0.57, 0.73, 0.0); - break; - - default: - color.set_hsv(p_type / float(Variant::VARIANT_MAX), 0.3, 0.3); - } - } - - return color; -} - -void VisualScriptEditor::_update_graph_connections() { - graph->clear_connections(); - - List<VisualScript::SequenceConnection> sequence_conns; - script->get_sequence_connection_list(&sequence_conns); - - for (const VisualScript::SequenceConnection &E : sequence_conns) { - graph->connect_node(itos(E.from_node), E.from_output, itos(E.to_node), 0); - } - - List<VisualScript::DataConnection> data_conns; - script->get_data_connection_list(&data_conns); - - for (VisualScript::DataConnection &dc : data_conns) { - Ref<VisualScriptNode> from_node = script->get_node(dc.from_node); - Ref<VisualScriptNode> to_node = script->get_node(dc.to_node); - - if (to_node->has_input_sequence_port()) { - dc.to_port++; - } - - dc.from_port += from_node->get_output_sequence_port_count(); - - graph->connect_node(itos(dc.from_node), dc.from_port, itos(dc.to_node), dc.to_port); - } -} - -void VisualScriptEditor::_update_graph(int p_only_id) { - if (updating_graph) { - return; - } - - updating_graph = true; - - //byebye all nodes - if (p_only_id >= 0) { - if (graph->has_node(itos(p_only_id))) { - Node *gid = graph->get_node(itos(p_only_id)); - if (gid) { - memdelete(gid); - } - } - } else { - for (int i = 0; i < graph->get_child_count(); i++) { - if (Object::cast_to<GraphNode>(graph->get_child(i))) { - memdelete(graph->get_child(i)); - i--; - } - } - } - graph->show(); - select_func_text->hide(); - - Ref<Texture2D> type_icons[Variant::VARIANT_MAX] = { - Control::get_theme_icon(SNAME("Variant"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("bool"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("int"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("float"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("String"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Vector2"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Vector2i"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Rect2"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Rect2i"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Vector3"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Vector3i"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Transform2D"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Plane"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Quaternion"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("AABB"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Basis"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Transform3D"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Color"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("StringName"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("NodePath"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("RID"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("MiniObject"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Callable"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Signal"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Dictionary"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Array"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("PackedByteArray"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("PackedInt32Array"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("PackedInt64Array"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("PackedFloat32Array"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("PackedFloat64Array"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("PackedStringArray"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("PackedVector2Array"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("PackedVector3Array"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("PackedColorArray"), SNAME("EditorIcons")) - }; - - // Visual script specific theme for MSDF font. - Ref<Theme> vstheme; - vstheme.instantiate(); - Ref<Font> label_font = EditorNode::get_singleton()->get_editor_theme()->get_font("main_msdf", "EditorFonts"); - vstheme->set_font("font", "Label", label_font); - vstheme->set_font("font", "LineEdit", label_font); - vstheme->set_font("font", "Button", label_font); - - Ref<Texture2D> seq_port = Control::get_theme_icon(SNAME("VisualShaderPort"), SNAME("EditorIcons")); - List<int> node_ids; - script->get_node_list(&node_ids); - - List<int> ids; - script->get_node_list(&ids); - - for (int &E : ids) { - if (p_only_id >= 0 && p_only_id != E) { - continue; - } - - Ref<VisualScriptNode> node = script->get_node(E); - Vector2 pos = script->get_node_position(E); - - GraphNode *gnode = memnew(GraphNode); - gnode->set_title(node->get_caption()); - gnode->set_position_offset(pos * EDSCALE); - if (error_line == E) { - gnode->set_overlay(GraphNode::OVERLAY_POSITION); - } else if (node->is_breakpoint()) { - gnode->set_overlay(GraphNode::OVERLAY_BREAKPOINT); - } - - gnode->set_meta("__vnode", node); - gnode->set_name(itos(E)); - gnode->connect("dragged", callable_mp(this, &VisualScriptEditor::_node_moved).bind(E)); - gnode->connect("close_request", callable_mp(this, &VisualScriptEditor::_remove_node).bind(E), CONNECT_DEFERRED); - - { - Ref<VisualScriptFunction> v = node; - if (!v.is_valid()) { - gnode->set_show_close_button(true); - } - } - - bool has_gnode_text = false; - - Ref<VisualScriptLists> nd_list = node; - bool is_vslist = nd_list.is_valid(); - if (is_vslist) { - HBoxContainer *hbnc = memnew(HBoxContainer); - if (nd_list->is_input_port_editable()) { - has_gnode_text = true; - Button *btn = memnew(Button); - btn->set_text(TTR("Add Input Port")); - hbnc->add_child(btn); - btn->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_input_port).bind(E), CONNECT_DEFERRED); - } - if (nd_list->is_output_port_editable()) { - if (nd_list->is_input_port_editable()) { - hbnc->add_spacer(); - } - has_gnode_text = true; - Button *btn = memnew(Button); - btn->set_text(TTR("Add Output Port")); - hbnc->add_child(btn); - btn->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_output_port).bind(E), CONNECT_DEFERRED); - } - gnode->add_child(hbnc); - } else if (Object::cast_to<VisualScriptExpression>(node.ptr())) { - has_gnode_text = true; - LineEdit *line_edit = memnew(LineEdit); - line_edit->set_text(node->get_text()); - line_edit->set_expand_to_text_length_enabled(true); - line_edit->add_theme_font_override("font", get_theme_font(SNAME("source"), SNAME("EditorFonts"))); - gnode->add_child(line_edit); - line_edit->connect("text_changed", callable_mp(this, &VisualScriptEditor::_expression_text_changed).bind(E)); - } else { - String text = node->get_text(); - if (!text.is_empty()) { - has_gnode_text = true; - Label *label = memnew(Label); - label->set_text(text); - gnode->add_child(label); - } - } - - if (Object::cast_to<VisualScriptComment>(node.ptr())) { - Ref<VisualScriptComment> vsc = node; - gnode->set_comment(true); - gnode->set_resizable(true); - gnode->set_custom_minimum_size(vsc->get_size() * EDSCALE); - gnode->connect("resize_request", callable_mp(this, &VisualScriptEditor::_comment_node_resized).bind(E)); - } - - if (node_styles.has(node->get_category())) { - Ref<StyleBoxFlat> sbf = node_styles[node->get_category()]; - if (gnode->is_comment()) { - sbf = EditorNode::get_singleton()->get_theme_base()->get_theme()->get_stylebox(SNAME("comment"), SNAME("GraphNode")); - } - - Color c = sbf->get_border_color(); - c = ((c.r + c.g + c.b) / 3) < 0.7 ? Color(1.0, 1.0, 1.0, 0.85) : Color(0.0, 0.0, 0.0, 0.85); - Color ic = c; - gnode->add_theme_color_override("title_color", c); - c.a = 1; - gnode->add_theme_color_override("close_color", c); - gnode->add_theme_color_override("resizer_color", ic); - gnode->add_theme_style_override("frame", sbf); - } - - const Color mono_color = get_theme_color(SNAME("mono_color"), SNAME("Editor")); - - int slot_idx = 0; - - bool single_seq_output = node->get_output_sequence_port_count() == 1 && node->get_output_sequence_port_text(0) == String(); - if ((node->has_input_sequence_port() || single_seq_output) || has_gnode_text) { - // IF has_gnode_text is true BUT we have no sequence ports to draw (in here), - // we still draw the disabled default ones to shift up the slots by one, - // so the slots DON'T start with the content text. - - // IF has_gnode_text is false, but we DO want to draw default sequence ports, - // we draw a dummy text to take up the position of the sequence nodes, so all the other ports are still aligned correctly. - if (!has_gnode_text) { - Label *dummy = memnew(Label); - dummy->set_text(" "); - gnode->add_child(dummy); - } - gnode->set_slot(0, node->has_input_sequence_port(), TYPE_SEQUENCE, mono_color, single_seq_output, TYPE_SEQUENCE, mono_color, seq_port, seq_port); - slot_idx++; - } - - int mixed_seq_ports = 0; - - if (!single_seq_output) { - if (node->has_mixed_input_and_sequence_ports()) { - mixed_seq_ports = node->get_output_sequence_port_count(); - } else { - for (int i = 0; i < node->get_output_sequence_port_count(); i++) { - Label *text2 = memnew(Label); - text2->set_text(node->get_output_sequence_port_text(i)); - text2->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT); - gnode->add_child(text2); - gnode->set_slot(slot_idx, false, 0, Color(), true, TYPE_SEQUENCE, mono_color, seq_port, seq_port); - slot_idx++; - } - } - } - - for (int i = 0; i < MAX(node->get_output_value_port_count(), MAX(mixed_seq_ports, node->get_input_value_port_count())); i++) { - bool left_ok = false; - Variant::Type left_type = Variant::NIL; - String left_name; - - if (i < node->get_input_value_port_count()) { - PropertyInfo pi = node->get_input_value_port_info(i); - left_ok = true; - left_type = pi.type; - left_name = pi.name; - } - - bool right_ok = false; - Variant::Type right_type = Variant::NIL; - String right_name; - - if (i >= mixed_seq_ports && i < node->get_output_value_port_count() + mixed_seq_ports) { - PropertyInfo pi = node->get_output_value_port_info(i - mixed_seq_ports); - right_ok = true; - right_type = pi.type; - right_name = pi.name; - } - VBoxContainer *vbc = memnew(VBoxContainer); - HBoxContainer *hbc = memnew(HBoxContainer); - HBoxContainer *hbc2 = memnew(HBoxContainer); - vbc->add_child(hbc); - vbc->add_child(hbc2); - if (left_ok) { - Ref<Texture2D> t; - if (left_type >= 0 && left_type < Variant::VARIANT_MAX) { - t = type_icons[left_type]; - } - if (t.is_valid()) { - TextureRect *tf = memnew(TextureRect); - tf->set_texture(t); - tf->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED); - hbc->add_child(tf); - } - - if (is_vslist) { - if (nd_list->is_input_port_name_editable()) { - LineEdit *name_box = memnew(LineEdit); - hbc->add_child(name_box); - name_box->set_custom_minimum_size(Size2(60 * EDSCALE, 0)); - name_box->set_text(left_name); - name_box->set_expand_to_text_length_enabled(true); - name_box->connect("resized", callable_mp(this, &VisualScriptEditor::_update_node_size).bind(E)); - name_box->connect("focus_exited", callable_mp(this, &VisualScriptEditor::_port_name_focus_out).bind(name_box, E, i, true)); - } else { - hbc->add_child(memnew(Label(left_name))); - } - - if (nd_list->is_input_port_type_editable()) { - OptionButton *opbtn = memnew(OptionButton); - for (int j = Variant::NIL; j < Variant::VARIANT_MAX; j++) { - opbtn->add_item(Variant::get_type_name(Variant::Type(j))); - } - opbtn->select(left_type); - opbtn->set_custom_minimum_size(Size2(100 * EDSCALE, 0)); - hbc->add_child(opbtn); - opbtn->connect("item_selected", callable_mp(this, &VisualScriptEditor::_change_port_type).bind(E, i, true), CONNECT_DEFERRED); - } - - Button *rmbtn = memnew(Button); - rmbtn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); - hbc->add_child(rmbtn); - rmbtn->connect("pressed", callable_mp(this, &VisualScriptEditor::_remove_input_port).bind(E, i), CONNECT_DEFERRED); - } else { - hbc->add_child(memnew(Label(left_name))); - } - - if (left_type != Variant::NIL && !script->is_input_value_port_connected(E, i)) { - PropertyInfo pi = node->get_input_value_port_info(i); - Button *button = memnew(Button); - Variant value = node->get_default_input_value(i); - if (value.get_type() != left_type) { - //different type? for now convert - //not the same, reconvert - Callable::CallError ce; - const Variant *existingp = &value; - Variant::construct(left_type, value, &existingp, 1, ce); - } - - if (left_type == Variant::COLOR) { - button->set_custom_minimum_size(Size2(30, 0) * EDSCALE); - button->connect("draw", callable_mp(this, &VisualScriptEditor::_draw_color_over_button).bind(button, value)); - } else if (left_type == Variant::OBJECT && Ref<Resource>(value).is_valid()) { - Ref<Resource> res = value; - Array arr; - arr.push_back(button->get_instance_id()); - arr.push_back(String(value)); - EditorResourcePreview::get_singleton()->queue_edited_resource_preview(res, this, "_button_resource_previewed", arr); - - } else if (pi.type == Variant::INT && pi.hint == PROPERTY_HINT_ENUM) { - bool found = false; - const Vector<String> options = pi.hint_string.split(","); - int64_t current_val = 0; - for (const String &option : options) { - Vector<String> text_split = option.split(":"); - if (text_split.size() != 1) { - current_val = text_split[1].to_int(); - } - if (value.operator int() == current_val) { - button->set_text(text_split[0]); - found = true; - break; - } - current_val += 1; - } - if (!found) { - button->set_text(value); - } - } else if (pi.type == Variant::INT && pi.hint == PROPERTY_HINT_FLAGS) { - Vector<String> value_texts; - const Vector<String> options = pi.hint_string.split(","); - uint32_t v = value; - for (const String &option : options) { - uint32_t current_val; - Vector<String> text_split = option.split(":"); - if (text_split.size() != -1) { - current_val = text_split[1].to_int(); - } else { - current_val = 1 << i; - } - if ((v & current_val) == current_val) { - value_texts.push_back(text_split[0]); - } - } - if (value_texts.size() != 0) { - String value_text = value_texts[0]; - for (const String &text : value_texts) { - value_text += " | " + text; - } - button->set_text(value_text); - } else { - button->set_text(value); - } - } else { - button->set_text(value); - } - button->connect("pressed", callable_mp(this, &VisualScriptEditor::_default_value_edited).bind(button, E, i)); - hbc2->add_child(button); - } - } else { - Control *c = memnew(Control); - c->set_custom_minimum_size(Size2(10, 0) * EDSCALE); - hbc->add_child(c); - } - - hbc->add_spacer(); - hbc2->add_spacer(); - - if (i < mixed_seq_ports) { - Label *text2 = memnew(Label); - text2->set_text(node->get_output_sequence_port_text(i)); - text2->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT); - hbc->add_child(text2); - } - - if (right_ok) { - if (is_vslist) { - Button *rmbtn = memnew(Button); - rmbtn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); - hbc->add_child(rmbtn); - rmbtn->connect("pressed", callable_mp(this, &VisualScriptEditor::_remove_output_port).bind(E, i), CONNECT_DEFERRED); - - if (nd_list->is_output_port_type_editable()) { - OptionButton *opbtn = memnew(OptionButton); - for (int j = Variant::NIL; j < Variant::VARIANT_MAX; j++) { - opbtn->add_item(Variant::get_type_name(Variant::Type(j))); - } - opbtn->select(right_type); - opbtn->set_custom_minimum_size(Size2(100 * EDSCALE, 0)); - hbc->add_child(opbtn); - opbtn->connect("item_selected", callable_mp(this, &VisualScriptEditor::_change_port_type).bind(E, i, false), CONNECT_DEFERRED); - } - - if (nd_list->is_output_port_name_editable()) { - LineEdit *name_box = memnew(LineEdit); - hbc->add_child(name_box); - name_box->set_custom_minimum_size(Size2(60 * EDSCALE, 0)); - name_box->set_text(right_name); - name_box->set_expand_to_text_length_enabled(true); - name_box->connect("resized", callable_mp(this, &VisualScriptEditor::_update_node_size).bind(E)); - name_box->connect("focus_exited", callable_mp(this, &VisualScriptEditor::_port_name_focus_out).bind(name_box, E, i, false)); - } else { - hbc->add_child(memnew(Label(right_name))); - } - } else { - hbc->add_child(memnew(Label(right_name))); - } - - Ref<Texture2D> t; - if (right_type >= 0 && right_type < Variant::VARIANT_MAX) { - t = type_icons[right_type]; - } - if (t.is_valid()) { - TextureRect *tf = memnew(TextureRect); - tf->set_texture(t); - tf->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED); - hbc->add_child(tf); - } - } - - gnode->add_child(vbc); - - bool dark_theme = get_theme_constant(SNAME("dark_theme"), SNAME("Editor")); - if (i < mixed_seq_ports) { - gnode->set_slot(slot_idx, left_ok, left_type, _color_from_type(left_type, dark_theme), true, TYPE_SEQUENCE, mono_color, Ref<Texture2D>(), seq_port); - } else { - gnode->set_slot(slot_idx, left_ok, left_type, _color_from_type(left_type, dark_theme), right_ok, right_type, _color_from_type(right_type, dark_theme)); - } - - slot_idx++; - } - graph->add_child(gnode); - gnode->set_theme(vstheme); - if (gnode->is_comment()) { - graph->move_child(gnode, 0); - } - } - - _update_graph_connections(); - - float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity"); - graph->set_minimap_opacity(graph_minimap_opacity); - - float graph_lines_curvature = EditorSettings::get_singleton()->get("editors/visual_editors/lines_curvature"); - graph->set_connection_lines_curvature(graph_lines_curvature); - - // Use default_func instead of default_func for now I think that should be good stop gap solution to ensure not breaking anything. - graph->call_deferred(SNAME("set_scroll_ofs"), script->get_scroll() * EDSCALE); - updating_graph = false; -} - -void VisualScriptEditor::_change_port_type(int p_select, int p_id, int p_port, bool is_input) { - Ref<VisualScriptLists> vsn = script->get_node(p_id); - if (!vsn.is_valid()) { - return; - } - - undo_redo->create_action(TTR("Change Port Type")); - if (is_input) { - undo_redo->add_do_method(vsn.ptr(), "set_input_data_port_type", p_port, Variant::Type(p_select)); - undo_redo->add_undo_method(vsn.ptr(), "set_input_data_port_type", p_port, vsn->get_input_value_port_info(p_port).type); - } else { - undo_redo->add_do_method(vsn.ptr(), "set_output_data_port_type", p_port, Variant::Type(p_select)); - undo_redo->add_undo_method(vsn.ptr(), "set_output_data_port_type", p_port, vsn->get_output_value_port_info(p_port).type); - } - undo_redo->commit_action(); -} - -void VisualScriptEditor::_update_node_size(int p_id) { - Node *node = graph->get_node(itos(p_id)); - if (Object::cast_to<Control>(node)) { - Object::cast_to<Control>(node)->reset_size(); // Shrink if text is smaller. - } -} - -void VisualScriptEditor::_port_name_focus_out(const Node *p_name_box, int p_id, int p_port, bool is_input) { - Ref<VisualScriptLists> vsn = script->get_node(p_id); - if (!vsn.is_valid()) { - return; - } - - String text; - - if (Object::cast_to<LineEdit>(p_name_box)) { - text = Object::cast_to<LineEdit>(p_name_box)->get_text(); - } else { - return; - } - - undo_redo->create_action(TTR("Change Port Name")); - if (is_input) { - undo_redo->add_do_method(vsn.ptr(), "set_input_data_port_name", p_port, text); - undo_redo->add_undo_method(vsn.ptr(), "set_input_data_port_name", p_port, vsn->get_input_value_port_info(p_port).name); - } else { - undo_redo->add_do_method(vsn.ptr(), "set_output_data_port_name", p_port, text); - undo_redo->add_undo_method(vsn.ptr(), "set_output_data_port_name", p_port, vsn->get_output_value_port_info(p_port).name); - } - undo_redo->commit_action(); -} - -void VisualScriptEditor::_update_members() { - ERR_FAIL_COND(!script.is_valid()); - - updating_members = true; - - members->clear(); - TreeItem *root = members->create_item(); - - TreeItem *functions = members->create_item(root); - functions->set_selectable(0, false); - functions->set_text(0, TTR("Functions:")); - functions->add_button(0, Control::get_theme_icon(SNAME("Override"), SNAME("EditorIcons")), 1, false, TTR("Override an existing built-in function.")); - functions->add_button(0, Control::get_theme_icon(SNAME("Add"), SNAME("EditorIcons")), 0, false, TTR("Create a new function.")); - functions->set_custom_color(0, Control::get_theme_color(SNAME("mono_color"), SNAME("Editor"))); - - List<StringName> func_names; - script->get_function_list(&func_names); - func_names.sort_custom<StringName::AlphCompare>(); - for (const StringName &E : func_names) { - TreeItem *ti = members->create_item(functions); - ti->set_text(0, E); - ti->set_selectable(0, true); - ti->set_metadata(0, E); - ti->add_button(0, Control::get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), 0); - if (selected == E) { - ti->select(0); - } - } - - TreeItem *variables = members->create_item(root); - variables->set_selectable(0, false); - variables->set_text(0, TTR("Variables:")); - variables->add_button(0, Control::get_theme_icon(SNAME("Add"), SNAME("EditorIcons")), -1, false, TTR("Create a new variable.")); - variables->set_custom_color(0, Control::get_theme_color(SNAME("mono_color"), SNAME("Editor"))); - - Ref<Texture2D> type_icons[Variant::VARIANT_MAX] = { - Control::get_theme_icon(SNAME("Variant"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("bool"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("int"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("float"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("String"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Vector2"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Vector2i"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Rect2"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Rect2i"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Vector3"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Vector3i"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Transform2D"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Plane"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Quaternion"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("AABB"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Basis"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Transform3D"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Color"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("StringName"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("NodePath"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("RID"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("MiniObject"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Callable"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Signal"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Dictionary"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("Array"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("PackedByteArray"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("PackedInt32Array"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("PackedInt64Array"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("PackedFloat32Array"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("PackedFloat64Array"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("PackedStringArray"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("PackedVector2Array"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("PackedVector3Array"), SNAME("EditorIcons")), - Control::get_theme_icon(SNAME("PackedColorArray"), SNAME("EditorIcons")) - }; - - List<StringName> var_names; - script->get_variable_list(&var_names); - var_names.sort_custom<StringName::AlphCompare>(); - for (const StringName &E : var_names) { - TreeItem *ti = members->create_item(variables); - - ti->set_text(0, E); - - ti->set_suffix(0, "= " + _sanitized_variant_text(E)); - ti->set_icon(0, type_icons[script->get_variable_info(E).type]); - - ti->set_selectable(0, true); - ti->set_editable(0, true); - ti->set_metadata(0, E); - if (selected == E) { - ti->select(0); - } - } - - TreeItem *_signals = members->create_item(root); - _signals->set_selectable(0, false); - _signals->set_text(0, TTR("Signals:")); - _signals->add_button(0, Control::get_theme_icon(SNAME("Add"), SNAME("EditorIcons")), -1, false, TTR("Create a new signal.")); - _signals->set_custom_color(0, Control::get_theme_color(SNAME("mono_color"), SNAME("Editor"))); - - List<StringName> signal_names; - script->get_custom_signal_list(&signal_names); - for (const StringName &E : signal_names) { - TreeItem *ti = members->create_item(_signals); - ti->set_text(0, E); - ti->set_selectable(0, true); - ti->set_editable(0, true); - ti->set_metadata(0, E); - if (selected == E) { - ti->select(0); - } - } - - String base_type = script->get_instance_base_type(); - String icon_type = base_type; - if (!Control::has_theme_icon(base_type, SNAME("EditorIcons"))) { - icon_type = "Object"; - } - - base_type_select->set_text(base_type); - base_type_select->set_icon(Control::get_theme_icon(icon_type, SNAME("EditorIcons"))); - - updating_members = false; -} - -String VisualScriptEditor::_sanitized_variant_text(const StringName &property_name) { - Variant var = script->get_variable_default_value(property_name); - - if (script->get_variable_info(property_name).type != Variant::NIL) { - Callable::CallError ce; - const Variant *converted = &var; - Variant n; - Variant::construct(script->get_variable_info(property_name).type, n, &converted, 1, ce); - var = n; - } - - return String(var); -} - -void VisualScriptEditor::_member_selected() { - if (updating_members) { - return; - } - - TreeItem *ti = members->get_selected(); - ERR_FAIL_COND(!ti); - - selected = ti->get_metadata(0); - - if (ti->get_parent() == members->get_root()->get_first_child()) { -#ifdef MACOS_ENABLED - bool held_ctrl = Input::get_singleton()->is_key_pressed(Key::META); -#else - bool held_ctrl = Input::get_singleton()->is_key_pressed(Key::CTRL); -#endif - if (held_ctrl) { - ERR_FAIL_COND(!script->has_function(selected)); - _center_on_node(script->get_function_node_id(selected)); - } - } -} - -void VisualScriptEditor::_member_edited() { - if (updating_members) { - return; - } - - TreeItem *ti = members->get_edited(); - ERR_FAIL_COND(!ti); - - String name = ti->get_metadata(0); - String new_name = ti->get_text(0); - - if (name == new_name) { - return; - } - - if (!new_name.is_valid_identifier()) { - EditorNode::get_singleton()->show_warning(TTR("Name is not a valid identifier:") + " " + new_name); - updating_members = true; - ti->set_text(0, name); - updating_members = false; - return; - } - - if (script->has_function(new_name) || script->has_variable(new_name) || script->has_custom_signal(new_name)) { - EditorNode::get_singleton()->show_warning(TTR("Name already in use by another func/var/signal:") + " " + new_name); - updating_members = true; - ti->set_text(0, name); - updating_members = false; - return; - } - - TreeItem *root = members->get_root(); - - if (ti->get_parent() == root->get_first_child()) { - selected = new_name; - - int node_id = script->get_function_node_id(name); - Ref<VisualScriptFunction> func; - if (script->has_node(node_id)) { - func = script->get_node(node_id); - } - undo_redo->create_action(TTR("Rename Function")); - undo_redo->add_do_method(script.ptr(), "rename_function", name, new_name); - undo_redo->add_undo_method(script.ptr(), "rename_function", new_name, name); - if (func.is_valid()) { - undo_redo->add_do_method(func.ptr(), "set_name", new_name); - undo_redo->add_undo_method(func.ptr(), "set_name", name); - } - - // Also fix all function calls. - List<int> lst; - script->get_node_list(&lst); - for (int &F : lst) { - Ref<VisualScriptFunctionCall> fncall = script->get_node(F); - if (!fncall.is_valid()) { - continue; - } - if (fncall->get_function() == name) { - undo_redo->add_do_method(fncall.ptr(), "set_function", new_name); - undo_redo->add_undo_method(fncall.ptr(), "set_function", name); - } - } - - undo_redo->add_do_method(this, "_update_members"); - undo_redo->add_undo_method(this, "_update_members"); - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - undo_redo->add_do_method(this, "emit_signal", "edited_script_changed"); - undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed"); - undo_redo->commit_action(); - - return; // Or crash because it will become invalid. - } - - if (ti->get_parent() == root->get_first_child()->get_next()) { - selected = new_name; - undo_redo->create_action(TTR("Rename Variable")); - undo_redo->add_do_method(script.ptr(), "rename_variable", name, new_name); - undo_redo->add_undo_method(script.ptr(), "rename_variable", new_name, name); - - // Also fix all variable setter & getter calls - List<int> lst; - script->get_node_list(&lst); - for (int &P : lst) { - Ref<VisualScriptPropertySet> pset = script->get_node(P); - if (pset.is_valid() && pset->get_property() == name) { - undo_redo->add_do_method(pset.ptr(), "set_property", new_name); - undo_redo->add_undo_method(pset.ptr(), "set_property", name); - } - Ref<VisualScriptPropertyGet> pget = script->get_node(P); - if (pget.is_valid() && pget->get_property() == name) { - undo_redo->add_do_method(pget.ptr(), "set_property", new_name); - undo_redo->add_undo_method(pget.ptr(), "set_property", name); - } - } - - undo_redo->add_do_method(this, "_update_members"); - undo_redo->add_undo_method(this, "_update_members"); - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - undo_redo->add_do_method(this, "emit_signal", "edited_script_changed"); - undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed"); - undo_redo->commit_action(); - - return; // Or crash because it will become invalid. - } - - if (ti->get_parent() == root->get_first_child()->get_next()->get_next()) { - selected = new_name; - undo_redo->create_action(TTR("Rename Signal")); - undo_redo->add_do_method(script.ptr(), "rename_custom_signal", name, new_name); - undo_redo->add_undo_method(script.ptr(), "rename_custom_signal", new_name, name); - - // Also fix all signal emitting nodes - List<int> lst; - script->get_node_list(&lst); - for (int &P : lst) { - Ref<VisualScriptEmitSignal> psig = script->get_node(P); - if (psig.is_valid() && psig->get_signal() == name) { - undo_redo->add_do_method(psig.ptr(), "set_signal", new_name); - undo_redo->add_undo_method(psig.ptr(), "set_signal", name); - } - } - - undo_redo->add_do_method(this, "_update_members"); - undo_redo->add_undo_method(this, "_update_members"); - undo_redo->add_do_method(this, "emit_signal", "edited_script_changed"); - undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed"); - undo_redo->commit_action(); - - return; // Or crash because it will become invalid. - } -} - -void VisualScriptEditor::_create_function_dialog() { - function_create_dialog->popup_centered(); - func_name_box->set_text(""); - func_name_box->grab_focus(); - for (int i = 0; i < func_input_vbox->get_child_count(); i++) { - Node *nd = func_input_vbox->get_child(i); - nd->queue_delete(); - } -} - -void VisualScriptEditor::_create_function() { - String name = _validate_name((func_name_box->get_text().is_empty()) ? "new_func" : func_name_box->get_text()); - selected = name; - Vector2 pos = _get_available_pos(); - - Ref<VisualScriptFunction> func_node; - func_node.instantiate(); - func_node->set_name(name); - - for (int i = 0; i < func_input_vbox->get_child_count(); i++) { - OptionButton *opbtn = Object::cast_to<OptionButton>(func_input_vbox->get_child(i)->get_child(3)); - LineEdit *lne = Object::cast_to<LineEdit>(func_input_vbox->get_child(i)->get_child(1)); - if (!opbtn || !lne) { - continue; - } - Variant::Type arg_type = Variant::Type(opbtn->get_selected()); - String arg_name = lne->get_text(); - func_node->add_argument(arg_type, arg_name); - } - - int func_node_id = script->get_available_id(); - - undo_redo->create_action(TTR("Add Function")); - undo_redo->add_do_method(script.ptr(), "add_function", name, func_node_id); - undo_redo->add_undo_method(script.ptr(), "remove_function", name); - undo_redo->add_do_method(script.ptr(), "add_node", func_node_id, func_node, pos); - undo_redo->add_undo_method(script.ptr(), "remove_node", func_node_id); - undo_redo->add_do_method(this, "_update_members"); - undo_redo->add_undo_method(this, "_update_members"); - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - undo_redo->add_do_method(this, "emit_signal", "edited_script_changed"); - undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed"); - undo_redo->commit_action(); - - _update_graph(); -} - -void VisualScriptEditor::_add_node_dialog() { - _generic_search(graph->get_global_position() + Vector2(55, 80), true); -} - -void VisualScriptEditor::_add_func_input() { - HBoxContainer *hbox = memnew(HBoxContainer); - hbox->set_h_size_flags(SIZE_EXPAND_FILL); - - Label *name_label = memnew(Label); - name_label->set_text(TTR("Name:")); - hbox->add_child(name_label); - - LineEdit *name_box = memnew(LineEdit); - name_box->set_h_size_flags(SIZE_EXPAND_FILL); - name_box->set_text("input"); - name_box->connect("focus_entered", callable_mp(this, &VisualScriptEditor::_deselect_input_names)); - hbox->add_child(name_box); - - Label *type_label = memnew(Label); - type_label->set_text(TTR("Type:")); - hbox->add_child(type_label); - - OptionButton *type_box = memnew(OptionButton); - type_box->set_custom_minimum_size(Size2(120 * EDSCALE, 0)); - for (int i = Variant::NIL; i < Variant::VARIANT_MAX; i++) { - type_box->add_item(Variant::get_type_name(Variant::Type(i))); - } - type_box->select(1); - hbox->add_child(type_box); - - Button *delete_button = memnew(Button); - delete_button->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons"))); - delete_button->set_tooltip(vformat(TTR("Delete input port"))); - hbox->add_child(delete_button); - - for (int i = 0; i < func_input_vbox->get_child_count(); i++) { - LineEdit *line_edit = (LineEdit *)func_input_vbox->get_child(i)->get_child(1); - line_edit->deselect(); - } - - func_input_vbox->add_child(hbox); - hbox->set_meta("id", hbox->get_index()); - - delete_button->connect("pressed", callable_mp(this, &VisualScriptEditor::_remove_func_input).bind(hbox)); - - name_box->select_all(); - name_box->grab_focus(); -} - -void VisualScriptEditor::_remove_func_input(Node *p_node) { - func_input_vbox->remove_child(p_node); - p_node->queue_delete(); -} - -void VisualScriptEditor::_deselect_input_names() { - int cn = func_input_vbox->get_child_count(); - for (int i = 0; i < cn; i++) { - LineEdit *lne = Object::cast_to<LineEdit>(func_input_vbox->get_child(i)->get_child(1)); - if (lne) { - lne->deselect(); - } - } -} - -void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_button, MouseButton p_mouse_button) { - if (p_mouse_button != MouseButton::LEFT) { - return; - } - - TreeItem *ti = Object::cast_to<TreeItem>(p_item); - - TreeItem *root = members->get_root(); - - if (ti->get_parent() == root) { - //main buttons - if (ti == root->get_first_child()) { - // Add function, this one uses menu. - - if (p_button == 1) { - // Ensure script base exists otherwise use custom base type. - ERR_FAIL_COND(script.is_null()); - new_virtual_method_select->select_method_from_base_type(script->get_instance_base_type(), true); - return; - } else if (p_button == 0) { - String name = _validate_name("new_function"); - selected = name; - Vector2 pos = _get_available_pos(); - - Ref<VisualScriptFunction> func_node; - func_node.instantiate(); - func_node->set_name(name); - int fn_id = script->get_available_id(); - - undo_redo->create_action(TTR("Add Function")); - undo_redo->add_do_method(script.ptr(), "add_function", name, fn_id); - undo_redo->add_do_method(script.ptr(), "add_node", fn_id, func_node, pos); - undo_redo->add_undo_method(script.ptr(), "remove_function", name); - undo_redo->add_undo_method(script.ptr(), "remove_node", fn_id); - undo_redo->add_do_method(this, "_update_members"); - undo_redo->add_undo_method(this, "_update_members"); - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - undo_redo->add_do_method(this, "emit_signal", "edited_script_changed"); - undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed"); - undo_redo->commit_action(); - - _update_graph(); - } - - return; // Or crash because it will become invalid. - } - - if (ti == root->get_first_child()->get_next()) { - // Add variable. - String name = _validate_name("new_variable"); - selected = name; - - undo_redo->create_action(TTR("Add Variable")); - undo_redo->add_do_method(script.ptr(), "add_variable", name); - undo_redo->add_undo_method(script.ptr(), "remove_variable", name); - undo_redo->add_do_method(this, "_update_members"); - undo_redo->add_undo_method(this, "_update_members"); - undo_redo->add_do_method(this, "emit_signal", "edited_script_changed"); - undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed"); - undo_redo->commit_action(); - return; // Or crash because it will become invalid. - } - - if (ti == root->get_first_child()->get_next()->get_next()) { - // Add variable. - String name = _validate_name("new_signal"); - selected = name; - - undo_redo->create_action(TTR("Add Signal")); - undo_redo->add_do_method(script.ptr(), "add_custom_signal", name); - undo_redo->add_undo_method(script.ptr(), "remove_custom_signal", name); - undo_redo->add_do_method(this, "_update_members"); - undo_redo->add_undo_method(this, "_update_members"); - undo_redo->add_do_method(this, "emit_signal", "edited_script_changed"); - undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed"); - undo_redo->commit_action(); - return; // Or crash because it will become invalid. - } - } else if (ti->get_parent() == root->get_first_child()) { - selected = ti->get_text(0); - function_name_edit->set_position(get_screen_position() + get_local_mouse_position() - Vector2(60, -10)); - function_name_edit->popup(); - function_name_box->set_text(selected); - function_name_box->select_all(); - function_name_box->grab_focus(); - } -} - -void VisualScriptEditor::_add_input_port(int p_id) { - Ref<VisualScriptLists> vsn = script->get_node(p_id); - if (!vsn.is_valid()) { - return; - } - - updating_graph = true; - - undo_redo->create_action(TTR("Add Input Port"), UndoRedo::MERGE_ENDS); - undo_redo->add_do_method(vsn.ptr(), "add_input_data_port", Variant::NIL, "arg", -1); - undo_redo->add_do_method(this, "_update_graph", p_id); - - undo_redo->add_undo_method(vsn.ptr(), "remove_input_data_port", vsn->get_input_value_port_count()); - undo_redo->add_undo_method(this, "_update_graph", p_id); - - updating_graph = false; - - undo_redo->commit_action(); -} - -void VisualScriptEditor::_add_output_port(int p_id) { - Ref<VisualScriptLists> vsn = script->get_node(p_id); - if (!vsn.is_valid()) { - return; - } - - updating_graph = true; - - undo_redo->create_action(TTR("Add Output Port"), UndoRedo::MERGE_ENDS); - undo_redo->add_do_method(vsn.ptr(), "add_output_data_port", Variant::NIL, "arg", -1); - undo_redo->add_do_method(this, "_update_graph", p_id); - - undo_redo->add_undo_method(vsn.ptr(), "remove_output_data_port", vsn->get_output_value_port_count()); - undo_redo->add_undo_method(this, "_update_graph", p_id); - - updating_graph = false; - - undo_redo->commit_action(); -} - -void VisualScriptEditor::_remove_input_port(int p_id, int p_port) { - Ref<VisualScriptLists> vsn = script->get_node(p_id); - if (!vsn.is_valid()) { - return; - } - - updating_graph = true; - - undo_redo->create_action(TTR("Remove Input Port"), UndoRedo::MERGE_ENDS); - - int conn_from = -1, conn_port = -1; - script->get_input_value_port_connection_source(p_id, p_port, &conn_from, &conn_port); - - if (conn_from != -1) { - undo_redo->add_do_method(script.ptr(), "data_disconnect", conn_from, conn_port, p_id, p_port); - } - - undo_redo->add_do_method(vsn.ptr(), "remove_input_data_port", p_port); - undo_redo->add_do_method(this, "_update_graph", p_id); - - if (conn_from != -1) { - undo_redo->add_undo_method(script.ptr(), "data_connect", conn_from, conn_port, p_id, p_port); - } - - undo_redo->add_undo_method(vsn.ptr(), "add_input_data_port", vsn->get_input_value_port_info(p_port).type, vsn->get_input_value_port_info(p_port).name, p_port); - undo_redo->add_undo_method(this, "_update_graph", p_id); - - updating_graph = false; - - undo_redo->commit_action(); -} - -void VisualScriptEditor::_remove_output_port(int p_id, int p_port) { - Ref<VisualScriptLists> vsn = script->get_node(p_id); - if (!vsn.is_valid()) { - return; - } - - updating_graph = true; - - undo_redo->create_action(TTR("Remove Output Port"), UndoRedo::MERGE_ENDS); - - List<VisualScript::DataConnection> data_connections; - script->get_data_connection_list(&data_connections); - - HashMap<int, RBSet<int>> conn_map; - for (const VisualScript::DataConnection &E : data_connections) { - if (E.from_node == p_id && E.from_port == p_port) { - // Push into the connections map. - if (!conn_map.has(E.to_node)) { - conn_map.insert(E.to_node, RBSet<int>()); - } - conn_map[E.to_node].insert(E.to_port); - } - } - - undo_redo->add_do_method(vsn.ptr(), "remove_output_data_port", p_port); - undo_redo->add_do_method(this, "_update_graph", p_id); - - for (const KeyValue<int, RBSet<int>> &E : conn_map) { - for (const int &F : E.value) { - undo_redo->add_undo_method(script.ptr(), "data_connect", p_id, p_port, E.key, F); - } - } - - undo_redo->add_undo_method(vsn.ptr(), "add_output_data_port", vsn->get_output_value_port_info(p_port).type, vsn->get_output_value_port_info(p_port).name, p_port); - undo_redo->add_undo_method(this, "_update_graph", p_id); - - updating_graph = false; - - undo_redo->commit_action(); -} - -void VisualScriptEditor::_expression_text_changed(const String &p_text, int p_id) { - Ref<VisualScriptExpression> vse = script->get_node(p_id); - if (!vse.is_valid()) { - return; - } - - updating_graph = true; - - undo_redo->create_action(TTR("Change Expression"), UndoRedo::MERGE_ENDS); - undo_redo->add_do_property(vse.ptr(), "expression", p_text); - undo_redo->add_undo_property(vse.ptr(), "expression", vse->get("expression")); - undo_redo->add_do_method(this, "_update_graph", p_id); - undo_redo->add_undo_method(this, "_update_graph", p_id); - undo_redo->commit_action(); - - Node *node = graph->get_node(itos(p_id)); - if (Object::cast_to<Control>(node)) { - Object::cast_to<Control>(node)->reset_size(); // Shrink if text is smaller. - } - - updating_graph = false; -} - -Vector2 VisualScriptEditor::_get_pos_in_graph(Vector2 p_point) const { - Vector2 pos = (graph->get_scroll_ofs() + p_point) / (graph->get_zoom() * EDSCALE); - if (graph->is_using_snap()) { - int snap = graph->get_snap(); - pos = pos.snapped(Vector2(snap, snap)); - } - return pos; -} - -Vector2 VisualScriptEditor::_get_available_pos(bool p_centered, Vector2 p_pos) const { - if (p_centered) { - p_pos = _get_pos_in_graph(graph->get_size() * 0.5); - } - - while (true) { - bool exists = false; - List<int> existing; - script->get_node_list(&existing); - for (int &E : existing) { - Point2 pos = script->get_node_position(E); - if (pos.distance_to(p_pos) < 50) { - p_pos += Vector2(graph->get_snap(), graph->get_snap()); - exists = true; - break; - } - } - if (exists) { - continue; - } - break; - } - - return p_pos; -} - -String VisualScriptEditor::_validate_name(const String &p_name) const { - String valid = p_name; - - int counter = 1; - while (true) { - bool exists = script->has_function(valid) || script->has_variable(valid) || script->has_custom_signal(valid); - - if (exists) { - counter++; - valid = p_name + "_" + itos(counter); - continue; - } - - break; - } - - return valid; -} - -void VisualScriptEditor::_on_nodes_copy() { - clipboard->nodes.clear(); - clipboard->data_connections.clear(); - clipboard->sequence_connections.clear(); - - for (int i = 0; i < graph->get_child_count(); i++) { - GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); - if (gn) { - if (gn->is_selected()) { - int id = gn->get_name().operator String().to_int(); - Ref<VisualScriptNode> node = script->get_node(id); - if (Object::cast_to<VisualScriptFunction>(*node)) { - EditorNode::get_singleton()->show_warning(TTR("Can't copy the function node.")); - return; - } - if (node.is_valid()) { - clipboard->nodes[id] = node->duplicate(true); - clipboard->nodes_positions[id] = script->get_node_position(id); - } - } - } - } - - if (clipboard->nodes.is_empty()) { - return; - } - - List<VisualScript::SequenceConnection> sequence_connections; - script->get_sequence_connection_list(&sequence_connections); - - for (const VisualScript::SequenceConnection &E : sequence_connections) { - if (clipboard->nodes.has(E.from_node) && clipboard->nodes.has(E.to_node)) { - clipboard->sequence_connections.insert(E); - } - } - - List<VisualScript::DataConnection> data_connections; - script->get_data_connection_list(&data_connections); - - for (const VisualScript::DataConnection &E : data_connections) { - if (clipboard->nodes.has(E.from_node) && clipboard->nodes.has(E.to_node)) { - clipboard->data_connections.insert(E); - } - } -} - -void VisualScriptEditor::_on_nodes_paste() { - if (clipboard->nodes.is_empty()) { - EditorNode::get_singleton()->show_warning(TTR("Clipboard is empty!")); - return; - } - - HashMap<int, int> remap; - - undo_redo->create_action(TTR("Paste VisualScript Nodes")); - int idc = script->get_available_id() + 1; - - RBSet<int> to_select; - - RBSet<Vector2> existing_positions; - - { - List<int> nodes; - script->get_node_list(&nodes); - for (int &E : nodes) { - Vector2 pos = script->get_node_position(E).snapped(Vector2(2, 2)); - existing_positions.insert(pos); - } - } - - bool first_paste = true; - Vector2 position_offset = Vector2(0, 0); - - for (KeyValue<int, Ref<VisualScriptNode>> &E : clipboard->nodes) { - Ref<VisualScriptNode> node = E.value->duplicate(); - - int new_id = idc++; - to_select.insert(new_id); - - remap[E.key] = new_id; - - Vector2 paste_pos = clipboard->nodes_positions[E.key]; - - if (first_paste) { - position_offset = _get_pos_in_graph(mouse_up_position - graph->get_global_position()) - paste_pos; - first_paste = false; - } - - paste_pos += position_offset; - - while (existing_positions.has(paste_pos.snapped(Vector2(2, 2)))) { - paste_pos += Vector2(20, 20) * EDSCALE; - } - - undo_redo->add_do_method(script.ptr(), "add_node", new_id, node, paste_pos); - undo_redo->add_undo_method(script.ptr(), "remove_node", new_id); - } - - for (const VisualScript::SequenceConnection &E : clipboard->sequence_connections) { - undo_redo->add_do_method(script.ptr(), "sequence_connect", remap[E.from_node], E.from_output, remap[E.to_node]); - undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", remap[E.from_node], E.from_output, remap[E.to_node]); - } - - for (const VisualScript::DataConnection &E : clipboard->data_connections) { - undo_redo->add_do_method(script.ptr(), "data_connect", remap[E.from_node], E.from_port, remap[E.to_node], E.to_port); - undo_redo->add_undo_method(script.ptr(), "data_disconnect", remap[E.from_node], E.from_port, remap[E.to_node], E.to_port); - } - - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - - undo_redo->commit_action(); - - for (int i = 0; i < graph->get_child_count(); i++) { - GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); - if (gn) { - int id = gn->get_name().operator String().to_int(); - gn->set_selected(to_select.has(id)); - } - } -} - -void VisualScriptEditor::_on_nodes_delete() { - // Delete all the selected nodes. - - List<int> to_erase; - - for (int i = 0; i < graph->get_child_count(); i++) { - GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); - if (gn) { - if (gn->is_selected() && gn->is_close_button_visible()) { - to_erase.push_back(gn->get_name().operator String().to_int()); - } - } - } - - if (to_erase.is_empty()) { - return; - } - - undo_redo->create_action(TTR("Remove VisualScript Nodes")); - - for (int &F : to_erase) { - int cr_node = F; - - undo_redo->add_do_method(script.ptr(), "remove_node", cr_node); - undo_redo->add_undo_method(script.ptr(), "add_node", cr_node, script->get_node(cr_node), script->get_node_position(cr_node)); - - List<VisualScript::SequenceConnection> sequence_conns; - script->get_sequence_connection_list(&sequence_conns); - - for (const VisualScript::SequenceConnection &E : sequence_conns) { - if (E.from_node == cr_node || E.to_node == cr_node) { - undo_redo->add_undo_method(script.ptr(), "sequence_connect", E.from_node, E.from_output, E.to_node); - } - } - - List<VisualScript::DataConnection> data_conns; - script->get_data_connection_list(&data_conns); - - for (const VisualScript::DataConnection &E : data_conns) { - if (E.from_node == F || E.to_node == F) { - undo_redo->add_undo_method(script.ptr(), "data_connect", E.from_node, E.from_port, E.to_node, E.to_port); - } - } - } - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - - undo_redo->commit_action(); -} - -void VisualScriptEditor::_on_nodes_duplicate() { - RBSet<int> to_duplicate; - - for (int i = 0; i < graph->get_child_count(); i++) { - GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); - if (gn) { - if (gn->is_selected() && gn->is_close_button_visible()) { - int id = gn->get_name().operator String().to_int(); - to_duplicate.insert(id); - } - } - } - - if (to_duplicate.is_empty()) { - return; - } - - undo_redo->create_action(TTR("Duplicate VisualScript Nodes")); - int idc = script->get_available_id() + 1; - - RBSet<int> to_select; - HashMap<int, int> remap; - - for (const int &F : to_duplicate) { - // Duplicate from the specific function but place it into the default func as it would lack the connections. - Ref<VisualScriptNode> node = script->get_node(F); - - Ref<VisualScriptNode> dupe = node->duplicate(true); - - int new_id = idc++; - remap.insert(F, new_id); - - to_select.insert(new_id); - undo_redo->add_do_method(script.ptr(), "add_node", new_id, dupe, script->get_node_position(F) + Vector2(20, 20)); - undo_redo->add_undo_method(script.ptr(), "remove_node", new_id); - } - - List<VisualScript::SequenceConnection> seqs; - script->get_sequence_connection_list(&seqs); - for (const VisualScript::SequenceConnection &E : seqs) { - if (to_duplicate.has(E.from_node) && to_duplicate.has(E.to_node)) { - undo_redo->add_do_method(script.ptr(), "sequence_connect", remap[E.from_node], E.from_output, remap[E.to_node]); - } - } - - List<VisualScript::DataConnection> data; - script->get_data_connection_list(&data); - for (const VisualScript::DataConnection &E : data) { - if (to_duplicate.has(E.from_node) && to_duplicate.has(E.to_node)) { - undo_redo->add_do_method(script.ptr(), "data_connect", remap[E.from_node], E.from_port, remap[E.to_node], E.to_port); - } - } - - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - - undo_redo->commit_action(); - - for (int i = 0; i < graph->get_child_count(); i++) { - GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); - if (gn) { - int id = gn->get_name().operator String().to_int(); - gn->set_selected(to_select.has(id)); - } - } - - if (to_select.size()) { - EditorNode::get_singleton()->push_item(script->get_node(to_select.front()->get()).ptr()); - } -} - -void VisualScriptEditor::_generic_search(Vector2 pos, bool node_centered) { - if (node_centered) { - port_action_pos = graph->get_size() / 2.0f; - } else { - port_action_pos = graph->get_viewport()->get_mouse_position() - graph->get_global_position(); - } - - new_connect_node_select->select_from_visual_script(script, false); // do not reset text -} - -void VisualScriptEditor::input(const Ref<InputEvent> &p_event) { - ERR_FAIL_COND(p_event.is_null()); - - // GUI input for VS Editor Plugin - Ref<InputEventMouseButton> key = p_event; - - if (key.is_valid() && key->is_pressed()) { - mouse_up_position = get_screen_position() + get_local_mouse_position(); - } -} - -void VisualScriptEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { - Ref<InputEventMouseButton> key = p_event; - - if (key.is_valid() && key->is_pressed() && key->get_button_mask() == MouseButton::RIGHT) { - bool is_empty_selection = true; - - for (int i = 0; i < graph->get_child_count(); i++) { - GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); - if (gn && gn->is_selected()) { - is_empty_selection = false; - break; - } - } - if (is_empty_selection && clipboard->nodes.is_empty()) { - _generic_search(); - } else { - popup_menu->set_item_disabled(int(EDIT_CUT_NODES), is_empty_selection); - popup_menu->set_item_disabled(int(EDIT_COPY_NODES), is_empty_selection); - popup_menu->set_item_disabled(int(EDIT_PASTE_NODES), clipboard->nodes.is_empty()); - popup_menu->set_item_disabled(int(EDIT_DELETE_NODES), is_empty_selection); - popup_menu->set_item_disabled(int(EDIT_DUPLICATE_NODES), is_empty_selection); - popup_menu->set_item_disabled(int(EDIT_CLEAR_COPY_BUFFER), clipboard->nodes.is_empty()); - - popup_menu->set_position(mouse_up_position); - popup_menu->popup(); - } - } -} - -void VisualScriptEditor::_members_gui_input(const Ref<InputEvent> &p_event) { - Ref<InputEventKey> key = p_event; - if (key.is_valid() && key->is_pressed() && !key->is_echo()) { - if (members->has_focus()) { - TreeItem *ti = members->get_selected(); - if (ti) { - TreeItem *root = members->get_root(); - if (ti->get_parent() == root->get_first_child()) { - member_type = MEMBER_FUNCTION; - } - if (ti->get_parent() == root->get_first_child()->get_next()) { - member_type = MEMBER_VARIABLE; - } - if (ti->get_parent() == root->get_first_child()->get_next()->get_next()) { - member_type = MEMBER_SIGNAL; - } - member_name = ti->get_text(0); - } - if (ED_IS_SHORTCUT("ui_graph_delete", p_event)) { - _member_option(MEMBER_REMOVE); - } - if (ED_IS_SHORTCUT("visual_script_editor/edit_member", p_event)) { - _member_option(MEMBER_EDIT); - } - } - } - - Ref<InputEventMouseButton> btn = p_event; - if (btn.is_valid() && btn->is_double_click()) { - TreeItem *ti = members->get_selected(); - if (ti && ti->get_parent() == members->get_root()->get_first_child()) { // to check if it's a function - _center_on_node(script->get_function_node_id(ti->get_metadata(0))); - } - } -} - -void VisualScriptEditor::_rename_function(const String &name, const String &new_name) { - if (!new_name.is_valid_identifier()) { - EditorNode::get_singleton()->show_warning(TTR("Name is not a valid identifier:") + " " + new_name); - return; - } - - if (script->has_function(new_name) || script->has_variable(new_name) || script->has_custom_signal(new_name)) { - EditorNode::get_singleton()->show_warning(TTR("Name already in use by another func/var/signal:") + " " + new_name); - return; - } - - int node_id = script->get_function_node_id(name); - Ref<VisualScriptFunction> func; - if (script->has_node(node_id)) { - func = script->get_node(node_id); - } - undo_redo->create_action(TTR("Rename Function")); - undo_redo->add_do_method(script.ptr(), "rename_function", name, new_name); - undo_redo->add_undo_method(script.ptr(), "rename_function", new_name, name); - if (func.is_valid()) { - undo_redo->add_do_method(func.ptr(), "set_name", new_name); - undo_redo->add_undo_method(func.ptr(), "set_name", name); - } - - // Also fix all function calls. - List<int> lst; - script->get_node_list(&lst); - for (int &F : lst) { - Ref<VisualScriptFunctionCall> fncall = script->get_node(F); - if (!fncall.is_valid()) { - continue; - } - if (fncall->get_function() == name) { - undo_redo->add_do_method(fncall.ptr(), "set_function", new_name); - undo_redo->add_undo_method(fncall.ptr(), "set_function", name); - } - } - - undo_redo->add_do_method(this, "_update_members"); - undo_redo->add_undo_method(this, "_update_members"); - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - undo_redo->add_do_method(this, "emit_signal", "edited_script_changed"); - undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed"); - undo_redo->commit_action(); -} - -void VisualScriptEditor::_fn_name_box_input(const Ref<InputEvent> &p_event) { - if (!function_name_edit->is_visible()) { - return; - } - - Ref<InputEventKey> key = p_event; - if (key.is_valid() && key->is_pressed() && key->get_keycode() == Key::ENTER) { - function_name_edit->hide(); - _on_fn_name_box_confirmed(); - function_name_box->clear(); - } -} - -void VisualScriptEditor::_on_fn_name_box_confirmed() { - _rename_function(selected, function_name_box->get_text()); -} - -Variant VisualScriptEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) { - if (p_from == members) { - TreeItem *it = members->get_item_at_position(p_point); - if (!it) { - return Variant(); - } - - String type = it->get_metadata(0); - - if (type.is_empty()) { - return Variant(); - } - - Dictionary dd; - TreeItem *root = members->get_root(); - - if (it->get_parent() == root->get_first_child()) { - dd["type"] = "visual_script_function_drag"; - dd["function"] = type; - } else if (it->get_parent() == root->get_first_child()->get_next()) { - dd["type"] = "visual_script_variable_drag"; - dd["variable"] = type; - } else if (it->get_parent() == root->get_first_child()->get_next()->get_next()) { - dd["type"] = "visual_script_signal_drag"; - dd["signal"] = type; - - } else { - return Variant(); - } - - Label *label = memnew(Label); - label->set_text(it->get_text(0)); - set_drag_preview(label); - return dd; - } - return Variant(); -} - -bool VisualScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const { - if (p_from == graph) { - Dictionary d = p_data; - if (d.has("type") && - (String(d["type"]) == "visual_script_node_drag" || - String(d["type"]) == "visual_script_function_drag" || - String(d["type"]) == "visual_script_variable_drag" || - String(d["type"]) == "visual_script_signal_drag" || - String(d["type"]) == "obj_property" || - String(d["type"]) == "resource" || - String(d["type"]) == "files" || - String(d["type"]) == "nodes")) { - if (String(d["type"]) == "obj_property") { -#ifdef MACOS_ENABLED - const_cast<VisualScriptEditor *>(this)->_show_hint(vformat(TTR("Hold %s to drop a Getter. Hold Shift to drop a generic signature."), find_keycode_name(Key::META))); -#else - const_cast<VisualScriptEditor *>(this)->_show_hint(TTR("Hold Ctrl to drop a Getter. Hold Shift to drop a generic signature.")); -#endif - } - - if (String(d["type"]) == "nodes") { -#ifdef MACOS_ENABLED - const_cast<VisualScriptEditor *>(this)->_show_hint(vformat(TTR("Hold %s to drop a simple reference to the node."), find_keycode_name(Key::META))); -#else - const_cast<VisualScriptEditor *>(this)->_show_hint(TTR("Hold Ctrl to drop a simple reference to the node.")); -#endif - } - - if (String(d["type"]) == "visual_script_variable_drag") { -#ifdef MACOS_ENABLED - const_cast<VisualScriptEditor *>(this)->_show_hint(vformat(TTR("Hold %s to drop a Variable Setter."), find_keycode_name(Key::META))); -#else - const_cast<VisualScriptEditor *>(this)->_show_hint(TTR("Hold Ctrl to drop a Variable Setter.")); -#endif - } - - return true; - } - } - - return false; -} - -static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) { - if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene) { - return nullptr; - } - - Ref<Script> scr = p_current_node->get_script(); - - if (scr.is_valid() && scr == script) { - return p_current_node; - } - - for (int i = 0; i < p_current_node->get_child_count(); i++) { - Node *n = _find_script_node(p_edited_scene, p_current_node->get_child(i), script); - if (n) { - return n; - } - } - - return nullptr; -} - -void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { - if (p_from != graph) { - return; - } - - Dictionary d = p_data; - - if (!d.has("type")) { - return; - } - - if (String(d["type"]) == "visual_script_node_drag") { - if (!d.has("node_type") || String(d["node_type"]) == "Null") { - return; - } - - Vector2 pos = _get_pos_in_graph(p_point); - - int new_id = _create_new_node_from_name(d["node_type"], pos); - - Node *node = graph->get_node(itos(new_id)); - if (node) { - graph->set_selected(node); - _node_selected(node); - } - } - - if (String(d["type"]) == "visual_script_variable_drag") { -#ifdef MACOS_ENABLED - bool use_set = Input::get_singleton()->is_key_pressed(Key::META); -#else - bool use_set = Input::get_singleton()->is_key_pressed(Key::CTRL); -#endif - Vector2 pos = _get_pos_in_graph(p_point); - - Ref<VisualScriptNode> vnode; - if (use_set) { - Ref<VisualScriptPropertySet> pset; - pset.instantiate(); - vnode = pset; - } else { - Ref<VisualScriptPropertyGet> pget; - pget.instantiate(); - vnode = pget; - } - - int new_id = script->get_available_id(); - undo_redo->create_action(TTR("Add Node")); - undo_redo->add_do_method(vnode.ptr(), "set_property", d["variable"]); - undo_redo->add_do_method(vnode.ptr(), "set_base_script", script->get_path()); - - undo_redo->add_do_method(script.ptr(), "add_node", new_id, vnode, pos); - undo_redo->add_undo_method(script.ptr(), "remove_node", new_id); - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - undo_redo->commit_action(); - - Node *node = graph->get_node(itos(new_id)); - if (node) { - graph->set_selected(node); - _node_selected(node); - } - } - - if (String(d["type"]) == "visual_script_function_drag") { - Vector2 pos = _get_pos_in_graph(p_point); - - Ref<VisualScriptFunctionCall> vnode; - vnode.instantiate(); - vnode->set_call_mode(VisualScriptFunctionCall::CALL_MODE_SELF); - - int new_id = script->get_available_id(); - - undo_redo->create_action(TTR("Add Node")); - undo_redo->add_do_method(script.ptr(), "add_node", new_id, vnode, pos); - undo_redo->add_do_method(vnode.ptr(), "set_base_type", script->get_instance_base_type()); - undo_redo->add_do_method(vnode.ptr(), "set_function", d["function"]); - - undo_redo->add_undo_method(script.ptr(), "remove_node", new_id); - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - undo_redo->commit_action(); - - Node *node = graph->get_node(itos(new_id)); - if (node) { - graph->set_selected(node); - _node_selected(node); - } - } - - if (String(d["type"]) == "visual_script_signal_drag") { - Vector2 pos = _get_pos_in_graph(p_point); - - Ref<VisualScriptEmitSignal> vnode; - vnode.instantiate(); - vnode->set_signal(d["signal"]); - - int new_id = script->get_available_id(); - - undo_redo->create_action(TTR("Add Node")); - undo_redo->add_do_method(script.ptr(), "add_node", new_id, vnode, pos); - undo_redo->add_undo_method(script.ptr(), "remove_node", new_id); - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - undo_redo->commit_action(); - - Node *node = graph->get_node(itos(new_id)); - if (node) { - graph->set_selected(node); - _node_selected(node); - } - } - - if (String(d["type"]) == "resource") { - Vector2 pos = _get_pos_in_graph(p_point); - - Ref<VisualScriptPreload> prnode; - prnode.instantiate(); - prnode->set_preload(d["resource"]); - - int new_id = script->get_available_id(); - - undo_redo->create_action(TTR("Add Preload Node")); - undo_redo->add_do_method(script.ptr(), "add_node", new_id, prnode, pos); - undo_redo->add_undo_method(script.ptr(), "remove_node", new_id); - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - undo_redo->commit_action(); - - Node *node = graph->get_node(itos(new_id)); - if (node) { - graph->set_selected(node); - _node_selected(node); - } - } - - if (String(d["type"]) == "files") { -#ifdef MACOS_ENABLED - bool use_preload = Input::get_singleton()->is_key_pressed(Key::META); -#else - bool use_preload = Input::get_singleton()->is_key_pressed(Key::CTRL); -#endif - Vector2 pos = _get_pos_in_graph(p_point); - - Array files = d["files"]; - - List<int> new_ids; - int new_id = script->get_available_id(); - - if (files.size()) { - undo_redo->create_action(TTR("Add Node(s)")); - - for (int i = 0; i < files.size(); i++) { - Ref<Resource> res = ResourceLoader::load(files[i]); - if (!res.is_valid()) { - continue; - } - Ref<Script> drop_script = ResourceLoader::load(files[i]); - if (drop_script.is_valid() && drop_script->is_tool() && drop_script->get_instance_base_type() == "VisualScriptCustomNode" && !use_preload) { - Ref<VisualScriptCustomNode> vscn; - vscn.instantiate(); - vscn->set_script(drop_script); - - undo_redo->add_do_method(script.ptr(), "add_node", new_id, vscn, pos); - undo_redo->add_undo_method(script.ptr(), "remove_node", new_id); - } else { - Ref<VisualScriptPreload> prnode; - prnode.instantiate(); - prnode->set_preload(res); - - undo_redo->add_do_method(script.ptr(), "add_node", new_id, prnode, pos); - undo_redo->add_undo_method(script.ptr(), "remove_node", new_id); - } - new_ids.push_back(new_id); - new_id++; - pos += Vector2(20, 20); - } - - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - undo_redo->commit_action(); - } - - for (int &E : new_ids) { - Node *node = graph->get_node(itos(E)); - if (node) { - graph->set_selected(node); - _node_selected(node); - } - } - } - - if (String(d["type"]) == "nodes") { - Node *sn = _find_script_node(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root(), script); - - if (!sn) { - EditorNode::get_singleton()->show_warning(vformat(TTR("Can't drop nodes because script '%s' is not used in this scene."), get_name())); - return; - } - -#ifdef MACOS_ENABLED - bool use_node = Input::get_singleton()->is_key_pressed(Key::META); -#else - bool use_node = Input::get_singleton()->is_key_pressed(Key::CTRL); -#endif - - Array nodes = d["nodes"]; - - Vector2 pos = _get_pos_in_graph(p_point); - - undo_redo->create_action(TTR("Add Node(s) From Tree")); - int base_id = script->get_available_id(); - - if (use_node || nodes.size() > 1) { - for (int i = 0; i < nodes.size(); i++) { - NodePath np = nodes[i]; - Node *node = get_node(np); - if (!node) { - continue; - } - - Ref<VisualScriptNode> n; - - Ref<VisualScriptSceneNode> scene_node; - scene_node.instantiate(); - scene_node->set_node_path(sn->get_path_to(node)); - n = scene_node; - - undo_redo->add_do_method(script.ptr(), "add_node", base_id, n, pos); - undo_redo->add_undo_method(script.ptr(), "remove_node", base_id); - - base_id++; - pos += Vector2(25, 25); - } - - } else { - NodePath np = nodes[0]; - Node *node = get_node(np); - drop_position = pos; - drop_node = node; - drop_path = sn->get_path_to(node); - new_connect_node_select->select_from_instance(node, false); - } - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - undo_redo->commit_action(); - } - - if (String(d["type"]) == "obj_property") { - Node *sn = _find_script_node(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root(), script); - - if (!sn && !Input::get_singleton()->is_key_pressed(Key::SHIFT)) { - EditorNode::get_singleton()->show_warning(vformat(TTR("Can't drop properties because script '%s' is not used in this scene.\nDrop holding 'Shift' to just copy the signature."), get_name())); - return; - } - - Object *obj = d["object"]; - - if (!obj) { - return; - } - - Node *node = Object::cast_to<Node>(obj); - Vector2 pos = _get_pos_in_graph(p_point); - -#ifdef MACOS_ENABLED - bool use_get = Input::get_singleton()->is_key_pressed(Key::META); -#else - bool use_get = Input::get_singleton()->is_key_pressed(Key::CTRL); -#endif - - if (!node || Input::get_singleton()->is_key_pressed(Key::SHIFT)) { - if (use_get) { - undo_redo->create_action(TTR("Add Getter Property")); - } else { - undo_redo->create_action(TTR("Add Setter Property")); - } - - int base_id = script->get_available_id(); - - Ref<VisualScriptNode> vnode; - - if (!use_get) { - Ref<VisualScriptPropertySet> pset; - pset.instantiate(); - pset->set_call_mode(VisualScriptPropertySet::CALL_MODE_INSTANCE); - pset->set_base_type(obj->get_class()); - vnode = pset; - } else { - Ref<VisualScriptPropertyGet> pget; - pget.instantiate(); - pget->set_call_mode(VisualScriptPropertyGet::CALL_MODE_INSTANCE); - pget->set_base_type(obj->get_class()); - vnode = pget; - } - - undo_redo->add_do_method(script.ptr(), "add_node", base_id, vnode, pos); - undo_redo->add_do_method(vnode.ptr(), "set_property", d["property"]); - if (!obj->get_script().is_null()) { - undo_redo->add_do_method(vnode.ptr(), "set_base_script", Ref<Script>(obj->get_script())->get_path()); - } - if (!use_get) { - undo_redo->add_do_method(vnode.ptr(), "set_default_input_value", 0, d["value"]); - } - - undo_redo->add_undo_method(script.ptr(), "remove_node", base_id); - - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - undo_redo->commit_action(); - - } else { - if (use_get) { - undo_redo->create_action(TTR("Add Getter Property")); - } else { - undo_redo->create_action(TTR("Add Setter Property")); - } - - int base_id = script->get_available_id(); - - Ref<VisualScriptNode> vnode; - - if (!use_get) { - Ref<VisualScriptPropertySet> pset; - pset.instantiate(); - if (sn == node) { - pset->set_call_mode(VisualScriptPropertySet::CALL_MODE_SELF); - } else { - pset->set_call_mode(VisualScriptPropertySet::CALL_MODE_NODE_PATH); - pset->set_base_path(sn->get_path_to(node)); - } - vnode = pset; - } else { - Ref<VisualScriptPropertyGet> pget; - pget.instantiate(); - if (sn == node) { - pget->set_call_mode(VisualScriptPropertyGet::CALL_MODE_SELF); - } else { - pget->set_call_mode(VisualScriptPropertyGet::CALL_MODE_NODE_PATH); - pget->set_base_path(sn->get_path_to(node)); - } - vnode = pget; - } - undo_redo->add_do_method(script.ptr(), "add_node", base_id, vnode, pos); - undo_redo->add_do_method(vnode.ptr(), "set_property", d["property"]); - if (!obj->get_script().is_null()) { - undo_redo->add_do_method(vnode.ptr(), "set_base_script", Ref<Script>(obj->get_script())->get_path()); - } - if (!use_get) { - undo_redo->add_do_method(vnode.ptr(), "set_default_input_value", 0, d["value"]); - } - - undo_redo->add_undo_method(script.ptr(), "remove_node", base_id); - - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - undo_redo->commit_action(); - } - } -} - -void VisualScriptEditor::_draw_color_over_button(Object *obj, Color p_color) { - Button *button = Object::cast_to<Button>(obj); - if (!button) { - return; - } - - Ref<StyleBox> normal = get_theme_stylebox(SNAME("normal"), SNAME("Button")); - button->draw_rect(Rect2(normal->get_offset(), button->get_size() - normal->get_minimum_size()), p_color); -} - -void VisualScriptEditor::_button_resource_previewed(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, Variant p_ud) { - Array ud = p_ud; - ERR_FAIL_COND(ud.size() != 2); - - ObjectID id = ud[0]; - Object *obj = ObjectDB::get_instance(id); - - if (!obj) { - return; - } - - Button *b = Object::cast_to<Button>(obj); - ERR_FAIL_COND(!b); - - if (p_preview.is_null()) { - b->set_text(ud[1]); - } else { - b->set_icon(p_preview); - } -} - -///////////////////////// - -void VisualScriptEditor::apply_code() { -} - -Ref<Resource> VisualScriptEditor::get_edited_resource() const { - return script; -} - -void VisualScriptEditor::set_edited_resource(const Ref<Resource> &p_res) { - ERR_FAIL_COND(script.is_valid()); - ERR_FAIL_COND(p_res.is_null()); - script = p_res; - signal_editor->script = script; - signal_editor->undo_redo = undo_redo; - variable_editor->script = script; - variable_editor->undo_redo = undo_redo; - - script->connect("node_ports_changed", callable_mp(this, &VisualScriptEditor::_node_ports_changed)); - - _update_graph(); - call_deferred(SNAME("_update_members")); -} - -void VisualScriptEditor::enable_editor() { -} - -Vector<String> VisualScriptEditor::get_functions() { - return Vector<String>(); -} - -void VisualScriptEditor::reload_text() { -} - -String VisualScriptEditor::get_name() { - String name; - - name = script->get_path().get_file(); - if (name.is_empty()) { - // This appears for newly created built-in scripts before saving the scene. - name = TTR("[unsaved]"); - } else if (script->is_built_in()) { - const String &script_name = script->get_name(); - if (!script_name.is_empty()) { - // If the built-in script has a custom resource name defined, - // display the built-in script name as follows: `ResourceName (scene_file.tscn)` - name = vformat("%s (%s)", script_name, name.get_slice("::", 0)); - } - } - - if (is_unsaved()) { - name += "(*)"; - } - - return name; -} - -Ref<Texture2D> VisualScriptEditor::get_theme_icon() { - String icon_name = "VisualScript"; - if (script->is_built_in()) { - icon_name += "Internal"; - } - - if (Control::has_theme_icon(icon_name, "EditorIcons")) { - return Control::get_theme_icon(icon_name, SNAME("EditorIcons")); - } - - return Control::get_theme_icon(SNAME("VisualScript"), SNAME("EditorIcons")); -} - -bool VisualScriptEditor::is_unsaved() { - bool unsaved = - script->is_edited() || - script->are_subnodes_edited() || - script->get_path().is_empty(); // In memory. - return unsaved; -} - -Variant VisualScriptEditor::get_edit_state() { - Dictionary d; - d["scroll"] = graph->get_scroll_ofs(); - d["zoom"] = graph->get_zoom(); - d["using_snap"] = graph->is_using_snap(); - d["snap"] = graph->get_snap(); - return d; -} - -void VisualScriptEditor::set_edit_state(const Variant &p_state) { - Dictionary d = p_state; - - _update_graph(); - _update_members(); - - if (d.has("scroll")) { - graph->set_scroll_ofs(d["scroll"]); - } - if (d.has("zoom")) { - graph->set_zoom(d["zoom"]); - } - if (d.has("snap")) { - graph->set_snap(d["snap"]); - } - if (d.has("snap_enabled")) { - graph->set_use_snap(d["snap_enabled"]); - } -} - -void VisualScriptEditor::_center_on_node(int p_id) { - Node *n = graph->get_node(itos(p_id)); - GraphNode *gn = Object::cast_to<GraphNode>(n); - - // Clear selection. - for (int i = 0; i < graph->get_child_count(); i++) { - GraphNode *gnd = Object::cast_to<GraphNode>(graph->get_child(i)); - if (gnd) { - gnd->set_selected(false); - } - } - - if (gn) { - gn->set_selected(true); - Vector2 new_scroll = gn->get_position_offset() * graph->get_zoom() - graph->get_size() * 0.5 + gn->get_size() * 0.5; - graph->set_scroll_ofs(new_scroll); - script->set_scroll(new_scroll / EDSCALE); - script->set_edited(true); - } -} - -void VisualScriptEditor::goto_line(int p_line, bool p_with_error) { - p_line += 1; // Add one because script lines begin from 0. - - if (p_with_error) { - error_line = p_line; - } - - if (script->has_node(p_line)) { - _update_graph(); - _update_members(); - - call_deferred(SNAME("call_deferred"), "_center_on_node", p_line); // The editor might be just created and size might not exist yet. - } -} - -void VisualScriptEditor::set_executing_line(int p_line) { - // todo: add a way to show which node is executing right now. -} - -void VisualScriptEditor::clear_executing_line() { - // todo: add a way to show which node is executing right now. -} - -void VisualScriptEditor::trim_trailing_whitespace() { -} - -void VisualScriptEditor::insert_final_newline() { -} - -void VisualScriptEditor::convert_indent_to_spaces() { -} - -void VisualScriptEditor::convert_indent_to_tabs() { -} - -void VisualScriptEditor::ensure_focus() { - graph->grab_focus(); -} - -void VisualScriptEditor::tag_saved_version() { -} - -void VisualScriptEditor::reload(bool p_soft) { - _update_graph(); -} - -PackedInt32Array VisualScriptEditor::get_breakpoints() { - PackedInt32Array breakpoints; - List<StringName> functions; - script->get_function_list(&functions); - for (int i = 0; i < functions.size(); i++) { - List<int> nodes; - script->get_node_list(&nodes); - for (int &F : nodes) { - Ref<VisualScriptNode> vsn = script->get_node(F); - if (vsn->is_breakpoint()) { - breakpoints.push_back(F - 1); // Subtract 1 because breakpoints in text start from zero. - } - } - } - return breakpoints; -} - -void VisualScriptEditor::add_callback(const String &p_function, PackedStringArray p_args) { - if (script->has_function(p_function)) { - _update_members(); - _update_graph(); - _center_on_node(script->get_function_node_id(p_function)); - return; - } - - Ref<VisualScriptFunction> func; - func.instantiate(); - for (int i = 0; i < p_args.size(); i++) { - String name = p_args[i]; - Variant::Type type = Variant::NIL; - - if (name.contains(":")) { - String tt = name.get_slice(":", 1); - name = name.get_slice(":", 0); - for (int j = 0; j < Variant::VARIANT_MAX; j++) { - String tname = Variant::get_type_name(Variant::Type(j)); - if (tname == tt) { - type = Variant::Type(j); - break; - } - } - } - - func->add_argument(type, name); - } - int fn_id = script->get_available_id(); - func->set_name(p_function); - script->add_function(p_function, fn_id); - script->add_node(fn_id, func); - - _update_members(); - _update_graph(); - - _center_on_node(script->get_function_node_id(p_function)); -} - -bool VisualScriptEditor::show_members_overview() { - return false; -} - -void VisualScriptEditor::update_settings() { - _update_graph(); -} - -void VisualScriptEditor::set_debugger_active(bool p_active) { - if (!p_active) { - error_line = -1; - _update_graph(); //clear line break - } -} - -Control *VisualScriptEditor::get_base_editor() const { - return graph; -} - -void VisualScriptEditor::set_tooltip_request_func(const Callable &p_toolip_callback) { -} - -Control *VisualScriptEditor::get_edit_menu() { - return edit_menu; -} - -void VisualScriptEditor::_change_base_type() { - select_base_type->popup_create(true, true, script->get_instance_base_type()); -} - -void VisualScriptEditor::_toggle_tool_script() { - script->set_tool_enabled(!script->is_tool()); -} - -void VisualScriptEditor::clear_edit_menu() { - memdelete(edit_menu); - memdelete(members_section); -} - -void VisualScriptEditor::_change_base_type_callback() { - String bt = select_base_type->get_selected_type(); - - ERR_FAIL_COND(bt.is_empty()); - undo_redo->create_action(TTR("Change Base Type")); - undo_redo->add_do_method(script.ptr(), "set_instance_base_type", bt); - undo_redo->add_undo_method(script.ptr(), "set_instance_base_type", script->get_instance_base_type()); - undo_redo->add_do_method(this, "_update_members"); - undo_redo->add_undo_method(this, "_update_members"); - undo_redo->commit_action(); -} - -void VisualScriptEditor::_node_selected(Node *p_node) { - Ref<VisualScriptNode> vnode = p_node->get_meta("__vnode"); - if (vnode.is_null()) { - return; - } - - EditorNode::get_singleton()->push_item(vnode.ptr()); //edit node in inspector -} - -static bool _get_out_slot(const Ref<VisualScriptNode> &p_node, int p_slot, int &r_real_slot, bool &r_sequence) { - if (p_slot < p_node->get_output_sequence_port_count()) { - r_sequence = true; - r_real_slot = p_slot; - - return true; - } - - r_real_slot = p_slot - p_node->get_output_sequence_port_count(); - r_sequence = false; - - return (r_real_slot < p_node->get_output_value_port_count()); -} - -static bool _get_in_slot(const Ref<VisualScriptNode> &p_node, int p_slot, int &r_real_slot, bool &r_sequence) { - if (p_slot == 0 && p_node->has_input_sequence_port()) { - r_sequence = true; - r_real_slot = 0; - return true; - } - - r_real_slot = p_slot - (p_node->has_input_sequence_port() ? 1 : 0); - r_sequence = false; - - return r_real_slot < p_node->get_input_value_port_count(); -} - -void VisualScriptEditor::_begin_node_move() { - undo_redo->create_action(TTR("Move Node(s)")); -} - -void VisualScriptEditor::_end_node_move() { - undo_redo->commit_action(); -} - -void VisualScriptEditor::_move_node(int p_id, const Vector2 &p_to) { - if (!script->has_node(p_id)) { - return; - } - - Node *node = graph->get_node(itos(p_id)); - - if (Object::cast_to<GraphNode>(node)) { - Object::cast_to<GraphNode>(node)->set_position_offset(p_to); - } - - script->set_node_position(p_id, p_to / EDSCALE); -} - -void VisualScriptEditor::_node_moved(Vector2 p_from, Vector2 p_to, int p_id) { - undo_redo->add_do_method(this, "_move_node", p_id, p_to); - undo_redo->add_undo_method(this, "_move_node", p_id, p_from); -} - -void VisualScriptEditor::_remove_node(int p_id) { - undo_redo->create_action(TTR("Remove VisualScript Node")); - - undo_redo->add_do_method(script.ptr(), "remove_node", p_id); - undo_redo->add_undo_method(script.ptr(), "add_node", p_id, script->get_node(p_id), script->get_node_position(p_id)); - - List<VisualScript::SequenceConnection> sequence_conns; - script->get_sequence_connection_list(&sequence_conns); - - for (const VisualScript::SequenceConnection &E : sequence_conns) { - if (E.from_node == p_id || E.to_node == p_id) { - undo_redo->add_undo_method(script.ptr(), "sequence_connect", E.from_node, E.from_output, E.to_node); - } - } - - List<VisualScript::DataConnection> data_conns; - script->get_data_connection_list(&data_conns); - - for (const VisualScript::DataConnection &E : data_conns) { - if (E.from_node == p_id || E.to_node == p_id) { - undo_redo->add_undo_method(script.ptr(), "data_connect", E.from_node, E.from_port, E.to_node, E.to_port); - } - } - - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - - undo_redo->commit_action(); -} - -void VisualScriptEditor::_node_ports_changed(int p_id) { - _update_graph(p_id); -} - -bool VisualScriptEditor::node_has_sequence_connections(int p_id) { - List<VisualScript::SequenceConnection> sequence_conns; - script->get_sequence_connection_list(&sequence_conns); - - for (const VisualScript::SequenceConnection &E : sequence_conns) { - int from = E.from_node; - int to = E.to_node; - - if (to == p_id || from == p_id) { - return true; - } - } - - return false; -} - -void VisualScriptEditor::_graph_connected(const String &p_from, int p_from_slot, const String &p_to, int p_to_slot) { - Ref<VisualScriptNode> from_node = script->get_node(p_from.to_int()); - ERR_FAIL_COND(!from_node.is_valid()); - - bool from_seq; - int from_port; - - if (!_get_out_slot(from_node, p_from_slot, from_port, from_seq)) { - return; //can't connect this, it's invalid - } - - Ref<VisualScriptNode> to_node = script->get_node(p_to.to_int()); - ERR_FAIL_COND(!to_node.is_valid()); - - bool to_seq; - int to_port; - - if (!_get_in_slot(to_node, p_to_slot, to_port, to_seq)) { - return; //can't connect this, it's invalid - } - - ERR_FAIL_COND(from_seq != to_seq); - - // Checking to prevent warnings. - if (from_seq) { - if (script->has_sequence_connection(p_from.to_int(), from_port, p_to.to_int())) { - return; - } - } else if (script->has_data_connection(p_from.to_int(), from_port, p_to.to_int(), to_port)) { - return; - } - - // Preventing connection to itself. - if (p_from.to_int() == p_to.to_int()) { - return; - } - - // Do all the checks here. - StringName func; // This the func where we store the one the nodes at the end of the resolution on having multiple nodes. - - undo_redo->create_action(TTR("Connect Nodes")); - - if (from_seq) { - undo_redo->add_do_method(script.ptr(), "sequence_connect", p_from.to_int(), from_port, p_to.to_int()); - // This undo error on undo after move can't be removed without painful gymnastics - undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", p_from.to_int(), from_port, p_to.to_int()); - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - } else { - bool converted = false; - - Ref<VisualScriptOperator> oper = to_node; - if (oper.is_valid() && oper->get_typed() == Variant::NIL) { - // It's an operator Node and if the type is already nil - if (from_node->get_output_value_port_info(from_port).type != Variant::NIL) { - oper->set_typed(from_node->get_output_value_port_info(from_port).type); - } - } - - Ref<VisualScriptOperator> operf = from_node; - if (operf.is_valid() && operf->get_typed() == Variant::NIL) { - // It's an operator Node and if the type is already nil - if (to_node->get_input_value_port_info(to_port).type != Variant::NIL) { - operf->set_typed(to_node->get_input_value_port_info(to_port).type); - } - } - - // Disconnect current, and connect the new one - if (script->is_input_value_port_connected(p_to.to_int(), to_port)) { - if (can_swap && data_disconnect_node == p_to.to_int()) { - int conn_from; - int conn_port; - script->get_input_value_port_connection_source(p_to.to_int(), to_port, &conn_from, &conn_port); - undo_redo->add_do_method(script.ptr(), "data_disconnect", conn_from, conn_port, p_to.to_int(), to_port); - undo_redo->add_do_method(script.ptr(), "data_connect", conn_from, conn_port, data_disconnect_node, data_disconnect_port); - undo_redo->add_undo_method(script.ptr(), "data_disconnect", conn_from, conn_port, data_disconnect_node, data_disconnect_port); - undo_redo->add_undo_method(script.ptr(), "data_connect", conn_from, conn_port, p_to.to_int(), to_port); - can_swap = false; // swapped - } else { - int conn_from; - int conn_port; - script->get_input_value_port_connection_source(p_to.to_int(), to_port, &conn_from, &conn_port); - undo_redo->add_do_method(script.ptr(), "data_disconnect", conn_from, conn_port, p_to.to_int(), to_port); - undo_redo->add_undo_method(script.ptr(), "data_connect", conn_from, conn_port, p_to.to_int(), to_port); - } - } - if (!converted) { - undo_redo->add_do_method(script.ptr(), "data_connect", p_from.to_int(), from_port, p_to.to_int(), to_port); - undo_redo->add_undo_method(script.ptr(), "data_disconnect", p_from.to_int(), from_port, p_to.to_int(), to_port); - - // Update nodes in graph - undo_redo->add_do_method(this, "_update_graph", p_from.to_int()); - undo_redo->add_do_method(this, "_update_graph", p_to.to_int()); - undo_redo->add_undo_method(this, "_update_graph", p_from.to_int()); - undo_redo->add_undo_method(this, "_update_graph", p_to.to_int()); - } else { - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - } - } - - undo_redo->commit_action(); -} - -void VisualScriptEditor::_graph_disconnected(const String &p_from, int p_from_slot, const String &p_to, int p_to_slot) { - Ref<VisualScriptNode> from_node = script->get_node(p_from.to_int()); - ERR_FAIL_COND(!from_node.is_valid()); - - bool from_seq; - int from_port; - - if (!_get_out_slot(from_node, p_from_slot, from_port, from_seq)) { - return; // Can't connect this, it's invalid. - } - - Ref<VisualScriptNode> to_node = script->get_node(p_to.to_int()); - ERR_FAIL_COND(!to_node.is_valid()); - - bool to_seq; - int to_port; - - if (!_get_in_slot(to_node, p_to_slot, to_port, to_seq)) { - return; // Can't connect this, it's invalid. - } - - ERR_FAIL_COND(from_seq != to_seq); - - undo_redo->create_action(TTR("Disconnect Nodes")); - - if (from_seq) { - undo_redo->add_do_method(script.ptr(), "sequence_disconnect", p_from.to_int(), from_port, p_to.to_int()); - undo_redo->add_undo_method(script.ptr(), "sequence_connect", p_from.to_int(), from_port, p_to.to_int()); - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - } else { - can_swap = true; - data_disconnect_node = p_to.to_int(); - data_disconnect_port = to_port; - - undo_redo->add_do_method(script.ptr(), "data_disconnect", p_from.to_int(), from_port, p_to.to_int(), to_port); - undo_redo->add_undo_method(script.ptr(), "data_connect", p_from.to_int(), from_port, p_to.to_int(), to_port); - // Update relevant nodes in the graph. - undo_redo->add_do_method(this, "_update_graph", p_from.to_int()); - undo_redo->add_do_method(this, "_update_graph", p_to.to_int()); - undo_redo->add_undo_method(this, "_update_graph", p_from.to_int()); - undo_redo->add_undo_method(this, "_update_graph", p_to.to_int()); - } - - undo_redo->commit_action(); -} - -void VisualScriptEditor::_graph_connect_to_empty(const String &p_from, int p_from_slot, const Vector2 &p_release_pos) { - Node *node = graph->get_node(p_from); - GraphNode *gn = Object::cast_to<GraphNode>(node); - if (!gn) { - return; - } - - Ref<VisualScriptNode> vsn = script->get_node(p_from.to_int()); - if (!vsn.is_valid()) { - return; - } - if (vsn->get_output_value_port_count() || vsn->get_output_sequence_port_count()) { - port_action_pos = p_release_pos; - } - - if (p_from_slot < vsn->get_output_sequence_port_count()) { - port_action_node = p_from.to_int(); - port_action_output = p_from_slot; - _port_action_menu(CREATE_ACTION); - } else { - port_action_output = p_from_slot - vsn->get_output_sequence_port_count(); - port_action_node = p_from.to_int(); - _port_action_menu(CREATE_CALL_SET_GET); - } -} - -VisualScriptNode::TypeGuess VisualScriptEditor::_guess_output_type(int p_port_action_node, int p_port_action_output, RBSet<int> &visited_nodes) { - VisualScriptNode::TypeGuess tg; - tg.type = Variant::NIL; - - if (visited_nodes.has(p_port_action_node)) { - return tg; //no loop - } - - visited_nodes.insert(p_port_action_node); - - Ref<VisualScriptNode> node = script->get_node(p_port_action_node); - - if (!node.is_valid() || node->get_output_value_port_count() <= p_port_action_output) { - return tg; - } - - Vector<VisualScriptNode::TypeGuess> in_guesses; - - for (int i = 0; i < node->get_input_value_port_count(); i++) { - PropertyInfo pi = node->get_input_value_port_info(i); - VisualScriptNode::TypeGuess g; - g.type = pi.type; - - if (g.type == Variant::NIL || g.type == Variant::OBJECT) { - // Any or object input, must further guess what this is. - int from_node; - int from_port; - - if (script->get_input_value_port_connection_source(p_port_action_node, i, &from_node, &from_port)) { - g = _guess_output_type(from_node, from_port, visited_nodes); - } else { - Variant defval = node->get_default_input_value(i); - if (defval.get_type() == Variant::OBJECT) { - Object *obj = defval; - - if (obj) { - g.type = Variant::OBJECT; - g.gdclass = obj->get_class(); - g.script = obj->get_script(); - } - } - } - } - - in_guesses.push_back(g); - } - - return node->guess_output_type(in_guesses.ptrw(), p_port_action_output); -} - -void VisualScriptEditor::_port_action_menu(int p_option) { - RBSet<int> vn; - - switch (p_option) { - case CREATE_CALL_SET_GET: { - Ref<VisualScriptFunctionCall> n; - n.instantiate(); - - VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn); - - if (tg.gdclass != StringName()) { - n->set_base_type(tg.gdclass); - } else { - n->set_base_type("Object"); - } - String type_string; - String base_script = ""; - if (script->get_node(port_action_node)->get_output_value_port_count() > 0) { - type_string = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint_string; - VisualScriptFunctionCall *vsfc = Object::cast_to<VisualScriptFunctionCall>(*script->get_node(port_action_node)); - if (vsfc) { - base_script = vsfc->get_base_script(); - } else { - VisualScriptPropertyGet *vspg = Object::cast_to<VisualScriptPropertyGet>(*script->get_node(port_action_node)); - if (vspg) { - base_script = vspg->get_base_script(); - } else { - VisualScriptPropertySet *vsps = Object::cast_to<VisualScriptPropertySet>(*script->get_node(port_action_node)); - if (vsps) { - base_script = vsps->get_base_script(); - } - } - } - } - if (tg.type == Variant::OBJECT) { - if (tg.script.is_valid()) { - new_connect_node_select->select_from_script(tg.script); - } else if (type_string != String()) { - new_connect_node_select->select_from_base_type(type_string, base_script); - } else { - new_connect_node_select->select_from_base_type(n->get_base_type(), base_script); - } - } else if (tg.type == Variant::NIL) { - new_connect_node_select->select_from_base_type("", base_script); - } else { - new_connect_node_select->select_from_basic_type(tg.type); - } - // Ensure that the dialog fits inside the graph. - Vector2 pos = mouse_up_position; - Size2 bounds = graph->get_global_position() + graph->get_size() - new_connect_node_select->get_size(); - pos.x = pos.x > bounds.x ? bounds.x : pos.x; - pos.y = pos.y > bounds.y ? bounds.y : pos.y; - new_connect_node_select->set_position(pos); - } break; - case CREATE_ACTION: { - VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn); - PropertyInfo property_info; - if (script->get_node(port_action_node)->get_output_value_port_count() > 0) { - property_info = script->get_node(port_action_node)->get_output_value_port_info(port_action_output); - } - if (tg.type == Variant::OBJECT) { - if (property_info.type == Variant::OBJECT && !property_info.hint_string.is_empty()) { - new_connect_node_select->select_from_action(property_info.hint_string); - } else { - new_connect_node_select->select_from_action(""); - } - } else if (tg.type == Variant::NIL) { - new_connect_node_select->select_from_action(""); - } else { - new_connect_node_select->select_from_action(Variant::get_type_name(tg.type)); - } - // Ensure that the dialog fits inside the graph. - Vector2 pos = mouse_up_position; - Size2 bounds = graph->get_global_position() + graph->get_size() - new_connect_node_select->get_size(); - pos.x = pos.x > bounds.x ? bounds.x : pos.x; - pos.y = pos.y > bounds.y ? bounds.y : pos.y; - new_connect_node_select->set_position(pos); - } break; - } -} - -void VisualScriptEditor::connect_data(Ref<VisualScriptNode> vnode_old, Ref<VisualScriptNode> vnode, int new_id) { - undo_redo->create_action(TTR("Connect Node Data")); - VisualScriptReturn *vnode_return = Object::cast_to<VisualScriptReturn>(vnode.ptr()); - if (vnode_return != nullptr && vnode_old->get_output_value_port_count() > 0) { - vnode_return->set_enable_return_value(true); - } - if (vnode_old->get_output_value_port_count() <= 0) { - undo_redo->commit_action(); - return; - } - if (vnode->get_input_value_port_count() <= 0) { - undo_redo->commit_action(); - return; - } - int port = port_action_output; - int value_count = vnode_old->get_output_value_port_count(); - if (port >= value_count) { - port = 0; - } - undo_redo->add_do_method(script.ptr(), "data_connect", port_action_node, port, new_id, 0); - undo_redo->add_undo_method(script.ptr(), "data_disconnect", port_action_node, port, new_id, 0); - undo_redo->commit_action(); -} - -void VisualScriptEditor::_selected_connect_node(const String &p_text, const String &p_category, const bool p_connecting) { -#ifdef MACOS_ENABLED - bool held_ctrl = Input::get_singleton()->is_key_pressed(Key::META); -#else - bool held_ctrl = Input::get_singleton()->is_key_pressed(Key::CTRL); -#endif - Vector2 pos = _get_pos_in_graph(port_action_pos); - - RBSet<int> vn; - bool port_node_exists = true; - - if (drop_position != Vector2()) { - pos = drop_position; - } - drop_position = Vector2(); - - Ref<VisualScriptNode> vnode; - Ref<VisualScriptNode> vnode_old; - if (port_node_exists && p_connecting) { - vnode_old = script->get_node(port_action_node); - } - - if (p_category.begins_with("VisualScriptNode")) { - Ref<VisualScriptNode> n = VisualScriptLanguage::singleton->create_node_from_name(p_text); - - if (Object::cast_to<VisualScriptTypeCast>(n.ptr()) && vnode_old.is_valid()) { - Variant::Type type = vnode_old->get_output_value_port_info(port_action_output).type; - String hint_name = vnode_old->get_output_value_port_info(port_action_output).hint_string; - - if (type == Variant::OBJECT) { - Object::cast_to<VisualScriptTypeCast>(n.ptr())->set_base_type(hint_name); - } else if (type == Variant::NIL) { - Object::cast_to<VisualScriptTypeCast>(n.ptr())->set_base_type(""); - } else { - Object::cast_to<VisualScriptTypeCast>(n.ptr())->set_base_type(Variant::get_type_name(type)); - } - } - vnode = n; - } - - if (p_category == String("Class") && !p_connecting) { - Ref<VisualScriptFunctionCall> n; - n.instantiate(); - n->set_call_mode(VisualScriptFunctionCall::CALL_MODE_SINGLETON); - n->set_singleton("ClassDB"); - n->set_function("instantiate"); - // Did not find a way to edit the input port value - vnode = n; - } else if (p_category == String("class_method")) { - Ref<VisualScriptFunctionCall> n; - n.instantiate(); - if (!drop_path.is_empty()) { - if (drop_path == ".") { - n->set_call_mode(VisualScriptFunctionCall::CALL_MODE_SELF); - } else { - n->set_call_mode(VisualScriptFunctionCall::CALL_MODE_NODE_PATH); - n->set_base_path(drop_path); - } - } else { - n->set_call_mode(VisualScriptFunctionCall::CALL_MODE_INSTANCE); - } - if (drop_node) { - n->set_base_type(drop_node->get_class()); - if (drop_node->get_script_instance()) { - n->set_base_script(drop_node->get_script_instance()->get_script()->get_path()); - } - } - vnode = n; - } else if (p_category == String("class_property")) { - Vector<String> property_path = p_text.split(":"); - if (held_ctrl) { - Ref<VisualScriptPropertySet> n; - n.instantiate(); - n->set_property(property_path[1]); - if (!drop_path.is_empty()) { - if (drop_path == ".") { - n->set_call_mode(VisualScriptPropertySet::CALL_MODE_SELF); - } else { - n->set_call_mode(VisualScriptPropertySet::CALL_MODE_NODE_PATH); - n->set_base_path(drop_path); - } - } - if (drop_node) { - n->set_base_type(drop_node->get_class()); - if (drop_node->get_script_instance()) { - n->set_base_script(drop_node->get_script_instance()->get_script()->get_path()); - } - } - vnode = n; - } else { - Ref<VisualScriptPropertyGet> n; - n.instantiate(); - n->set_property(property_path[1]); - if (!drop_path.is_empty()) { - if (drop_path == ".") { - n->set_call_mode(VisualScriptPropertyGet::CALL_MODE_SELF); - } else { - n->set_call_mode(VisualScriptPropertyGet::CALL_MODE_NODE_PATH); - n->set_base_path(drop_path); - } - } - if (drop_node) { - n->set_base_type(drop_node->get_class()); - if (drop_node->get_script_instance()) { - n->set_base_script(drop_node->get_script_instance()->get_script()->get_path()); - } - } - vnode = n; - } - } else if (p_category == String("class_constant")) { - Vector<String> property_path = p_text.split(":"); - if (ClassDB::class_exists(property_path[0])) { - Ref<VisualScriptClassConstant> n; - n.instantiate(); - n->set_base_type(property_path[0]); - n->set_class_constant(property_path[1]); - vnode = n; - } else { - Ref<VisualScriptBasicTypeConstant> n; - n.instantiate(); - if (property_path[0] == "Nil") { - n->set_basic_type(Variant::NIL); - } else if (property_path[0] == "bool") { - n->set_basic_type(Variant::BOOL); - } else if (property_path[0] == "int") { - n->set_basic_type(Variant::INT); - } else if (property_path[0] == "float") { - n->set_basic_type(Variant::FLOAT); - } else if (property_path[0] == "String") { - n->set_basic_type(Variant::STRING); - } else if (property_path[0] == "Vector2") { - n->set_basic_type(Variant::VECTOR2); - } else if (property_path[0] == "Vector2i") { - n->set_basic_type(Variant::VECTOR2I); - } else if (property_path[0] == "Rect2") { - n->set_basic_type(Variant::RECT2); - } else if (property_path[0] == "Rect2i") { - n->set_basic_type(Variant::RECT2I); - } else if (property_path[0] == "Transform2D") { - n->set_basic_type(Variant::TRANSFORM2D); - } else if (property_path[0] == "Vector3") { - n->set_basic_type(Variant::VECTOR3); - } else if (property_path[0] == "Vector3i") { - n->set_basic_type(Variant::VECTOR3I); - } else if (property_path[0] == "Plane") { - n->set_basic_type(Variant::PLANE); - } else if (property_path[0] == "ABB") { - n->set_basic_type(Variant::AABB); - } else if (property_path[0] == "Quaternion") { - n->set_basic_type(Variant::QUATERNION); - } else if (property_path[0] == "Basis") { - n->set_basic_type(Variant::BASIS); - } else if (property_path[0] == "Transform3D") { - n->set_basic_type(Variant::TRANSFORM3D); - } else if (property_path[0] == "Color") { - n->set_basic_type(Variant::COLOR); - } else if (property_path[0] == "RID") { - n->set_basic_type(Variant::RID); - } else if (property_path[0] == "Object") { - n->set_basic_type(Variant::OBJECT); - } else if (property_path[0] == "Callable") { - n->set_basic_type(Variant::CALLABLE); - } else if (property_path[0] == "Signal") { - n->set_basic_type(Variant::SIGNAL); - } else if (property_path[0] == "StringName") { - n->set_basic_type(Variant::STRING_NAME); - } else if (property_path[0] == "NodePath") { - n->set_basic_type(Variant::NODE_PATH); - } else if (property_path[0] == "Dictionary") { - n->set_basic_type(Variant::DICTIONARY); - } else if (property_path[0] == "Array") { - n->set_basic_type(Variant::ARRAY); - } else if (property_path[0] == "PackedByteArray") { - n->set_basic_type(Variant::PACKED_BYTE_ARRAY); - } else if (property_path[0] == "PackedInt32Array") { - n->set_basic_type(Variant::PACKED_INT32_ARRAY); - } else if (property_path[0] == "PackedInt64Array") { - n->set_basic_type(Variant::PACKED_INT64_ARRAY); - } else if (property_path[0] == "PackedFloat32Array") { - n->set_basic_type(Variant::PACKED_FLOAT32_ARRAY); - } else if (property_path[0] == "PackedStringArray") { - n->set_basic_type(Variant::PACKED_STRING_ARRAY); - } else if (property_path[0] == "PackedVector2Array") { - n->set_basic_type(Variant::PACKED_VECTOR2_ARRAY); - } else if (property_path[0] == "PackedVector3Array") { - n->set_basic_type(Variant::PACKED_VECTOR3_ARRAY); - } else if (property_path[0] == "PackedColorArray") { - n->set_basic_type(Variant::PACKED_COLOR_ARRAY); - } - n->set_basic_type_constant(property_path[1]); - vnode = n; - } - - } else if (p_category == String("class_signal")) { - Vector<String> property_path = p_text.split(":"); - ERR_FAIL_COND(!(script->has_custom_signal(property_path[1]) || ClassDB::has_signal(script->get_instance_base_type(), property_path[1]))); - - Ref<VisualScriptEmitSignal> n; - n.instantiate(); - n->set_signal(property_path[1]); - vnode = n; - } - if (vnode == nullptr) { - print_error("Category not handled: " + p_category.quote()); - } - - if (Object::cast_to<VisualScriptFunctionCall>(vnode.ptr()) && p_category != "Class" && p_category != "VisualScriptNode") { - Vector<String> property_path = p_text.split(":"); - String class_of_method = property_path[0]; - String method_name = property_path[1]; - - Ref<VisualScriptFunctionCall> vsfc = vnode; - vsfc->set_function(method_name); - - if (port_node_exists && p_connecting) { - VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn); - - if (tg.type == Variant::OBJECT) { - vsfc->set_call_mode(VisualScriptFunctionCall::CALL_MODE_INSTANCE); - vsfc->set_base_type(String("")); - if (tg.gdclass != StringName()) { - vsfc->set_base_type(tg.gdclass); - } else if (script->get_node(port_action_node).is_valid()) { - PropertyHint hint = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint; - String base_type = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint_string; - - if (!base_type.is_empty() && hint == PROPERTY_HINT_TYPE_STRING) { - vsfc->set_base_type(base_type); - } - if (method_name == "call" || method_name == "call_deferred") { - vsfc->set_function(String("")); - } - } - if (tg.script.is_valid()) { - vsfc->set_base_script(tg.script->get_path()); - } - } else if (tg.type == Variant::NIL) { - vsfc->set_call_mode(VisualScriptFunctionCall::CALL_MODE_INSTANCE); - vsfc->set_base_type(String("")); - } else { - vsfc->set_call_mode(VisualScriptFunctionCall::CALL_MODE_BASIC_TYPE); - vsfc->set_basic_type(tg.type); - } - } - } - - if (port_node_exists && p_connecting) { - if (Object::cast_to<VisualScriptPropertySet>(vnode.ptr())) { - Ref<VisualScriptPropertySet> vsp = vnode; - - VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn); - if (tg.type == Variant::OBJECT) { - vsp->set_call_mode(VisualScriptPropertySet::CALL_MODE_INSTANCE); - vsp->set_base_type(String("")); - if (tg.gdclass != StringName()) { - vsp->set_base_type(tg.gdclass); - - } else if (script->get_node(port_action_node).is_valid()) { - PropertyHint hint = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint; - String base_type = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint_string; - - if (!base_type.is_empty() && hint == PROPERTY_HINT_TYPE_STRING) { - vsp->set_base_type(base_type); - } - } - if (tg.script.is_valid()) { - vsp->set_base_script(tg.script->get_path()); - } - } else if (tg.type == Variant::NIL) { - vsp->set_call_mode(VisualScriptPropertySet::CALL_MODE_INSTANCE); - vsp->set_base_type(String("")); - } else { - vsp->set_call_mode(VisualScriptPropertySet::CALL_MODE_BASIC_TYPE); - vsp->set_basic_type(tg.type); - } - } - - if (Object::cast_to<VisualScriptPropertyGet>(vnode.ptr())) { - Ref<VisualScriptPropertyGet> vsp = vnode; - - VisualScriptNode::TypeGuess tg = _guess_output_type(port_action_node, port_action_output, vn); - if (tg.type == Variant::OBJECT) { - vsp->set_call_mode(VisualScriptPropertyGet::CALL_MODE_INSTANCE); - vsp->set_base_type(String("")); - if (tg.gdclass != StringName()) { - vsp->set_base_type(tg.gdclass); - - } else if (script->get_node(port_action_node).is_valid()) { - PropertyHint hint = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint; - String base_type = script->get_node(port_action_node)->get_output_value_port_info(port_action_output).hint_string; - if (!base_type.is_empty() && hint == PROPERTY_HINT_TYPE_STRING) { - vsp->set_base_type(base_type); - } - } - if (tg.script.is_valid()) { - vsp->set_base_script(tg.script->get_path()); - } - } else if (tg.type == Variant::NIL) { - vsp->set_call_mode(VisualScriptPropertyGet::CALL_MODE_INSTANCE); - vsp->set_base_type(String("")); - } else { - vsp->set_call_mode(VisualScriptPropertyGet::CALL_MODE_BASIC_TYPE); - vsp->set_basic_type(tg.type); - } - } - } - if (vnode == nullptr) { - print_error("Not able to create node from category: \"" + p_category + "\" and text \"" + p_text + "\" Not created"); - return; - } - - int new_id = script->get_available_id(); - undo_redo->create_action(TTR("Add Node")); - undo_redo->add_do_method(script.ptr(), "add_node", new_id, vnode, pos); - undo_redo->add_undo_method(script.ptr(), "remove_node", new_id); - undo_redo->add_do_method(this, "_update_graph", new_id); - undo_redo->add_undo_method(this, "_update_graph", new_id); - undo_redo->commit_action(); - - port_action_new_node = new_id; - - String base_script = ""; - String base_type = ""; - if (port_node_exists) { - if (vnode_old.is_valid()) { - if (Object::cast_to<VisualScriptTypeCast>(vnode_old.ptr())) { - base_type = Object::cast_to<VisualScriptTypeCast>(vnode_old.ptr())->get_base_type(); - base_script = Object::cast_to<VisualScriptTypeCast>(vnode_old.ptr())->get_base_script(); - } else if (Object::cast_to<VisualScriptFunctionCall>(vnode_old.ptr())) { - base_type = Object::cast_to<VisualScriptFunctionCall>(vnode_old.ptr())->get_base_type(); - base_script = Object::cast_to<VisualScriptFunctionCall>(vnode_old.ptr())->get_base_script(); - } else if (Object::cast_to<VisualScriptPropertySet>(vnode_old.ptr())) { - base_type = Object::cast_to<VisualScriptPropertySet>(vnode_old.ptr())->get_base_type(); - base_script = Object::cast_to<VisualScriptPropertySet>(vnode_old.ptr())->get_base_script(); - } else if (Object::cast_to<VisualScriptPropertyGet>(vnode_old.ptr())) { - base_type = Object::cast_to<VisualScriptPropertyGet>(vnode_old.ptr())->get_base_type(); - base_script = Object::cast_to<VisualScriptPropertyGet>(vnode_old.ptr())->get_base_script(); - } - } - - Vector<String> property_path = p_text.split(":"); - if (ClassDB::is_parent_class(script->get_instance_base_type(), property_path[0]) || script->get_path().ends_with(property_path[0].unquote())) { - if (!p_connecting) { - base_type = script->get_instance_base_type(); - base_script = script->get_path(); - } - } else { - base_type = property_path[0]; - base_script = ""; - } - - if (drop_node) { - Ref<Script> script = drop_node->get_script(); - if (script != nullptr) { - base_script = script->get_path(); - } - } - - if (vnode_old.is_valid() && p_connecting) { - if (base_type == "") { - base_type = property_path[0]; - } else if (ClassDB::is_parent_class(property_path[0], base_type)) { - base_type = property_path[0]; - } - connect_seq(vnode_old, vnode, port_action_new_node); - connect_data(vnode_old, vnode, port_action_new_node); - } - } - if (Object::cast_to<VisualScriptTypeCast>(vnode.ptr())) { - Object::cast_to<VisualScriptTypeCast>(vnode.ptr())->set_base_type(base_type); - Object::cast_to<VisualScriptTypeCast>(vnode.ptr())->set_base_script(base_script); - } else if (Object::cast_to<VisualScriptFunctionCall>(vnode.ptr())) { - if (base_type_map.has(base_type)) { - Object::cast_to<VisualScriptFunctionCall>(vnode.ptr())->set_basic_type(base_type_map[base_type]); - Object::cast_to<VisualScriptFunctionCall>(vnode.ptr())->set_call_mode(VisualScriptFunctionCall::CALL_MODE_BASIC_TYPE); - } else { - Object::cast_to<VisualScriptFunctionCall>(vnode.ptr())->set_base_type(base_type); - Object::cast_to<VisualScriptFunctionCall>(vnode.ptr())->set_base_script(base_script); - } - } else if (Object::cast_to<VisualScriptPropertySet>(vnode.ptr())) { - Object::cast_to<VisualScriptPropertySet>(vnode.ptr())->set_base_type(base_type); - Object::cast_to<VisualScriptPropertySet>(vnode.ptr())->set_base_script(base_script); - } else if (Object::cast_to<VisualScriptPropertyGet>(vnode.ptr())) { - Object::cast_to<VisualScriptPropertyGet>(vnode.ptr())->set_base_type(base_type); - Object::cast_to<VisualScriptPropertyGet>(vnode.ptr())->set_base_script(base_script); - } - - drop_path = String(); - drop_node = nullptr; - - _update_graph(port_action_new_node); -} - -void VisualScriptEditor::connect_seq(Ref<VisualScriptNode> vnode_old, Ref<VisualScriptNode> vnode_new, int new_id) { - VisualScriptOperator *vnode_operator = Object::cast_to<VisualScriptOperator>(vnode_new.ptr()); - if (vnode_operator != nullptr && !vnode_operator->has_input_sequence_port()) { - return; - } - VisualScriptConstructor *vnode_constructor = Object::cast_to<VisualScriptConstructor>(vnode_new.ptr()); - if (vnode_constructor != nullptr) { - return; - } - if (vnode_old->get_output_sequence_port_count() <= 0) { - return; - } - if (!vnode_new->has_input_sequence_port()) { - return; - } - - undo_redo->create_action(TTR("Connect Node Sequence")); - int pass_port = -vnode_old->get_output_sequence_port_count() + 1; - int return_port = port_action_output - 1; - if (vnode_old->get_output_value_port_info(port_action_output).name == String("pass") && - !script->get_output_sequence_ports_connected(port_action_node).has(pass_port)) { - undo_redo->add_do_method(script.ptr(), "sequence_connect", port_action_node, pass_port, new_id); - undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", port_action_node, pass_port, new_id); - } else if (vnode_old->get_output_value_port_info(port_action_output).name == String("return") && - !script->get_output_sequence_ports_connected(port_action_node).has(return_port)) { - undo_redo->add_do_method(script.ptr(), "sequence_connect", port_action_node, return_port, new_id); - undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", port_action_node, return_port, new_id); - } else { - for (int port = 0; port < vnode_old->get_output_sequence_port_count(); port++) { - int count = vnode_old->get_output_sequence_port_count(); - if (port_action_output < count && !script->get_output_sequence_ports_connected(port_action_node).has(port_action_output)) { - undo_redo->add_do_method(script.ptr(), "sequence_connect", port_action_node, port_action_output, new_id); - undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", port_action_node, port_action_output, new_id); - break; - } else if (!script->get_output_sequence_ports_connected(port_action_node).has(port)) { - undo_redo->add_do_method(script.ptr(), "sequence_connect", port_action_node, port, new_id); - undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", port_action_node, port, new_id); - break; - } - } - } - - undo_redo->commit_action(); -} - -void VisualScriptEditor::_selected_new_virtual_method(const String &p_text, const String &p_category, const bool p_connecting) { - String name = p_text.substr(p_text.find_char(':') + 1); - if (script->has_function(name)) { - EditorNode::get_singleton()->show_warning(vformat(TTR("Script already has function '%s'"), name)); - return; - } - - MethodInfo minfo; - { - List<MethodInfo> methods; - bool found = false; - ClassDB::get_virtual_methods(script->get_instance_base_type(), &methods); - for (const MethodInfo &E : methods) { - if (E.name == name) { - minfo = E; - found = true; - } - } - - ERR_FAIL_COND(!found); - } - - selected = name; - Ref<VisualScriptFunction> func_node; - func_node.instantiate(); - func_node->set_name(name); - int fn_id = script->get_available_id(); - undo_redo->create_action(TTR("Add Function")); - undo_redo->add_do_method(script.ptr(), "add_function", name, fn_id); - - for (int i = 0; i < minfo.arguments.size(); i++) { - func_node->add_argument(minfo.arguments[i].type, minfo.arguments[i].name, -1, minfo.arguments[i].hint, minfo.arguments[i].hint_string); - } - - Vector2 pos = _get_available_pos(); - - undo_redo->add_do_method(script.ptr(), "add_node", fn_id, func_node, pos); - undo_redo->add_undo_method(script.ptr(), "remove_node", fn_id); - if (minfo.return_val.type != Variant::NIL || minfo.return_val.usage & PROPERTY_USAGE_NIL_IS_VARIANT) { - Ref<VisualScriptReturn> ret_node; - ret_node.instantiate(); - ret_node->set_return_type(minfo.return_val.type); - ret_node->set_enable_return_value(true); - ret_node->set_name(name); - int nid = script->get_available_id() + 1; - undo_redo->add_do_method(script.ptr(), "add_node", nid, ret_node, _get_available_pos(false, pos + Vector2(500, 0))); - undo_redo->add_undo_method(script.ptr(), "remove_node", nid); - } - - undo_redo->add_undo_method(script.ptr(), "remove_function", name); - undo_redo->add_do_method(this, "_update_members"); - undo_redo->add_undo_method(this, "_update_members"); - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - - undo_redo->commit_action(); - - _update_graph(); -} - -void VisualScriptEditor::_cancel_connect_node() { - // Ensure the cancel is done. - port_action_new_node = -1; -} - -int VisualScriptEditor::_create_new_node_from_name(const String &p_text, const Vector2 &p_point) { - Ref<VisualScriptNode> vnode = VisualScriptLanguage::singleton->create_node_from_name(p_text); - int new_id = script->get_available_id(); - undo_redo->create_action(TTR("Add Node")); - undo_redo->add_do_method(script.ptr(), "add_node", new_id, vnode, p_point); - undo_redo->add_undo_method(script.ptr(), "remove_node", new_id); - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - undo_redo->commit_action(); - return new_id; -} - -void VisualScriptEditor::_default_value_changed(const StringName &p_property, const Variant &p_value, const String &p_field, bool p_changing) { - Ref<VisualScriptNode> vsn = script->get_node(editing_id); - if (vsn.is_null()) { - return; - } - - undo_redo->create_action(TTR("Change Input Value")); - undo_redo->add_do_method(vsn.ptr(), "set_default_input_value", editing_input, p_value); - undo_redo->add_undo_method(vsn.ptr(), "set_default_input_value", editing_input, vsn->get_default_input_value(editing_input)); - - undo_redo->add_do_method(this, "_update_graph", editing_id); - undo_redo->add_undo_method(this, "_update_graph", editing_id); - undo_redo->commit_action(); -} - -void VisualScriptEditor::_default_value_edited(Node *p_button, int p_id, int p_input_port) { - Ref<VisualScriptNode> vsn = script->get_node(p_id); - if (vsn.is_null()) { - return; - } - - PropertyInfo pinfo = vsn->get_input_value_port_info(p_input_port); - Variant existing = vsn->get_default_input_value(p_input_port); - if (pinfo.type != Variant::NIL && existing.get_type() != pinfo.type) { - Callable::CallError ce; - Variant e = existing; - const Variant *existingp = &e; - Variant::construct(pinfo.type, existing, &existingp, 1, ce); - } - - if (pinfo.type == Variant::NODE_PATH) { - Node *edited_scene = get_tree()->get_edited_scene_root(); - if (edited_scene) { // Fixing an old crash bug ( Visual Script Crashes on editing NodePath with an empty scene open). - Node *script_node = _find_script_node(edited_scene, edited_scene, script); - - if (script_node) { - // Pick a node relative to the script, IF the script exists. - pinfo.hint = PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE; - pinfo.hint_string = script_node->get_path(); - } else { - // Pick a path relative to edited scene. - pinfo.hint = PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE; - pinfo.hint_string = get_tree()->get_edited_scene_root()->get_path(); - } - } - } - - edited_default_property_holder->set_edited_property(existing); - - if (default_property_editor) { - default_property_editor->disconnect("property_changed", callable_mp(this, &VisualScriptEditor::_default_value_changed)); - default_property_editor_popup->remove_child(default_property_editor); - } - - default_property_editor = EditorInspector::instantiate_property_editor(edited_default_property_holder.ptr(), pinfo.type, "edited_property", pinfo.hint, pinfo.hint_string, PROPERTY_USAGE_NONE); - if (default_property_editor) { - default_property_editor->set_object_and_property(edited_default_property_holder.ptr(), "edited_property"); - default_property_editor->update_property(); - default_property_editor->set_name_split_ratio(0); - default_property_editor_popup->add_child(default_property_editor); - - default_property_editor->connect("property_changed", callable_mp(this, &VisualScriptEditor::_default_value_changed)); - - Button *button = Object::cast_to<Button>(p_button); - if (button) { - default_property_editor_popup->set_position(button->get_screen_position() + Vector2(0, button->get_size().height) * graph->get_zoom()); - } - - default_property_editor_popup->reset_size(); - - if (pinfo.hint == PROPERTY_HINT_MULTILINE_TEXT || !button) { - default_property_editor_popup->popup_centered_ratio(); - } else { - default_property_editor_popup->popup(); - } - } - - editing_id = p_id; - editing_input = p_input_port; -} - -void VisualScriptEditor::_show_hint(const String &p_hint) { - hint_text->set_text(p_hint); - hint_text->show(); - hint_text_timer->start(); -} - -void VisualScriptEditor::_hide_timer() { - hint_text->hide(); -} - -void VisualScriptEditor::_toggle_scripts_pressed() { - ScriptEditor::get_singleton()->toggle_scripts_panel(); - update_toggle_scripts_button(); -} - -void VisualScriptEditor::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_ENTER_TREE: - case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - graph->get_panner()->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/sub_editors_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); - graph->set_warped_panning(bool(EditorSettings::get_singleton()->get("editors/panning/warped_mouse_panning"))); - graph->set_minimap_opacity(EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity")); - graph->set_connection_lines_curvature(EditorSettings::get_singleton()->get("editors/visual_editors/lines_curvature")); - _update_graph(); - } break; - - case NOTIFICATION_READY: { - variable_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_members)); - variable_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_graph).bind(-1), CONNECT_DEFERRED); - signal_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_members)); - signal_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_graph).bind(-1), CONNECT_DEFERRED); - [[fallthrough]]; - } - case NOTIFICATION_THEME_CHANGED: { - if (p_what != NOTIFICATION_READY && !is_visible_in_tree()) { - return; - } - - update_toggle_scripts_button(); - - edit_variable_edit->add_theme_style_override("bg", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); - edit_signal_edit->add_theme_style_override("bg", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); - func_input_scroll->add_theme_style_override("bg", get_theme_stylebox(SNAME("bg"), SNAME("Tree"))); - - Ref<Theme> tm = EditorNode::get_singleton()->get_theme_base()->get_theme(); - - bool dark_theme = tm->get_constant("dark_theme", "Editor"); - - if (dark_theme) { - node_colors["flow_control"] = Color(0.96, 0.96, 0.96); - node_colors["functions"] = Color(0.96, 0.52, 0.51); - node_colors["data"] = Color(0.5, 0.96, 0.81); - node_colors["operators"] = Color(0.67, 0.59, 0.87); - node_colors["custom"] = Color(0.5, 0.73, 0.96); - node_colors["constants"] = Color(0.96, 0.5, 0.69); - } else { - node_colors["flow_control"] = Color(0.26, 0.26, 0.26); - node_colors["functions"] = Color(0.95, 0.4, 0.38); - node_colors["data"] = Color(0.07, 0.73, 0.51); - node_colors["operators"] = Color(0.51, 0.4, 0.82); - node_colors["custom"] = Color(0.31, 0.63, 0.95); - node_colors["constants"] = Color(0.94, 0.18, 0.49); - } - - for (const KeyValue<StringName, Color> &E : node_colors) { - const Ref<StyleBoxFlat> sb = tm->get_stylebox(SNAME("frame"), SNAME("GraphNode")); - - if (!sb.is_null()) { - Ref<StyleBoxFlat> frame_style = sb->duplicate(); - // Adjust the border color to be close to the GraphNode's background color. - // This keeps the node's title area from being too distracting. - Color color = dark_theme ? E.value.darkened(0.75) : E.value.lightened(0.75); - color.a = 0.9; - frame_style->set_border_color(color); - node_styles[E.key] = frame_style; - } - } - - if (is_visible_in_tree() && script.is_valid()) { - _update_members(); - _update_graph(); - } - } break; - - case NOTIFICATION_VISIBILITY_CHANGED: { - update_toggle_scripts_button(); - members_section->set_visible(is_visible_in_tree()); - } break; - } -} - -void VisualScriptEditor::_graph_ofs_changed(const Vector2 &p_ofs) { - if (updating_graph || !script.is_valid()) { - return; - } - - updating_graph = true; - - script->set_scroll(graph->get_scroll_ofs() / EDSCALE); - script->set_edited(true); - updating_graph = false; -} - -void VisualScriptEditor::_comment_node_resized(const Vector2 &p_new_size, int p_node) { - if (updating_graph) { - return; - } - Ref<VisualScriptComment> vsc = script->get_node(p_node); - if (vsc.is_null()) { - return; - } - - Node *node = graph->get_node(itos(p_node)); - GraphNode *gn = Object::cast_to<GraphNode>(node); - if (!gn) { - return; - } - - Vector2 new_size = p_new_size; - if (graph->is_using_snap()) { - Vector2 snap = Vector2(graph->get_snap(), graph->get_snap()); - Vector2 min_size = (gn->get_minimum_size() + (snap * 0.5)).snapped(snap); - new_size = new_size.snapped(snap).max(min_size); - } - - updating_graph = true; - - graph->set_block_minimum_size_adjust(true); //faster resize - - undo_redo->create_action(TTR("Resize Comment"), UndoRedo::MERGE_ENDS); - undo_redo->add_do_method(vsc.ptr(), "set_size", new_size / EDSCALE); - undo_redo->add_undo_method(vsc.ptr(), "set_size", vsc->get_size()); - undo_redo->commit_action(); - - gn->set_custom_minimum_size(new_size); - gn->reset_size(); - graph->set_block_minimum_size_adjust(false); - updating_graph = false; -} - -void VisualScriptEditor::_menu_option(int p_what) { - switch (p_what) { - case EDIT_ADD_NODE: { - _generic_search(); - } break; - case EDIT_DELETE_NODES: { - _on_nodes_delete(); - } break; - case EDIT_TOGGLE_BREAKPOINT: { - List<String> reselect; - for (int i = 0; i < graph->get_child_count(); i++) { - GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); - if (gn) { - if (gn->is_selected()) { - int id = String(gn->get_name()).to_int(); - Ref<VisualScriptNode> vsn = script->get_node(id); - if (vsn.is_valid()) { - vsn->set_breakpoint(!vsn->is_breakpoint()); - reselect.push_back(gn->get_name()); - } - } - } - } - - _update_graph(); - - for (const String &E : reselect) { - GraphNode *gn = Object::cast_to<GraphNode>(graph->get_node(E)); - gn->set_selected(true); - } - - } break; - case EDIT_FIND_NODE_TYPE: { - _generic_search(); - } break; - case EDIT_COPY_NODES: { - _on_nodes_copy(); - } break; - case EDIT_CUT_NODES: { - _on_nodes_copy(); - _on_nodes_delete(); - } break; - case EDIT_PASTE_NODES: { - _on_nodes_paste(); - } break; - case EDIT_DUPLICATE_NODES: { - _on_nodes_duplicate(); - } break; - case EDIT_CREATE_FUNCTION: { - // Create Function. - HashMap<int, Ref<VisualScriptNode>> nodes; - RBSet<int> selections; - for (int i = 0; i < graph->get_child_count(); i++) { - GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); - if (gn) { - if (gn->is_selected()) { - int id = String(gn->get_name()).to_int(); - Ref<VisualScriptNode> node = script->get_node(id); - if (Object::cast_to<VisualScriptFunction>(*node)) { - EditorNode::get_singleton()->show_warning(TTR("Can't create function with a function node.")); - return; - } - if (node.is_valid()) { - nodes.insert(id, node); - selections.insert(id); - } - } - } - } - - if (nodes.size() == 0) { - return; // nothing to be done if there are no valid nodes selected - } - - RBSet<VisualScript::SequenceConnection> seqmove; - RBSet<VisualScript::DataConnection> datamove; - - RBSet<VisualScript::SequenceConnection> seqext; - RBSet<VisualScript::DataConnection> dataext; - - int start_node = -1; - RBSet<int> end_nodes; - if (nodes.size() == 1) { - Ref<VisualScriptNode> nd = script->get_node(nodes.begin()->key); - if (nd.is_valid() && nd->has_input_sequence_port()) { - start_node = nodes.begin()->key; - } else { - EditorNode::get_singleton()->show_warning(TTR("Select at least one node with sequence port.")); - return; - } - } else { - List<VisualScript::SequenceConnection> seqs; - script->get_sequence_connection_list(&seqs); - - if (seqs.size() == 0) { - // In case there are no sequence connections, - // select the top most node cause that's probably how, - // the user wants to connect the nodes. - int top_nd = -1; - Vector2 top; - for (const KeyValue<int, Ref<VisualScriptNode>> &E : nodes) { - Ref<VisualScriptNode> nd = script->get_node(E.key); - if (nd.is_valid() && nd->has_input_sequence_port()) { - if (top_nd < 0) { - top_nd = E.key; - top = script->get_node_position(top_nd); - } - Vector2 pos = script->get_node_position(E.key); - if (top.y > pos.y) { - top_nd = E.key; - top = pos; - } - } - } - Ref<VisualScriptNode> nd = script->get_node(top_nd); - if (nd.is_valid() && nd->has_input_sequence_port()) { - start_node = top_nd; - } else { - EditorNode::get_singleton()->show_warning(TTR("Select at least one node with sequence port.")); - return; - } - } else { - // Pick the node with input sequence. - RBSet<int> nodes_from; - RBSet<int> nodes_to; - for (const VisualScript::SequenceConnection &E : seqs) { - if (nodes.has(E.from_node) && nodes.has(E.to_node)) { - seqmove.insert(E); - nodes_from.insert(E.from_node); - } else if (nodes.has(E.from_node) && !nodes.has(E.to_node)) { - seqext.insert(E); - } else if (!nodes.has(E.from_node) && nodes.has(E.to_node)) { - if (start_node == -1) { - seqext.insert(E); - start_node = E.to_node; - } else { - EditorNode::get_singleton()->show_warning(TTR("Try to only have one sequence input in selection.")); - return; - } - } - nodes_to.insert(E.to_node); - } - - // To use to add return nodes. - _get_ends(start_node, seqs, selections, end_nodes); - - if (start_node == -1) { - // If we still don't have a start node then, - // run through the nodes and select the first tree node, - // i.e. node without any input sequence but output sequence. - for (const int &E : nodes_from) { - if (!nodes_to.has(E)) { - start_node = E; - } - } - } - } - } - - if (start_node == -1) { - return; // This should not happen, but just in case something goes wrong. - } - - List<Variant::Type> inputs; // input types - List<Pair<int, int>> input_connections; - { - List<VisualScript::DataConnection> dats; - script->get_data_connection_list(&dats); - for (const VisualScript::DataConnection &E : dats) { - if (nodes.has(E.from_node) && nodes.has(E.to_node)) { - datamove.insert(E); - } else if (!nodes.has(E.from_node) && nodes.has(E.to_node)) { - // Add all these as inputs for the Function. - Ref<VisualScriptNode> node = script->get_node(E.to_node); - if (node.is_valid()) { - dataext.insert(E); - PropertyInfo pi = node->get_input_value_port_info(E.to_port); - inputs.push_back(pi.type); - input_connections.push_back(Pair<int, int>(E.to_node, E.to_port)); - } - } else if (nodes.has(E.from_node) && !nodes.has(E.to_node)) { - dataext.insert(E); - } - } - } - int fn_id = script->get_available_id(); - { - String new_fn = _validate_name("new_function"); - - Vector2 pos = _get_available_pos(false, script->get_node_position(start_node) - Vector2(80, 150)); - - Ref<VisualScriptFunction> func_node; - func_node.instantiate(); - func_node->set_name(new_fn); - - undo_redo->create_action(TTR("Create Function")); - - undo_redo->add_do_method(script.ptr(), "add_function", new_fn, fn_id); - undo_redo->add_do_method(script.ptr(), "add_node", fn_id, func_node, pos); - undo_redo->add_undo_method(script.ptr(), "remove_function", new_fn); - undo_redo->add_undo_method(script.ptr(), "remove_node", fn_id); - undo_redo->add_do_method(this, "_update_members"); - undo_redo->add_undo_method(this, "_update_members"); - undo_redo->add_do_method(this, "emit_signal", "edited_script_changed"); - undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed"); - // Might make the system more intelligent by checking port from info. - int i = 0; - List<Pair<int, int>>::Element *F = input_connections.front(); - for (List<Variant::Type>::Element *E = inputs.front(); E && F; E = E->next(), F = F->next()) { - func_node->add_argument(E->get(), "arg_" + String::num_int64(i), i); - undo_redo->add_do_method(script.ptr(), "data_connect", fn_id, i, F->get().first, F->get().second); - i++; // increment i - } - // Ensure Preview Selection is of newly created function node. - if (selections.size()) { - EditorNode::get_singleton()->push_item(func_node.ptr()); - } - } - // Move the nodes. - - // Handles reconnection of sequence connections on undo, start here in case of issues. - for (const VisualScript::SequenceConnection &E : seqext) { - undo_redo->add_do_method(script.ptr(), "sequence_disconnect", E.from_node, E.from_output, E.to_node); - undo_redo->add_undo_method(script.ptr(), "sequence_connect", E.from_node, E.from_output, E.to_node); - } - for (const VisualScript::DataConnection &E : dataext) { - undo_redo->add_do_method(script.ptr(), "data_disconnect", E.from_node, E.from_port, E.to_node, E.to_port); - undo_redo->add_undo_method(script.ptr(), "data_connect", E.from_node, E.from_port, E.to_node, E.to_port); - } - - // I don't really think we need support for non sequenced functions at this moment. - undo_redo->add_do_method(script.ptr(), "sequence_connect", fn_id, 0, start_node); - - // Could fail with the new changes, start here when searching for bugs in create function shortcut. - int m = 1; - for (const int &G : end_nodes) { - Ref<VisualScriptReturn> ret_node; - ret_node.instantiate(); - - int ret_id = fn_id + (m++); - selections.insert(ret_id); - Vector2 posi = _get_available_pos(false, script->get_node_position(G) + Vector2(80, -100)); - undo_redo->add_do_method(script.ptr(), "add_node", ret_id, ret_node, posi); - undo_redo->add_undo_method(script.ptr(), "remove_node", ret_id); - - undo_redo->add_do_method(script.ptr(), "sequence_connect", G, 0, ret_id); - // Add data outputs from each of the end_nodes. - Ref<VisualScriptNode> vsn = script->get_node(G); - if (vsn.is_valid() && vsn->get_output_value_port_count() > 0) { - ret_node->set_enable_return_value(true); - // Use the zeroth data port cause that's the likely one that is planned to be used. - ret_node->set_return_type(vsn->get_output_value_port_info(0).type); - undo_redo->add_do_method(script.ptr(), "data_connect", G, 0, ret_id, 0); - } - } - - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - - undo_redo->commit_action(); - - // Make sure all Nodes get marked for selection so that they can be moved together. - selections.insert(fn_id); - for (int k = 0; k < graph->get_child_count(); k++) { - GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(k)); - if (gn) { - int id = gn->get_name().operator String().to_int(); - gn->set_selected(selections.has(id)); - } - } - - } break; - case REFRESH_GRAPH: { - _update_graph(); - } break; - case EDIT_CLEAR_COPY_BUFFER: { - clipboard->nodes.clear(); - clipboard->nodes_positions.clear(); - clipboard->data_connections.clear(); - clipboard->sequence_connections.clear(); - } break; - } -} - -// This is likely going to be very slow and I am not sure if I should keep it, -// but I hope that it will not be a problem considering that we won't be creating functions so frequently, -// and cyclic connections would be a problem but hopefully we won't let them get to this point. -void VisualScriptEditor::_get_ends(int p_node, const List<VisualScript::SequenceConnection> &p_seqs, const RBSet<int> &p_selected, RBSet<int> &r_end_nodes) { - for (const VisualScript::SequenceConnection &E : p_seqs) { - int from = E.from_node; - int to = E.to_node; - - if (from == p_node && p_selected.has(to)) { - // This is an interior connection move forward to the to node. - _get_ends(to, p_seqs, p_selected, r_end_nodes); - } else if (from == p_node && !p_selected.has(to)) { - r_end_nodes.insert(from); - } - } -} - -void VisualScriptEditor::_member_rmb_selected(const Vector2 &p_pos, MouseButton p_button) { - if (p_button != MouseButton::RIGHT) { - return; - } - - TreeItem *ti = members->get_selected(); - ERR_FAIL_COND(!ti); - - member_popup->clear(); - member_popup->set_position(members->get_screen_position() + p_pos); - member_popup->reset_size(); - - function_name_edit->set_position(members->get_screen_position() + p_pos); - function_name_edit->reset_size(); - - TreeItem *root = members->get_root(); - - Ref<Texture2D> del_icon = Control::get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")); - - Ref<Texture2D> edit_icon = Control::get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")); - - if (ti->get_parent() == root->get_first_child()) { - member_type = MEMBER_FUNCTION; - member_name = ti->get_text(0); - member_popup->add_icon_shortcut(edit_icon, ED_GET_SHORTCUT("visual_script_editor/edit_member"), MEMBER_EDIT); - member_popup->add_separator(); - member_popup->add_icon_shortcut(del_icon, ED_GET_SHORTCUT("ui_graph_delete"), MEMBER_REMOVE); - member_popup->popup(); - return; - } - - if (ti->get_parent() == root->get_first_child()->get_next()) { - member_type = MEMBER_VARIABLE; - member_name = ti->get_text(0); - member_popup->add_icon_shortcut(edit_icon, ED_GET_SHORTCUT("visual_script_editor/edit_member"), MEMBER_EDIT); - member_popup->add_separator(); - member_popup->add_icon_shortcut(del_icon, ED_GET_SHORTCUT("ui_graph_delete"), MEMBER_REMOVE); - member_popup->popup(); - return; - } - - if (ti->get_parent() == root->get_first_child()->get_next()->get_next()) { - member_type = MEMBER_SIGNAL; - member_name = ti->get_text(0); - member_popup->add_icon_shortcut(edit_icon, ED_GET_SHORTCUT("visual_script_editor/edit_member"), MEMBER_EDIT); - member_popup->add_separator(); - member_popup->add_icon_shortcut(del_icon, ED_GET_SHORTCUT("ui_graph_delete"), MEMBER_REMOVE); - member_popup->popup(); - return; - } -} - -void VisualScriptEditor::_member_option(int p_option) { - switch (member_type) { - case MEMBER_FUNCTION: { - if (p_option == MEMBER_REMOVE) { - // Delete the function. - String name = member_name; - List<String> lst; - int fn_node = script->get_function_node_id(name); - undo_redo->create_action(TTR("Remove Function")); - undo_redo->add_do_method(script.ptr(), "remove_function", name); - undo_redo->add_do_method(script.ptr(), "remove_node", fn_node); - undo_redo->add_undo_method(script.ptr(), "add_function", name, fn_node); - undo_redo->add_undo_method(script.ptr(), "add_node", fn_node, script->get_node(fn_node), script->get_node_position(fn_node)); - List<VisualScript::SequenceConnection> seqcons; - script->get_sequence_connection_list(&seqcons); - for (const VisualScript::SequenceConnection &E : seqcons) { - if (E.from_node == fn_node) { - undo_redo->add_undo_method(script.ptr(), "sequence_connect", fn_node, E.from_output, E.to_node); - } - } - List<VisualScript::DataConnection> datcons; - script->get_data_connection_list(&datcons); - for (const VisualScript::DataConnection &E : datcons) { - if (E.from_node == fn_node) { - undo_redo->add_undo_method(script.ptr(), "data_connect", fn_node, E.from_port, E.to_node, E.to_port); - } - } - undo_redo->add_do_method(this, "_update_members"); - undo_redo->add_undo_method(this, "_update_members"); - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - undo_redo->commit_action(); - } else if (p_option == MEMBER_EDIT) { - selected = members->get_selected()->get_text(0); - function_name_edit->popup(); - function_name_box->set_text(selected); - function_name_box->select_all(); - function_name_box->grab_focus(); - } - } break; - case MEMBER_VARIABLE: { - String name = member_name; - - if (p_option == MEMBER_REMOVE) { - undo_redo->create_action(TTR("Remove Variable")); - undo_redo->add_do_method(script.ptr(), "remove_variable", name); - undo_redo->add_undo_method(script.ptr(), "add_variable", name, script->get_variable_default_value(name)); - undo_redo->add_undo_method(script.ptr(), "set_variable_info", name, script->call("get_variable_info", name)); //return as dict - undo_redo->add_do_method(this, "_update_members"); - undo_redo->add_undo_method(this, "_update_members"); - undo_redo->commit_action(); - } else if (p_option == MEMBER_EDIT) { - variable_editor->edit(name); - edit_variable_dialog->set_title(TTR("Editing Variable:") + " " + name); - edit_variable_dialog->popup_centered(Size2(400, 200) * EDSCALE); - } - } break; - case MEMBER_SIGNAL: { - String name = member_name; - - if (p_option == MEMBER_REMOVE) { - undo_redo->create_action(TTR("Remove Signal")); - undo_redo->add_do_method(script.ptr(), "remove_custom_signal", name); - undo_redo->add_undo_method(script.ptr(), "add_custom_signal", name); - - for (int i = 0; i < script->custom_signal_get_argument_count(name); i++) { - undo_redo->add_undo_method(script.ptr(), "custom_signal_add_argument", name, script->custom_signal_get_argument_name(name, i), script->custom_signal_get_argument_type(name, i)); - } - - undo_redo->add_do_method(this, "_update_members"); - undo_redo->add_undo_method(this, "_update_members"); - undo_redo->commit_action(); - } else if (p_option == MEMBER_EDIT) { - signal_editor->edit(name); - edit_signal_dialog->set_title(TTR("Editing Signal:") + " " + name); - edit_signal_dialog->popup_centered(Size2(400, 300) * EDSCALE); - } - } break; - } -} - -void VisualScriptEditor::add_syntax_highlighter(Ref<EditorSyntaxHighlighter> p_highlighter) { -} - -void VisualScriptEditor::set_syntax_highlighter(Ref<EditorSyntaxHighlighter> p_highlighter) { -} - -void VisualScriptEditor::update_toggle_scripts_button() { - if (is_layout_rtl()) { - toggle_scripts_button->set_icon(Control::get_theme_icon(ScriptEditor::get_singleton()->is_scripts_panel_toggled() ? SNAME("Forward") : SNAME("Back"), SNAME("EditorIcons"))); - } else { - toggle_scripts_button->set_icon(Control::get_theme_icon(ScriptEditor::get_singleton()->is_scripts_panel_toggled() ? SNAME("Back") : SNAME("Forward"), SNAME("EditorIcons"))); - } - toggle_scripts_button->set_tooltip(vformat("%s (%s)", TTR("Toggle Scripts Panel"), ED_GET_SHORTCUT("script_editor/toggle_scripts_panel")->get_as_text())); -} - -void VisualScriptEditor::_bind_methods() { - ClassDB::bind_method("_move_node", &VisualScriptEditor::_move_node); - ClassDB::bind_method("_update_graph", &VisualScriptEditor::_update_graph, DEFVAL(-1)); - - ClassDB::bind_method("_center_on_node", &VisualScriptEditor::_center_on_node); - ClassDB::bind_method("_button_resource_previewed", &VisualScriptEditor::_button_resource_previewed); - ClassDB::bind_method("_port_action_menu", &VisualScriptEditor::_port_action_menu); - - ClassDB::bind_method("_create_new_node_from_name", &VisualScriptEditor::_create_new_node_from_name); - - ClassDB::bind_method("_get_drag_data_fw", &VisualScriptEditor::get_drag_data_fw); - ClassDB::bind_method("_can_drop_data_fw", &VisualScriptEditor::can_drop_data_fw); - ClassDB::bind_method("_drop_data_fw", &VisualScriptEditor::drop_data_fw); - - ClassDB::bind_method("_update_graph_connections", &VisualScriptEditor::_update_graph_connections); - ClassDB::bind_method("_update_members", &VisualScriptEditor::_update_members); - - ClassDB::bind_method("_generic_search", &VisualScriptEditor::_generic_search); -} - -VisualScriptEditor::VisualScriptEditor() { - if (!clipboard) { - clipboard = memnew(Clipboard); - } - - edit_menu = memnew(MenuButton); - edit_menu->set_shortcut_context(this); - edit_menu->set_text(TTR("Edit")); - edit_menu->set_switch_on_hover(true); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_graph_delete"), EDIT_DELETE_NODES); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/toggle_breakpoint"), EDIT_TOGGLE_BREAKPOINT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/find_node_type"), EDIT_FIND_NODE_TYPE); - edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY_NODES); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT_NODES); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE_NODES); - edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/create_function"), EDIT_CREATE_FUNCTION); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/refresh_nodes"), REFRESH_GRAPH); - edit_menu->get_popup()->connect("id_pressed", callable_mp(this, &VisualScriptEditor::_menu_option)); - - members_section = memnew(VBoxContainer); - // Add but wait until done setting up this. - ScriptEditor::get_singleton()->get_left_list_split()->call_deferred(SNAME("add_child"), members_section); - members_section->set_v_size_flags(SIZE_EXPAND_FILL); - - CheckButton *tool_script_check = memnew(CheckButton); - tool_script_check->set_text(TTR("Make Tool:")); - members_section->add_child(tool_script_check); - tool_script_check->connect("pressed", callable_mp(this, &VisualScriptEditor::_toggle_tool_script)); - - /// Members /// - - members = memnew(Tree); - members_section->add_margin_child(TTR("Members:"), members, true); - members->set_custom_minimum_size(Size2(0, 50 * EDSCALE)); - members->set_hide_root(true); - members->connect("button_clicked", callable_mp(this, &VisualScriptEditor::_member_button)); - members->connect("item_edited", callable_mp(this, &VisualScriptEditor::_member_edited)); - members->connect("cell_selected", callable_mp(this, &VisualScriptEditor::_member_selected), CONNECT_DEFERRED); - members->connect("gui_input", callable_mp(this, &VisualScriptEditor::_members_gui_input)); - members->connect("item_mouse_selected", callable_mp(this, &VisualScriptEditor::_member_rmb_selected)); - members->set_allow_rmb_select(true); - members->set_allow_reselect(true); - members->set_hide_folding(true); - members->set_drag_forwarding(this); - - member_popup = memnew(PopupMenu); - add_child(member_popup); - member_popup->connect("id_pressed", callable_mp(this, &VisualScriptEditor::_member_option)); - - function_name_edit = memnew(AcceptDialog); - function_name_edit->set_title(TTR("Rename Function")); - function_name_box = memnew(LineEdit); - function_name_edit->add_child(function_name_box); - function_name_box->connect("gui_input", callable_mp(this, &VisualScriptEditor::_fn_name_box_input)); - function_name_edit->get_ok_button()->connect("pressed", callable_mp(this, &VisualScriptEditor::_on_fn_name_box_confirmed)); - function_name_box->set_expand_to_text_length_enabled(true); - add_child(function_name_edit); - - /// Actual Graph /// - - graph = memnew(GraphEdit); - add_child(graph); - graph->set_v_size_flags(Control::SIZE_EXPAND_FILL); - graph->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); - graph->set_show_zoom_label(true); - graph->connect("node_selected", callable_mp(this, &VisualScriptEditor::_node_selected)); - graph->connect("begin_node_move", callable_mp(this, &VisualScriptEditor::_begin_node_move)); - graph->connect("end_node_move", callable_mp(this, &VisualScriptEditor::_end_node_move)); - graph->connect("copy_nodes_request", callable_mp(this, &VisualScriptEditor::_on_nodes_copy)); - graph->connect("paste_nodes_request", callable_mp(this, &VisualScriptEditor::_on_nodes_paste)); - graph->connect("delete_nodes_request", callable_mp(this, &VisualScriptEditor::_on_nodes_delete)); - graph->connect("duplicate_nodes_request", callable_mp(this, &VisualScriptEditor::_on_nodes_duplicate)); - graph->connect("gui_input", callable_mp(this, &VisualScriptEditor::_graph_gui_input)); - graph->set_drag_forwarding(this); - float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity"); - graph->set_minimap_opacity(graph_minimap_opacity); - float graph_lines_curvature = EditorSettings::get_singleton()->get("editors/visual_editors/lines_curvature"); - graph->set_connection_lines_curvature(graph_lines_curvature); - graph->hide(); - graph->connect("scroll_offset_changed", callable_mp(this, &VisualScriptEditor::_graph_ofs_changed)); - - status_bar = memnew(HBoxContainer); - add_child(status_bar); - status_bar->set_h_size_flags(SIZE_EXPAND_FILL); - status_bar->set_custom_minimum_size(Size2(0, 24 * EDSCALE)); - - toggle_scripts_button = memnew(Button); - toggle_scripts_button->set_flat(true); - toggle_scripts_button->connect("pressed", callable_mp(this, &VisualScriptEditor::_toggle_scripts_pressed)); - status_bar->add_child(toggle_scripts_button); - - /// Add Buttons to Top Bar/Zoom bar. - HBoxContainer *graph_hbc = graph->get_zoom_hbox(); - - Label *base_lbl = memnew(Label); - base_lbl->set_text(TTR("Change Base Type:") + " "); - graph_hbc->add_child(base_lbl); - - base_type_select = memnew(Button); - base_type_select->connect("pressed", callable_mp(this, &VisualScriptEditor::_change_base_type)); - graph_hbc->add_child(base_type_select); - - Button *add_nds = memnew(Button); - add_nds->set_text(TTR("Add Nodes...")); - graph_hbc->add_child(add_nds); - add_nds->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_node_dialog)); - - Button *fn_btn = memnew(Button); - fn_btn->set_text(TTR("Add Function...")); - graph_hbc->add_child(fn_btn); - fn_btn->connect("pressed", callable_mp(this, &VisualScriptEditor::_create_function_dialog)); - - // Add Function Dialog. - VBoxContainer *function_vb = memnew(VBoxContainer); - function_vb->set_v_size_flags(SIZE_EXPAND_FILL); - function_vb->set_custom_minimum_size(Size2(450, 300) * EDSCALE); - - HBoxContainer *func_name_hbox = memnew(HBoxContainer); - function_vb->add_child(func_name_hbox); - - Label *func_name_label = memnew(Label); - func_name_label->set_text(TTR("Name:")); - func_name_hbox->add_child(func_name_label); - - func_name_box = memnew(LineEdit); - func_name_box->set_h_size_flags(SIZE_EXPAND_FILL); - func_name_box->set_placeholder(TTR("function_name")); - func_name_box->set_text(""); - func_name_box->connect("focus_entered", callable_mp(this, &VisualScriptEditor::_deselect_input_names)); - func_name_hbox->add_child(func_name_box); - - // Add minor setting for function if needed, here! - - function_vb->add_child(memnew(HSeparator)); - - Button *add_input_button = memnew(Button); - add_input_button->set_h_size_flags(SIZE_EXPAND_FILL); - add_input_button->set_text(TTR("Add Input")); - add_input_button->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_func_input)); - function_vb->add_child(add_input_button); - - func_input_scroll = memnew(ScrollContainer); - func_input_scroll->set_v_size_flags(SIZE_EXPAND_FILL); - function_vb->add_child(func_input_scroll); - - func_input_vbox = memnew(VBoxContainer); - func_input_vbox->set_h_size_flags(SIZE_EXPAND_FILL); - func_input_scroll->add_child(func_input_vbox); - - function_create_dialog = memnew(ConfirmationDialog); - function_create_dialog->set_title(TTR("Create Function")); - function_create_dialog->add_child(function_vb); - function_create_dialog->set_ok_button_text(TTR("Create")); - function_create_dialog->get_ok_button()->connect("pressed", callable_mp(this, &VisualScriptEditor::_create_function)); - add_child(function_create_dialog); - - select_func_text = memnew(Label); - select_func_text->set_text(TTR("Select or create a function to edit its graph.")); - select_func_text->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); - select_func_text->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER); - select_func_text->set_h_size_flags(SIZE_EXPAND_FILL); - add_child(select_func_text); - - hint_text = memnew(Label); - hint_text->set_anchor_and_offset(SIDE_TOP, ANCHOR_END, -100); - hint_text->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, 0); - hint_text->set_anchor_and_offset(SIDE_RIGHT, ANCHOR_END, 0); - hint_text->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); - hint_text->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER); - graph->add_child(hint_text); - - hint_text_timer = memnew(Timer); - hint_text_timer->set_wait_time(4); - hint_text_timer->connect("timeout", callable_mp(this, &VisualScriptEditor::_hide_timer)); - add_child(hint_text_timer); - - // Allowed casts (connections). - for (int i = 0; i < Variant::VARIANT_MAX; i++) { - graph->add_valid_connection_type(Variant::NIL, i); - graph->add_valid_connection_type(i, Variant::NIL); - for (int j = 0; j < Variant::VARIANT_MAX; j++) { - if (Variant::can_convert(Variant::Type(i), Variant::Type(j))) { - graph->add_valid_connection_type(i, j); - } - } - - graph->add_valid_right_disconnect_type(i); - } - - graph->add_valid_left_disconnect_type(TYPE_SEQUENCE); - - graph->connect("connection_request", callable_mp(this, &VisualScriptEditor::_graph_connected)); - graph->connect("disconnection_request", callable_mp(this, &VisualScriptEditor::_graph_disconnected)); - graph->connect("connection_to_empty", callable_mp(this, &VisualScriptEditor::_graph_connect_to_empty)); - - edit_signal_dialog = memnew(AcceptDialog); - edit_signal_dialog->set_ok_button_text(TTR("Close")); - add_child(edit_signal_dialog); - - signal_editor = memnew(VisualScriptEditorSignalEdit); - edit_signal_edit = memnew(EditorInspector); - edit_signal_dialog->add_child(edit_signal_edit); - - edit_signal_edit->edit(signal_editor); - - edit_variable_dialog = memnew(AcceptDialog); - edit_variable_dialog->set_ok_button_text(TTR("Close")); - add_child(edit_variable_dialog); - - variable_editor = memnew(VisualScriptEditorVariableEdit); - edit_variable_edit = memnew(EditorInspector); - edit_variable_dialog->add_child(edit_variable_edit); - - edit_variable_edit->edit(variable_editor); - - select_base_type = memnew(CreateDialog); - select_base_type->set_base_type("Object"); // Anything goes. - select_base_type->connect("create", callable_mp(this, &VisualScriptEditor::_change_base_type_callback)); - add_child(select_base_type); - - undo_redo = EditorNode::get_singleton()->get_undo_redo(); - - set_process_input(true); - - default_property_editor_popup = memnew(PopupPanel); - default_property_editor_popup->set_min_size(Size2i(180, 0) * EDSCALE); - add_child(default_property_editor_popup); - - edited_default_property_holder.instantiate(); - - new_connect_node_select = memnew(VisualScriptPropertySelector); - add_child(new_connect_node_select); - new_connect_node_select->connect("selected", callable_mp(this, &VisualScriptEditor::_selected_connect_node)); - new_connect_node_select->get_cancel_button()->connect("pressed", callable_mp(this, &VisualScriptEditor::_cancel_connect_node)); - - new_virtual_method_select = memnew(VisualScriptPropertySelector); - add_child(new_virtual_method_select); - new_virtual_method_select->connect("selected", callable_mp(this, &VisualScriptEditor::_selected_new_virtual_method)); - - popup_menu = memnew(PopupMenu); - add_child(popup_menu); - popup_menu->add_item(TTR("Add Node"), EDIT_ADD_NODE); - popup_menu->add_separator(); - popup_menu->add_item(TTR("Cut"), EDIT_CUT_NODES); - popup_menu->add_item(TTR("Copy"), EDIT_COPY_NODES); - popup_menu->add_item(TTR("Paste"), EDIT_PASTE_NODES); - popup_menu->add_item(TTR("Delete"), EDIT_DELETE_NODES); - popup_menu->add_item(TTR("Duplicate"), EDIT_DUPLICATE_NODES); - popup_menu->add_item(TTR("Clear Copy Buffer"), EDIT_CLEAR_COPY_BUFFER); - popup_menu->connect("id_pressed", callable_mp(this, &VisualScriptEditor::_menu_option)); - - base_type_map.insert("String", Variant::STRING); - base_type_map.insert("Vector2", Variant::VECTOR2); - base_type_map.insert("Vector2i", Variant::VECTOR2I); - base_type_map.insert("Rect2", Variant::RECT2); - base_type_map.insert("Rect2i", Variant::RECT2I); - base_type_map.insert("Vector3", Variant::VECTOR3); - base_type_map.insert("Vector3i", Variant::VECTOR3I); - base_type_map.insert("Vector4", Variant::VECTOR4); - base_type_map.insert("Vector4i", Variant::VECTOR4I); - base_type_map.insert("Transform2D", Variant::TRANSFORM2D); - base_type_map.insert("Plane", Variant::PLANE); - base_type_map.insert("Quaternion", Variant::QUATERNION); - base_type_map.insert("AABB", Variant::AABB); - base_type_map.insert("Basis", Variant::BASIS); - base_type_map.insert("Transform3D", Variant::TRANSFORM3D); - base_type_map.insert("Projection", Variant::PROJECTION); - base_type_map.insert("Color", Variant::COLOR); - base_type_map.insert("NodePath", Variant::NODE_PATH); - base_type_map.insert("RID", Variant::RID); - base_type_map.insert("Callable", Variant::CALLABLE); - base_type_map.insert("Dictionary", Variant::DICTIONARY); - base_type_map.insert("Array", Variant::ARRAY); - base_type_map.insert("PackedByteArray", Variant::PACKED_BYTE_ARRAY); - base_type_map.insert("PackedInt32Array", Variant::PACKED_INT32_ARRAY); - base_type_map.insert("PackedFloat32Array", Variant::PACKED_FLOAT32_ARRAY); - base_type_map.insert("PackedInt64Array", Variant::PACKED_INT64_ARRAY); - base_type_map.insert("PackedFloat64Array", Variant::PACKED_FLOAT64_ARRAY); - base_type_map.insert("PackedStringArray", Variant::PACKED_STRING_ARRAY); - base_type_map.insert("PackedVector2Array", Variant::PACKED_VECTOR2_ARRAY); - base_type_map.insert("PackedVector3Array", Variant::PACKED_VECTOR3_ARRAY); - base_type_map.insert("PackedColorArray", Variant::PACKED_COLOR_ARRAY); -} - -VisualScriptEditor::~VisualScriptEditor() { - undo_redo->clear_history(); // Avoid crashes. - memdelete(signal_editor); - memdelete(variable_editor); -} - -static ScriptEditorBase *create_editor(const Ref<Resource> &p_resource) { - if (Object::cast_to<VisualScript>(*p_resource)) { - return memnew(VisualScriptEditor); - } - - return nullptr; -} - -VisualScriptEditor::Clipboard *VisualScriptEditor::clipboard = nullptr; - -void VisualScriptEditor::free_clipboard() { - if (clipboard) { - memdelete(clipboard); - } -} - -static void register_editor_callback() { - ScriptEditor::register_create_script_editor_function(create_editor); - - ED_SHORTCUT("visual_script_editor/toggle_breakpoint", TTR("Toggle Breakpoint"), Key::F9); - ED_SHORTCUT("visual_script_editor/find_node_type", TTR("Find Node Type"), KeyModifierMask::CMD + Key::F); - ED_SHORTCUT("visual_script_editor/create_function", TTR("Make Function"), KeyModifierMask::CMD + Key::G); - ED_SHORTCUT("visual_script_editor/refresh_nodes", TTR("Refresh Graph"), KeyModifierMask::CMD + Key::R); - ED_SHORTCUT("visual_script_editor/edit_member", TTR("Edit Member"), KeyModifierMask::CMD + Key::E); -} - -void VisualScriptEditor::register_editor() { - // Too early to register stuff here, request a callback. - EditorNode::add_plugin_init_callback(register_editor_callback); -} - -void VisualScriptEditor::validate() { -} - -// VisualScriptCustomNodes - -Ref<VisualScriptNode> VisualScriptCustomNodes::create_node_custom(const String &p_name) { - Ref<VisualScriptCustomNode> node; - node.instantiate(); - node->set_script(singleton->custom_nodes[p_name]); - return node; -} - -VisualScriptCustomNodes *VisualScriptCustomNodes::singleton = nullptr; -HashMap<String, Ref<RefCounted>> VisualScriptCustomNodes::custom_nodes; - -VisualScriptCustomNodes::VisualScriptCustomNodes() { - singleton = this; -} - -VisualScriptCustomNodes::~VisualScriptCustomNodes() { - custom_nodes.clear(); -} - -void VisualScriptCustomNodes::add_custom_node(const String &p_name, const String &p_category, const Ref<Script> &p_script) { - String node_name = "custom/" + p_category + "/" + p_name; - custom_nodes.insert(node_name, p_script); - VisualScriptLanguage::singleton->add_register_func(node_name, &VisualScriptCustomNodes::create_node_custom); - emit_signal(SNAME("custom_nodes_updated")); -} - -void VisualScriptCustomNodes::remove_custom_node(const String &p_name, const String &p_category) { - String node_name = "custom/" + p_category + "/" + p_name; - custom_nodes.erase(node_name); - VisualScriptLanguage::singleton->remove_register_func(node_name); - emit_signal(SNAME("custom_nodes_updated")); -} - -void VisualScriptCustomNodes::_bind_methods() { - ClassDB::bind_method(D_METHOD("add_custom_node", "name", "category", "script"), &VisualScriptCustomNodes::add_custom_node); - ClassDB::bind_method(D_METHOD("remove_custom_node", "name", "category"), &VisualScriptCustomNodes::remove_custom_node); - ADD_SIGNAL(MethodInfo("custom_nodes_updated")); -} - -#endif diff --git a/modules/visual_script/editor/visual_script_editor.h b/modules/visual_script/editor/visual_script_editor.h deleted file mode 100644 index 0378da9700..0000000000 --- a/modules/visual_script/editor/visual_script_editor.h +++ /dev/null @@ -1,395 +0,0 @@ -/*************************************************************************/ -/* visual_script_editor.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef VISUAL_SCRIPT_EDITOR_H -#define VISUAL_SCRIPT_EDITOR_H - -#include "../visual_script.h" -#include "editor/create_dialog.h" -#include "editor/plugins/script_editor_plugin.h" -#include "visual_script_property_selector.h" - -class GraphEdit; - -class EditorUndoRedoManager; -class VisualScriptEditorSignalEdit; -class VisualScriptEditorVariableEdit; - -#ifdef TOOLS_ENABLED - -class VisualScriptEditedProperty : public RefCounted { - GDCLASS(VisualScriptEditedProperty, RefCounted); - -private: - Variant edited_property; - -protected: - static void _bind_methods(); - -public: - void set_edited_property(Variant p_variant); - Variant get_edited_property() const; - - VisualScriptEditedProperty() {} -}; - -// TODO: Maybe this class should be refactored. -// See https://github.com/godotengine/godot/issues/51913 -class VisualScriptEditor : public ScriptEditorBase { - GDCLASS(VisualScriptEditor, ScriptEditorBase); - - enum { - TYPE_SEQUENCE = 1000, - INDEX_BASE_SEQUENCE = 1024 - }; - - enum { - EDIT_ADD_NODE, - EDIT_SEPARATOR, // popup menu separator - ignored - EDIT_CUT_NODES, - EDIT_COPY_NODES, - EDIT_PASTE_NODES, - EDIT_DELETE_NODES, - EDIT_DUPLICATE_NODES, - EDIT_CLEAR_COPY_BUFFER, - - EDIT_CREATE_FUNCTION, - EDIT_TOGGLE_BREAKPOINT, - EDIT_FIND_NODE_TYPE, - REFRESH_GRAPH, - }; - - enum PortAction { - CREATE_CALL_SET_GET, - CREATE_ACTION, - }; - - enum MemberAction { - MEMBER_EDIT, - MEMBER_REMOVE - }; - - enum MemberType { - MEMBER_FUNCTION, - MEMBER_VARIABLE, - MEMBER_SIGNAL - }; - - VBoxContainer *members_section = nullptr; - MenuButton *edit_menu = nullptr; - - Ref<VisualScript> script; - - Button *base_type_select = nullptr; - - LineEdit *func_name_box = nullptr; - ScrollContainer *func_input_scroll = nullptr; - VBoxContainer *func_input_vbox = nullptr; - ConfirmationDialog *function_create_dialog = nullptr; - - GraphEdit *graph = nullptr; - HBoxContainer *status_bar = nullptr; - Button *toggle_scripts_button = nullptr; - - VisualScriptEditorSignalEdit *signal_editor = nullptr; - - AcceptDialog *edit_signal_dialog = nullptr; - EditorInspector *edit_signal_edit = nullptr; - - VisualScriptPropertySelector *method_select = nullptr; - VisualScriptPropertySelector *new_connect_node_select = nullptr; - VisualScriptPropertySelector *new_virtual_method_select = nullptr; - - VisualScriptEditorVariableEdit *variable_editor = nullptr; - - AcceptDialog *edit_variable_dialog = nullptr; - EditorInspector *edit_variable_edit = nullptr; - - PopupPanel *default_property_editor_popup = nullptr; - EditorProperty *default_property_editor = nullptr; - Ref<VisualScriptEditedProperty> edited_default_property_holder; - - Ref<EditorUndoRedoManager> undo_redo; - Tree *members = nullptr; - AcceptDialog *function_name_edit = nullptr; - LineEdit *function_name_box = nullptr; - - Label *hint_text = nullptr; - Timer *hint_text_timer = nullptr; - - Label *select_func_text = nullptr; - - bool updating_graph = false; - - void _show_hint(const String &p_hint); - void _hide_timer(); - - CreateDialog *select_base_type = nullptr; - - struct VirtualInMenu { - String name; - Variant::Type ret; - bool ret_variant; - Vector<Pair<Variant::Type, String>> args; - }; - - HashMap<StringName, Color> node_colors; - HashMap<StringName, Ref<StyleBox>> node_styles; - HashMap<StringName, Variant::Type> base_type_map; - - void _update_graph_connections(); - void _update_graph(int p_only_id = -1); - - bool updating_members = false; - - void _update_members(); - String _sanitized_variant_text(const StringName &property_name); - - StringName selected; - - String _validate_name(const String &p_name) const; - - struct Clipboard { - HashMap<int, Ref<VisualScriptNode>> nodes; - HashMap<int, Vector2> nodes_positions; - - RBSet<VisualScript::SequenceConnection> sequence_connections; - RBSet<VisualScript::DataConnection> data_connections; - }; - - static Clipboard *clipboard; - - PopupMenu *popup_menu = nullptr; - PopupMenu *member_popup = nullptr; - MemberType member_type; - String member_name; - - PortAction port_action; - int port_action_node = 0; - int port_action_output = 0; - Vector2 port_action_pos; - int port_action_new_node = 0; - - bool saved_pos_dirty = false; - - Vector2 mouse_up_position; - - void _port_action_menu(int p_option); - - void connect_data(Ref<VisualScriptNode> vnode_old, Ref<VisualScriptNode> vnode, int new_id); - - NodePath drop_path; - Node *drop_node = nullptr; - Vector2 drop_position; - void _selected_connect_node(const String &p_text, const String &p_category, const bool p_connecting = true); - void connect_seq(Ref<VisualScriptNode> vnode_old, Ref<VisualScriptNode> vnode_new, int new_id); - - void _cancel_connect_node(); - int _create_new_node_from_name(const String &p_text, const Vector2 &p_point); - void _selected_new_virtual_method(const String &p_text, const String &p_category, const bool p_connecting); - - int error_line = -1; - - void _node_selected(Node *p_node); - void _center_on_node(int p_id); - - void _node_filter_changed(const String &p_text); - void _change_base_type_callback(); - void _change_base_type(); - void _toggle_tool_script(); - void _member_selected(); - void _member_edited(); - - void _begin_node_move(); - void _end_node_move(); - void _move_node(int p_id, const Vector2 &p_to); - - void _get_ends(int p_node, const List<VisualScript::SequenceConnection> &p_seqs, const RBSet<int> &p_selected, RBSet<int> &r_end_nodes); - - void _node_moved(Vector2 p_from, Vector2 p_to, int p_id); - void _remove_node(int p_id); - void _graph_connected(const String &p_from, int p_from_slot, const String &p_to, int p_to_slot); - void _graph_disconnected(const String &p_from, int p_from_slot, const String &p_to, int p_to_slot); - void _graph_connect_to_empty(const String &p_from, int p_from_slot, const Vector2 &p_release_pos); - - void _node_ports_changed(int p_id); - void _node_create(); - - void _update_available_nodes(); - - void _member_button(Object *p_item, int p_column, int p_button, MouseButton p_mouse_button); - - void _expression_text_changed(const String &p_text, int p_id); - void _add_input_port(int p_id); - void _add_output_port(int p_id); - void _remove_input_port(int p_id, int p_port); - void _remove_output_port(int p_id, int p_port); - void _change_port_type(int p_select, int p_id, int p_port, bool is_input); - void _update_node_size(int p_id); - void _port_name_focus_out(const Node *p_name_box, int p_id, int p_port, bool is_input); - - Vector2 _get_pos_in_graph(Vector2 p_point) const; - Vector2 _get_available_pos(bool p_centered = true, Vector2 p_pos = Vector2()) const; - - bool node_has_sequence_connections(int p_id); - - void _generic_search(Vector2 pos = Vector2(), bool node_centered = false); - - virtual void input(const Ref<InputEvent> &p_event) override; - void _graph_gui_input(const Ref<InputEvent> &p_event); - void _members_gui_input(const Ref<InputEvent> &p_event); - void _fn_name_box_input(const Ref<InputEvent> &p_event); - void _on_fn_name_box_confirmed(); - void _rename_function(const String &p_name, const String &p_new_name); - - void _create_function_dialog(); - void _create_function(); - void _add_func_input(); - void _remove_func_input(Node *p_node); - void _deselect_input_names(); - void _add_node_dialog(); - void _node_item_selected(); - void _node_item_unselected(); - - void _on_nodes_copy(); - void _on_nodes_paste(); - void _on_nodes_delete(); - void _on_nodes_duplicate(); - - Variant get_drag_data_fw(const Point2 &p_point, Control *p_from); - bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; - void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); - - int editing_id = 0; - int editing_input = 0; - - bool can_swap = false; - int data_disconnect_node = 0; - int data_disconnect_port = 0; - - void _default_value_changed(const StringName &p_property, const Variant &p_value, const String &p_field, bool p_changing); - void _default_value_edited(Node *p_button, int p_id, int p_input_port); - - void _menu_option(int p_what); - - void _graph_ofs_changed(const Vector2 &p_ofs); - void _comment_node_resized(const Vector2 &p_new_size, int p_node); - - void _draw_color_over_button(Object *obj, Color p_color); - void _button_resource_previewed(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, Variant p_ud); - - VisualScriptNode::TypeGuess _guess_output_type(int p_port_action_node, int p_port_action_output, RBSet<int> &p_visited_nodes); - - void _member_rmb_selected(const Vector2 &p_pos, MouseButton p_button); - void _member_option(int p_option); - - void _toggle_scripts_pressed(); - -protected: - void _notification(int p_what); - static void _bind_methods(); - -public: - virtual void add_syntax_highlighter(Ref<EditorSyntaxHighlighter> p_highlighter) override; - virtual void set_syntax_highlighter(Ref<EditorSyntaxHighlighter> p_highlighter) override; - - virtual void apply_code() override; - virtual Ref<Resource> get_edited_resource() const override; - virtual void set_edited_resource(const Ref<Resource> &p_res) override; - virtual void enable_editor() override; - virtual Vector<String> get_functions() override; - virtual void reload_text() override; - virtual String get_name() override; - virtual Ref<Texture2D> get_theme_icon() override; - virtual bool is_unsaved() override; - virtual Variant get_edit_state() override; - virtual void set_edit_state(const Variant &p_state) override; - virtual void goto_line(int p_line, bool p_with_error = false) override; - virtual void set_executing_line(int p_line) override; - virtual void clear_executing_line() override; - virtual void trim_trailing_whitespace() override; - virtual void insert_final_newline() override; - virtual void convert_indent_to_spaces() override; - virtual void convert_indent_to_tabs() override; - virtual void ensure_focus() override; - virtual void tag_saved_version() override; - virtual void reload(bool p_soft) override; - virtual PackedInt32Array get_breakpoints() override; - virtual void set_breakpoint(int p_line, bool p_enable) override{}; - virtual void clear_breakpoints() override{}; - virtual void add_callback(const String &p_function, PackedStringArray p_args) override; - virtual void update_settings() override; - virtual bool show_members_overview() override; - virtual void set_debugger_active(bool p_active) override; - virtual void set_tooltip_request_func(const Callable &p_toolip_callback) override; - virtual Control *get_edit_menu() override; - virtual void clear_edit_menu() override; - virtual void set_find_replace_bar(FindReplaceBar *p_bar) override { p_bar->hide(); }; // Not needed here. - virtual bool can_lose_focus_on_node_selection() override { return false; } - virtual void validate() override; - - virtual Control *get_base_editor() const override; - - static void register_editor(); - - static void free_clipboard(); - - void update_toggle_scripts_button() override; - - VisualScriptEditor(); - ~VisualScriptEditor(); -}; - -// Singleton -class VisualScriptCustomNodes : public Object { - GDCLASS(VisualScriptCustomNodes, Object); - - friend class VisualScriptLanguage; - -protected: - static void _bind_methods(); - static VisualScriptCustomNodes *singleton; - - static HashMap<String, Ref<RefCounted>> custom_nodes; - static Ref<VisualScriptNode> create_node_custom(const String &p_name); - -public: - static VisualScriptCustomNodes *get_singleton() { return singleton; } - - void add_custom_node(const String &p_name, const String &p_category, const Ref<Script> &p_script); - void remove_custom_node(const String &p_name, const String &p_category); - - VisualScriptCustomNodes(); - ~VisualScriptCustomNodes(); -}; - -#endif - -#endif // VISUAL_SCRIPT_EDITOR_H diff --git a/modules/visual_script/editor/visual_script_property_selector.cpp b/modules/visual_script/editor/visual_script_property_selector.cpp deleted file mode 100644 index 712c89368b..0000000000 --- a/modules/visual_script/editor/visual_script_property_selector.cpp +++ /dev/null @@ -1,1277 +0,0 @@ -/*************************************************************************/ -/* visual_script_property_selector.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "visual_script_property_selector.h" - -#include "../visual_script.h" -#include "../visual_script_builtin_funcs.h" -#include "../visual_script_flow_control.h" -#include "../visual_script_func_nodes.h" -#include "../visual_script_nodes.h" -#include "core/os/keyboard.h" -#include "editor/doc_tools.h" -#include "editor/editor_feature_profile.h" -#include "editor/editor_scale.h" -#include "editor/editor_settings.h" -#include "scene/main/node.h" -#include "scene/main/window.h" - -void VisualScriptPropertySelector::_update_icons() { - search_box->set_right_icon(results_tree->get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); - search_box->set_clear_button_enabled(true); - search_box->add_theme_icon_override("right_icon", results_tree->get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); - - search_visual_script_nodes->set_icon(results_tree->get_theme_icon(SNAME("VisualScript"), SNAME("EditorIcons"))); - search_classes->set_icon(results_tree->get_theme_icon(SNAME("Object"), SNAME("EditorIcons"))); - search_methods->set_icon(results_tree->get_theme_icon(SNAME("MemberMethod"), SNAME("EditorIcons"))); - search_operators->set_icon(results_tree->get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); - search_signals->set_icon(results_tree->get_theme_icon(SNAME("MemberSignal"), SNAME("EditorIcons"))); - search_constants->set_icon(results_tree->get_theme_icon(SNAME("MemberConstant"), SNAME("EditorIcons"))); - search_properties->set_icon(results_tree->get_theme_icon(SNAME("MemberProperty"), SNAME("EditorIcons"))); - search_theme_items->set_icon(results_tree->get_theme_icon(SNAME("MemberTheme"), SNAME("EditorIcons"))); - - case_sensitive_button->set_icon(results_tree->get_theme_icon(SNAME("MatchCase"), SNAME("EditorIcons"))); - hierarchy_button->set_icon(results_tree->get_theme_icon(SNAME("ClassList"), SNAME("EditorIcons"))); -} - -void VisualScriptPropertySelector::_sbox_input(const Ref<InputEvent> &p_ie) { - Ref<InputEventKey> k = p_ie; - - if (k.is_valid()) { - switch (k->get_keycode()) { - case Key::UP: - case Key::DOWN: - case Key::PAGEUP: - case Key::PAGEDOWN: { - results_tree->gui_input(k); - search_box->accept_event(); - } break; - default: - break; - } - } -} - -void VisualScriptPropertySelector::_update_results_i(int p_int) { - _update_results(); -} - -void VisualScriptPropertySelector::_update_results_s(String p_string) { - _update_results(); -} - -void VisualScriptPropertySelector::_update_results_search_all() { - if (search_classes->is_pressed()) { - scope_combo->select(COMBO_ALL); - } - _update_results(); -} - -void VisualScriptPropertySelector::_update_results() { - _update_icons(); - search_runner = Ref<SearchRunner>(memnew(SearchRunner(this, results_tree))); - set_process(true); -} - -void VisualScriptPropertySelector::_confirmed() { - TreeItem *ti = results_tree->get_selected(); - if (!ti) { - return; - } - emit_signal(SNAME("selected"), ti->get_metadata(0), ti->get_metadata(1), connecting); - set_visible(false); -} - -void VisualScriptPropertySelector::_item_selected() { - help_bit->set_text(results_tree->get_selected()->get_meta("description", "No description available")); -} - -void VisualScriptPropertySelector::_hide_requested() { - _cancel_pressed(); // From AcceptDialog. -} - -void VisualScriptPropertySelector::_notification(int p_what) { - switch (p_what) { - case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - _update_icons(); - } break; - - case NOTIFICATION_ENTER_TREE: { - connect("confirmed", callable_mp(this, &VisualScriptPropertySelector::_confirmed)); - } break; - - case NOTIFICATION_PROCESS: { - // Update background search. - if (search_runner.is_valid()) { - if (search_runner->work()) { - // Search done. - get_ok_button()->set_disabled(!results_tree->get_selected()); - - search_runner = Ref<SearchRunner>(); - set_process(false); - } - } else { - // if one is valid - set_process(false); - } - } break; - } -} - -void VisualScriptPropertySelector::select_method_from_base_type(const String &p_base, const bool p_virtuals_only, const bool p_connecting, bool clear_text) { - set_title(TTR("Select method from base type")); - base_type = p_base; - base_script = ""; - type = Variant::NIL; - connecting = p_connecting; - - if (clear_text) { - if (p_virtuals_only) { - search_box->set_text("._"); // show all _methods - search_box->set_caret_column(2); - } else { - search_box->set_text("."); // show all methods - search_box->set_caret_column(1); - } - } - - search_visual_script_nodes->set_pressed(false); - search_classes->set_pressed(false); - search_methods->set_pressed(true); - search_operators->set_pressed(false); - search_signals->set_pressed(false); - search_constants->set_pressed(false); - search_properties->set_pressed(false); - search_theme_items->set_pressed(false); - - scope_combo->select(COMBO_BASE); - - results_tree->clear(); - show_window(.5f); - search_box->grab_focus(); - - _update_results(); -} - -void VisualScriptPropertySelector::select_from_base_type(const String &p_base, const String &p_base_script, bool p_virtuals_only, const bool p_connecting, bool clear_text) { - set_title(TTR("Select from base type")); - base_type = p_base; - base_script = p_base_script.trim_prefix("res://").quote(); // filepath to EditorHelp::get_doc_data().name - type = Variant::NIL; - connecting = p_connecting; - - if (clear_text) { - if (p_virtuals_only) { - search_box->set_text("_"); - } else { - search_box->set_text(" "); - } - } - search_box->select_all(); - - search_visual_script_nodes->set_pressed(false); - search_classes->set_pressed(false); - search_methods->set_pressed(true); - search_operators->set_pressed(false); - search_signals->set_pressed(true); - search_constants->set_pressed(false); - search_properties->set_pressed(true); - search_theme_items->set_pressed(false); - - scope_combo->select(COMBO_RELATED); - - results_tree->clear(); - show_window(.5f); - search_box->grab_focus(); - _update_results(); -} - -void VisualScriptPropertySelector::select_from_script(const Ref<Script> &p_script, const bool p_connecting, bool clear_text) { - set_title(TTR("Select from script")); - ERR_FAIL_COND(p_script.is_null()); - - base_type = p_script->get_instance_base_type(); - base_script = p_script->get_path().trim_prefix("res://").quote(); // filepath to EditorHelp::get_doc_data().name - type = Variant::NIL; - script = p_script->get_instance_id(); - connecting = p_connecting; - - if (clear_text) { - search_box->set_text(""); - } - search_box->select_all(); - - search_visual_script_nodes->set_pressed(false); - search_classes->set_pressed(true); - search_methods->set_pressed(true); - search_operators->set_pressed(true); - search_signals->set_pressed(true); - search_constants->set_pressed(true); - search_properties->set_pressed(true); - search_theme_items->set_pressed(false); - - scope_combo->select(COMBO_BASE); - - results_tree->clear(); - show_window(.5f); - search_box->grab_focus(); - _update_results(); -} - -void VisualScriptPropertySelector::select_from_basic_type(Variant::Type p_type, const bool p_connecting, bool clear_text) { - set_title(TTR("Select from basic type")); - ERR_FAIL_COND(p_type == Variant::NIL); - base_type = Variant::get_type_name(p_type); - base_script = ""; - type = p_type; - connecting = p_connecting; - - if (clear_text) { - search_box->set_text(" "); - } - search_box->select_all(); - - search_visual_script_nodes->set_pressed(false); - search_classes->set_pressed(false); - search_methods->set_pressed(true); - search_operators->set_pressed(true); - search_signals->set_pressed(false); - search_constants->set_pressed(true); - search_properties->set_pressed(true); - search_theme_items->set_pressed(false); - - scope_combo->select(COMBO_BASE); - - results_tree->clear(); - show_window(.5f); - search_box->grab_focus(); - - _update_results(); -} - -void VisualScriptPropertySelector::select_from_action(const String &p_type, const bool p_connecting, bool clear_text) { - set_title(TTR("Select from action")); - base_type = p_type; - base_script = ""; - type = Variant::NIL; - connecting = p_connecting; - - if (clear_text) { - search_box->set_text(""); - } - search_box->select_all(); - - search_visual_script_nodes->set_pressed(true); - search_classes->set_pressed(false); - search_methods->set_pressed(false); - search_operators->set_pressed(false); - search_signals->set_pressed(false); - search_constants->set_pressed(false); - search_properties->set_pressed(false); - search_theme_items->set_pressed(false); - - scope_combo->select(COMBO_RELATED); - - results_tree->clear(); - show_window(.5f); - search_box->grab_focus(); - _update_results(); -} - -void VisualScriptPropertySelector::select_from_instance(Object *p_instance, const bool p_connecting, bool clear_text) { - set_title(TTR("Select from instance")); - base_type = p_instance->get_class(); - - const Ref<Script> &p_script = p_instance->get_script(); - if (p_script == nullptr) { - base_script = ""; - } else { - base_script = p_script->get_path().trim_prefix("res://").quote(); // filepath to EditorHelp::get_doc_data().name - } - - type = Variant::NIL; - connecting = p_connecting; - - if (clear_text) { - search_box->set_text(" "); - } - search_box->select_all(); - - search_visual_script_nodes->set_pressed(false); - search_classes->set_pressed(false); - search_methods->set_pressed(true); - search_operators->set_pressed(false); - search_signals->set_pressed(true); - search_constants->set_pressed(true); - search_properties->set_pressed(true); - search_theme_items->set_pressed(false); - - scope_combo->select(COMBO_BASE); - - results_tree->clear(); - show_window(.5f); - search_box->grab_focus(); - _update_results(); -} - -void VisualScriptPropertySelector::select_from_visual_script(const Ref<Script> &p_script, bool clear_text) { - set_title(TTR("Select from visual script")); - base_type = p_script->get_instance_base_type(); - if (p_script == nullptr) { - base_script = ""; - } else { - base_script = p_script->get_path().trim_prefix("res://").quote(); // filepath to EditorHelp::get_doc_data().name - } - type = Variant::NIL; - connecting = false; - - if (clear_text) { - search_box->set_text(" "); - } - search_box->select_all(); - - search_visual_script_nodes->set_pressed(true); - search_classes->set_pressed(false); - search_methods->set_pressed(true); - search_operators->set_pressed(false); - search_signals->set_pressed(true); - search_constants->set_pressed(true); - search_properties->set_pressed(true); - search_theme_items->set_pressed(false); - - scope_combo->select(COMBO_BASE); - - results_tree->clear(); - show_window(.5f); - search_box->grab_focus(); - _update_results(); -} - -void VisualScriptPropertySelector::show_window(float p_screen_ratio) { - popup_centered_ratio(p_screen_ratio); -} - -void VisualScriptPropertySelector::_bind_methods() { - ADD_SIGNAL(MethodInfo("selected", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::STRING, "category"), PropertyInfo(Variant::BOOL, "connecting"))); -} - -VisualScriptPropertySelector::VisualScriptPropertySelector() { - vbox = memnew(VBoxContainer); - add_child(vbox); - - HBoxContainer *hbox = memnew(HBoxContainer); - hbox->set_alignment(hbox->ALIGNMENT_CENTER); - vbox->add_child(hbox); - - case_sensitive_button = memnew(Button); - case_sensitive_button->set_flat(true); - case_sensitive_button->set_tooltip(TTR("Case Sensitive")); - case_sensitive_button->connect("pressed", callable_mp(this, &VisualScriptPropertySelector::_update_results)); - case_sensitive_button->set_toggle_mode(true); - case_sensitive_button->set_focus_mode(Control::FOCUS_NONE); - hbox->add_child(case_sensitive_button); - - hierarchy_button = memnew(Button); - hierarchy_button->set_flat(true); - hierarchy_button->set_tooltip(TTR("Show Hierarchy")); - hierarchy_button->connect("pressed", callable_mp(this, &VisualScriptPropertySelector::_update_results)); - hierarchy_button->set_toggle_mode(true); - hierarchy_button->set_pressed(true); - hierarchy_button->set_focus_mode(Control::FOCUS_NONE); - hbox->add_child(hierarchy_button); - - hbox->add_child(memnew(VSeparator)); - - search_visual_script_nodes = memnew(Button); - search_visual_script_nodes->set_flat(true); - search_visual_script_nodes->set_tooltip(TTR("Search Visual Script Nodes")); - search_visual_script_nodes->connect("pressed", callable_mp(this, &VisualScriptPropertySelector::_update_results)); - search_visual_script_nodes->set_toggle_mode(true); - search_visual_script_nodes->set_pressed(true); - search_visual_script_nodes->set_focus_mode(Control::FOCUS_NONE); - hbox->add_child(search_visual_script_nodes); - - search_classes = memnew(Button); - search_classes->set_flat(true); - search_classes->set_tooltip(TTR("Search Classes")); - search_classes->connect("pressed", callable_mp(this, &VisualScriptPropertySelector::_update_results_search_all)); - search_classes->set_toggle_mode(true); - search_classes->set_pressed(true); - search_classes->set_focus_mode(Control::FOCUS_NONE); - hbox->add_child(search_classes); - - search_operators = memnew(Button); - search_operators->set_flat(true); - search_operators->set_tooltip(TTR("Search Operators")); - search_operators->connect("pressed", callable_mp(this, &VisualScriptPropertySelector::_update_results)); - search_operators->set_toggle_mode(true); - search_operators->set_pressed(true); - search_operators->set_focus_mode(Control::FOCUS_NONE); - hbox->add_child(search_operators); - - hbox->add_child(memnew(VSeparator)); - - search_methods = memnew(Button); - search_methods->set_flat(true); - search_methods->set_tooltip(TTR("Search Methods")); - search_methods->connect("pressed", callable_mp(this, &VisualScriptPropertySelector::_update_results)); - search_methods->set_toggle_mode(true); - search_methods->set_pressed(true); - search_methods->set_focus_mode(Control::FOCUS_NONE); - hbox->add_child(search_methods); - - search_signals = memnew(Button); - search_signals->set_flat(true); - search_signals->set_tooltip(TTR("Search Signals")); - search_signals->connect("pressed", callable_mp(this, &VisualScriptPropertySelector::_update_results)); - search_signals->set_toggle_mode(true); - search_signals->set_pressed(true); - search_signals->set_focus_mode(Control::FOCUS_NONE); - hbox->add_child(search_signals); - - search_constants = memnew(Button); - search_constants->set_flat(true); - search_constants->set_tooltip(TTR("Search Constants")); - search_constants->connect("pressed", callable_mp(this, &VisualScriptPropertySelector::_update_results)); - search_constants->set_toggle_mode(true); - search_constants->set_pressed(true); - search_constants->set_focus_mode(Control::FOCUS_NONE); - hbox->add_child(search_constants); - - search_properties = memnew(Button); - search_properties->set_flat(true); - search_properties->set_tooltip(TTR("Search Properties")); - search_properties->connect("pressed", callable_mp(this, &VisualScriptPropertySelector::_update_results)); - search_properties->set_toggle_mode(true); - search_properties->set_pressed(true); - search_properties->set_focus_mode(Control::FOCUS_NONE); - hbox->add_child(search_properties); - - search_theme_items = memnew(Button); - search_theme_items->set_flat(true); - search_theme_items->set_tooltip(TTR("Search Theme Items")); - search_theme_items->connect("pressed", callable_mp(this, &VisualScriptPropertySelector::_update_results)); - search_theme_items->set_toggle_mode(true); - search_theme_items->set_pressed(true); - search_theme_items->set_focus_mode(Control::FOCUS_NONE); - hbox->add_child(search_theme_items); - - scope_combo = memnew(OptionButton); - scope_combo->set_custom_minimum_size(Size2(200, 0) * EDSCALE); - scope_combo->set_tooltip(TTR("Select the search limits")); - scope_combo->set_stretch_ratio(0); // Fixed width. - scope_combo->add_item(TTR("Search Related"), SCOPE_RELATED); - scope_combo->add_separator(); - scope_combo->add_item(TTR("Search Base"), SCOPE_BASE); - scope_combo->add_item(TTR("Search Inheriters"), SCOPE_INHERITERS); - scope_combo->add_item(TTR("Search Unrelated"), SCOPE_UNRELATED); - scope_combo->add_item(TTR("Search All"), SCOPE_ALL); - scope_combo->connect("item_selected", callable_mp(this, &VisualScriptPropertySelector::_update_results_i)); - hbox->add_child(scope_combo); - - search_box = memnew(LineEdit); - search_box->set_tooltip(TTR("Enter \" \" to show all filtered options\nEnter \".\" to show all filtered methods, operators and constructors\nUse CTRL_KEY to drop property setters")); - search_box->set_custom_minimum_size(Size2(200, 0) * EDSCALE); - search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); - search_box->connect("text_changed", callable_mp(this, &VisualScriptPropertySelector::_update_results_s)); - search_box->connect("gui_input", callable_mp(this, &VisualScriptPropertySelector::_sbox_input)); - register_text_enter(search_box); - vbox->add_child(search_box); - - results_tree = memnew(Tree); - results_tree->set_v_size_flags(Control::SIZE_EXPAND_FILL); - results_tree->set_hide_root(true); - results_tree->set_hide_folding(false); - results_tree->set_columns(2); - results_tree->set_column_title(0, TTR("Name")); - results_tree->set_column_clip_content(0, true); - results_tree->set_column_title(1, TTR("Member Type")); - results_tree->set_column_expand(1, false); - results_tree->set_column_custom_minimum_width(1, 150 * EDSCALE); - results_tree->set_column_clip_content(1, true); - results_tree->set_custom_minimum_size(Size2(0, 100) * EDSCALE); - results_tree->set_select_mode(Tree::SELECT_ROW); - results_tree->connect("item_activated", callable_mp(this, &VisualScriptPropertySelector::_confirmed)); - results_tree->connect("item_selected", callable_mp(this, &VisualScriptPropertySelector::_item_selected)); - vbox->add_child(results_tree); - - ScrollContainer *scroller = memnew(ScrollContainer); - scroller->set_horizontal_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED); - scroller->set_v_size_flags(Control::SIZE_EXPAND_FILL); - scroller->set_custom_minimum_size(Size2(600, 400) * EDSCALE); - vbox->add_child(scroller); - - help_bit = memnew(EditorHelpBit); - help_bit->set_h_size_flags(Control::SIZE_EXPAND_FILL); - help_bit->set_v_size_flags(Control::SIZE_EXPAND_FILL); - scroller->add_child(help_bit); - - help_bit->connect("request_hide", callable_mp(this, &VisualScriptPropertySelector::_hide_requested)); - set_ok_button_text(TTR("Open")); - get_ok_button()->set_disabled(true); - set_hide_on_ok(false); -} - -bool VisualScriptPropertySelector::SearchRunner::_is_class_disabled_by_feature_profile(const StringName &p_class) { - Ref<EditorFeatureProfile> profile = EditorFeatureProfileManager::get_singleton()->get_current_profile(); - if (profile.is_null()) { - return false; - } - - StringName class_name = p_class; - while (class_name != StringName()) { - if (!ClassDB::class_exists(class_name)) { - return false; - } - - if (profile->is_class_disabled(class_name)) { - return true; - } - class_name = ClassDB::get_parent_class(class_name); - } - - return false; -} - -bool VisualScriptPropertySelector::SearchRunner::_is_class_disabled_by_scope(const StringName &p_class) { - bool is_base_script = false; - if (p_class == selector_ui->base_script) { - is_base_script = true; - } - bool is_base = false; - if (selector_ui->base_type == p_class) { - is_base = true; - } - bool is_parent = false; - if ((ClassDB::is_parent_class(selector_ui->base_type, p_class)) && !is_base) { - is_parent = true; - } - - bool is_inheriter = false; - List<StringName> inheriters; - ClassDB::get_inheriters_from_class(selector_ui->base_type, &inheriters); - if (inheriters.find(p_class)) { - is_inheriter = true; - } - - if (scope_flags & SCOPE_BASE) { - if (is_base_script || is_base || is_parent) { - return false; - } - } - if (scope_flags & SCOPE_INHERITERS) { - if (is_base_script || is_base || is_inheriter) { - return false; - } - } - // if (scope_flags & SCOPE_RELATED) { - // /* code */ - // } - if (scope_flags & SCOPE_UNRELATED) { - if (!is_base_script && !is_base && !is_inheriter) { - return false; - } - } - return true; -} - -bool VisualScriptPropertySelector::SearchRunner::_slice() { - bool phase_done = false; - switch (phase) { - case PHASE_INIT: - phase_done = _phase_init(); - break; - case PHASE_MATCH_CLASSES_INIT: - phase_done = _phase_match_classes_init(); - break; - case PHASE_NODE_CLASSES_INIT: - phase_done = _phase_node_classes_init(); - break; - case PHASE_NODE_CLASSES_BUILD: - phase_done = _phase_node_classes_build(); - break; - case PHASE_MATCH_CLASSES: - phase_done = _phase_match_classes(); - break; - case PHASE_CLASS_ITEMS_INIT: - phase_done = _phase_class_items_init(); - break; - case PHASE_CLASS_ITEMS: - phase_done = _phase_class_items(); - break; - case PHASE_MEMBER_ITEMS_INIT: - phase_done = _phase_member_items_init(); - break; - case PHASE_MEMBER_ITEMS: - phase_done = _phase_member_items(); - break; - case PHASE_SELECT_MATCH: - phase_done = _phase_select_match(); - break; - case PHASE_MAX: - return true; - default: - WARN_PRINT("Invalid or unhandled phase in EditorHelpSearch::Runner, aborting search."); - return true; - }; - - if (phase_done) { - phase++; - } - return false; -} - -bool VisualScriptPropertySelector::SearchRunner::_phase_init() { - search_flags = 0; // selector_ui->filter_combo->get_selected_id(); - if (selector_ui->search_visual_script_nodes->is_pressed()) { - search_flags |= SEARCH_VISUAL_SCRIPT_NODES; - } - if (selector_ui->search_classes->is_pressed()) { - search_flags |= SEARCH_CLASSES; - } - // if (selector_ui->search_constructors->is_pressed()) { - search_flags |= SEARCH_CONSTRUCTORS; - // } - if (selector_ui->search_methods->is_pressed()) { - search_flags |= SEARCH_METHODS; - } - if (selector_ui->search_operators->is_pressed()) { - search_flags |= SEARCH_OPERATORS; - } - if (selector_ui->search_signals->is_pressed()) { - search_flags |= SEARCH_SIGNALS; - } - if (selector_ui->search_constants->is_pressed()) { - search_flags |= SEARCH_CONSTANTS; - } - if (selector_ui->search_properties->is_pressed()) { - search_flags |= SEARCH_PROPERTIES; - } - if (selector_ui->search_theme_items->is_pressed()) { - search_flags |= SEARCH_THEME_ITEMS; - } - if (selector_ui->case_sensitive_button->is_pressed()) { - search_flags |= SEARCH_CASE_SENSITIVE; - } - if (selector_ui->hierarchy_button->is_pressed()) { - search_flags |= SEARCH_SHOW_HIERARCHY; - } - scope_flags = selector_ui->scope_combo->get_selected_id(); - - return true; -} - -bool VisualScriptPropertySelector::SearchRunner::_phase_match_classes_init() { - combined_docs = EditorHelp::get_doc_data()->class_list; - matches.clear(); - matched_item = nullptr; - match_highest_score = 0; - - if ( - (selector_ui->base_script.unquote() != "") && - (selector_ui->base_script.unquote() != ".") && - !combined_docs.has(selector_ui->base_script)) { - String file_path = "res://" + selector_ui->base_script.unquote(); // EditorHelp::get_doc_data().name to filepath - Ref<Script> script; - script = ResourceLoader::load(file_path); - if (!script.is_null()) { - DocData::ClassDoc class_doc = DocData::ClassDoc(); - - class_doc.name = selector_ui->base_script; - - class_doc.inherits = script->get_instance_base_type(); - class_doc.brief_description = ".vs files not supported by EditorHelp::get_doc_data()"; - class_doc.description = ""; - - Object *obj = ObjectDB::get_instance(script->get_instance_id()); - if (Object::cast_to<Script>(obj)) { - List<MethodInfo> methods; - Object::cast_to<Script>(obj)->get_script_method_list(&methods); - for (List<MethodInfo>::Element *M = methods.front(); M; M = M->next()) { - class_doc.methods.push_back(_get_method_doc(M->get())); - } - - List<MethodInfo> signals; - Object::cast_to<Script>(obj)->get_script_signal_list(&signals); - for (List<MethodInfo>::Element *S = signals.front(); S; S = S->next()) { - class_doc.signals.push_back(_get_method_doc(S->get())); - } - - List<PropertyInfo> properties; - Object::cast_to<Script>(obj)->get_script_property_list(&properties); - for (List<PropertyInfo>::Element *P = properties.front(); P; P = P->next()) { - DocData::PropertyDoc pd = DocData::PropertyDoc(); - pd.name = P->get().name; - pd.type = Variant::get_type_name(P->get().type); - class_doc.properties.push_back(pd); - } - } - combined_docs.insert(class_doc.name, class_doc); - } - } - iterator_doc = combined_docs.begin(); - return true; -} - -bool VisualScriptPropertySelector::SearchRunner::_phase_node_classes_init() { - VisualScriptLanguage::singleton->get_registered_node_names(&vs_nodes); - _add_class_doc("functions", "", ""); - _add_class_doc("operators", "", ""); - return true; -} - -bool VisualScriptPropertySelector::SearchRunner::_phase_node_classes_build() { - if (vs_nodes.is_empty()) { - return true; - } - String registered_node_name = vs_nodes[0]; - vs_nodes.pop_front(); - - Vector<String> path = registered_node_name.split("/"); - if (path[0] == "constants") { - _add_class_doc(registered_node_name, "", "constants"); - } else if (path[0] == "custom") { - _add_class_doc(registered_node_name, "", "custom"); - } else if (path[0] == "data") { - _add_class_doc(registered_node_name, "", "data"); - } else if (path[0] == "flow_control") { - _add_class_doc(registered_node_name, "", "flow_control"); - } else if (path[0] == "functions") { - if (path[1] == "built_in") { - _add_class_doc(registered_node_name, "functions", "built_in"); - } else if (path[1] == "by_type") { - // No action is required. - // Using function references from ClassDB to remove confusion for users. - } else if (path[1] == "constructors") { - _add_class_doc(registered_node_name, "", "constructors"); - } else if (path[1] == "deconstruct") { - _add_class_doc(registered_node_name, "", "deconstruct"); - } else if (path[1] == "wait") { - _add_class_doc(registered_node_name, "functions", "yield"); - } else { - _add_class_doc(registered_node_name, "functions", ""); - } - } else if (path[0] == "index") { - _add_class_doc(registered_node_name, "", "index"); - } else if (path[0] == "operators") { - if (path[1] == "bitwise") { - _add_class_doc(registered_node_name, "operators", "bitwise"); - } else if (path[1] == "compare") { - _add_class_doc(registered_node_name, "operators", "compare"); - } else if (path[1] == "logic") { - _add_class_doc(registered_node_name, "operators", "logic"); - } else if (path[1] == "math") { - _add_class_doc(registered_node_name, "operators", "math"); - } else { - _add_class_doc(registered_node_name, "operators", ""); - } - } - return false; -} - -bool VisualScriptPropertySelector::SearchRunner::_phase_match_classes() { - DocData::ClassDoc &class_doc = iterator_doc->value; - if ( - (!_is_class_disabled_by_feature_profile(class_doc.name) && !_is_class_disabled_by_scope(class_doc.name)) || - _match_visual_script(class_doc)) { - if (class_doc.inherits == "VisualScriptCustomNode") { - class_doc.script_path = "res://" + class_doc.name.unquote(); - Ref<Script> script = ResourceLoader::load(class_doc.script_path); - Ref<VisualScriptCustomNode> vsn; - vsn.instantiate(); - vsn->set_script(script); - class_doc.name = vsn->get_caption(); - if (combined_docs.has(vsn->get_category())) { - class_doc.inherits = vsn->get_category(); - } else if (combined_docs.has("VisualScriptNode/" + vsn->get_category())) { - class_doc.inherits = "VisualScriptNode/" + vsn->get_category(); - } else if (combined_docs.has("VisualScriptCustomNode/" + vsn->get_category())) { - class_doc.inherits = "VisualScriptCustomNode/" + vsn->get_category(); - } else { - class_doc.inherits = ""; - } - class_doc.category = "VisualScriptCustomNode/" + vsn->get_category(); - class_doc.brief_description = ""; - class_doc.constructors.clear(); - class_doc.methods.clear(); - class_doc.operators.clear(); - class_doc.signals.clear(); - class_doc.constants.clear(); - class_doc.enums.clear(); - class_doc.properties.clear(); - class_doc.theme_properties.clear(); - } - - matches[class_doc.name] = ClassMatch(); - ClassMatch &match = matches[class_doc.name]; - - match.category = class_doc.category; - match.doc = &class_doc; - // Match class name. - if (search_flags & SEARCH_CLASSES || _match_visual_script(class_doc)) { - if (term == "") { - match.name = !_match_is_hidden(class_doc); - } else { - match.name = _match_string(term, class_doc.name); - } - // match.name = term == "" || _match_string(term, class_doc.name); - } - - // Match members if the term is long enough. - if (term.length() >= 0) { - if (search_flags & SEARCH_CONSTRUCTORS) { - for (int i = 0; i < class_doc.constructors.size(); i++) { - String method_name = (search_flags & SEARCH_CASE_SENSITIVE) ? class_doc.constructors[i].name : class_doc.constructors[i].name.to_lower(); - if (method_name.find(term) > -1 || - term == " " || - (term.begins_with(".") && method_name.begins_with(term.substr(1))) || - (term.ends_with("(") && method_name.ends_with(term.left(term.length() - 1).strip_edges())) || - (term.begins_with(".") && term.ends_with("(") && method_name == term.substr(1, term.length() - 2).strip_edges())) { - match.constructors.push_back(const_cast<DocData::MethodDoc *>(&class_doc.constructors[i])); - } - } - } - if (search_flags & SEARCH_METHODS) { - for (int i = 0; i < class_doc.methods.size(); i++) { - String method_name = (search_flags & SEARCH_CASE_SENSITIVE) ? class_doc.methods[i].name : class_doc.methods[i].name.to_lower(); - if (method_name.find(term) > -1 || - term == " " || - (term.begins_with(".") && method_name.begins_with(term.substr(1))) || - (term.ends_with("(") && method_name.ends_with(term.left(term.length() - 1).strip_edges())) || - (term.begins_with(".") && term.ends_with("(") && method_name == term.substr(1, term.length() - 2).strip_edges())) { - match.methods.push_back(const_cast<DocData::MethodDoc *>(&class_doc.methods[i])); - } - } - } - if (search_flags & SEARCH_OPERATORS) { - for (int i = 0; i < class_doc.operators.size(); i++) { - String method_name = (search_flags & SEARCH_CASE_SENSITIVE) ? class_doc.operators[i].name : class_doc.operators[i].name.to_lower(); - if (method_name.find(term) > -1 || - term == " " || - (term.begins_with(".") && method_name.begins_with(term.substr(1))) || - (term.ends_with("(") && method_name.ends_with(term.left(term.length() - 1).strip_edges())) || - (term.begins_with(".") && term.ends_with("(") && method_name == term.substr(1, term.length() - 2).strip_edges())) { - match.operators.push_back(const_cast<DocData::MethodDoc *>(&class_doc.operators[i])); - } - } - } - if (search_flags & SEARCH_SIGNALS) { - for (int i = 0; i < class_doc.signals.size(); i++) { - if (_match_string(term, class_doc.signals[i].name) || - term == " ") { - match.signals.push_back(const_cast<DocData::MethodDoc *>(&class_doc.signals[i])); - } - } - } - if (search_flags & SEARCH_CONSTANTS) { - for (int i = 0; i < class_doc.constants.size(); i++) { - if (_match_string(term, class_doc.constants[i].name) || - term == " ") { - match.constants.push_back(const_cast<DocData::ConstantDoc *>(&class_doc.constants[i])); - } - } - } - if (search_flags & SEARCH_PROPERTIES) { - for (int i = 0; i < class_doc.properties.size(); i++) { - if (_match_string(term, class_doc.properties[i].name) || - term == " " || - _match_string(term, class_doc.properties[i].getter) || - _match_string(term, class_doc.properties[i].setter)) { - match.properties.push_back(const_cast<DocData::PropertyDoc *>(&class_doc.properties[i])); - } - } - } - if (search_flags & SEARCH_THEME_ITEMS) { - for (int i = 0; i < class_doc.theme_properties.size(); i++) { - if (_match_string(term, class_doc.theme_properties[i].name) || - term == " ") { - match.theme_properties.push_back(const_cast<DocData::ThemeItemDoc *>(&class_doc.theme_properties[i])); - } - } - } - } - } - - ++iterator_doc; - return !iterator_doc; -} - -bool VisualScriptPropertySelector::SearchRunner::_phase_class_items_init() { - results_tree->clear(); - iterator_match = matches.begin(); - - root_item = results_tree->create_item(); - class_items.clear(); - - return true; -} - -bool VisualScriptPropertySelector::SearchRunner::_phase_class_items() { - if (!iterator_match) { - return true; - } - - ClassMatch &match = iterator_match->value; - - if (search_flags & SEARCH_SHOW_HIERARCHY) { - if (match.required()) { - _create_class_hierarchy(match); - } - } else { - if (match.name) { - _create_class_item(root_item, match.doc, true); - } - } - - ++iterator_match; - return !iterator_match; -} - -bool VisualScriptPropertySelector::SearchRunner::_phase_member_items_init() { - iterator_match = matches.begin(); - - return true; -} - -bool VisualScriptPropertySelector::SearchRunner::_phase_member_items() { - if (!iterator_match) { - return true; - } - - ClassMatch &match = iterator_match->value; - - TreeItem *parent = (search_flags & SEARCH_SHOW_HIERARCHY) ? class_items[match.doc->name] : root_item; - bool constructor_created = false; - for (int i = 0; i < match.methods.size(); i++) { - String text = match.methods[i]->name; - if (!constructor_created) { - if (match.doc->name == match.methods[i]->name) { - text += " " + TTR("(constructors)"); - constructor_created = true; - } - } else { - if (match.doc->name == match.methods[i]->name) { - continue; - } - } - _create_method_item(parent, match.doc, text, match.methods[i]); - } - for (int i = 0; i < match.signals.size(); i++) { - _create_signal_item(parent, match.doc, match.signals[i]); - } - for (int i = 0; i < match.constants.size(); i++) { - _create_constant_item(parent, match.doc, match.constants[i]); - } - for (int i = 0; i < match.properties.size(); i++) { - _create_property_item(parent, match.doc, match.properties[i]); - } - for (int i = 0; i < match.theme_properties.size(); i++) { - _create_theme_property_item(parent, match.doc, match.theme_properties[i]); - } - - ++iterator_match; - return !iterator_match; -} - -bool VisualScriptPropertySelector::SearchRunner::_phase_select_match() { - if (matched_item) { - matched_item->select(0); - } - return true; -} - -bool VisualScriptPropertySelector::SearchRunner::_match_string(const String &p_term, const String &p_string) const { - if (search_flags & SEARCH_CASE_SENSITIVE) { - return p_string.find(p_term) > -1; - } else { - return p_string.findn(p_term) > -1; - } -} - -bool VisualScriptPropertySelector::SearchRunner::_match_visual_script(DocData::ClassDoc &class_doc) { - if (class_doc.category.ends_with("_class")) { - if (class_doc.category.begins_with("VisualScript") && search_flags & SEARCH_CLASSES) { - if (matches.has(class_doc.inherits)) { - return true; - } - } - return false; - } - if (class_doc.category.begins_with("VisualScript") && search_flags & SEARCH_VISUAL_SCRIPT_NODES) { - return true; - } - if (class_doc.name.begins_with("operators") && search_flags & SEARCH_OPERATORS) { - return true; - } - if (class_doc.category.begins_with("VisualScriptNode/deconstruct")) { - if (class_doc.name.find(selector_ui->base_type, 0) > -1) { - return true; - } - } - - return false; -} - -bool VisualScriptPropertySelector::SearchRunner::_match_is_hidden(DocData::ClassDoc &class_doc) { - if (class_doc.category.begins_with("VisualScript")) { - if (class_doc.name.begins_with("flow_control")) { - return false; - } else if (class_doc.name.begins_with("operators")) { - return !(search_flags & SEARCH_OPERATORS); - } else if (class_doc.name.begins_with("functions/built_in/print")) { - return false; - } - return true; - } - return false; -} - -void VisualScriptPropertySelector::SearchRunner::_match_item(TreeItem *p_item, const String &p_text) { - float inverse_length = 1.f / float(p_text.length()); - - // Favor types where search term is a substring close to the start of the type. - float w = 0.5f; - int pos = p_text.findn(term); - float score = (pos > -1) ? 1.0f - w * MIN(1, 3 * pos * inverse_length) : MAX(0.f, .9f - w); - - // Favor shorter items: they resemble the search term more. - w = 0.1f; - score *= (1 - w) + w * (term.length() * inverse_length); - - if (match_highest_score == 0 || score > match_highest_score) { - matched_item = p_item; - match_highest_score = score; - } -} - -void VisualScriptPropertySelector::SearchRunner::_add_class_doc(String class_name, String inherits, String category) { - DocData::ClassDoc class_doc = DocData::ClassDoc(); - class_doc.name = class_name; - class_doc.inherits = inherits; - class_doc.category = "VisualScriptNode/" + category; - class_doc.brief_description = category; - combined_docs.insert(class_doc.name, class_doc); -} - -DocData::MethodDoc VisualScriptPropertySelector::SearchRunner::_get_method_doc(MethodInfo method_info) { - DocData::MethodDoc method_doc = DocData::MethodDoc(); - method_doc.name = method_info.name; - method_doc.return_type = Variant::get_type_name(method_info.return_val.type); - method_doc.description = "No description available"; - for (List<PropertyInfo>::Element *P = method_info.arguments.front(); P; P = P->next()) { - DocData::ArgumentDoc argument_doc = DocData::ArgumentDoc(); - argument_doc.name = P->get().name; - argument_doc.type = Variant::get_type_name(P->get().type); - method_doc.arguments.push_back(argument_doc); - } - return method_doc; -} - -TreeItem *VisualScriptPropertySelector::SearchRunner::_create_class_hierarchy(const ClassMatch &p_match) { - if (class_items.has(p_match.doc->name)) { - return class_items[p_match.doc->name]; - } - - // Ensure parent nodes are created first. - TreeItem *parent = root_item; - if (p_match.doc->inherits != "") { - if (class_items.has(p_match.doc->inherits)) { - parent = class_items[p_match.doc->inherits]; - } else if (matches.has(p_match.doc->inherits)) { - ClassMatch &base_match = matches[p_match.doc->inherits]; - parent = _create_class_hierarchy(base_match); - } - } - - TreeItem *class_item = _create_class_item(parent, p_match.doc, !p_match.name); - class_items[p_match.doc->name] = class_item; - return class_item; -} - -TreeItem *VisualScriptPropertySelector::SearchRunner::_create_class_item(TreeItem *p_parent, const DocData::ClassDoc *p_doc, bool p_gray) { - Ref<Texture2D> icon = empty_icon; - String text_0 = p_doc->name; - String text_1 = "Class"; - - String what = "Class"; - String details = p_doc->name; - if (p_doc->category.begins_with("VisualScriptCustomNode/")) { - Vector<String> path = p_doc->name.split("/"); - icon = ui_service->get_theme_icon(SNAME("VisualScript"), SNAME("EditorIcons")); - text_0 = path[path.size() - 1]; - text_1 = "VisualScriptCustomNode"; - what = "VisualScriptCustomNode"; - details = "CustomNode"; - } else if (p_doc->category.begins_with("VisualScriptNode/")) { - Vector<String> path = p_doc->name.split("/"); - icon = ui_service->get_theme_icon(SNAME("VisualScript"), SNAME("EditorIcons")); - text_0 = path[path.size() - 1]; - if (p_doc->category.begins_with("VisualScriptNode/deconstruct")) { - text_0 = "deconstruct " + text_0; - } - text_1 = "VisualScriptNode"; - what = "VisualScriptNode"; - details = p_doc->name; - - if (path.size() == 1) { - if (path[0] == "functions" || path[0] == "operators") { - text_1 = "VisualScript"; - p_gray = true; - what = "no_result"; - details = ""; - } - } - - } else { - if (p_doc->name.is_quoted()) { - text_0 = p_doc->name.unquote().get_file(); - if (ui_service->has_theme_icon(p_doc->inherits, "EditorIcons")) { - icon = ui_service->get_theme_icon(p_doc->inherits, "EditorIcons"); - } - } else if (ui_service->has_theme_icon(p_doc->name, "EditorIcons")) { - icon = ui_service->get_theme_icon(p_doc->name, "EditorIcons"); - } else if (ClassDB::class_exists(p_doc->name) && ClassDB::is_parent_class(p_doc->name, "Object")) { - icon = ui_service->get_theme_icon(SNAME("Object"), SNAME("EditorIcons")); - } - } - String tooltip = p_doc->brief_description.strip_edges(); - - TreeItem *item = results_tree->create_item(p_parent); - item->set_icon(0, icon); - item->set_text(0, text_0); - item->set_text(1, TTR(text_1)); - item->set_tooltip(0, tooltip); - item->set_tooltip(1, tooltip); - item->set_metadata(0, details); - item->set_metadata(1, what); - if (p_gray) { - item->set_custom_color(0, disabled_color); - item->set_custom_color(1, disabled_color); - } - - _match_item(item, p_doc->name); - - return item; -} - -TreeItem *VisualScriptPropertySelector::SearchRunner::_create_method_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const String &p_text, const DocData::MethodDoc *p_doc) { - String tooltip = p_doc->return_type + " " + p_class_doc->name + "." + p_doc->name + "("; - for (int i = 0; i < p_doc->arguments.size(); i++) { - const DocData::ArgumentDoc &arg = p_doc->arguments[i]; - tooltip += arg.type + " " + arg.name; - if (arg.default_value != "") { - tooltip += " = " + arg.default_value; - } - if (i < p_doc->arguments.size() - 1) { - tooltip += ", "; - } - } - tooltip += ")"; - return _create_member_item(p_parent, p_class_doc->name, "MemberMethod", p_doc->name, p_text, TTRC("Method"), "method", tooltip, p_doc->description); -} - -TreeItem *VisualScriptPropertySelector::SearchRunner::_create_signal_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::MethodDoc *p_doc) { - String tooltip = p_doc->return_type + " " + p_class_doc->name + "." + p_doc->name + "("; - for (int i = 0; i < p_doc->arguments.size(); i++) { - const DocData::ArgumentDoc &arg = p_doc->arguments[i]; - tooltip += arg.type + " " + arg.name; - if (arg.default_value != "") { - tooltip += " = " + arg.default_value; - } - if (i < p_doc->arguments.size() - 1) { - tooltip += ", "; - } - } - tooltip += ")"; - return _create_member_item(p_parent, p_class_doc->name, "MemberSignal", p_doc->name, p_doc->name, TTRC("Signal"), "signal", tooltip, p_doc->description); -} - -TreeItem *VisualScriptPropertySelector::SearchRunner::_create_constant_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::ConstantDoc *p_doc) { - String tooltip = p_class_doc->name + "." + p_doc->name; - return _create_member_item(p_parent, p_class_doc->name, "MemberConstant", p_doc->name, p_doc->name, TTRC("Constant"), "constant", tooltip, p_doc->description); -} - -TreeItem *VisualScriptPropertySelector::SearchRunner::_create_property_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::PropertyDoc *p_doc) { - String tooltip = p_doc->type + " " + p_class_doc->name + "." + p_doc->name; - tooltip += "\n " + p_class_doc->name + "." + p_doc->setter + "(value) setter"; - tooltip += "\n " + p_class_doc->name + "." + p_doc->getter + "() getter"; - return _create_member_item(p_parent, p_class_doc->name, "MemberProperty", p_doc->name, p_doc->name, TTRC("Property"), "property", tooltip, p_doc->description); -} - -TreeItem *VisualScriptPropertySelector::SearchRunner::_create_theme_property_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::ThemeItemDoc *p_doc) { - String tooltip = p_doc->type + " " + p_class_doc->name + "." + p_doc->name; - return _create_member_item(p_parent, p_class_doc->name, "MemberTheme", p_doc->name, p_doc->name, TTRC("Theme Property"), "theme_item", tooltip, p_doc->description); -} - -TreeItem *VisualScriptPropertySelector::SearchRunner::_create_member_item(TreeItem *p_parent, const String &p_class_name, const String &p_icon, const String &p_name, const String &p_text, const String &p_type, const String &p_metatype, const String &p_tooltip, const String &p_description) { - Ref<Texture2D> icon; - String text; - if (search_flags & SEARCH_SHOW_HIERARCHY) { - icon = ui_service->get_theme_icon(p_icon, SNAME("EditorIcons")); - text = p_text; - } else { - icon = ui_service->get_theme_icon(p_icon, SNAME("EditorIcons")); - text = p_class_name + "." + p_text; - } - - TreeItem *item = results_tree->create_item(p_parent); - item->set_icon(0, icon); - item->set_text(0, text); - item->set_text(1, TTRGET(p_type)); - item->set_tooltip(0, p_tooltip); - item->set_tooltip(1, p_tooltip); - item->set_metadata(0, p_class_name + ":" + p_name); - item->set_metadata(1, "class_" + p_metatype); - item->set_meta("description", p_description); - - _match_item(item, p_name); - - return item; -} - -bool VisualScriptPropertySelector::SearchRunner::work(uint64_t slot) { - // Return true when the search has been completed, otherwise false. - const uint64_t until = OS::get_singleton()->get_ticks_usec() + slot; - while (!_slice()) { - if (OS::get_singleton()->get_ticks_usec() > until) { - return false; - } - } - return true; -} - -VisualScriptPropertySelector::SearchRunner::SearchRunner(VisualScriptPropertySelector *p_selector_ui, Tree *p_results_tree) : - selector_ui(p_selector_ui), - ui_service(p_selector_ui->vbox), - results_tree(p_results_tree), - term(p_selector_ui->search_box->get_text()), - empty_icon(ui_service->get_theme_icon(SNAME("ArrowRight"), SNAME("EditorIcons"))), - disabled_color(ui_service->get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"))) { -} diff --git a/modules/visual_script/editor/visual_script_property_selector.h b/modules/visual_script/editor/visual_script_property_selector.h deleted file mode 100644 index 4de626467e..0000000000 --- a/modules/visual_script/editor/visual_script_property_selector.h +++ /dev/null @@ -1,229 +0,0 @@ -/*************************************************************************/ -/* visual_script_property_selector.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef VISUAL_SCRIPT_PROPERTY_SELECTOR_H -#define VISUAL_SCRIPT_PROPERTY_SELECTOR_H - -#include "../visual_script.h" -#include "editor/editor_help.h" -#include "scene/gui/rich_text_label.h" -#include "scene/gui/tree.h" - -class VisualScriptPropertySelector : public ConfirmationDialog { - GDCLASS(VisualScriptPropertySelector, ConfirmationDialog); - - enum SearchFlags { - SEARCH_CLASSES = 1 << 0, - SEARCH_CONSTRUCTORS = 1 << 1, - SEARCH_METHODS = 1 << 2, - SEARCH_OPERATORS = 1 << 3, - SEARCH_SIGNALS = 1 << 4, - SEARCH_CONSTANTS = 1 << 5, - SEARCH_PROPERTIES = 1 << 6, - SEARCH_THEME_ITEMS = 1 << 7, - SEARCH_VISUAL_SCRIPT_NODES = 1 << 8, - SEARCH_ALL = SEARCH_CLASSES | SEARCH_CONSTRUCTORS | SEARCH_METHODS | SEARCH_OPERATORS | SEARCH_SIGNALS | SEARCH_CONSTANTS | SEARCH_PROPERTIES | SEARCH_THEME_ITEMS, - SEARCH_CASE_SENSITIVE = 1 << 29, - SEARCH_SHOW_HIERARCHY = 1 << 30, - }; - - enum ScopeFlags { - SCOPE_BASE = 1 << 0, - SCOPE_INHERITERS = 1 << 1, - SCOPE_UNRELATED = 1 << 2, - SCOPE_RELATED = SCOPE_BASE | SCOPE_INHERITERS, - SCOPE_ALL = SCOPE_BASE | SCOPE_INHERITERS | SCOPE_UNRELATED - }; - - enum ScopeCombo { - COMBO_RELATED, - COMBO_SEPARATOR, - COMBO_BASE, - COMBO_INHERITERS, - COMBO_UNRELATED, - COMBO_ALL, - }; - - LineEdit *search_box = nullptr; - - Button *case_sensitive_button = nullptr; - Button *hierarchy_button = nullptr; - - Button *search_visual_script_nodes = nullptr; - Button *search_classes = nullptr; - Button *search_operators = nullptr; - - Button *search_methods = nullptr; - Button *search_signals = nullptr; - Button *search_constants = nullptr; - Button *search_properties = nullptr; - Button *search_theme_items = nullptr; - - OptionButton *scope_combo = nullptr; - Tree *results_tree = nullptr; - - class SearchRunner; - Ref<SearchRunner> search_runner; - - void _update_icons(); - - void _sbox_input(const Ref<InputEvent> &p_ie); - void _update_results_i(int p_int); - void _update_results_s(String p_string); - void _update_results_search_all(); - void _update_results(); - - void _confirmed(); - void _item_selected(); - void _hide_requested(); - - EditorHelpBit *help_bit = nullptr; - - bool properties = false; - bool visual_script_generic = false; - bool connecting = false; - String selected; - Variant::Type type; - String base_type; - String base_script; - ObjectID script; - Object *instance = nullptr; - bool virtuals_only = false; - VBoxContainer *vbox = nullptr; - -protected: - void _notification(int p_what); - static void _bind_methods(); - -public: - void select_method_from_base_type(const String &p_base, const bool p_virtuals_only = false, const bool p_connecting = true, bool clear_text = true); - void select_from_base_type(const String &p_base, const String &p_base_script = "", bool p_virtuals_only = false, const bool p_connecting = true, bool clear_text = true); - void select_from_script(const Ref<Script> &p_script, const bool p_connecting = true, bool clear_text = true); - void select_from_basic_type(Variant::Type p_type, const bool p_connecting = true, bool clear_text = true); - void select_from_action(const String &p_type, const bool p_connecting = true, bool clear_text = true); - void select_from_instance(Object *p_instance, const bool p_connecting = true, bool clear_text = true); - void select_from_visual_script(const Ref<Script> &p_script, bool clear_text = true); - - void show_window(float p_screen_ratio); - - VisualScriptPropertySelector(); -}; - -class VisualScriptPropertySelector::SearchRunner : public RefCounted { - enum Phase { - PHASE_INIT, - PHASE_MATCH_CLASSES_INIT, - PHASE_NODE_CLASSES_INIT, - PHASE_NODE_CLASSES_BUILD, - PHASE_MATCH_CLASSES, - PHASE_CLASS_ITEMS_INIT, - PHASE_CLASS_ITEMS, - PHASE_MEMBER_ITEMS_INIT, - PHASE_MEMBER_ITEMS, - PHASE_SELECT_MATCH, - PHASE_MAX - }; - int phase = 0; - - struct ClassMatch { - DocData::ClassDoc *doc; - bool name = false; - String category = ""; - Vector<DocData::MethodDoc *> constructors; - Vector<DocData::MethodDoc *> methods; - Vector<DocData::MethodDoc *> operators; - Vector<DocData::MethodDoc *> signals; - Vector<DocData::ConstantDoc *> constants; - Vector<DocData::PropertyDoc *> properties; - Vector<DocData::ThemeItemDoc *> theme_properties; - - bool required() { - return name || methods.size() || signals.size() || constants.size() || properties.size() || theme_properties.size(); - } - }; - - VisualScriptPropertySelector *selector_ui = nullptr; - Control *ui_service = nullptr; - Tree *results_tree = nullptr; - String term; - int search_flags = 0; - int scope_flags = 0; - - Ref<Texture2D> empty_icon; - Color disabled_color; - - HashMap<String, DocData::ClassDoc>::Iterator iterator_doc; - HashMap<String, ClassMatch> matches; - HashMap<String, ClassMatch>::Iterator iterator_match; - TreeItem *root_item = nullptr; - HashMap<String, TreeItem *> class_items; - TreeItem *matched_item = nullptr; - float match_highest_score = 0; - - HashMap<String, DocData::ClassDoc> combined_docs; - List<String> vs_nodes; - - bool _is_class_disabled_by_feature_profile(const StringName &p_class); - bool _is_class_disabled_by_scope(const StringName &p_class); - - bool _slice(); - bool _phase_init(); - bool _phase_match_classes_init(); - bool _phase_node_classes_init(); - bool _phase_node_classes_build(); - bool _phase_match_classes(); - bool _phase_class_items_init(); - bool _phase_class_items(); - bool _phase_member_items_init(); - bool _phase_member_items(); - bool _phase_select_match(); - - bool _match_string(const String &p_term, const String &p_string) const; - bool _match_visual_script(DocData::ClassDoc &class_doc); - bool _match_is_hidden(DocData::ClassDoc &class_doc); - void _match_item(TreeItem *p_item, const String &p_text); - void _add_class_doc(String class_name, String inherits, String category); - DocData::MethodDoc _get_method_doc(MethodInfo method_info); - TreeItem *_create_class_hierarchy(const ClassMatch &p_match); - TreeItem *_create_class_item(TreeItem *p_parent, const DocData::ClassDoc *p_doc, bool p_gray); - TreeItem *_create_method_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const String &p_text, const DocData::MethodDoc *p_doc); - TreeItem *_create_signal_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::MethodDoc *p_doc); - TreeItem *_create_constant_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::ConstantDoc *p_doc); - TreeItem *_create_property_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::PropertyDoc *p_doc); - TreeItem *_create_theme_property_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::ThemeItemDoc *p_doc); - TreeItem *_create_member_item(TreeItem *p_parent, const String &p_class_name, const String &p_icon, const String &p_name, const String &p_text, const String &p_type, const String &p_metatype, const String &p_tooltip, const String &p_description); - -public: - bool work(uint64_t slot = 100000); - - SearchRunner(VisualScriptPropertySelector *p_selector_ui, Tree *p_results_tree); -}; - -#endif // VISUAL_SCRIPT_PROPERTY_SELECTOR_H diff --git a/modules/visual_script/icons/VisualScript.svg b/modules/visual_script/icons/VisualScript.svg deleted file mode 100644 index bc698247c9..0000000000 --- a/modules/visual_script/icons/VisualScript.svg +++ /dev/null @@ -1 +0,0 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><ellipse cx="3" cy="1039.4" fill="#e0e0e0"/><path d="m7 1-.56445 2.2578a5 5 0 0 0 -.68945.2793l-1.9883-1.1934-1.4141 1.4141 1.1953 1.9941a5 5 0 0 0 -.28516.68555l-2.2539.5625v2h5.2715a2 2 0 0 1 -.27148-1 2 2 0 0 1 2-2 2 2 0 0 1 2 2 2 2 0 0 1 -.26953 1h5.2695v-2l-2.2578-.56445a5 5 0 0 0 -.2793-.6875l1.1934-1.9902-1.4141-1.4141-1.9941 1.1953a5 5 0 0 0 -.68555-.28516l-.5625-2.2539h-2zm-4 9v6h2a3 3 0 0 0 3-3v-3h-2v3a1 1 0 0 1 -1 1v-4zm8 0a2 2 0 0 0 -1.7324 1 2 2 0 0 0 0 2 2 2 0 0 0 1.7324 1h-2v2h2a2 2 0 0 0 1.7324-1 2 2 0 0 0 0-2 2 2 0 0 0 -1.7324-1h2v-2z" fill="#e0e0e0" transform="translate(0 1036.4)"/></g></svg> diff --git a/modules/visual_script/icons/VisualScriptInternal.svg b/modules/visual_script/icons/VisualScriptInternal.svg deleted file mode 100644 index 8ab39ad929..0000000000 --- a/modules/visual_script/icons/VisualScriptInternal.svg +++ /dev/null @@ -1 +0,0 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><circle cx="3" cy="3.000024" fill="#e0e0e0" r="0"/><path d="m11 10a2 2 0 0 0 -1.7324 1 2 2 0 0 0 0 2 2 2 0 0 0 1.7324 1h-2v2h2a2 2 0 0 0 1.7324-1 2 2 0 0 0 0-2 2 2 0 0 0 -1.7324-1h2v-2z" fill="#e0e0e0"/><path d="m3 10v6h2a3 3 0 0 0 3-3v-3h-2v3a1 1 0 0 1 -1 1v-4z" fill="#e0e0e0"/><path d="m7 1-.56445 2.2578a5 5 0 0 0 -.68945.2793l-1.9883-1.1934-1.4141 1.4141 1.1953 1.9941a5 5 0 0 0 -.28516.68555l-2.2539.5625v2h5.2715a2 2 0 0 1 -.27148-1 2 2 0 0 1 2-2 2 2 0 0 1 2 2 2 2 0 0 1 -.26953 1h5.2695v-2l-2.2578-.56445a5 5 0 0 0 -.2793-.6875l1.1934-1.9902-1.4141-1.4141-1.9941 1.1953a5 5 0 0 0 -.68555-.28516l-.5625-2.2539h-2z" fill="none" stroke="#e0e0e0"/></svg> diff --git a/modules/visual_script/register_types.cpp b/modules/visual_script/register_types.cpp deleted file mode 100644 index 04a7442d0a..0000000000 --- a/modules/visual_script/register_types.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/*************************************************************************/ -/* register_types.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "register_types.h" - -#include "core/config/engine.h" -#include "core/io/resource_loader.h" -#include "visual_script.h" -#include "visual_script_builtin_funcs.h" -#include "visual_script_expression.h" -#include "visual_script_flow_control.h" -#include "visual_script_func_nodes.h" -#include "visual_script_nodes.h" -#include "visual_script_yield_nodes.h" - -VisualScriptLanguage *visual_script_language = nullptr; - -#ifdef TOOLS_ENABLED -#include "editor/visual_script_editor.h" -static VisualScriptCustomNodes *vs_custom_nodes_singleton = nullptr; -#endif - -void initialize_visual_script_module(ModuleInitializationLevel p_level) { - if (p_level == MODULE_INITIALIZATION_LEVEL_SERVERS) { - visual_script_language = memnew(VisualScriptLanguage); - //script_language_gd->init(); - ScriptServer::register_language(visual_script_language); - - GDREGISTER_CLASS(VisualScript); - GDREGISTER_ABSTRACT_CLASS(VisualScriptNode); - GDREGISTER_CLASS(VisualScriptFunctionState); - GDREGISTER_CLASS(VisualScriptFunction); - GDREGISTER_ABSTRACT_CLASS(VisualScriptLists); - GDREGISTER_CLASS(VisualScriptComposeArray); - GDREGISTER_CLASS(VisualScriptOperator); - GDREGISTER_CLASS(VisualScriptVariableSet); - GDREGISTER_CLASS(VisualScriptVariableGet); - GDREGISTER_CLASS(VisualScriptConstant); - GDREGISTER_CLASS(VisualScriptIndexGet); - GDREGISTER_CLASS(VisualScriptIndexSet); - GDREGISTER_CLASS(VisualScriptGlobalConstant); - GDREGISTER_CLASS(VisualScriptClassConstant); - GDREGISTER_CLASS(VisualScriptMathConstant); - GDREGISTER_CLASS(VisualScriptBasicTypeConstant); - GDREGISTER_CLASS(VisualScriptEngineSingleton); - GDREGISTER_CLASS(VisualScriptSceneNode); - GDREGISTER_CLASS(VisualScriptSceneTree); - GDREGISTER_CLASS(VisualScriptResourcePath); - GDREGISTER_CLASS(VisualScriptSelf); - GDREGISTER_CLASS(VisualScriptCustomNode); - GDREGISTER_CLASS(VisualScriptSubCall); - GDREGISTER_CLASS(VisualScriptComment); - GDREGISTER_CLASS(VisualScriptConstructor); - GDREGISTER_CLASS(VisualScriptLocalVar); - GDREGISTER_CLASS(VisualScriptLocalVarSet); - GDREGISTER_CLASS(VisualScriptInputAction); - GDREGISTER_CLASS(VisualScriptDeconstruct); - GDREGISTER_CLASS(VisualScriptPreload); - GDREGISTER_CLASS(VisualScriptTypeCast); - - GDREGISTER_CLASS(VisualScriptFunctionCall); - GDREGISTER_CLASS(VisualScriptPropertySet); - GDREGISTER_CLASS(VisualScriptPropertyGet); - //ClassDB::register_type<VisualScriptScriptCall>(); - GDREGISTER_CLASS(VisualScriptEmitSignal); - - GDREGISTER_CLASS(VisualScriptReturn); - GDREGISTER_CLASS(VisualScriptCondition); - GDREGISTER_CLASS(VisualScriptWhile); - GDREGISTER_CLASS(VisualScriptIterator); - GDREGISTER_CLASS(VisualScriptSequence); - //GDREGISTER_CLASS(VisualScriptInputFilter); - GDREGISTER_CLASS(VisualScriptSwitch); - GDREGISTER_CLASS(VisualScriptSelect); - - GDREGISTER_CLASS(VisualScriptYield); - GDREGISTER_CLASS(VisualScriptYieldSignal); - - GDREGISTER_CLASS(VisualScriptBuiltinFunc); - - GDREGISTER_CLASS(VisualScriptExpression); - - register_visual_script_nodes(); - register_visual_script_func_nodes(); - register_visual_script_builtin_func_node(); - register_visual_script_flow_control_nodes(); - register_visual_script_yield_nodes(); - register_visual_script_expression_node(); - } - -#ifdef TOOLS_ENABLED - if (p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) { - ClassDB::set_current_api(ClassDB::API_EDITOR); - GDREGISTER_CLASS(VisualScriptCustomNodes); - ClassDB::set_current_api(ClassDB::API_CORE); - vs_custom_nodes_singleton = memnew(VisualScriptCustomNodes); - Engine::get_singleton()->add_singleton(Engine::Singleton("VisualScriptCustomNodes", VisualScriptCustomNodes::get_singleton())); - - VisualScriptEditor::register_editor(); - } -#endif -} - -void uninitialize_visual_script_module(ModuleInitializationLevel p_level) { - if (p_level == MODULE_INITIALIZATION_LEVEL_SERVERS) { - unregister_visual_script_nodes(); - - ScriptServer::unregister_language(visual_script_language); - - if (visual_script_language) { - memdelete(visual_script_language); - } - } - -#ifdef TOOLS_ENABLED - if (p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) { - VisualScriptEditor::free_clipboard(); - if (vs_custom_nodes_singleton) { - memdelete(vs_custom_nodes_singleton); - } - } -#endif -} diff --git a/modules/visual_script/register_types.h b/modules/visual_script/register_types.h deleted file mode 100644 index 90f84de11c..0000000000 --- a/modules/visual_script/register_types.h +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************/ -/* register_types.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef VISUAL_SCRIPT_REGISTER_TYPES_H -#define VISUAL_SCRIPT_REGISTER_TYPES_H - -#include "modules/register_module_types.h" - -void initialize_visual_script_module(ModuleInitializationLevel p_level); -void uninitialize_visual_script_module(ModuleInitializationLevel p_level); - -#endif // VISUAL_SCRIPT_REGISTER_TYPES_H diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp deleted file mode 100644 index 73249371cd..0000000000 --- a/modules/visual_script/visual_script.cpp +++ /dev/null @@ -1,2506 +0,0 @@ -/*************************************************************************/ -/* visual_script.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "visual_script.h" - -#include "core/config/project_settings.h" -#include "core/core_string_names.h" -#include "core/os/os.h" -#include "scene/main/node.h" -#include "visual_script_nodes.h" - -// Used by editor, this is not really saved. -void VisualScriptNode::set_breakpoint(bool p_breakpoint) { - breakpoint = p_breakpoint; -} - -bool VisualScriptNode::is_breakpoint() const { - return breakpoint; -} - -void VisualScriptNode::ports_changed_notify() { - emit_signal(SNAME("ports_changed")); -} - -void VisualScriptNode::set_default_input_value(int p_port, const Variant &p_value) { - ERR_FAIL_INDEX(p_port, default_input_values.size()); - - default_input_values[p_port] = p_value; - -#ifdef TOOLS_ENABLED - if (script_used.is_valid()) { - script_used->set_edited(true); - } -#endif -} - -Variant VisualScriptNode::get_default_input_value(int p_port) const { - ERR_FAIL_INDEX_V(p_port, default_input_values.size(), Variant()); - return default_input_values[p_port]; -} - -void VisualScriptNode::_set_default_input_values(Array p_values) { - default_input_values = p_values; -} - -void VisualScriptNode::validate_input_default_values() { - default_input_values.resize(MAX(default_input_values.size(), get_input_value_port_count())); //let it grow as big as possible, we don't want to lose values on resize - - // Actually validate on save. - for (int i = 0; i < get_input_value_port_count(); i++) { - Variant::Type expected = get_input_value_port_info(i).type; - - if (expected == Variant::NIL || expected == default_input_values[i].get_type()) { - continue; - } else { - // Not the same, reconvert. - Callable::CallError ce; - Variant existing = default_input_values[i]; - const Variant *existingp = &existing; - Variant::construct(expected, default_input_values[i], &existingp, 1, ce); - if (ce.error != Callable::CallError::CALL_OK) { - //could not convert? force.. - Variant::construct(expected, default_input_values[i], nullptr, 0, ce); - } - } - } -} - -Array VisualScriptNode::_get_default_input_values() const { - // Validate on save, since on load there is little info about this. - Array values = default_input_values; - values.resize(get_input_value_port_count()); - - return values; -} - -String VisualScriptNode::get_text() const { - return ""; -} - -void VisualScriptNode::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_visual_script"), &VisualScriptNode::get_visual_script); - ClassDB::bind_method(D_METHOD("set_default_input_value", "port_idx", "value"), &VisualScriptNode::set_default_input_value); - ClassDB::bind_method(D_METHOD("get_default_input_value", "port_idx"), &VisualScriptNode::get_default_input_value); - ClassDB::bind_method(D_METHOD("ports_changed_notify"), &VisualScriptNode::ports_changed_notify); - ClassDB::bind_method(D_METHOD("_set_default_input_values", "values"), &VisualScriptNode::_set_default_input_values); - ClassDB::bind_method(D_METHOD("_get_default_input_values"), &VisualScriptNode::_get_default_input_values); - - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_default_input_values", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_default_input_values", "_get_default_input_values"); - ADD_SIGNAL(MethodInfo("ports_changed")); -} - -VisualScriptNode::TypeGuess VisualScriptNode::guess_output_type(TypeGuess *p_inputs, int p_output) const { - ERR_FAIL_COND_V(get_output_value_port_count() <= p_output, TypeGuess()); - - PropertyInfo pinfo = get_output_value_port_info(p_output); - - TypeGuess tg; - - tg.type = pinfo.type; - if (pinfo.hint == PROPERTY_HINT_RESOURCE_TYPE) { - tg.gdclass = pinfo.hint_string; - } - - return tg; -} - -Ref<VisualScript> VisualScriptNode::get_visual_script() const { - return script_used; -} - -VisualScriptNode::VisualScriptNode() { -} - -//////////////// - -///////////////////// - -VisualScriptNodeInstance::VisualScriptNodeInstance() { -} - -VisualScriptNodeInstance::~VisualScriptNodeInstance() { - if (sequence_outputs) { - memdelete_arr(sequence_outputs); - } - - if (input_ports) { - memdelete_arr(input_ports); - } - - if (output_ports) { - memdelete_arr(output_ports); - } -} - -void VisualScript::add_function(const StringName &p_name, int p_func_node_id) { - ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!String(p_name).is_valid_identifier()); - ERR_FAIL_COND(functions.has(p_name)); - ERR_FAIL_COND(variables.has(p_name)); - ERR_FAIL_COND(custom_signals.has(p_name)); - - functions[p_name] = Function(); - functions[p_name].func_id = p_func_node_id; -} - -bool VisualScript::has_function(const StringName &p_name) const { - return functions.has(p_name); -} - -void VisualScript::remove_function(const StringName &p_name) { - ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!functions.has(p_name)); - - // Let the editor handle the node removal. - functions.erase(p_name); -} - -void VisualScript::rename_function(const StringName &p_name, const StringName &p_new_name) { - ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!functions.has(p_name)); - if (p_new_name == p_name) { - return; - } - - ERR_FAIL_COND(!String(p_new_name).is_valid_identifier()); - - ERR_FAIL_COND(functions.has(p_new_name)); - ERR_FAIL_COND(variables.has(p_new_name)); - ERR_FAIL_COND(custom_signals.has(p_new_name)); - - functions[p_new_name] = functions[p_name]; - functions.erase(p_name); -} - -void VisualScript::set_scroll(const Vector2 &p_scroll) { - scroll = p_scroll; -} - -Vector2 VisualScript::get_scroll() const { - return scroll; -} - -void VisualScript::get_function_list(List<StringName> *r_functions) const { - for (const KeyValue<StringName, Function> &E : functions) { - r_functions->push_back(E.key); - } -} - -int VisualScript::get_function_node_id(const StringName &p_name) const { - ERR_FAIL_COND_V(!functions.has(p_name), -1); - - return functions[p_name].func_id; -} - -void VisualScript::_node_ports_changed(int p_id) { - Ref<VisualScriptNode> vsn = nodes[p_id].node; - - vsn->validate_input_default_values(); - - // Must revalidate all the functions. - - { - List<SequenceConnection> to_remove; - - for (const SequenceConnection &E : sequence_connections) { - if (E.from_node == p_id && E.from_output >= vsn->get_output_sequence_port_count()) { - to_remove.push_back(E); - } - if (E.to_node == p_id && !vsn->has_input_sequence_port()) { - to_remove.push_back(E); - } - } - - while (to_remove.size()) { - sequence_connections.erase(to_remove.front()->get()); - to_remove.pop_front(); - } - } - - { - List<DataConnection> to_remove; - - for (const DataConnection &E : data_connections) { - if (E.from_node == p_id && E.from_port >= vsn->get_output_value_port_count()) { - to_remove.push_back(E); - } - if (E.to_node == p_id && E.to_port >= vsn->get_input_value_port_count()) { - to_remove.push_back(E); - } - } - - while (to_remove.size()) { - data_connections.erase(to_remove.front()->get()); - to_remove.pop_front(); - } - } - -#ifdef TOOLS_ENABLED - set_edited(true); // Something changed, let's set as edited. - emit_signal(SNAME("node_ports_changed"), p_id); -#endif -} - -void VisualScript::add_node(int p_id, const Ref<VisualScriptNode> &p_node, const Point2 &p_pos) { - ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(nodes.has(p_id)); // ID can exist only one in script. - ERR_FAIL_COND(p_node.is_null()); - - NodeData nd; - nd.node = p_node; - nd.pos = p_pos; - - Ref<VisualScriptNode> vsn = p_node; - vsn->connect("ports_changed", callable_mp(this, &VisualScript::_node_ports_changed).bind(p_id)); - vsn->script_used = Ref<VisualScript>(this); - vsn->validate_input_default_values(); // Validate when fully loaded. - - nodes[p_id] = nd; -} - -void VisualScript::remove_node(int p_id) { - ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!nodes.has(p_id)); - { - List<SequenceConnection> to_remove; - - for (const SequenceConnection &E : sequence_connections) { - if (E.from_node == p_id || E.to_node == p_id) { - to_remove.push_back(E); - } - } - - while (to_remove.size()) { - sequence_connections.erase(to_remove.front()->get()); - to_remove.pop_front(); - } - } - - { - List<DataConnection> to_remove; - - for (const DataConnection &E : data_connections) { - if (E.from_node == p_id || E.to_node == p_id) { - to_remove.push_back(E); - } - } - - while (to_remove.size()) { - data_connections.erase(to_remove.front()->get()); - to_remove.pop_front(); - } - } - - nodes[p_id].node->disconnect("ports_changed", callable_mp(this, &VisualScript::_node_ports_changed)); - nodes[p_id].node->script_used.unref(); - - nodes.erase(p_id); -} - -bool VisualScript::has_node(int p_id) const { - return nodes.has(p_id); -} - -Ref<VisualScriptNode> VisualScript::get_node(int p_id) const { - ERR_FAIL_COND_V(!nodes.has(p_id), Ref<VisualScriptNode>()); - - return nodes[p_id].node; -} - -void VisualScript::set_node_position(int p_id, const Point2 &p_pos) { - ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!nodes.has(p_id)); - nodes[p_id].pos = p_pos; -} - -Point2 VisualScript::get_node_position(int p_id) const { - ERR_FAIL_COND_V(!nodes.has(p_id), Point2()); - return nodes[p_id].pos; -} - -void VisualScript::get_node_list(List<int> *r_nodes) const { - for (const KeyValue<int, NodeData> &E : nodes) { - r_nodes->push_back(E.key); - } -} - -void VisualScript::sequence_connect(int p_from_node, int p_from_output, int p_to_node) { - ERR_FAIL_COND(instances.size()); - - SequenceConnection sc; - sc.from_node = p_from_node; - sc.from_output = p_from_output; - sc.to_node = p_to_node; - ERR_FAIL_COND(sequence_connections.has(sc)); - - sequence_connections.insert(sc); -} - -void VisualScript::sequence_disconnect(int p_from_node, int p_from_output, int p_to_node) { - SequenceConnection sc; - sc.from_node = p_from_node; - sc.from_output = p_from_output; - sc.to_node = p_to_node; - ERR_FAIL_COND(!sequence_connections.has(sc)); - - sequence_connections.erase(sc); -} - -bool VisualScript::has_sequence_connection(int p_from_node, int p_from_output, int p_to_node) const { - SequenceConnection sc; - sc.from_node = p_from_node; - sc.from_output = p_from_output; - sc.to_node = p_to_node; - - return sequence_connections.has(sc); -} - -void VisualScript::get_sequence_connection_list(List<SequenceConnection> *r_connection) const { - for (const SequenceConnection &E : sequence_connections) { - r_connection->push_back(E); - } -} - -void VisualScript::data_connect(int p_from_node, int p_from_port, int p_to_node, int p_to_port) { - ERR_FAIL_COND(instances.size()); - - DataConnection dc; - dc.from_node = p_from_node; - dc.from_port = p_from_port; - dc.to_node = p_to_node; - dc.to_port = p_to_port; - - ERR_FAIL_COND(data_connections.has(dc)); - - data_connections.insert(dc); -} - -void VisualScript::data_disconnect(int p_from_node, int p_from_port, int p_to_node, int p_to_port) { - DataConnection dc; - dc.from_node = p_from_node; - dc.from_port = p_from_port; - dc.to_node = p_to_node; - dc.to_port = p_to_port; - - ERR_FAIL_COND(!data_connections.has(dc)); - - data_connections.erase(dc); -} - -bool VisualScript::has_data_connection(int p_from_node, int p_from_port, int p_to_node, int p_to_port) const { - DataConnection dc; - dc.from_node = p_from_node; - dc.from_port = p_from_port; - dc.to_node = p_to_node; - dc.to_port = p_to_port; - - return data_connections.has(dc); -} - -bool VisualScript::is_input_value_port_connected(int p_node, int p_port) const { - for (const DataConnection &E : data_connections) { - if (E.to_node == p_node && E.to_port == p_port) { - return true; - } - } - return false; -} - -bool VisualScript::get_input_value_port_connection_source(int p_node, int p_port, int *r_node, int *r_port) const { - for (const DataConnection &E : data_connections) { - if (E.to_node == p_node && E.to_port == p_port) { - *r_node = E.from_node; - *r_port = E.from_port; - return true; - } - } - return false; -} - -void VisualScript::get_data_connection_list(List<DataConnection> *r_connection) const { - for (const DataConnection &E : data_connections) { - r_connection->push_back(E); - } -} - -void VisualScript::set_tool_enabled(bool p_enabled) { - is_tool_script = p_enabled; -} - -void VisualScript::add_variable(const StringName &p_name, const Variant &p_default_value, bool p_export) { - ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!String(p_name).is_valid_identifier()); - ERR_FAIL_COND(variables.has(p_name)); - - Variable v; - v.default_value = p_default_value; - v.info.type = p_default_value.get_type(); - v.info.name = p_name; - v.info.hint = PROPERTY_HINT_NONE; - v._export = p_export; - - variables[p_name] = v; - -#ifdef TOOLS_ENABLED - _update_placeholders(); -#endif -} - -bool VisualScript::has_variable(const StringName &p_name) const { - return variables.has(p_name); -} - -void VisualScript::remove_variable(const StringName &p_name) { - ERR_FAIL_COND(!variables.has(p_name)); - variables.erase(p_name); - -#ifdef TOOLS_ENABLED - _update_placeholders(); -#endif -} - -void VisualScript::set_variable_default_value(const StringName &p_name, const Variant &p_value) { - ERR_FAIL_COND(!variables.has(p_name)); - - variables[p_name].default_value = p_value; - -#ifdef TOOLS_ENABLED - _update_placeholders(); -#endif -} - -Variant VisualScript::get_variable_default_value(const StringName &p_name) const { - ERR_FAIL_COND_V(!variables.has(p_name), Variant()); - return variables[p_name].default_value; -} - -void VisualScript::set_variable_info(const StringName &p_name, const PropertyInfo &p_info) { - ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!variables.has(p_name)); - variables[p_name].info = p_info; - variables[p_name].info.name = p_name; - -#ifdef TOOLS_ENABLED - _update_placeholders(); -#endif -} - -PropertyInfo VisualScript::get_variable_info(const StringName &p_name) const { - ERR_FAIL_COND_V(!variables.has(p_name), PropertyInfo()); - return variables[p_name].info; -} - -void VisualScript::set_variable_export(const StringName &p_name, bool p_export) { - ERR_FAIL_COND(!variables.has(p_name)); - - variables[p_name]._export = p_export; -#ifdef TOOLS_ENABLED - _update_placeholders(); -#endif -} - -bool VisualScript::get_variable_export(const StringName &p_name) const { - ERR_FAIL_COND_V(!variables.has(p_name), false); - return variables[p_name]._export; -} - -void VisualScript::_set_variable_info(const StringName &p_name, const Dictionary &p_info) { - PropertyInfo pinfo; - if (p_info.has("type")) { - pinfo.type = Variant::Type(int(p_info["type"])); - } - if (p_info.has("name")) { - pinfo.name = p_info["name"]; - } - if (p_info.has("hint")) { - pinfo.hint = PropertyHint(int(p_info["hint"])); - } - if (p_info.has("hint_string")) { - pinfo.hint_string = p_info["hint_string"]; - } - if (p_info.has("usage")) { - pinfo.usage = p_info["usage"]; - } - - set_variable_info(p_name, pinfo); -} - -Dictionary VisualScript::_get_variable_info(const StringName &p_name) const { - PropertyInfo pinfo = get_variable_info(p_name); - Dictionary d; - d["type"] = pinfo.type; - d["name"] = pinfo.name; - d["hint"] = pinfo.hint; - d["hint_string"] = pinfo.hint_string; - d["usage"] = pinfo.usage; - - return d; -} - -void VisualScript::get_variable_list(List<StringName> *r_variables) const { - for (const KeyValue<StringName, Variable> &E : variables) { - r_variables->push_back(E.key); - } -} - -void VisualScript::set_instance_base_type(const StringName &p_type) { - ERR_FAIL_COND(instances.size()); - base_type = p_type; -} - -void VisualScript::rename_variable(const StringName &p_name, const StringName &p_new_name) { - ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!variables.has(p_name)); - if (p_new_name == p_name) { - return; - } - - ERR_FAIL_COND(!String(p_new_name).is_valid_identifier()); - - ERR_FAIL_COND(functions.has(p_new_name)); - ERR_FAIL_COND(variables.has(p_new_name)); - ERR_FAIL_COND(custom_signals.has(p_new_name)); - - variables[p_new_name] = variables[p_name]; - variables.erase(p_name); - List<int> ids; - get_node_list(&ids); - for (int &E : ids) { - Ref<VisualScriptVariableGet> nodeget = get_node(E); - if (nodeget.is_valid()) { - if (nodeget->get_variable() == p_name) { - nodeget->set_variable(p_new_name); - } - } else { - Ref<VisualScriptVariableSet> nodeset = get_node(E); - if (nodeset.is_valid()) { - if (nodeset->get_variable() == p_name) { - nodeset->set_variable(p_new_name); - } - } - } - } -} - -void VisualScript::add_custom_signal(const StringName &p_name) { - ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!String(p_name).is_valid_identifier()); - ERR_FAIL_COND(custom_signals.has(p_name)); - - custom_signals[p_name] = Vector<Argument>(); -} - -bool VisualScript::has_custom_signal(const StringName &p_name) const { - return custom_signals.has(p_name); -} - -void VisualScript::custom_signal_add_argument(const StringName &p_func, Variant::Type p_type, const String &p_name, int p_index) { - ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!custom_signals.has(p_func)); - Argument arg; - arg.type = p_type; - arg.name = p_name; - if (p_index < 0) { - custom_signals[p_func].push_back(arg); - } else { - custom_signals[p_func].insert(0, arg); - } -} - -void VisualScript::custom_signal_set_argument_type(const StringName &p_func, int p_argidx, Variant::Type p_type) { - ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!custom_signals.has(p_func)); - ERR_FAIL_INDEX(p_argidx, custom_signals[p_func].size()); - custom_signals[p_func].write[p_argidx].type = p_type; -} - -Variant::Type VisualScript::custom_signal_get_argument_type(const StringName &p_func, int p_argidx) const { - ERR_FAIL_COND_V(!custom_signals.has(p_func), Variant::NIL); - ERR_FAIL_INDEX_V(p_argidx, custom_signals[p_func].size(), Variant::NIL); - return custom_signals[p_func][p_argidx].type; -} - -void VisualScript::custom_signal_set_argument_name(const StringName &p_func, int p_argidx, const String &p_name) { - ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!custom_signals.has(p_func)); - ERR_FAIL_INDEX(p_argidx, custom_signals[p_func].size()); - custom_signals[p_func].write[p_argidx].name = p_name; -} - -String VisualScript::custom_signal_get_argument_name(const StringName &p_func, int p_argidx) const { - ERR_FAIL_COND_V(!custom_signals.has(p_func), String()); - ERR_FAIL_INDEX_V(p_argidx, custom_signals[p_func].size(), String()); - return custom_signals[p_func][p_argidx].name; -} - -void VisualScript::custom_signal_remove_argument(const StringName &p_func, int p_argidx) { - ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!custom_signals.has(p_func)); - ERR_FAIL_INDEX(p_argidx, custom_signals[p_func].size()); - custom_signals[p_func].remove_at(p_argidx); -} - -int VisualScript::custom_signal_get_argument_count(const StringName &p_func) const { - ERR_FAIL_COND_V(!custom_signals.has(p_func), 0); - return custom_signals[p_func].size(); -} - -void VisualScript::custom_signal_swap_argument(const StringName &p_func, int p_argidx, int p_with_argidx) { - ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!custom_signals.has(p_func)); - ERR_FAIL_INDEX(p_argidx, custom_signals[p_func].size()); - ERR_FAIL_INDEX(p_with_argidx, custom_signals[p_func].size()); - - SWAP(custom_signals[p_func].write[p_argidx], custom_signals[p_func].write[p_with_argidx]); -} - -void VisualScript::remove_custom_signal(const StringName &p_name) { - ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!custom_signals.has(p_name)); - custom_signals.erase(p_name); -} - -void VisualScript::rename_custom_signal(const StringName &p_name, const StringName &p_new_name) { - ERR_FAIL_COND(instances.size()); - ERR_FAIL_COND(!custom_signals.has(p_name)); - if (p_new_name == p_name) { - return; - } - - ERR_FAIL_COND(!String(p_new_name).is_valid_identifier()); - - ERR_FAIL_COND(functions.has(p_new_name)); - ERR_FAIL_COND(variables.has(p_new_name)); - ERR_FAIL_COND(custom_signals.has(p_new_name)); - - custom_signals[p_new_name] = custom_signals[p_name]; - custom_signals.erase(p_name); -} - -void VisualScript::get_custom_signal_list(List<StringName> *r_custom_signals) const { - for (const KeyValue<StringName, Vector<Argument>> &E : custom_signals) { - r_custom_signals->push_back(E.key); - } - - r_custom_signals->sort_custom<StringName::AlphCompare>(); -} - -int VisualScript::get_available_id() const { - // This is infinitely increasing, - // so one might want to implement a better solution, - // if the there is a case for huge number of nodes to be added to visual script. - - int max = -1; - for (const KeyValue<int, NodeData> &E : nodes) { - if (E.key > max) { - max = E.key; - } - } - return (max + 1); -} - -///////////////////////////////// - -bool VisualScript::can_instantiate() const { - return true; // ScriptServer::is_scripting_enabled(); -} - -StringName VisualScript::get_instance_base_type() const { - return base_type; -} - -Ref<Script> VisualScript::get_base_script() const { - return Ref<Script>(); // No inheritance in visual script. -} - -#ifdef TOOLS_ENABLED -void VisualScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder) { - placeholders.erase(p_placeholder); -} - -void VisualScript::_update_placeholders() { - if (placeholders.size() == 0) { - return; // No bother if no placeholders. - } - List<PropertyInfo> pinfo; - HashMap<StringName, Variant> values; - - for (const KeyValue<StringName, Variable> &E : variables) { - if (!variables[E.key]._export) { - continue; - } - - PropertyInfo p = variables[E.key].info; - p.name = String(E.key); - pinfo.push_back(p); - values[p.name] = variables[E.key].default_value; - } - - for (PlaceHolderScriptInstance *E : placeholders) { - E->update(pinfo, values); - } -} - -#endif - -ScriptInstance *VisualScript::instance_create(Object *p_this) { -#ifdef TOOLS_ENABLED - - if (!ScriptServer::is_scripting_enabled() && !is_tool_script) { - PlaceHolderScriptInstance *sins = memnew(PlaceHolderScriptInstance(VisualScriptLanguage::singleton, Ref<Script>((Script *)this), p_this)); - placeholders.insert(sins); - - List<PropertyInfo> pinfo; - HashMap<StringName, Variant> values; - - for (const KeyValue<StringName, Variable> &E : variables) { - if (!variables[E.key]._export) { - continue; - } - - PropertyInfo p = variables[E.key].info; - p.name = String(E.key); - pinfo.push_back(p); - values[p.name] = variables[E.key].default_value; - } - sins->update(pinfo, values); - - return sins; - } -#endif - - VisualScriptInstance *instance = memnew(VisualScriptInstance); - instance->create(Ref<VisualScript>(this), p_this); - - { - MutexLock lock(VisualScriptLanguage::singleton->lock); - - instances[p_this] = instance; - } - - return instance; -} - -bool VisualScript::instance_has(const Object *p_this) const { - return instances.has((Object *)p_this); -} - -bool VisualScript::has_source_code() const { - return false; -} - -String VisualScript::get_source_code() const { - return String(); -} - -void VisualScript::set_source_code(const String &p_code) { -} - -Error VisualScript::reload(bool p_keep_state) { - return OK; -} - -bool VisualScript::is_tool() const { - return is_tool_script; -} - -bool VisualScript::is_valid() const { - return true; // Always valid. -} - -ScriptLanguage *VisualScript::get_language() const { - return VisualScriptLanguage::singleton; -} - -bool VisualScript::has_script_signal(const StringName &p_signal) const { - return custom_signals.has(p_signal); -} - -void VisualScript::get_script_signal_list(List<MethodInfo> *r_signals) const { - for (const KeyValue<StringName, Vector<Argument>> &E : custom_signals) { - MethodInfo mi; - mi.name = E.key; - for (int i = 0; i < E.value.size(); i++) { - PropertyInfo arg; - arg.type = E.value[i].type; - arg.name = E.value[i].name; - mi.arguments.push_back(arg); - } - - r_signals->push_back(mi); - } -} - -bool VisualScript::get_property_default_value(const StringName &p_property, Variant &r_value) const { - if (!variables.has(p_property)) { - return false; - } - - r_value = variables[p_property].default_value; - return true; -} - -void VisualScript::get_script_method_list(List<MethodInfo> *p_list) const { - for (const KeyValue<StringName, Function> &E : functions) { - MethodInfo mi; - mi.name = E.key; - if (functions[E.key].func_id >= 0) { - Ref<VisualScriptFunction> func = nodes[functions[E.key].func_id].node; - if (func.is_valid()) { - for (int i = 0; i < func->get_argument_count(); i++) { - PropertyInfo arg; - arg.name = func->get_argument_name(i); - arg.type = func->get_argument_type(i); - mi.arguments.push_back(arg); - } - - p_list->push_back(mi); - } - } - } -} - -bool VisualScript::has_method(const StringName &p_method) const { - return functions.has(p_method); -} - -MethodInfo VisualScript::get_method_info(const StringName &p_method) const { - const Function funct = functions[p_method]; - if (funct.func_id == -1) { - return MethodInfo(); - } - - MethodInfo mi; - mi.name = p_method; - if (funct.func_id >= 0) { - Ref<VisualScriptFunction> func = nodes[funct.func_id].node; - if (func.is_valid()) { - for (int i = 0; i < func->get_argument_count(); i++) { - PropertyInfo arg; - arg.name = func->get_argument_name(i); - arg.type = func->get_argument_type(i); - mi.arguments.push_back(arg); - } - - if (!func->is_sequenced()) { - mi.flags |= METHOD_FLAG_CONST; - } - } - } - - return mi; -} - -void VisualScript::get_script_property_list(List<PropertyInfo> *p_list) const { - List<StringName> vars; - get_variable_list(&vars); - - for (const StringName &E : vars) { - if (!variables[E]._export) { - continue; - } - PropertyInfo pi = variables[E].info; - pi.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE; - p_list->push_back(pi); - } -} - -int VisualScript::get_member_line(const StringName &p_member) const { - return functions[p_member].func_id; // will be -1 if not found -} - -#ifdef TOOLS_ENABLED -bool VisualScript::are_subnodes_edited() const { - for (const KeyValue<int, NodeData> &F : nodes) { - if (F.value.node->is_edited()) { - return true; - } - } - return false; -} -#endif - -const Variant VisualScript::get_rpc_config() const { - return rpc_functions; -} - -void VisualScript::_set_data(const Dictionary &p_data) { - Dictionary d = p_data; - if (d.has("base_type")) { - base_type = d["base_type"]; - } - - variables.clear(); - Array vars = d["variables"]; - for (int i = 0; i < vars.size(); i++) { - Dictionary v = vars[i]; - StringName name = v["name"]; - add_variable(name); - _set_variable_info(name, v); - set_variable_default_value(name, v["default_value"]); - set_variable_export(name, v.has("export") && bool(v["export"])); - } - - custom_signals.clear(); - Array sigs = d["signals"]; - for (int i = 0; i < sigs.size(); i++) { - Dictionary cs = sigs[i]; - add_custom_signal(cs["name"]); - - Array args = cs["arguments"]; - for (int j = 0; j < args.size(); j += 2) { - custom_signal_add_argument(cs["name"], Variant::Type(int(args[j + 1])), args[j]); - } - } - - Array funcs = d["functions"]; - functions.clear(); - - for (int i = 0; i < funcs.size(); i++) { - Dictionary func = funcs[i]; - add_function(func["name"], func["function_id"]); - } - { - Array nodes = d["nodes"]; - for (int i = 0; i < nodes.size(); i += 3) { - add_node(nodes[i], nodes[i + 2], nodes[i + 1]); - } - - Array sequence_connections = d["sequence_connections"]; - for (int j = 0; j < sequence_connections.size(); j += 3) { - sequence_connect(sequence_connections[j + 0], sequence_connections[j + 1], sequence_connections[j + 2]); - } - - Array data_connections = d["data_connections"]; - for (int j = 0; j < data_connections.size(); j += 4) { - data_connect(data_connections[j + 0], data_connections[j + 1], data_connections[j + 2], data_connections[j + 3]); - } - } - is_tool_script = d["is_tool_script"]; - scroll = d["scroll"]; - - // Takes all the rpc methods. - rpc_functions.clear(); - for (const KeyValue<StringName, Function> &E : functions) { - if (E.value.func_id >= 0 && nodes.has(E.value.func_id)) { - Ref<VisualScriptFunction> vsf = nodes[E.value.func_id].node; - if (!vsf.is_valid() || vsf->get_rpc_mode() == MultiplayerAPI::RPC_MODE_DISABLED) { - continue; - } - Dictionary nd; - nd["rpc_mode"] = vsf->get_rpc_mode(); - nd["transfer_mode"] = MultiplayerPeer::TRANSFER_MODE_RELIABLE; // TODO - nd["call_local"] = false; // TODO - rpc_functions[E.key] = nd; - } - } -} - -Dictionary VisualScript::_get_data() const { - Dictionary d; - d["base_type"] = base_type; - - Array vars; - for (const KeyValue<StringName, Variable> &E : variables) { - Dictionary var = _get_variable_info(E.key); - var["name"] = E.key; // Make sure it's the right one. - var["default_value"] = E.value.default_value; - var["export"] = E.value._export; - vars.push_back(var); - } - d["variables"] = vars; - - Array sigs; - for (const KeyValue<StringName, Vector<Argument>> &E : custom_signals) { - Dictionary cs; - cs["name"] = E.key; - Array args; - for (int i = 0; i < E.value.size(); i++) { - args.push_back(E.value[i].name); - args.push_back(E.value[i].type); - } - cs["arguments"] = args; - - sigs.push_back(cs); - } - - d["signals"] = sigs; - - Array funcs; - for (const KeyValue<StringName, Function> &E : functions) { - Dictionary func; - func["name"] = E.key; - func["function_id"] = E.value.func_id; - funcs.push_back(func); - } - d["functions"] = funcs; - - Array nds; - for (const KeyValue<int, NodeData> &F : nodes) { - nds.push_back(F.key); - nds.push_back(F.value.pos); - nds.push_back(F.value.node); - } - d["nodes"] = nds; - - Array seqconns; - for (const SequenceConnection &F : sequence_connections) { - seqconns.push_back(F.from_node); - seqconns.push_back(F.from_output); - seqconns.push_back(F.to_node); - } - d["sequence_connections"] = seqconns; - - Array dataconns; - for (const DataConnection &F : data_connections) { - dataconns.push_back(F.from_node); - dataconns.push_back(F.from_port); - dataconns.push_back(F.to_node); - dataconns.push_back(F.to_port); - } - d["data_connections"] = dataconns; - - d["is_tool_script"] = is_tool_script; - d["scroll"] = scroll; - - return d; -} - -void VisualScript::_bind_methods() { - ClassDB::bind_method(D_METHOD("add_function", "name", "func_node_id"), &VisualScript::add_function); - ClassDB::bind_method(D_METHOD("has_function", "name"), &VisualScript::has_function); - ClassDB::bind_method(D_METHOD("remove_function", "name"), &VisualScript::remove_function); - ClassDB::bind_method(D_METHOD("rename_function", "name", "new_name"), &VisualScript::rename_function); - ClassDB::bind_method(D_METHOD("set_scroll", "offset"), &VisualScript::set_scroll); - ClassDB::bind_method(D_METHOD("get_scroll"), &VisualScript::get_scroll); - - ClassDB::bind_method(D_METHOD("add_node", "id", "node", "position"), &VisualScript::add_node, DEFVAL(Point2())); - ClassDB::bind_method(D_METHOD("remove_node", "id"), &VisualScript::remove_node); - ClassDB::bind_method(D_METHOD("get_function_node_id", "name"), &VisualScript::get_function_node_id); - - ClassDB::bind_method(D_METHOD("get_node", "id"), &VisualScript::get_node); - ClassDB::bind_method(D_METHOD("has_node", "id"), &VisualScript::has_node); - ClassDB::bind_method(D_METHOD("set_node_position", "id", "position"), &VisualScript::set_node_position); - ClassDB::bind_method(D_METHOD("get_node_position", "id"), &VisualScript::get_node_position); - - ClassDB::bind_method(D_METHOD("sequence_connect", "from_node", "from_output", "to_node"), &VisualScript::sequence_connect); - ClassDB::bind_method(D_METHOD("sequence_disconnect", "from_node", "from_output", "to_node"), &VisualScript::sequence_disconnect); - ClassDB::bind_method(D_METHOD("has_sequence_connection", "from_node", "from_output", "to_node"), &VisualScript::has_sequence_connection); - - ClassDB::bind_method(D_METHOD("data_connect", "from_node", "from_port", "to_node", "to_port"), &VisualScript::data_connect); - ClassDB::bind_method(D_METHOD("data_disconnect", "from_node", "from_port", "to_node", "to_port"), &VisualScript::data_disconnect); - ClassDB::bind_method(D_METHOD("has_data_connection", "from_node", "from_port", "to_node", "to_port"), &VisualScript::has_data_connection); - - ClassDB::bind_method(D_METHOD("add_variable", "name", "default_value", "export"), &VisualScript::add_variable, DEFVAL(Variant()), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("has_variable", "name"), &VisualScript::has_variable); - ClassDB::bind_method(D_METHOD("remove_variable", "name"), &VisualScript::remove_variable); - ClassDB::bind_method(D_METHOD("set_variable_default_value", "name", "value"), &VisualScript::set_variable_default_value); - ClassDB::bind_method(D_METHOD("get_variable_default_value", "name"), &VisualScript::get_variable_default_value); - ClassDB::bind_method(D_METHOD("set_variable_info", "name", "value"), &VisualScript::_set_variable_info); - ClassDB::bind_method(D_METHOD("get_variable_info", "name"), &VisualScript::_get_variable_info); - ClassDB::bind_method(D_METHOD("set_variable_export", "name", "enable"), &VisualScript::set_variable_export); - ClassDB::bind_method(D_METHOD("get_variable_export", "name"), &VisualScript::get_variable_export); - ClassDB::bind_method(D_METHOD("rename_variable", "name", "new_name"), &VisualScript::rename_variable); - - ClassDB::bind_method(D_METHOD("add_custom_signal", "name"), &VisualScript::add_custom_signal); - ClassDB::bind_method(D_METHOD("has_custom_signal", "name"), &VisualScript::has_custom_signal); - ClassDB::bind_method(D_METHOD("custom_signal_add_argument", "name", "type", "argname", "index"), &VisualScript::custom_signal_add_argument, DEFVAL(-1)); - ClassDB::bind_method(D_METHOD("custom_signal_set_argument_type", "name", "argidx", "type"), &VisualScript::custom_signal_set_argument_type); - ClassDB::bind_method(D_METHOD("custom_signal_get_argument_type", "name", "argidx"), &VisualScript::custom_signal_get_argument_type); - ClassDB::bind_method(D_METHOD("custom_signal_set_argument_name", "name", "argidx", "argname"), &VisualScript::custom_signal_set_argument_name); - ClassDB::bind_method(D_METHOD("custom_signal_get_argument_name", "name", "argidx"), &VisualScript::custom_signal_get_argument_name); - ClassDB::bind_method(D_METHOD("custom_signal_remove_argument", "name", "argidx"), &VisualScript::custom_signal_remove_argument); - ClassDB::bind_method(D_METHOD("custom_signal_get_argument_count", "name"), &VisualScript::custom_signal_get_argument_count); - ClassDB::bind_method(D_METHOD("custom_signal_swap_argument", "name", "argidx", "withidx"), &VisualScript::custom_signal_swap_argument); - ClassDB::bind_method(D_METHOD("remove_custom_signal", "name"), &VisualScript::remove_custom_signal); - ClassDB::bind_method(D_METHOD("rename_custom_signal", "name", "new_name"), &VisualScript::rename_custom_signal); - - ClassDB::bind_method(D_METHOD("set_instance_base_type", "type"), &VisualScript::set_instance_base_type); - - ClassDB::bind_method(D_METHOD("_set_data", "data"), &VisualScript::_set_data); - ClassDB::bind_method(D_METHOD("_get_data"), &VisualScript::_get_data); - - ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data"); - - ADD_SIGNAL(MethodInfo("node_ports_changed", PropertyInfo(Variant::INT, "id"))); -} - -VisualScript::VisualScript() { - base_type = "Object"; - is_tool_script = false; -} - -bool VisualScript::inherits_script(const Ref<Script> &p_script) const { - return this == p_script.ptr(); // There is no inheritance in visual scripts, so this is enough. -} - -RBSet<int> VisualScript::get_output_sequence_ports_connected(int from_node) { - List<VisualScript::SequenceConnection> *sc = memnew(List<VisualScript::SequenceConnection>); - get_sequence_connection_list(sc); - RBSet<int> connected; - for (List<VisualScript::SequenceConnection>::Element *E = sc->front(); E; E = E->next()) { - if (E->get().from_node == from_node) { - connected.insert(E->get().from_output); - } - } - memdelete(sc); - return connected; -} - -VisualScript::~VisualScript() { - // Remove all nodes and stuff that hold data refs. - for (const KeyValue<int, NodeData> &E : nodes) { - remove_node(E.key); - } -} - -//////////////////////////////////////////// - -bool VisualScriptInstance::set(const StringName &p_name, const Variant &p_value) { - HashMap<StringName, Variant>::Iterator E = variables.find(p_name); - if (!E) { - return false; - } - - E->value = p_value; - - return true; -} - -bool VisualScriptInstance::get(const StringName &p_name, Variant &r_ret) const { - HashMap<StringName, Variant>::ConstIterator E = variables.find(p_name); - if (!E) { - return false; - } - - r_ret = E->value; - return true; -} - -void VisualScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const { -#ifdef TOOLS_ENABLED - p_properties->push_back(script->get_class_category()); -#endif // TOOLS_ENABLED - - for (const KeyValue<StringName, VisualScript::Variable> &E : script->variables) { - if (!E.value._export) { - continue; - } - PropertyInfo p = E.value.info; - p.name = String(E.key); - p.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE; - p_properties->push_back(p); - } -} - -Variant::Type VisualScriptInstance::get_property_type(const StringName &p_name, bool *r_is_valid) const { - if (!script->variables.has(p_name)) { - if (r_is_valid) { - *r_is_valid = false; - } - ERR_FAIL_V(Variant::NIL); - } - - if (r_is_valid) { - *r_is_valid = true; - } - - return script->variables[p_name].info.type; -} - -void VisualScriptInstance::get_method_list(List<MethodInfo> *p_list) const { - for (const KeyValue<StringName, VisualScript::Function> &E : script->functions) { - MethodInfo mi; - mi.name = E.key; - if (E.value.func_id >= 0 && script->nodes.has(E.value.func_id)) { - Ref<VisualScriptFunction> vsf = script->nodes[E.value.func_id].node; - if (vsf.is_valid()) { - for (int i = 0; i < vsf->get_argument_count(); i++) { - PropertyInfo arg; - arg.name = vsf->get_argument_name(i); - arg.type = vsf->get_argument_type(i); - - mi.arguments.push_back(arg); - } - - if (!vsf->is_sequenced()) { // Assumed constant if not sequenced. - mi.flags |= METHOD_FLAG_CONST; - } - } - } - p_list->push_back(mi); - } -} - -bool VisualScriptInstance::has_method(const StringName &p_method) const { - return script->functions.has(p_method); -} - -//#define VSDEBUG(m_text) print_line(m_text) -#define VSDEBUG(m_text) - -void VisualScriptInstance::_dependency_step(VisualScriptNodeInstance *node, int p_pass, int *pass_stack, const Variant **input_args, Variant **output_args, Variant *variant_stack, Callable::CallError &r_error, String &error_str, VisualScriptNodeInstance **r_error_node) { - ERR_FAIL_COND(node->pass_idx == -1); - - if (pass_stack[node->pass_idx] == p_pass) { - return; - } - - pass_stack[node->pass_idx] = p_pass; - - if (!node->dependencies.is_empty()) { - int dc = node->dependencies.size(); - VisualScriptNodeInstance **deps = node->dependencies.ptrw(); - - for (int i = 0; i < dc; i++) { - _dependency_step(deps[i], p_pass, pass_stack, input_args, output_args, variant_stack, r_error, error_str, r_error_node); - if (r_error.error != Callable::CallError::CALL_OK) { - return; - } - } - } - - for (int i = 0; i < node->input_port_count; i++) { - int index = node->input_ports[i] & VisualScriptNodeInstance::INPUT_MASK; - - if (node->input_ports[i] & VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT) { - // Is a default value (unassigned input port). - input_args[i] = &default_values[index]; - } else { - // Regular temporary in stack. - input_args[i] = &variant_stack[index]; - } - } - for (int i = 0; i < node->output_port_count; i++) { - output_args[i] = &variant_stack[node->output_ports[i]]; - } - - Variant *working_mem = node->working_mem_idx >= 0 ? &variant_stack[node->working_mem_idx] : (Variant *)nullptr; - - node->step(input_args, output_args, VisualScriptNodeInstance::START_MODE_BEGIN_SEQUENCE, working_mem, r_error, error_str); - // Ignore return. - if (r_error.error != Callable::CallError::CALL_OK) { - *r_error_node = node; - } -} - -Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p_stack, int p_stack_size, VisualScriptNodeInstance *p_node, int p_flow_stack_pos, int p_pass, bool p_resuming_yield, Callable::CallError &r_error) { - HashMap<StringName, Function>::Iterator F = functions.find(p_method); - ERR_FAIL_COND_V(!F, Variant()); - Function *f = &F->value; - - // This call goes separate, so it can be yielded and suspended. - Variant *variant_stack = (Variant *)p_stack; - bool *sequence_bits = (bool *)(variant_stack + f->max_stack); - const Variant **input_args = (const Variant **)(sequence_bits + f->node_count); - Variant **output_args = (Variant **)(input_args + max_input_args); - int flow_max = f->flow_stack_size; - int *flow_stack = flow_max ? (int *)(output_args + max_output_args) : (int *)nullptr; - int *pass_stack = flow_stack ? (int *)(flow_stack + flow_max) : (int *)nullptr; - - String error_str; - - VisualScriptNodeInstance *node = p_node; - bool error = false; - int current_node_id = f->node; - Variant return_value; - Variant *working_mem = nullptr; - - int flow_stack_pos = p_flow_stack_pos; - -#ifdef DEBUG_ENABLED - if (EngineDebugger::is_active()) { - VisualScriptLanguage::singleton->enter_function(this, &p_method, variant_stack, &working_mem, ¤t_node_id); - } -#endif - - while (true) { - p_pass++; // Increment pass. - current_node_id = node->get_id(); - - VSDEBUG("==========AT NODE: " + itos(current_node_id) + " base: " + node->get_base_node()->get_class_name()); - VSDEBUG("AT STACK POS: " + itos(flow_stack_pos)); - - // Setup working mem. - working_mem = node->working_mem_idx >= 0 ? &variant_stack[node->working_mem_idx] : (Variant *)nullptr; - - VSDEBUG("WORKING MEM: " + itos(node->working_mem_idx)); - - if (current_node_id == f->node) { - // If function node, set up function arguments from beginning of stack. - - for (int i = 0; i < f->argument_count; i++) { - input_args[i] = &variant_stack[i]; - } - } else { - // Run dependencies first. - - if (!node->dependencies.is_empty()) { - int dc = node->dependencies.size(); - VisualScriptNodeInstance **deps = node->dependencies.ptrw(); - - for (int i = 0; i < dc; i++) { - _dependency_step(deps[i], p_pass, pass_stack, input_args, output_args, variant_stack, r_error, error_str, &node); - if (r_error.error != Callable::CallError::CALL_OK) { - error = true; - current_node_id = node->id; - break; - } - } - } - - if (!error) { - // Setup input pointers normally. - VSDEBUG("INPUT PORTS: " + itos(node->input_port_count)); - - for (int i = 0; i < node->input_port_count; i++) { - int index = node->input_ports[i] & VisualScriptNodeInstance::INPUT_MASK; - - if (node->input_ports[i] & VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT) { - // Is a default value (unassigned input port). - input_args[i] = &default_values[index]; - VSDEBUG("\tPORT " + itos(i) + " DEFAULT VAL"); - } else { - // Regular temporary in stack. - input_args[i] = &variant_stack[index]; - VSDEBUG("PORT " + itos(i) + " AT STACK " + itos(index)); - } - } - } - } - - if (error) { - break; - } - - // Setup output pointers. - - VSDEBUG("OUTPUT PORTS: " + itos(node->output_port_count)); - for (int i = 0; i < node->output_port_count; i++) { - output_args[i] = &variant_stack[node->output_ports[i]]; - VSDEBUG("PORT " + itos(i) + " AT STACK " + itos(node->output_ports[i])); - } - - // Do step. - - VisualScriptNodeInstance::StartMode start_mode; - { - if (p_resuming_yield) { - start_mode = VisualScriptNodeInstance::START_MODE_RESUME_YIELD; - p_resuming_yield = false; // Should resume only the first time. - } else if (flow_stack && (flow_stack[flow_stack_pos] & VisualScriptNodeInstance::FLOW_STACK_PUSHED_BIT)) { - // If there is a push bit, it means we are continuing a sequence. - start_mode = VisualScriptNodeInstance::START_MODE_CONTINUE_SEQUENCE; - } else { - start_mode = VisualScriptNodeInstance::START_MODE_BEGIN_SEQUENCE; - } - } - - VSDEBUG("STEP - STARTSEQ: " + itos(start_mode)); - - int ret = node->step(input_args, output_args, start_mode, working_mem, r_error, error_str); - - if (r_error.error != Callable::CallError::CALL_OK) { - // Use error from step. - error = true; - break; - } - - if (ret & VisualScriptNodeInstance::STEP_YIELD_BIT) { - // Yielded! - if (node->get_working_memory_size() == 0) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - error_str = RTR("A node yielded without working memory, please read the docs on how to yield properly!"); - error = true; - break; - - } else { - Ref<VisualScriptFunctionState> state = *working_mem; - if (!state.is_valid()) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - error_str = RTR("Node yielded, but did not return a function state in the first working memory."); - error = true; - break; - } - - // Step 1, capture all state. - state->instance_id = get_owner_ptr()->get_instance_id(); - state->script_id = get_script()->get_instance_id(); - state->instance = this; - state->function = p_method; - state->working_mem_index = node->working_mem_idx; - state->variant_stack_size = f->max_stack; - state->node = node; - state->flow_stack_pos = flow_stack_pos; - state->stack.resize(p_stack_size); - state->pass = p_pass; - memcpy(state->stack.ptrw(), p_stack, p_stack_size); - // Step 2, run away, return directly. - r_error.error = Callable::CallError::CALL_OK; - -#ifdef DEBUG_ENABLED - // Will re-enter later, so exiting. - if (EngineDebugger::is_active()) { - VisualScriptLanguage::singleton->exit_function(); - } -#endif - - return state; - } - } - -#ifdef DEBUG_ENABLED - if (EngineDebugger::is_active()) { - // line - bool do_break = false; - - if (EngineDebugger::get_script_debugger()->get_lines_left() > 0) { - if (EngineDebugger::get_script_debugger()->get_depth() <= 0) { - EngineDebugger::get_script_debugger()->set_lines_left(EngineDebugger::get_script_debugger()->get_lines_left() - 1); - } - if (EngineDebugger::get_script_debugger()->get_lines_left() <= 0) { - do_break = true; - } - } - - if (EngineDebugger::get_script_debugger()->is_breakpoint(current_node_id, source)) { - do_break = true; - } - - if (do_break) { - VisualScriptLanguage::singleton->debug_break("Breakpoint", true); - } - - EngineDebugger::get_singleton()->line_poll(); - } -#endif - int output = ret & VisualScriptNodeInstance::STEP_MASK; - - VSDEBUG("STEP RETURN: " + itos(ret)); - - if (ret & VisualScriptNodeInstance::STEP_EXIT_FUNCTION_BIT) { - if (node->get_working_memory_size() == 0) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - error_str = RTR("Return value must be assigned to first element of node working memory! Fix your node please."); - error = true; - } else { - // Assign from working memory, first element. - return_value = *working_mem; - } - - VSDEBUG("EXITING FUNCTION - VALUE " + String(return_value)); - break; // Exit function requested, bye - } - - VisualScriptNodeInstance *next = nullptr; // Next node. - - if ((ret == output || ret & VisualScriptNodeInstance::STEP_FLAG_PUSH_STACK_BIT) && node->sequence_output_count) { - // If no exit bit was set, and has sequence outputs, guess next node. - if (output >= node->sequence_output_count) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - error_str = RTR("Node returned an invalid sequence output:") + " " + itos(output); - error = true; - break; - } - - next = node->sequence_outputs[output]; - VSDEBUG("GOT NEXT NODE - " + (next ? itos(next->get_id()) : "Null")); - } - - if (flow_stack) { - // Update flow stack pos (may have changed). - flow_stack[flow_stack_pos] = current_node_id; - - // Add stack push bit if requested. - if (ret & VisualScriptNodeInstance::STEP_FLAG_PUSH_STACK_BIT) { - flow_stack[flow_stack_pos] |= VisualScriptNodeInstance::FLOW_STACK_PUSHED_BIT; - sequence_bits[node->sequence_index] = true; // Remember sequence bit. - VSDEBUG("NEXT SEQ - FLAG BIT"); - } else { - sequence_bits[node->sequence_index] = false; // Forget sequence bit. - VSDEBUG("NEXT SEQ - NORMAL"); - } - - if (ret & VisualScriptNodeInstance::STEP_FLAG_GO_BACK_BIT) { - // Go back request. - - if (flow_stack_pos > 0) { - flow_stack_pos--; - node = instances[flow_stack[flow_stack_pos] & VisualScriptNodeInstance::FLOW_STACK_MASK]; - VSDEBUG("NEXT IS GO BACK"); - } else { - VSDEBUG("NEXT IS GO BACK, BUT NO NEXT SO EXIT"); - break; // Simply exit without value or error. - } - } else if (next) { - if (sequence_bits[next->sequence_index]) { - // What happened here is that we are entering a node that is in the middle of doing a sequence (pushed stack) from the front - // because each node has a working memory, we can't really do a sub-sequence - // as a result, the sequence will be restarted and the stack will roll back to find where this node - // started the sequence. - - bool found = false; - - for (int i = flow_stack_pos; i >= 0; i--) { - if ((flow_stack[i] & VisualScriptNodeInstance::FLOW_STACK_MASK) == next->get_id()) { - flow_stack_pos = i; // Roll back and remove bit. - flow_stack[i] = next->get_id(); - sequence_bits[next->sequence_index] = false; - found = true; - } - } - - if (!found) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - error_str = RTR("Found sequence bit but not the node in the stack (please report)."); - error = true; - break; - } - - node = next; - VSDEBUG("RE-ENTERED A LOOP, RETURNED STACK POS TO - " + itos(flow_stack_pos)); - - } else { - // Check for stack overflow. - if (flow_stack_pos + 1 >= flow_max) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - error_str = vformat(RTR("Stack overflow (stack size: %s). Check for infinite recursion in your script."), output); - error = true; - break; - } - - node = next; - - flow_stack_pos++; - flow_stack[flow_stack_pos] = node->get_id(); - - VSDEBUG("INCREASE FLOW STACK"); - } - - } else { - // No next node, try to go back in stack to pushed bit. - - bool found = false; - - for (int i = flow_stack_pos; i >= 0; i--) { - VSDEBUG("FS " + itos(i) + " - " + itos(flow_stack[i])); - if (flow_stack[i] & VisualScriptNodeInstance::FLOW_STACK_PUSHED_BIT) { - node = instances[flow_stack[i] & VisualScriptNodeInstance::FLOW_STACK_MASK]; - flow_stack_pos = i; - found = true; - break; - } - } - - if (!found) { - VSDEBUG("NO NEXT NODE, NO GO BACK, EXITING"); - break; // Done, couldn't find a push stack bit. - } - - VSDEBUG("NO NEXT NODE, GO BACK TO: " + itos(flow_stack_pos)); - } - } else { - node = next; // Stackless mode, simply assign next node. - } - } - - if (error) { - // Error - // Function, file, line, error, explanation. - String err_file = script->get_path(); - String err_func = p_method; - int err_line = current_node_id; // Not a line but it works as one. - - if (node && (r_error.error != Callable::CallError::CALL_ERROR_INVALID_METHOD || error_str.is_empty())) { - if (!error_str.is_empty()) { - error_str += " "; - } - - if (r_error.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) { - int errorarg = r_error.argument; - error_str += "Cannot convert argument " + itos(errorarg + 1) + " to " + Variant::get_type_name(Variant::Type(r_error.expected)) + "."; - } else if (r_error.error == Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) { - error_str += "Expected " + itos(r_error.argument) + " arguments."; - } else if (r_error.error == Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) { - error_str += "Expected " + itos(r_error.argument) + " arguments."; - } else if (r_error.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) { - error_str += "Invalid Call."; - } else if (r_error.error == Callable::CallError::CALL_ERROR_METHOD_NOT_CONST) { - error_str += "Method not const in a const instance."; - } else if (r_error.error == Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL) { - error_str += "Base Instance is null"; - } - } - - //if (!GDScriptLanguage::get_singleton()->debug_break(err_text,false)) { - // debugger break did not happen - - if (!VisualScriptLanguage::singleton->debug_break(error_str, false)) { - _err_print_error(err_func.utf8().get_data(), err_file.utf8().get_data(), err_line, error_str.utf8().get_data(), false, ERR_HANDLER_SCRIPT); - } - - //} - } else { - //return_value= - } - -#ifdef DEBUG_ENABLED - if (EngineDebugger::is_active()) { - VisualScriptLanguage::singleton->exit_function(); - } -#endif - - // Clean up variant stack. - for (int i = 0; i < f->max_stack; i++) { - variant_stack[i].~Variant(); - } - - return return_value; -} - -Variant VisualScriptInstance::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { - r_error.error = Callable::CallError::CALL_OK; //ok by default - - HashMap<StringName, Function>::Iterator F = functions.find(p_method); - if (!F) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - return Variant(); - } - - VSDEBUG("CALLING: " + String(p_method)); - - Function *f = &F->value; - - int total_stack_size = 0; - - total_stack_size += f->max_stack * sizeof(Variant); //variants - total_stack_size += f->node_count * sizeof(bool); - total_stack_size += (max_input_args + max_output_args) * sizeof(Variant *); //arguments - total_stack_size += f->flow_stack_size * sizeof(int); //flow - total_stack_size += f->pass_stack_size * sizeof(int); - - VSDEBUG("STACK SIZE: " + itos(total_stack_size)); - VSDEBUG("STACK VARIANTS: : " + itos(f->max_stack)); - VSDEBUG("SEQBITS: : " + itos(f->node_count)); - VSDEBUG("MAX INPUT: " + itos(max_input_args)); - VSDEBUG("MAX OUTPUT: " + itos(max_output_args)); - VSDEBUG("FLOW STACK SIZE: " + itos(f->flow_stack_size)); - VSDEBUG("PASS STACK SIZE: " + itos(f->pass_stack_size)); - - void *stack = alloca(total_stack_size); - - Variant *variant_stack = (Variant *)stack; - bool *sequence_bits = (bool *)(variant_stack + f->max_stack); - const Variant **input_args = (const Variant **)(sequence_bits + f->node_count); - Variant **output_args = (Variant **)(input_args + max_input_args); - int flow_max = f->flow_stack_size; - int *flow_stack = flow_max ? (int *)(output_args + max_output_args) : (int *)nullptr; - int *pass_stack = flow_stack ? (int *)(flow_stack + flow_max) : (int *)nullptr; - - for (int i = 0; i < f->node_count; i++) { - sequence_bits[i] = false; // All starts as false. - } - - memset(pass_stack, 0, f->pass_stack_size * sizeof(int)); - - HashMap<int, VisualScriptNodeInstance *>::Iterator E = instances.find(f->node); - if (!E) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - - ERR_FAIL_V_MSG(Variant(), "No VisualScriptFunction node in function."); - } - - VisualScriptNodeInstance *node = E->value; - - if (flow_stack) { - flow_stack[0] = node->get_id(); - } - - VSDEBUG("ARGUMENTS: " + itos(f->argument_count) = " RECEIVED: " + itos(p_argcount)); - - if (p_argcount < f->argument_count) { - r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; - r_error.argument = node->get_input_port_count(); - - return Variant(); - } - - if (p_argcount > f->argument_count) { - r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; - r_error.argument = node->get_input_port_count(); - - return Variant(); - } - - // Allocate variant stack. - for (int i = 0; i < f->max_stack; i++) { - memnew_placement(&variant_stack[i], Variant); - } - - // Allocate function arguments (must be copied for yield to work properly). - for (int i = 0; i < p_argcount; i++) { - variant_stack[i] = *p_args[i]; - } - - return _call_internal(p_method, stack, total_stack_size, node, 0, 0, false, r_error); -} - -void VisualScriptInstance::notification(int p_notification) { - // Do nothing as this is called using virtual. - - Variant what = p_notification; - const Variant *whatp = &what; - Callable::CallError ce; - callp(VisualScriptLanguage::singleton->notification, &whatp, 1, ce); // Do as call. -} - -String VisualScriptInstance::to_string(bool *r_valid) { - if (has_method(CoreStringNames::get_singleton()->_to_string)) { - Callable::CallError ce; - Variant ret = callp(CoreStringNames::get_singleton()->_to_string, nullptr, 0, ce); - if (ce.error == Callable::CallError::CALL_OK) { - if (ret.get_type() != Variant::STRING) { - if (r_valid) { - *r_valid = false; - } - ERR_FAIL_V_MSG(String(), "Wrong type for " + CoreStringNames::get_singleton()->_to_string + ", must be a String."); - } - if (r_valid) { - *r_valid = true; - } - return ret.operator String(); - } - } - if (r_valid) { - *r_valid = false; - } - return String(); -} - -Ref<Script> VisualScriptInstance::get_script() const { - return script; -} - -const Variant VisualScriptInstance::get_rpc_config() const { - return script->get_rpc_config(); -} - -void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_owner) { - script = p_script; - owner = p_owner; - source = p_script->get_path(); - - max_input_args = 0; - max_output_args = 0; - - // Setup variables. - { - for (const KeyValue<StringName, VisualScript::Variable> &E : script->variables) { - variables[E.key] = E.value.default_value; - } - } - - // Setup functions from sequence trees. - { - for (const KeyValue<StringName, VisualScript::Function> &E : script->functions) { - const VisualScript::Function &vsfn = E.value; - Function function; - function.node = vsfn.func_id; - function.max_stack = 0; - function.flow_stack_size = 0; - function.pass_stack_size = 0; - function.node_count = 0; - - HashMap<StringName, int> local_var_indices; - - if (function.node < 0) { - VisualScriptLanguage::singleton->debug_break_parse(get_script()->get_path(), 0, "No start node in function: " + String(E.key)); - ERR_CONTINUE(function.node < 0); - } - - { - Ref<VisualScriptFunction> func_node = script->get_node(vsfn.func_id); - - if (func_node.is_null()) { - VisualScriptLanguage::singleton->debug_break_parse(get_script()->get_path(), 0, "No VisualScriptFunction typed start node in function: " + String(E.key)); - } - - ERR_CONTINUE(!func_node.is_valid()); - - function.argument_count = func_node->get_argument_count(); - function.max_stack += function.argument_count; - function.flow_stack_size = func_node->is_stack_less() ? 0 : func_node->get_stack_size(); - max_input_args = MAX(max_input_args, function.argument_count); - } - // Function nodes graphs. - RBSet<VisualScript::SequenceConnection> seqconns; - RBSet<VisualScript::DataConnection> dataconns; - RBSet<int> node_ids; - node_ids.insert(function.node); - { - List<int> nd_queue; - nd_queue.push_back(function.node); - while (!nd_queue.is_empty()) { - for (const VisualScript::SequenceConnection &F : script->sequence_connections) { - if (nd_queue.front()->get() == F.from_node && !node_ids.has(F.to_node)) { - nd_queue.push_back(F.to_node); - node_ids.insert(F.to_node); - } - if (nd_queue.front()->get() == F.from_node && !seqconns.has(F)) { - seqconns.insert(F); - } - } - nd_queue.pop_front(); - } - HashMap<int, HashMap<int, Pair<int, int>>> dc_lut; // :: to -> to_port -> (from, from_port) - for (const VisualScript::DataConnection &F : script->data_connections) { - dc_lut[F.to_node][F.to_port] = Pair<int, int>(F.from_node, F.from_port); - } - for (const int &F : node_ids) { - nd_queue.push_back(F); - } - List<int> dc_keys; - while (!nd_queue.is_empty()) { - int ky = nd_queue.front()->get(); - for (const KeyValue<int, Pair<int, int>> &F : dc_lut[ky]) { - VisualScript::DataConnection dc; - dc.from_node = F.value.first; - dc.from_port = F.value.second; - dc.to_node = ky; - dc.to_port = F.key; - dataconns.insert(dc); - nd_queue.push_back(dc.from_node); - node_ids.insert(dc.from_node); - } - dc_keys.clear(); // Necessary as get_key_list does a push_back not a set. - nd_queue.pop_front(); - } - } - - //Multiple passes are required to set up this complex thing.. - //First create the nodes. - for (const int &F : node_ids) { - Ref<VisualScriptNode> node = script->nodes[F].node; - - VisualScriptNodeInstance *instance = node->instantiate(this); // Create instance. - ERR_FAIL_COND(!instance); - - instance->base = node.ptr(); - - instance->id = F; - instance->input_port_count = node->get_input_value_port_count(); - instance->input_ports = nullptr; - instance->output_port_count = node->get_output_value_port_count(); - instance->output_ports = nullptr; - instance->sequence_output_count = node->get_output_sequence_port_count(); - instance->sequence_index = function.node_count++; - instance->sequence_outputs = nullptr; - instance->pass_idx = -1; - - if (instance->input_port_count) { - instance->input_ports = memnew_arr(int, instance->input_port_count); - for (int i = 0; i < instance->input_port_count; i++) { - instance->input_ports[i] = -1; // If not assigned, will become default value. - } - } - - if (instance->output_port_count) { - instance->output_ports = memnew_arr(int, instance->output_port_count); - for (int i = 0; i < instance->output_port_count; i++) { - instance->output_ports[i] = -1; // If not assigned, will output to trash. - } - } - - if (instance->sequence_output_count) { - instance->sequence_outputs = memnew_arr(VisualScriptNodeInstance *, instance->sequence_output_count); - for (int i = 0; i < instance->sequence_output_count; i++) { - instance->sequence_outputs[i] = nullptr; // If it remains null, flow ends here. - } - } - - if (Object::cast_to<VisualScriptLocalVar>(node.ptr()) || Object::cast_to<VisualScriptLocalVarSet>(*node)) { - // Working memory is shared only for this node, for the same variables. - Ref<VisualScriptLocalVar> vslv = node; - - StringName var_name; - - if (Object::cast_to<VisualScriptLocalVar>(*node)) { - var_name = String(Object::cast_to<VisualScriptLocalVar>(*node)->get_var_name()).strip_edges(); - } else { - var_name = String(Object::cast_to<VisualScriptLocalVarSet>(*node)->get_var_name()).strip_edges(); - } - - if (!local_var_indices.has(var_name)) { - local_var_indices[var_name] = function.max_stack; - function.max_stack++; - } - - instance->working_mem_idx = local_var_indices[var_name]; - - } else if (instance->get_working_memory_size()) { - instance->working_mem_idx = function.max_stack; - function.max_stack += instance->get_working_memory_size(); - } else { - instance->working_mem_idx = -1; //no working mem - } - - max_input_args = MAX(max_input_args, instance->input_port_count); - max_output_args = MAX(max_output_args, instance->output_port_count); - - instances[F] = instance; - } - - function.trash_pos = function.max_stack++; // create pos for trash - - // Second pass, do data connections. - for (const VisualScript::DataConnection &F : dataconns) { - VisualScript::DataConnection dc = F; - ERR_CONTINUE(!instances.has(dc.from_node)); - VisualScriptNodeInstance *from = instances[dc.from_node]; - ERR_CONTINUE(!instances.has(dc.to_node)); - VisualScriptNodeInstance *to = instances[dc.to_node]; - ERR_CONTINUE(dc.from_port >= from->output_port_count); - ERR_CONTINUE(dc.to_port >= to->input_port_count); - - if (from->output_ports[dc.from_port] == -1) { - int stack_pos = function.max_stack++; - from->output_ports[dc.from_port] = stack_pos; - } - - if (from->get_sequence_output_count() == 0 && to->dependencies.find(from) == -1) { - // If the node we are reading from has no output sequence, we must call step() before reading from it. - if (from->pass_idx == -1) { - from->pass_idx = function.pass_stack_size; - function.pass_stack_size++; - } - to->dependencies.push_back(from); - } - - to->input_ports[dc.to_port] = from->output_ports[dc.from_port]; // Read from wherever the stack is. - } - - // Third pass, do sequence connections. - for (const VisualScript::SequenceConnection &F : seqconns) { - VisualScript::SequenceConnection sc = F; - ERR_CONTINUE(!instances.has(sc.from_node)); - VisualScriptNodeInstance *from = instances[sc.from_node]; - ERR_CONTINUE(!instances.has(sc.to_node)); - VisualScriptNodeInstance *to = instances[sc.to_node]; - ERR_CONTINUE(sc.from_output >= from->sequence_output_count); - - from->sequence_outputs[sc.from_output] = to; - } - - //fourth pass: - // 1) unassigned input ports to default values - // 2) connect unassigned output ports to trash - for (const int &F : node_ids) { - ERR_CONTINUE(!instances.has(F)); - - Ref<VisualScriptNode> node = script->nodes[F].node; - VisualScriptNodeInstance *instance = instances[F]; - - // Connect to default values. - for (int i = 0; i < instance->input_port_count; i++) { - if (instance->input_ports[i] == -1) { - // Unassigned, connect to default val. - instance->input_ports[i] = default_values.size() | VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT; - default_values.push_back(node->get_default_input_value(i)); - } - } - - // Connect to trash. - for (int i = 0; i < instance->output_port_count; i++) { - if (instance->output_ports[i] == -1) { - instance->output_ports[i] = function.trash_pos; //trash is same for all - } - } - } - - functions[E.key] = function; - } - } -} - -ScriptLanguage *VisualScriptInstance::get_language() { - return VisualScriptLanguage::singleton; -} - -VisualScriptInstance::VisualScriptInstance() { -} - -VisualScriptInstance::~VisualScriptInstance() { - { - MutexLock lock(VisualScriptLanguage::singleton->lock); - - script->instances.erase(owner); - } - - for (const KeyValue<int, VisualScriptNodeInstance *> &E : instances) { - memdelete(E.value); - } -} - -///////////////////////////////////////////// - -///////////////////// - -Variant VisualScriptFunctionState::_signal_callback(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { - ERR_FAIL_COND_V(function == StringName(), Variant()); - -#ifdef DEBUG_ENABLED - - ERR_FAIL_COND_V_MSG(instance_id.is_valid() && !ObjectDB::get_instance(instance_id), Variant(), "Resumed after yield, but class instance is gone."); - ERR_FAIL_COND_V_MSG(script_id.is_valid() && !ObjectDB::get_instance(script_id), Variant(), "Resumed after yield, but script is gone."); - -#endif - - r_error.error = Callable::CallError::CALL_OK; - - Array args; - - if (p_argcount == 0) { - r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; - r_error.argument = 1; - return Variant(); - } else if (p_argcount == 1) { - //noooneee, reserved for me, me and only me. - } else { - for (int i = 0; i < p_argcount - 1; i++) { - args.push_back(*p_args[i]); - } - } - - Ref<VisualScriptFunctionState> self = *p_args[p_argcount - 1]; //hi, I'm myself, needed this to remain alive. - - if (self.is_null()) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = p_argcount - 1; - r_error.expected = Variant::OBJECT; - return Variant(); - } - - r_error.error = Callable::CallError::CALL_OK; - - Variant *working_mem = ((Variant *)stack.ptr()) + working_mem_index; - - *working_mem = args; // Arguments go to working mem. - - Variant ret = instance->_call_internal(function, stack.ptrw(), stack.size(), node, flow_stack_pos, pass, true, r_error); - function = StringName(); //invalidate - return ret; -} - -void VisualScriptFunctionState::connect_to_signal(Object *p_obj, const String &p_signal, Array p_binds) { - ERR_FAIL_NULL(p_obj); - Vector<Variant> binds; - for (int i = 0; i < p_binds.size(); i++) { - binds.push_back(p_binds[i]); - } - binds.push_back(Ref<VisualScriptFunctionState>(this)); //add myself on the back to avoid dying from unreferencing - - Vector<const Variant *> bind_ptrs; - bind_ptrs.resize(p_binds.size()); - for (int i = 0; i < bind_ptrs.size(); i++) { - bind_ptrs.write[i] = &binds.write[i]; - } - - p_obj->connect(p_signal, Callable(this, "_signal_callback").bindp((const Variant **)bind_ptrs.ptr(), bind_ptrs.size()), CONNECT_ONESHOT); -} - -bool VisualScriptFunctionState::is_valid() const { - return function != StringName(); -} - -Variant VisualScriptFunctionState::resume(Array p_args) { - ERR_FAIL_COND_V(function == StringName(), Variant()); -#ifdef DEBUG_ENABLED - - ERR_FAIL_COND_V_MSG(instance_id.is_valid() && !ObjectDB::get_instance(instance_id), Variant(), "Resumed after yield, but class instance is gone."); - ERR_FAIL_COND_V_MSG(script_id.is_valid() && !ObjectDB::get_instance(script_id), Variant(), "Resumed after yield, but script is gone."); - -#endif - - Callable::CallError r_error; - r_error.error = Callable::CallError::CALL_OK; - - Variant *working_mem = ((Variant *)stack.ptr()) + working_mem_index; - - *working_mem = p_args; // Arguments go to working mem. - - Variant ret = instance->_call_internal(function, stack.ptrw(), stack.size(), node, flow_stack_pos, pass, true, r_error); - function = StringName(); //invalidate - return ret; -} - -void VisualScriptFunctionState::_bind_methods() { - ClassDB::bind_method(D_METHOD("connect_to_signal", "obj", "signals", "args"), &VisualScriptFunctionState::connect_to_signal); - ClassDB::bind_method(D_METHOD("resume", "args"), &VisualScriptFunctionState::resume, DEFVAL(Array())); - ClassDB::bind_method(D_METHOD("is_valid"), &VisualScriptFunctionState::is_valid); - ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "_signal_callback", &VisualScriptFunctionState::_signal_callback, MethodInfo("_signal_callback")); -} - -VisualScriptFunctionState::VisualScriptFunctionState() { -} - -VisualScriptFunctionState::~VisualScriptFunctionState() { - if (function != StringName()) { - Variant *s = ((Variant *)stack.ptr()); - for (int i = 0; i < variant_stack_size; i++) { - s[i].~Variant(); - } - } -} - -/////////////////////////////////////////////// - -String VisualScriptLanguage::get_name() const { - return "VisualScript"; -} - -/* LANGUAGE FUNCTIONS */ -void VisualScriptLanguage::init() { -} - -String VisualScriptLanguage::get_type() const { - return "VisualScript"; -} - -String VisualScriptLanguage::get_extension() const { - return "vs"; -} - -Error VisualScriptLanguage::execute_file(const String &p_path) { - return OK; -} - -void VisualScriptLanguage::finish() { -} - -/* EDITOR FUNCTIONS */ -void VisualScriptLanguage::get_reserved_words(List<String> *p_words) const { -} - -bool VisualScriptLanguage::is_control_flow_keyword(String p_keyword) const { - return false; -} - -void VisualScriptLanguage::get_comment_delimiters(List<String> *p_delimiters) const { -} - -void VisualScriptLanguage::get_string_delimiters(List<String> *p_delimiters) const { -} - -bool VisualScriptLanguage::is_using_templates() { - return false; -} - -Ref<Script> VisualScriptLanguage::make_template(const String &p_template, const String &p_class_name, const String &p_base_class_name) const { - Ref<VisualScript> script; - script.instantiate(); - script->set_instance_base_type(p_base_class_name); - return script; -} - -bool VisualScriptLanguage::validate(const String &p_script, const String &p_path, List<String> *r_functions, List<ScriptLanguage::ScriptError> *r_errors, List<ScriptLanguage::Warning> *r_warnings, HashSet<int> *r_safe_lines) const { - return false; -} - -Script *VisualScriptLanguage::create_script() const { - return memnew(VisualScript); -} - -bool VisualScriptLanguage::has_named_classes() const { - return false; -} - -bool VisualScriptLanguage::supports_builtin_mode() const { - return true; -} - -int VisualScriptLanguage::find_function(const String &p_function, const String &p_code) const { - return -1; -} - -String VisualScriptLanguage::make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const { - return String(); -} - -void VisualScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int p_to_line) const { -} - -void VisualScriptLanguage::add_global_constant(const StringName &p_variable, const Variant &p_value) { -} - -/* DEBUGGER FUNCTIONS */ - -bool VisualScriptLanguage::debug_break_parse(const String &p_file, int p_node, const String &p_error) { - // Break because of parse error. - - if (EngineDebugger::is_active() && Thread::get_caller_id() == Thread::get_main_id()) { - _debug_parse_err_node = p_node; - _debug_parse_err_file = p_file; - _debug_error = p_error; - EngineDebugger::get_script_debugger()->debug(this, false, true); - return true; - } else { - return false; - } -} - -bool VisualScriptLanguage::debug_break(const String &p_error, bool p_allow_continue) { - if (EngineDebugger::is_active() && Thread::get_caller_id() == Thread::get_main_id()) { - _debug_parse_err_node = -1; - _debug_parse_err_file = ""; - _debug_error = p_error; - EngineDebugger::get_script_debugger()->debug(this, p_allow_continue, true); - return true; - } else { - return false; - } -} - -String VisualScriptLanguage::debug_get_error() const { - return _debug_error; -} - -int VisualScriptLanguage::debug_get_stack_level_count() const { - if (_debug_parse_err_node >= 0) { - return 1; - } - - return _debug_call_stack_pos; -} - -int VisualScriptLanguage::debug_get_stack_level_line(int p_level) const { - if (_debug_parse_err_node >= 0) { - return _debug_parse_err_node; - } - - ERR_FAIL_INDEX_V(p_level, _debug_call_stack_pos, -1); - - int l = _debug_call_stack_pos - p_level - 1; - - return *(_call_stack[l].current_id); -} - -String VisualScriptLanguage::debug_get_stack_level_function(int p_level) const { - if (_debug_parse_err_node >= 0) { - return ""; - } - - ERR_FAIL_INDEX_V(p_level, _debug_call_stack_pos, ""); - int l = _debug_call_stack_pos - p_level - 1; - return *_call_stack[l].function; -} - -String VisualScriptLanguage::debug_get_stack_level_source(int p_level) const { - if (_debug_parse_err_node >= 0) { - return _debug_parse_err_file; - } - - ERR_FAIL_INDEX_V(p_level, _debug_call_stack_pos, ""); - int l = _debug_call_stack_pos - p_level - 1; - return _call_stack[l].instance->get_script_ptr()->get_path(); -} - -void VisualScriptLanguage::debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) { - if (_debug_parse_err_node >= 0) { - return; - } - - ERR_FAIL_INDEX(p_level, _debug_call_stack_pos); - - int l = _debug_call_stack_pos - p_level - 1; - const StringName *f = _call_stack[l].function; - - ERR_FAIL_COND(!_call_stack[l].instance->functions.has(*f)); - - VisualScriptNodeInstance *node = _call_stack[l].instance->instances[*_call_stack[l].current_id]; - ERR_FAIL_COND(!node); - - p_locals->push_back("node_name"); - p_values->push_back(node->get_base_node()->get_text()); - - for (int i = 0; i < node->input_port_count; i++) { - String name = node->get_base_node()->get_input_value_port_info(i).name; - if (name.is_empty()) { - name = "in_" + itos(i); - } - - p_locals->push_back("input/" + name); - - //value is trickier - - int in_from = node->input_ports[i]; - int in_value = in_from & VisualScriptNodeInstance::INPUT_MASK; - - if (in_from & VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT) { - p_values->push_back(_call_stack[l].instance->default_values[in_value]); - } else { - p_values->push_back(_call_stack[l].stack[in_value]); - } - } - - for (int i = 0; i < node->output_port_count; i++) { - String name = node->get_base_node()->get_output_value_port_info(i).name; - if (name.is_empty()) { - name = "out_" + itos(i); - } - - p_locals->push_back("output/" + name); - - //value is trickier - - int in_from = node->output_ports[i]; - p_values->push_back(_call_stack[l].stack[in_from]); - } - - for (int i = 0; i < node->get_working_memory_size(); i++) { - p_locals->push_back("working_mem/mem_" + itos(i)); - p_values->push_back((*_call_stack[l].work_mem)[i]); - } -} - -void VisualScriptLanguage::debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems, int p_max_depth) { - if (_debug_parse_err_node >= 0) { - return; - } - - ERR_FAIL_INDEX(p_level, _debug_call_stack_pos); - int l = _debug_call_stack_pos - p_level - 1; - - Ref<VisualScript> vs = _call_stack[l].instance->get_script(); - if (vs.is_null()) { - return; - } - - List<StringName> vars; - vs->get_variable_list(&vars); - for (const StringName &E : vars) { - Variant v; - if (_call_stack[l].instance->get_variable(E, &v)) { - p_members->push_back("variables/" + E); - p_values->push_back(v); - } - } -} - -void VisualScriptLanguage::debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) { - // No globals are really reachable in gdscript. -} - -String VisualScriptLanguage::debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) { - return ""; -} - -void VisualScriptLanguage::reload_all_scripts() { -} - -void VisualScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload) { -} - -/* LOADER FUNCTIONS */ - -void VisualScriptLanguage::get_recognized_extensions(List<String> *p_extensions) const { - p_extensions->push_back("vs"); -} - -void VisualScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const { -} - -void VisualScriptLanguage::get_public_constants(List<Pair<String, Variant>> *p_constants) const { -} - -void VisualScriptLanguage::get_public_annotations(List<MethodInfo> *p_annotations) const { -} - -void VisualScriptLanguage::profiling_start() { -} - -void VisualScriptLanguage::profiling_stop() { -} - -int VisualScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) { - return 0; -} - -int VisualScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) { - return 0; -} - -VisualScriptLanguage *VisualScriptLanguage::singleton = nullptr; - -void VisualScriptLanguage::add_register_func(const String &p_name, VisualScriptNodeRegisterFunc p_func) { - ERR_FAIL_COND(register_funcs.has(p_name)); - register_funcs[p_name] = p_func; -} - -void VisualScriptLanguage::remove_register_func(const String &p_name) { - ERR_FAIL_COND(!register_funcs.has(p_name)); - register_funcs.erase(p_name); -} - -Ref<VisualScriptNode> VisualScriptLanguage::create_node_from_name(const String &p_name) { - ERR_FAIL_COND_V(!register_funcs.has(p_name), Ref<VisualScriptNode>()); - - return register_funcs[p_name](p_name); -} - -void VisualScriptLanguage::get_registered_node_names(List<String> *r_names) { - for (const KeyValue<String, VisualScriptNodeRegisterFunc> &E : register_funcs) { - r_names->push_back(E.key); - } -} - -VisualScriptLanguage::VisualScriptLanguage() { - singleton = this; - - int dmcs = GLOBAL_DEF("debug/settings/visual_script/max_call_stack", 1024); - ProjectSettings::get_singleton()->set_custom_property_info("debug/settings/visual_script/max_call_stack", PropertyInfo(Variant::INT, "debug/settings/visual_script/max_call_stack", PROPERTY_HINT_RANGE, "1024,4096,1,or_greater")); //minimum is 1024 - - if (EngineDebugger::is_active()) { - // Debugging enabled! - _debug_max_call_stack = dmcs; - _call_stack = memnew_arr(CallLevel, _debug_max_call_stack + 1); - - } else { - _debug_max_call_stack = 0; - _call_stack = nullptr; - } -} - -VisualScriptLanguage::~VisualScriptLanguage() { - if (_call_stack) { - memdelete_arr(_call_stack); - } - singleton = nullptr; -} diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h deleted file mode 100644 index d3a90d53fb..0000000000 --- a/modules/visual_script/visual_script.h +++ /dev/null @@ -1,630 +0,0 @@ -/*************************************************************************/ -/* visual_script.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef VISUAL_SCRIPT_H -#define VISUAL_SCRIPT_H - -#include "core/debugger/engine_debugger.h" -#include "core/debugger/script_debugger.h" -#include "core/doc_data.h" -#include "core/object/script_language.h" -#include "core/os/thread.h" -#include "core/templates/rb_set.h" - -class VisualScriptInstance; -class VisualScriptNodeInstance; -class VisualScript; - -class VisualScriptNode : public Resource { - GDCLASS(VisualScriptNode, Resource); - - friend class VisualScript; - - Ref<VisualScript> script_used; - - Array default_input_values; - bool breakpoint = false; - - void _set_default_input_values(Array p_values); - Array _get_default_input_values() const; - - void validate_input_default_values(); - -protected: - void ports_changed_notify(); - static void _bind_methods(); - -public: - Ref<VisualScript> get_visual_script() const; - - virtual int get_output_sequence_port_count() const = 0; - virtual bool has_input_sequence_port() const = 0; - - virtual String get_output_sequence_port_text(int p_port) const = 0; - - virtual bool has_mixed_input_and_sequence_ports() const { return false; } - - virtual int get_input_value_port_count() const = 0; - virtual int get_output_value_port_count() const = 0; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const = 0; - virtual PropertyInfo get_output_value_port_info(int p_idx) const = 0; - - void set_default_input_value(int p_port, const Variant &p_value); - Variant get_default_input_value(int p_port) const; - - virtual String get_caption() const = 0; - virtual String get_text() const; - virtual String get_category() const = 0; - - // Used by editor, this is not really saved. - void set_breakpoint(bool p_breakpoint); - bool is_breakpoint() const; - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) = 0; - - struct TypeGuess { - Variant::Type type = Variant::NIL; - StringName gdclass; - Ref<Script> script; - }; - - virtual TypeGuess guess_output_type(TypeGuess *p_inputs, int p_output) const; - - VisualScriptNode(); -}; - -class VisualScriptNodeInstance { - friend class VisualScriptInstance; - friend class VisualScriptLanguage; // For debugger. - - enum { // Input argument addressing. - INPUT_SHIFT = 1 << 24, - INPUT_MASK = INPUT_SHIFT - 1, - INPUT_DEFAULT_VALUE_BIT = INPUT_SHIFT, // from unassigned input port, using default value (edited by user) - }; - - int id = 0; - int sequence_index = 0; - VisualScriptNodeInstance **sequence_outputs = nullptr; - int sequence_output_count = 0; - Vector<VisualScriptNodeInstance *> dependencies; - int *input_ports = nullptr; - int input_port_count = 0; - int *output_ports = nullptr; - int output_port_count = 0; - int working_mem_idx = 0; - int pass_idx = 0; - - VisualScriptNode *base = nullptr; - -public: - enum StartMode { - START_MODE_BEGIN_SEQUENCE, - START_MODE_CONTINUE_SEQUENCE, - START_MODE_RESUME_YIELD - }; - - enum { - STEP_SHIFT = 1 << 24, - STEP_MASK = STEP_SHIFT - 1, - STEP_FLAG_PUSH_STACK_BIT = STEP_SHIFT, // push bit to stack - STEP_FLAG_GO_BACK_BIT = STEP_SHIFT << 1, // go back to previous node - STEP_NO_ADVANCE_BIT = STEP_SHIFT << 2, // do not advance past this node - STEP_EXIT_FUNCTION_BIT = STEP_SHIFT << 3, // return from function - STEP_YIELD_BIT = STEP_SHIFT << 4, // yield (will find VisualScriptFunctionState state in first working memory) - - FLOW_STACK_PUSHED_BIT = 1 << 30, // in flow stack, means bit was pushed (must go back here if end of sequence) - FLOW_STACK_MASK = FLOW_STACK_PUSHED_BIT - 1 - - }; - - _FORCE_INLINE_ int get_input_port_count() const { return input_port_count; } - _FORCE_INLINE_ int get_output_port_count() const { return output_port_count; } - _FORCE_INLINE_ int get_sequence_output_count() const { return sequence_output_count; } - - _FORCE_INLINE_ int get_id() const { return id; } - - virtual int get_working_memory_size() const { return 0; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) = 0; // Do a step, return which sequence port to go out. - - Ref<VisualScriptNode> get_base_node() { return Ref<VisualScriptNode>(base); } - - VisualScriptNodeInstance(); - virtual ~VisualScriptNodeInstance(); -}; - -class VisualScript : public Script { - GDCLASS(VisualScript, Script); - - RES_BASE_EXTENSION("vs"); - -public: - struct SequenceConnection { - union { - struct { - uint64_t from_node : 24; - uint64_t from_output : 16; - uint64_t to_node : 24; - }; - uint64_t id = 0; - }; - - bool operator<(const SequenceConnection &p_connection) const { - return id < p_connection.id; - } - }; - - struct DataConnection { - union { - struct { - uint64_t from_node : 24; - uint64_t from_port : 8; - uint64_t to_node : 24; - uint64_t to_port : 8; - }; - uint64_t id = 0; - }; - - bool operator<(const DataConnection &p_connection) const { - return id < p_connection.id; - } - }; - -private: - friend class VisualScriptInstance; - - StringName base_type; - struct Argument { - String name; - Variant::Type type = Variant::Type::NIL; - }; - - struct NodeData { - Point2 pos; - Ref<VisualScriptNode> node; - }; - - HashMap<int, NodeData> nodes; // Can be a sparse map. - - RBSet<SequenceConnection> sequence_connections; - RBSet<DataConnection> data_connections; - - Vector2 scroll; - - struct Function { - int func_id; - Function() { func_id = -1; } - }; - - struct Variable { - PropertyInfo info; - Variant default_value; - bool _export = false; - // Add getter & setter options here. - }; - - HashMap<StringName, Function> functions; - HashMap<StringName, Variable> variables; - HashMap<StringName, Vector<Argument>> custom_signals; - Dictionary rpc_functions; - - HashMap<Object *, VisualScriptInstance *> instances; - - bool is_tool_script; - -#ifdef TOOLS_ENABLED - RBSet<PlaceHolderScriptInstance *> placeholders; - // void _update_placeholder(PlaceHolderScriptInstance *p_placeholder); - virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder) override; - void _update_placeholders(); -#endif - - void _set_variable_info(const StringName &p_name, const Dictionary &p_info); - Dictionary _get_variable_info(const StringName &p_name) const; - - void _set_data(const Dictionary &p_data); - Dictionary _get_data() const; - -protected: - void _node_ports_changed(int p_id); - static void _bind_methods(); - -public: - bool inherits_script(const Ref<Script> &p_script) const override; - - void set_scroll(const Vector2 &p_scroll); - Vector2 get_scroll() const; - - void add_function(const StringName &p_name, int p_func_node_id); - bool has_function(const StringName &p_name) const; - void remove_function(const StringName &p_name); - void rename_function(const StringName &p_name, const StringName &p_new_name); - void get_function_list(List<StringName> *r_functions) const; - int get_function_node_id(const StringName &p_name) const; - void set_tool_enabled(bool p_enabled); - - void add_node(int p_id, const Ref<VisualScriptNode> &p_node, const Point2 &p_pos = Point2()); - void remove_node(int p_id); - bool has_node(int p_id) const; - Ref<VisualScriptNode> get_node(int p_id) const; - void set_node_position(int p_id, const Point2 &p_pos); - Point2 get_node_position(int p_id) const; - void get_node_list(List<int> *r_nodes) const; - - void sequence_connect(int p_from_node, int p_from_output, int p_to_node); - void sequence_disconnect(int p_from_node, int p_from_output, int p_to_node); - bool has_sequence_connection(int p_from_node, int p_from_output, int p_to_node) const; - void get_sequence_connection_list(List<SequenceConnection> *r_connection) const; - RBSet<int> get_output_sequence_ports_connected(int from_node); - - void data_connect(int p_from_node, int p_from_port, int p_to_node, int p_to_port); - void data_disconnect(int p_from_node, int p_from_port, int p_to_node, int p_to_port); - bool has_data_connection(int p_from_node, int p_from_port, int p_to_node, int p_to_port) const; - void get_data_connection_list(List<DataConnection> *r_connection) const; - - bool is_input_value_port_connected(int p_node, int p_port) const; - bool get_input_value_port_connection_source(int p_node, int p_port, int *r_node, int *r_port) const; - - void add_variable(const StringName &p_name, const Variant &p_default_value = Variant(), bool p_export = false); - bool has_variable(const StringName &p_name) const; - void remove_variable(const StringName &p_name); - void set_variable_default_value(const StringName &p_name, const Variant &p_value); - Variant get_variable_default_value(const StringName &p_name) const; - void set_variable_info(const StringName &p_name, const PropertyInfo &p_info); - PropertyInfo get_variable_info(const StringName &p_name) const; - void set_variable_export(const StringName &p_name, bool p_export); - bool get_variable_export(const StringName &p_name) const; - void get_variable_list(List<StringName> *r_variables) const; - void rename_variable(const StringName &p_name, const StringName &p_new_name); - - void add_custom_signal(const StringName &p_name); - bool has_custom_signal(const StringName &p_name) const; - void custom_signal_add_argument(const StringName &p_func, Variant::Type p_type, const String &p_name, int p_index = -1); - void custom_signal_set_argument_type(const StringName &p_func, int p_argidx, Variant::Type p_type); - Variant::Type custom_signal_get_argument_type(const StringName &p_func, int p_argidx) const; - void custom_signal_set_argument_name(const StringName &p_func, int p_argidx, const String &p_name); - String custom_signal_get_argument_name(const StringName &p_func, int p_argidx) const; - void custom_signal_remove_argument(const StringName &p_func, int p_argidx); - int custom_signal_get_argument_count(const StringName &p_func) const; - void custom_signal_swap_argument(const StringName &p_func, int p_argidx, int p_with_argidx); - void remove_custom_signal(const StringName &p_name); - void rename_custom_signal(const StringName &p_name, const StringName &p_new_name); - RBSet<int> get_output_sequence_ports_connected(const String &edited_func, int from_node); - - void get_custom_signal_list(List<StringName> *r_custom_signals) const; - - int get_available_id() const; - - void set_instance_base_type(const StringName &p_type); - - virtual bool can_instantiate() const override; - - virtual Ref<Script> get_base_script() const override; - virtual StringName get_instance_base_type() const override; - virtual ScriptInstance *instance_create(Object *p_this) override; - virtual bool instance_has(const Object *p_this) const override; - - virtual bool has_source_code() const override; - virtual String get_source_code() const override; - virtual void set_source_code(const String &p_code) override; - virtual Error reload(bool p_keep_state = false) override; - -#ifdef TOOLS_ENABLED - virtual Vector<DocData::ClassDoc> get_documentation() const override { - Vector<DocData::ClassDoc> docs; - return docs; - } -#endif // TOOLS_ENABLED - - virtual bool is_tool() const override; - virtual bool is_valid() const override; - - virtual ScriptLanguage *get_language() const override; - - virtual bool has_script_signal(const StringName &p_signal) const override; - virtual void get_script_signal_list(List<MethodInfo> *r_signals) const override; - - virtual bool get_property_default_value(const StringName &p_property, Variant &r_value) const override; - virtual void get_script_method_list(List<MethodInfo> *p_list) const override; - - virtual bool has_method(const StringName &p_method) const override; - virtual MethodInfo get_method_info(const StringName &p_method) const override; - - virtual void get_script_property_list(List<PropertyInfo> *p_list) const override; - - virtual int get_member_line(const StringName &p_member) const override; - - virtual const Variant get_rpc_config() const override; - -#ifdef TOOLS_ENABLED - virtual bool are_subnodes_edited() const; -#endif - - VisualScript(); - ~VisualScript(); -}; - -class VisualScriptInstance : public ScriptInstance { - Object *owner = nullptr; - Ref<VisualScript> script; - - HashMap<StringName, Variant> variables; // Using variable path, not script. - HashMap<int, VisualScriptNodeInstance *> instances; - - struct Function { - int node = 0; - int max_stack = 0; - int trash_pos = 0; - int flow_stack_size = 0; - int pass_stack_size = 0; - int node_count = 0; - int argument_count = 0; - }; - - HashMap<StringName, Function> functions; - - Vector<Variant> default_values; - int max_input_args = 0; - int max_output_args = 0; - - StringName source; - - void _dependency_step(VisualScriptNodeInstance *node, int p_pass, int *pass_stack, const Variant **input_args, Variant **output_args, Variant *variant_stack, Callable::CallError &r_error, String &error_str, VisualScriptNodeInstance **r_error_node); - Variant _call_internal(const StringName &p_method, void *p_stack, int p_stack_size, VisualScriptNodeInstance *p_node, int p_flow_stack_pos, int p_pass, bool p_resuming_yield, Callable::CallError &r_error); - - friend class VisualScriptFunctionState; // For yield. - friend class VisualScriptLanguage; // For debugger. -public: - virtual bool set(const StringName &p_name, const Variant &p_value); - virtual bool get(const StringName &p_name, Variant &r_ret) const; - virtual void get_property_list(List<PropertyInfo> *p_properties) const; - virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = nullptr) const; - - virtual bool property_can_revert(const StringName &p_name) const { return false; }; - virtual bool property_get_revert(const StringName &p_name, Variant &r_ret) const { return false; }; - - virtual void get_method_list(List<MethodInfo> *p_list) const; - virtual bool has_method(const StringName &p_method) const; - virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); - virtual void notification(int p_notification); - String to_string(bool *r_valid); - - bool set_variable(const StringName &p_variable, const Variant &p_value) { - HashMap<StringName, Variant>::Iterator E = variables.find(p_variable); - if (!E) { - return false; - } - - E->value = p_value; - return true; - } - - bool get_variable(const StringName &p_variable, Variant *r_variable) const { - HashMap<StringName, Variant>::ConstIterator E = variables.find(p_variable); - if (!E) { - return false; - } - - *r_variable = E->value; - return true; - } - - virtual Ref<Script> get_script() const; - - _FORCE_INLINE_ VisualScript *get_script_ptr() { return script.ptr(); } - _FORCE_INLINE_ Object *get_owner_ptr() { return owner; } - - void create(const Ref<VisualScript> &p_script, Object *p_owner); - - virtual ScriptLanguage *get_language(); - - virtual const Variant get_rpc_config() const; - - VisualScriptInstance(); - ~VisualScriptInstance(); -}; - -class VisualScriptFunctionState : public RefCounted { - GDCLASS(VisualScriptFunctionState, RefCounted); - friend class VisualScriptInstance; - - ObjectID instance_id; - ObjectID script_id; - VisualScriptInstance *instance = nullptr; - StringName function; - Vector<uint8_t> stack; - int working_mem_index = 0; - int variant_stack_size = 0; - VisualScriptNodeInstance *node = nullptr; - int flow_stack_pos = 0; - int pass = 0; - - Variant _signal_callback(const Variant **p_args, int p_argcount, Callable::CallError &r_error); - -protected: - static void _bind_methods(); - -public: - void connect_to_signal(Object *p_obj, const String &p_signal, Array p_binds); - bool is_valid() const; - Variant resume(Array p_args); - VisualScriptFunctionState(); - ~VisualScriptFunctionState(); -}; - -typedef Ref<VisualScriptNode> (*VisualScriptNodeRegisterFunc)(const String &p_type); - -class VisualScriptLanguage : public ScriptLanguage { - HashMap<String, VisualScriptNodeRegisterFunc> register_funcs; - - struct CallLevel { - Variant *stack = nullptr; - Variant **work_mem = nullptr; - const StringName *function = nullptr; - VisualScriptInstance *instance = nullptr; - int *current_id = nullptr; - }; - - int _debug_parse_err_node = -1; - String _debug_parse_err_file = ""; - String _debug_error; - int _debug_call_stack_pos = 0; - int _debug_max_call_stack; - CallLevel *_call_stack = nullptr; - -public: - StringName notification = "_notification"; - StringName _get_output_port_unsequenced; - StringName _step = "_step"; - StringName _subcall = "_subcall"; - - static VisualScriptLanguage *singleton; - - Mutex lock; - - bool debug_break(const String &p_error, bool p_allow_continue = true); - bool debug_break_parse(const String &p_file, int p_node, const String &p_error); - - _FORCE_INLINE_ void enter_function(VisualScriptInstance *p_instance, const StringName *p_function, Variant *p_stack, Variant **p_work_mem, int *current_id) { - if (Thread::get_main_id() != Thread::get_caller_id()) { - return; // No support for other threads than main for now. - } - - if (EngineDebugger::get_script_debugger()->get_lines_left() > 0 && EngineDebugger::get_script_debugger()->get_depth() >= 0) { - EngineDebugger::get_script_debugger()->set_depth(EngineDebugger::get_script_debugger()->get_depth() + 1); - } - - if (_debug_call_stack_pos >= _debug_max_call_stack) { - // Stack overflow. - _debug_error = vformat("Stack overflow (stack size: %s). Check for infinite recursion in your script.", _debug_max_call_stack); - EngineDebugger::get_script_debugger()->debug(this); - return; - } - - _call_stack[_debug_call_stack_pos].stack = p_stack; - _call_stack[_debug_call_stack_pos].instance = p_instance; - _call_stack[_debug_call_stack_pos].function = p_function; - _call_stack[_debug_call_stack_pos].work_mem = p_work_mem; - _call_stack[_debug_call_stack_pos].current_id = current_id; - _debug_call_stack_pos++; - } - - _FORCE_INLINE_ void exit_function() { - if (Thread::get_main_id() != Thread::get_caller_id()) { - return; // No support for other threads than main for now. - } - - if (EngineDebugger::get_script_debugger()->get_lines_left() > 0 && EngineDebugger::get_script_debugger()->get_depth() >= 0) { - EngineDebugger::get_script_debugger()->set_depth(EngineDebugger::get_script_debugger()->get_depth() - 1); - } - - if (_debug_call_stack_pos == 0) { - _debug_error = "Stack underflow (engine bug), please report."; - EngineDebugger::get_script_debugger()->debug(this); - return; - } - - _debug_call_stack_pos--; - } - - ////////////////////////////////////// - - virtual String get_name() const override; - - /* LANGUAGE FUNCTIONS */ - virtual void init() override; - virtual String get_type() const override; - virtual String get_extension() const override; - virtual Error execute_file(const String &p_path) override; - virtual void finish() override; - - /* EDITOR FUNCTIONS */ - virtual void get_reserved_words(List<String> *p_words) const override; - virtual bool is_control_flow_keyword(String p_keyword) const override; - virtual void get_comment_delimiters(List<String> *p_delimiters) const override; - virtual void get_string_delimiters(List<String> *p_delimiters) const override; - virtual bool is_using_templates() override; - virtual Ref<Script> make_template(const String &p_template, const String &p_class_name, const String &p_base_class_name) const override; - virtual bool validate(const String &p_script, const String &p_path = "", List<String> *r_functions = nullptr, List<ScriptLanguage::ScriptError> *r_errors = nullptr, List<ScriptLanguage::Warning> *r_warnings = nullptr, HashSet<int> *r_safe_lines = nullptr) const override; - virtual Script *create_script() const override; - virtual bool has_named_classes() const override; - virtual bool supports_builtin_mode() const override; - virtual int find_function(const String &p_function, const String &p_code) const override; - virtual String make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const override; - virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const override; - virtual void add_global_constant(const StringName &p_variable, const Variant &p_value) override; - - /* DEBUGGER FUNCTIONS */ - - virtual String debug_get_error() const override; - virtual int debug_get_stack_level_count() const override; - virtual int debug_get_stack_level_line(int p_level) const override; - virtual String debug_get_stack_level_function(int p_level) const override; - virtual String debug_get_stack_level_source(int p_level) const override; - virtual void debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) override; - virtual void debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) override; - virtual void debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) override; - virtual String debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems = -1, int p_max_depth = -1) override; - - virtual void reload_all_scripts() override; - virtual void reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload) override; - /* LOADER FUNCTIONS */ - - virtual void get_recognized_extensions(List<String> *p_extensions) const override; - virtual void get_public_functions(List<MethodInfo> *p_functions) const override; - virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const override; - virtual void get_public_annotations(List<MethodInfo> *p_annotations) const override; - - virtual void profiling_start() override; - virtual void profiling_stop() override; - - virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) override; - virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) override; - - void add_register_func(const String &p_name, VisualScriptNodeRegisterFunc p_func); - void remove_register_func(const String &p_name); - Ref<VisualScriptNode> create_node_from_name(const String &p_name); - void get_registered_node_names(List<String> *r_names); - - VisualScriptLanguage(); - ~VisualScriptLanguage(); -}; - -// Aid for registering. -template <class T> -static Ref<VisualScriptNode> create_node_generic(const String &p_name) { - Ref<T> node; - node.instantiate(); - return node; -} - -#endif // VISUAL_SCRIPT_H diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp deleted file mode 100644 index 44e792869d..0000000000 --- a/modules/visual_script/visual_script_builtin_funcs.cpp +++ /dev/null @@ -1,1380 +0,0 @@ -/*************************************************************************/ -/* visual_script_builtin_funcs.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "visual_script_builtin_funcs.h" - -#include "core/io/marshalls.h" -#include "core/math/math_funcs.h" -#include "core/object/class_db.h" -#include "core/object/ref_counted.h" -#include "core/os/os.h" -#include "core/variant/variant_parser.h" - -const char *VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX] = { - "sin", - "cos", - "tan", - "sinh", - "cosh", - "tanh", - "asin", - "acos", - "atan", - "atan2", - "sqrt", - "fmod", - "fposmod", - "floor", - "ceil", - "round", - "abs", - "sign", - "pow", - "log", - "exp", - "is_nan", - "is_inf", - "ease", - "step_decimals", - "snapped", - "lerp", - "cubic_interpolate", - "inverse_lerp", - "range_lerp", - "move_toward", - "randomize", - "randi", - "randf", - "randi_range", - "randf_range", - "randfn", - "seed", - "rand_seed", - "deg2rad", - "rad2deg", - "linear2db", - "db2linear", - "wrapi", - "wrapf", - "pingpong", - "max", - "min", - "clamp", - "nearest_po2", - "weakref", - "convert", - "typeof", - "type_exists", - "char", - "str", - "print", - "printerr", - "printraw", - "print_verbose", - "var2str", - "str2var", - "var2bytes", - "bytes2var", - "smoothstep", - "posmod", - "lerp_angle", - "ord", -}; - -VisualScriptBuiltinFunc::BuiltinFunc VisualScriptBuiltinFunc::find_function(const String &p_string) { - for (int i = 0; i < FUNC_MAX; i++) { - if (p_string == func_name[i]) { - return BuiltinFunc(i); - } - } - - return FUNC_MAX; -} - -String VisualScriptBuiltinFunc::get_func_name(BuiltinFunc p_func) { - ERR_FAIL_INDEX_V(p_func, FUNC_MAX, String()); - return func_name[p_func]; -} - -int VisualScriptBuiltinFunc::get_output_sequence_port_count() const { - return has_input_sequence_port() ? 1 : 0; -} - -bool VisualScriptBuiltinFunc::has_input_sequence_port() const { - switch (func) { - case MATH_RANDOMIZE: - case TEXT_PRINT: - case TEXT_PRINTERR: - case TEXT_PRINTRAW: - case TEXT_PRINT_VERBOSE: - case MATH_SEED: - return true; - default: - return false; - } -} - -int VisualScriptBuiltinFunc::get_func_argument_count(BuiltinFunc p_func) { - switch (p_func) { - case MATH_RANDOMIZE: - case MATH_RANDI: - case MATH_RANDF: - return 0; - case MATH_SIN: - case MATH_COS: - case MATH_TAN: - case MATH_SINH: - case MATH_COSH: - case MATH_TANH: - case MATH_ASIN: - case MATH_ACOS: - case MATH_ATAN: - case MATH_SQRT: - case MATH_FLOOR: - case MATH_CEIL: - case MATH_ROUND: - case MATH_ABS: - case MATH_SIGN: - case MATH_LOG: - case MATH_EXP: - case MATH_ISNAN: - case MATH_ISINF: - case MATH_STEP_DECIMALS: - case MATH_SEED: - case MATH_RANDSEED: - case MATH_DEG2RAD: - case MATH_RAD2DEG: - case MATH_LINEAR2DB: - case MATH_DB2LINEAR: - case LOGIC_NEAREST_PO2: - case OBJ_WEAKREF: - case TYPE_OF: - case TEXT_CHAR: - case TEXT_ORD: - case TEXT_STR: - case TEXT_PRINT: - case TEXT_PRINTERR: - case TEXT_PRINTRAW: - case TEXT_PRINT_VERBOSE: - case VAR_TO_STR: - case STR_TO_VAR: - case TYPE_EXISTS: - return 1; - case VAR_TO_BYTES: - case BYTES_TO_VAR: - case MATH_ATAN2: - case MATH_FMOD: - case MATH_FPOSMOD: - case MATH_POSMOD: - case MATH_PINGPONG: - case MATH_POW: - case MATH_EASE: - case MATH_SNAPPED: - case MATH_RANDI_RANGE: - case MATH_RANDF_RANGE: - case MATH_RANDFN: - case LOGIC_MAX: - case LOGIC_MIN: - case TYPE_CONVERT: - return 2; - case MATH_LERP: - case MATH_LERP_ANGLE: - case MATH_INVERSE_LERP: - case MATH_SMOOTHSTEP: - case MATH_MOVE_TOWARD: - case MATH_WRAP: - case MATH_WRAPF: - case LOGIC_CLAMP: - return 3; - case MATH_CUBIC_INTERPOLATE: - case MATH_RANGE_LERP: - return 5; - case FUNC_MAX: { - } - } - return 0; -} - -int VisualScriptBuiltinFunc::get_input_value_port_count() const { - return get_func_argument_count(func); -} - -int VisualScriptBuiltinFunc::get_output_value_port_count() const { - switch (func) { - case MATH_RANDOMIZE: - case TEXT_PRINT: - case TEXT_PRINTERR: - case TEXT_PRINTRAW: - case TEXT_PRINT_VERBOSE: - case MATH_SEED: - return 0; - case MATH_RANDSEED: - return 2; - default: - return 1; - } - - return 1; -} - -String VisualScriptBuiltinFunc::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const { - switch (func) { - case MATH_SIN: - case MATH_COS: - case MATH_TAN: - case MATH_SINH: - case MATH_COSH: - case MATH_TANH: - case MATH_ASIN: - case MATH_ACOS: - case MATH_ATAN: - case MATH_SQRT: - case MATH_FLOOR: - case MATH_CEIL: - case MATH_ROUND: - case MATH_ABS: - case MATH_SIGN: - case MATH_LOG: - case MATH_EXP: - case MATH_ISNAN: - case MATH_ISINF: { - return PropertyInfo(Variant::FLOAT, "s"); - } break; - case MATH_ATAN2: { - if (p_idx == 0) { - return PropertyInfo(Variant::FLOAT, "y"); - } else { - return PropertyInfo(Variant::FLOAT, "x"); - } - } break; - case MATH_FMOD: - case MATH_FPOSMOD: - case LOGIC_MAX: - case LOGIC_MIN: { - if (p_idx == 0) { - return PropertyInfo(Variant::FLOAT, "a"); - } else { - return PropertyInfo(Variant::FLOAT, "b"); - } - } break; - case MATH_POSMOD: { - if (p_idx == 0) { - return PropertyInfo(Variant::INT, "a"); - } else { - return PropertyInfo(Variant::INT, "b"); - } - } break; - case MATH_POW: { - if (p_idx == 0) { - return PropertyInfo(Variant::FLOAT, "base"); - } else { - return PropertyInfo(Variant::FLOAT, "exp"); - } - } break; - case MATH_EASE: { - if (p_idx == 0) { - return PropertyInfo(Variant::FLOAT, "s"); - } else { - return PropertyInfo(Variant::FLOAT, "curve"); - } - } break; - case MATH_STEP_DECIMALS: { - return PropertyInfo(Variant::FLOAT, "step"); - } break; - case MATH_SNAPPED: { - if (p_idx == 0) { - return PropertyInfo(Variant::FLOAT, "s"); - } else { - return PropertyInfo(Variant::FLOAT, "steps"); - } - } break; - case MATH_LERP: - case MATH_LERP_ANGLE: - case MATH_INVERSE_LERP: - case MATH_SMOOTHSTEP: { - if (p_idx == 0) { - return PropertyInfo(Variant::FLOAT, "from"); - } else if (p_idx == 1) { - return PropertyInfo(Variant::FLOAT, "to"); - } else { - return PropertyInfo(Variant::FLOAT, "weight"); - } - } break; - case MATH_CUBIC_INTERPOLATE: { - if (p_idx == 0) { - return PropertyInfo(Variant::FLOAT, "from"); - } else if (p_idx == 1) { - return PropertyInfo(Variant::FLOAT, "to"); - } else if (p_idx == 2) { - return PropertyInfo(Variant::FLOAT, "pre"); - } else if (p_idx == 3) { - return PropertyInfo(Variant::FLOAT, "post"); - } else { - return PropertyInfo(Variant::FLOAT, "weight"); - } - } break; - case MATH_RANGE_LERP: { - if (p_idx == 0) { - return PropertyInfo(Variant::FLOAT, "value"); - } else if (p_idx == 1) { - return PropertyInfo(Variant::FLOAT, "istart"); - } else if (p_idx == 2) { - return PropertyInfo(Variant::FLOAT, "istop"); - } else if (p_idx == 3) { - return PropertyInfo(Variant::FLOAT, "ostart"); - } else { - return PropertyInfo(Variant::FLOAT, "ostop"); - } - } break; - case MATH_MOVE_TOWARD: { - if (p_idx == 0) { - return PropertyInfo(Variant::FLOAT, "from"); - } else if (p_idx == 1) { - return PropertyInfo(Variant::FLOAT, "to"); - } else { - return PropertyInfo(Variant::FLOAT, "delta"); - } - } break; - case MATH_RANDOMIZE: - case MATH_RANDI: - case MATH_RANDF: { - } break; - case MATH_RANDI_RANGE: { - if (p_idx == 0) { - return PropertyInfo(Variant::INT, "from"); - } else { - return PropertyInfo(Variant::INT, "to"); - } - } break; - case MATH_RANDF_RANGE: { - if (p_idx == 0) { - return PropertyInfo(Variant::FLOAT, "from"); - } else { - return PropertyInfo(Variant::FLOAT, "to"); - } - } break; - case MATH_RANDFN: { - if (p_idx == 0) { - return PropertyInfo(Variant::FLOAT, "mean"); - } else { - return PropertyInfo(Variant::FLOAT, "deviation"); - } - } break; - case MATH_SEED: - case MATH_RANDSEED: { - return PropertyInfo(Variant::INT, "seed"); - } break; - case MATH_DEG2RAD: { - return PropertyInfo(Variant::FLOAT, "deg"); - } break; - case MATH_RAD2DEG: { - return PropertyInfo(Variant::FLOAT, "rad"); - } break; - case MATH_LINEAR2DB: { - return PropertyInfo(Variant::FLOAT, "nrg"); - } break; - case MATH_DB2LINEAR: { - return PropertyInfo(Variant::FLOAT, "db"); - } break; - case MATH_PINGPONG: { - if (p_idx == 0) { - return PropertyInfo(Variant::FLOAT, "value"); - } else { - return PropertyInfo(Variant::FLOAT, "length"); - } - } break; - case MATH_WRAP: { - if (p_idx == 0) { - return PropertyInfo(Variant::INT, "value"); - } else if (p_idx == 1) { - return PropertyInfo(Variant::INT, "min"); - } else { - return PropertyInfo(Variant::INT, "max"); - } - } break; - case MATH_WRAPF: - case LOGIC_CLAMP: { - if (p_idx == 0) { - return PropertyInfo(Variant::FLOAT, "value"); - } else if (p_idx == 1) { - return PropertyInfo(Variant::FLOAT, "min"); - } else { - return PropertyInfo(Variant::FLOAT, "max"); - } - } break; - case LOGIC_NEAREST_PO2: { - return PropertyInfo(Variant::INT, "value"); - } break; - case OBJ_WEAKREF: { - return PropertyInfo(Variant::OBJECT, "source"); - } break; - case TYPE_CONVERT: { - if (p_idx == 0) { - return PropertyInfo(Variant::NIL, "what"); - } else { - return PropertyInfo(Variant::STRING, "type"); - } - } break; - case TYPE_OF: { - return PropertyInfo(Variant::NIL, "what"); - } break; - case TYPE_EXISTS: { - return PropertyInfo(Variant::STRING, "type"); - } break; - case TEXT_ORD: { - return PropertyInfo(Variant::STRING, "character"); - } break; - case TEXT_CHAR: { - return PropertyInfo(Variant::INT, "ascii"); - } break; - case TEXT_STR: - case TEXT_PRINT: - case TEXT_PRINTERR: - case TEXT_PRINTRAW: - case TEXT_PRINT_VERBOSE: { - return PropertyInfo(Variant::NIL, "value"); - } break; - case STR_TO_VAR: { - return PropertyInfo(Variant::STRING, "string"); - } break; - case VAR_TO_STR: - case VAR_TO_BYTES: { - if (p_idx == 0) { - return PropertyInfo(Variant::NIL, "var"); - } else { - return PropertyInfo(Variant::BOOL, "full_objects"); - } - - } break; - case BYTES_TO_VAR: { - if (p_idx == 0) { - return PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytes"); - } else { - return PropertyInfo(Variant::BOOL, "allow_objects"); - } - } break; - case FUNC_MAX: { - } - } - - return PropertyInfo(); -} - -PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) const { - Variant::Type t = Variant::NIL; - switch (func) { - case MATH_SIN: - case MATH_COS: - case MATH_TAN: - case MATH_SINH: - case MATH_COSH: - case MATH_TANH: - case MATH_ASIN: - case MATH_ACOS: - case MATH_ATAN: - case MATH_ATAN2: - case MATH_SQRT: - case MATH_FMOD: - case MATH_FPOSMOD: - case MATH_FLOOR: - case MATH_CEIL: { - t = Variant::FLOAT; - } break; - case MATH_POSMOD: { - t = Variant::INT; - } break; - case MATH_ROUND: { - t = Variant::FLOAT; - } break; - case MATH_ABS: { - t = Variant::NIL; - } break; - case MATH_SIGN: { - t = Variant::NIL; - } break; - case MATH_POW: - case MATH_LOG: - case MATH_EXP: { - t = Variant::FLOAT; - } break; - case MATH_ISNAN: - case MATH_ISINF: { - t = Variant::BOOL; - } break; - case MATH_EASE: { - t = Variant::FLOAT; - } break; - case MATH_STEP_DECIMALS: { - t = Variant::INT; - } break; - case MATH_SNAPPED: - case MATH_LERP: - case MATH_CUBIC_INTERPOLATE: - case MATH_LERP_ANGLE: - case MATH_INVERSE_LERP: - case MATH_RANGE_LERP: - case MATH_SMOOTHSTEP: - case MATH_MOVE_TOWARD: - case MATH_RANDOMIZE: { - } break; - case MATH_RANDI: { - t = Variant::INT; - } break; - case MATH_RANDF: - case MATH_RANDFN: - case MATH_RANDF_RANGE: { - t = Variant::FLOAT; - } break; - case MATH_RANDI_RANGE: { - t = Variant::INT; - } break; - case MATH_SEED: { - } break; - case MATH_RANDSEED: { - if (p_idx == 0) { - return PropertyInfo(Variant::INT, "rnd"); - } else { - return PropertyInfo(Variant::INT, "seed"); - } - } break; - case MATH_DEG2RAD: - case MATH_RAD2DEG: - case MATH_LINEAR2DB: - case MATH_WRAPF: - case MATH_PINGPONG: - case MATH_DB2LINEAR: { - t = Variant::FLOAT; - } break; - case MATH_WRAP: { - t = Variant::INT; - } break; - case LOGIC_MAX: - case LOGIC_MIN: - case LOGIC_CLAMP: { - } break; - - case LOGIC_NEAREST_PO2: { - t = Variant::NIL; - } break; - case OBJ_WEAKREF: { - t = Variant::OBJECT; - - } break; - case TYPE_CONVERT: { - } break; - case TEXT_ORD: - case TYPE_OF: { - t = Variant::INT; - - } break; - case TYPE_EXISTS: { - t = Variant::BOOL; - - } break; - case TEXT_CHAR: - case TEXT_STR: { - t = Variant::STRING; - - } break; - case TEXT_PRINT: { - } break; - case TEXT_PRINTERR: { - } break; - case TEXT_PRINTRAW: { - } break; - case TEXT_PRINT_VERBOSE: { - } break; - case VAR_TO_STR: { - t = Variant::STRING; - } break; - case STR_TO_VAR: { - } break; - case VAR_TO_BYTES: { - if (p_idx == 0) { - t = Variant::PACKED_BYTE_ARRAY; - } else { - t = Variant::BOOL; - } - - } break; - case BYTES_TO_VAR: { - if (p_idx == 1) { - t = Variant::BOOL; - } - } break; - case FUNC_MAX: { - } - } - - return PropertyInfo(t, ""); -} - -/* -String VisualScriptBuiltinFunc::get_caption() const { - return "BuiltinFunc"; -} - -*/ - -String VisualScriptBuiltinFunc::get_caption() const { - return func_name[func]; -} - -void VisualScriptBuiltinFunc::set_func(BuiltinFunc p_which) { - ERR_FAIL_INDEX(p_which, FUNC_MAX); - func = p_which; - notify_property_list_changed(); - ports_changed_notify(); -} - -VisualScriptBuiltinFunc::BuiltinFunc VisualScriptBuiltinFunc::get_func() { - return func; -} - -#define VALIDATE_ARG_NUM(m_arg) \ - if (!p_inputs[m_arg]->is_num()) { \ - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; \ - r_error.argument = m_arg; \ - r_error.expected = Variant::FLOAT; \ - return; \ - } - -void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Callable::CallError &r_error, String &r_error_str) { - switch (p_func) { - case VisualScriptBuiltinFunc::MATH_SIN: { - VALIDATE_ARG_NUM(0); - *r_return = Math::sin((double)*p_inputs[0]); - } break; - case VisualScriptBuiltinFunc::MATH_COS: { - VALIDATE_ARG_NUM(0); - *r_return = Math::cos((double)*p_inputs[0]); - } break; - case VisualScriptBuiltinFunc::MATH_TAN: { - VALIDATE_ARG_NUM(0); - *r_return = Math::tan((double)*p_inputs[0]); - } break; - case VisualScriptBuiltinFunc::MATH_SINH: { - VALIDATE_ARG_NUM(0); - *r_return = Math::sinh((double)*p_inputs[0]); - } break; - case VisualScriptBuiltinFunc::MATH_COSH: { - VALIDATE_ARG_NUM(0); - *r_return = Math::cosh((double)*p_inputs[0]); - } break; - case VisualScriptBuiltinFunc::MATH_TANH: { - VALIDATE_ARG_NUM(0); - *r_return = Math::tanh((double)*p_inputs[0]); - } break; - case VisualScriptBuiltinFunc::MATH_ASIN: { - VALIDATE_ARG_NUM(0); - *r_return = Math::asin((double)*p_inputs[0]); - } break; - case VisualScriptBuiltinFunc::MATH_ACOS: { - VALIDATE_ARG_NUM(0); - *r_return = Math::acos((double)*p_inputs[0]); - } break; - case VisualScriptBuiltinFunc::MATH_ATAN: { - VALIDATE_ARG_NUM(0); - *r_return = Math::atan((double)*p_inputs[0]); - } break; - case VisualScriptBuiltinFunc::MATH_ATAN2: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - *r_return = Math::atan2((double)*p_inputs[0], (double)*p_inputs[1]); - } break; - case VisualScriptBuiltinFunc::MATH_SQRT: { - VALIDATE_ARG_NUM(0); - *r_return = Math::sqrt((double)*p_inputs[0]); - } break; - case VisualScriptBuiltinFunc::MATH_FMOD: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - *r_return = Math::fmod((double)*p_inputs[0], (double)*p_inputs[1]); - } break; - case VisualScriptBuiltinFunc::MATH_FPOSMOD: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - *r_return = Math::fposmod((double)*p_inputs[0], (double)*p_inputs[1]); - } break; - case VisualScriptBuiltinFunc::MATH_POSMOD: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - *r_return = Math::posmod((int64_t)*p_inputs[0], (int64_t)*p_inputs[1]); - } break; - case VisualScriptBuiltinFunc::MATH_FLOOR: { - VALIDATE_ARG_NUM(0); - *r_return = Math::floor((double)*p_inputs[0]); - } break; - case VisualScriptBuiltinFunc::MATH_CEIL: { - VALIDATE_ARG_NUM(0); - *r_return = Math::ceil((double)*p_inputs[0]); - } break; - case VisualScriptBuiltinFunc::MATH_ROUND: { - VALIDATE_ARG_NUM(0); - *r_return = Math::round((double)*p_inputs[0]); - } break; - case VisualScriptBuiltinFunc::MATH_ABS: { - if (p_inputs[0]->get_type() == Variant::INT) { - int64_t i = *p_inputs[0]; - *r_return = ABS(i); - } else if (p_inputs[0]->get_type() == Variant::FLOAT) { - real_t r = *p_inputs[0]; - *r_return = Math::abs(r); - } else { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::FLOAT; - } - } break; - case VisualScriptBuiltinFunc::MATH_SIGN: { - if (p_inputs[0]->get_type() == Variant::INT) { - int64_t i = *p_inputs[0]; - *r_return = i < 0 ? -1 : (i > 0 ? +1 : 0); - } else if (p_inputs[0]->get_type() == Variant::FLOAT) { - real_t r = *p_inputs[0]; - *r_return = r < 0.0 ? -1.0 : (r > 0.0 ? +1.0 : 0.0); - } else { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::FLOAT; - } - } break; - case VisualScriptBuiltinFunc::MATH_POW: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - *r_return = Math::pow((double)*p_inputs[0], (double)*p_inputs[1]); - } break; - case VisualScriptBuiltinFunc::MATH_LOG: { - VALIDATE_ARG_NUM(0); - *r_return = Math::log((double)*p_inputs[0]); - } break; - case VisualScriptBuiltinFunc::MATH_EXP: { - VALIDATE_ARG_NUM(0); - *r_return = Math::exp((double)*p_inputs[0]); - } break; - case VisualScriptBuiltinFunc::MATH_ISNAN: { - VALIDATE_ARG_NUM(0); - *r_return = Math::is_nan((double)*p_inputs[0]); - } break; - case VisualScriptBuiltinFunc::MATH_ISINF: { - VALIDATE_ARG_NUM(0); - *r_return = Math::is_inf((double)*p_inputs[0]); - } break; - case VisualScriptBuiltinFunc::MATH_EASE: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - *r_return = Math::ease((double)*p_inputs[0], (double)*p_inputs[1]); - } break; - case VisualScriptBuiltinFunc::MATH_STEP_DECIMALS: { - VALIDATE_ARG_NUM(0); - *r_return = Math::step_decimals((double)*p_inputs[0]); - } break; - case VisualScriptBuiltinFunc::MATH_SNAPPED: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - *r_return = Math::snapped((double)*p_inputs[0], (double)*p_inputs[1]); - } break; - case VisualScriptBuiltinFunc::MATH_LERP: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - VALIDATE_ARG_NUM(2); - *r_return = Math::lerp((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]); - } break; - case VisualScriptBuiltinFunc::MATH_CUBIC_INTERPOLATE: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - VALIDATE_ARG_NUM(2); - VALIDATE_ARG_NUM(3); - VALIDATE_ARG_NUM(4); - *r_return = Math::cubic_interpolate((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2], (double)*p_inputs[3], (double)*p_inputs[4]); - } break; - case VisualScriptBuiltinFunc::MATH_LERP_ANGLE: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - VALIDATE_ARG_NUM(2); - *r_return = Math::lerp_angle((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]); - } break; - case VisualScriptBuiltinFunc::MATH_INVERSE_LERP: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - VALIDATE_ARG_NUM(2); - *r_return = Math::inverse_lerp((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]); - } break; - case VisualScriptBuiltinFunc::MATH_RANGE_LERP: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - VALIDATE_ARG_NUM(2); - VALIDATE_ARG_NUM(3); - VALIDATE_ARG_NUM(4); - *r_return = Math::range_lerp((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2], (double)*p_inputs[3], (double)*p_inputs[4]); - } break; - case VisualScriptBuiltinFunc::MATH_SMOOTHSTEP: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - VALIDATE_ARG_NUM(2); - *r_return = Math::smoothstep((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]); - } break; - case VisualScriptBuiltinFunc::MATH_MOVE_TOWARD: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - VALIDATE_ARG_NUM(2); - *r_return = Math::move_toward((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]); - } break; - case VisualScriptBuiltinFunc::MATH_RANDOMIZE: { - Math::randomize(); - - } break; - case VisualScriptBuiltinFunc::MATH_RANDI: { - *r_return = Math::rand(); - } break; - case VisualScriptBuiltinFunc::MATH_RANDF: { - *r_return = Math::randf(); - } break; - case VisualScriptBuiltinFunc::MATH_RANDI_RANGE: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - *r_return = Math::random((int)*p_inputs[0], (int)*p_inputs[1]); - } break; - case VisualScriptBuiltinFunc::MATH_RANDF_RANGE: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - *r_return = Math::random((double)*p_inputs[0], (double)*p_inputs[1]); - } break; - case VisualScriptBuiltinFunc::MATH_RANDFN: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - *r_return = Math::randfn((double)*p_inputs[0], (double)*p_inputs[1]); - } break; - case VisualScriptBuiltinFunc::MATH_SEED: { - VALIDATE_ARG_NUM(0); - uint64_t seed = *p_inputs[0]; - Math::seed(seed); - - } break; - case VisualScriptBuiltinFunc::MATH_RANDSEED: { - VALIDATE_ARG_NUM(0); - uint64_t seed = *p_inputs[0]; - int ret = Math::rand_from_seed(&seed); - Array reta; - reta.push_back(ret); - reta.push_back(seed); - *r_return = reta; - - } break; - case VisualScriptBuiltinFunc::MATH_DEG2RAD: { - VALIDATE_ARG_NUM(0); - *r_return = Math::deg2rad((double)*p_inputs[0]); - } break; - case VisualScriptBuiltinFunc::MATH_RAD2DEG: { - VALIDATE_ARG_NUM(0); - *r_return = Math::rad2deg((double)*p_inputs[0]); - } break; - case VisualScriptBuiltinFunc::MATH_LINEAR2DB: { - VALIDATE_ARG_NUM(0); - *r_return = Math::linear2db((double)*p_inputs[0]); - } break; - case VisualScriptBuiltinFunc::MATH_DB2LINEAR: { - VALIDATE_ARG_NUM(0); - *r_return = Math::db2linear((double)*p_inputs[0]); - } break; - case VisualScriptBuiltinFunc::MATH_PINGPONG: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - *r_return = Math::pingpong((double)*p_inputs[0], (double)*p_inputs[1]); - } break; - case VisualScriptBuiltinFunc::MATH_WRAP: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - VALIDATE_ARG_NUM(2); - *r_return = Math::wrapi((int64_t)*p_inputs[0], (int64_t)*p_inputs[1], (int64_t)*p_inputs[2]); - } break; - case VisualScriptBuiltinFunc::MATH_WRAPF: { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - VALIDATE_ARG_NUM(2); - *r_return = Math::wrapf((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]); - } break; - case VisualScriptBuiltinFunc::LOGIC_MAX: { - if (p_inputs[0]->get_type() == Variant::INT && p_inputs[1]->get_type() == Variant::INT) { - int64_t a = *p_inputs[0]; - int64_t b = *p_inputs[1]; - *r_return = MAX(a, b); - } else { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - - real_t a = *p_inputs[0]; - real_t b = *p_inputs[1]; - - *r_return = MAX(a, b); - } - - } break; - case VisualScriptBuiltinFunc::LOGIC_MIN: { - if (p_inputs[0]->get_type() == Variant::INT && p_inputs[1]->get_type() == Variant::INT) { - int64_t a = *p_inputs[0]; - int64_t b = *p_inputs[1]; - *r_return = MIN(a, b); - } else { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - - real_t a = *p_inputs[0]; - real_t b = *p_inputs[1]; - - *r_return = MIN(a, b); - } - } break; - case VisualScriptBuiltinFunc::LOGIC_CLAMP: { - if (p_inputs[0]->get_type() == Variant::INT && p_inputs[1]->get_type() == Variant::INT && p_inputs[2]->get_type() == Variant::INT) { - int64_t a = *p_inputs[0]; - int64_t b = *p_inputs[1]; - int64_t c = *p_inputs[2]; - *r_return = CLAMP(a, b, c); - } else { - VALIDATE_ARG_NUM(0); - VALIDATE_ARG_NUM(1); - VALIDATE_ARG_NUM(2); - - real_t a = *p_inputs[0]; - real_t b = *p_inputs[1]; - real_t c = *p_inputs[2]; - - *r_return = CLAMP(a, b, c); - } - } break; - case VisualScriptBuiltinFunc::LOGIC_NEAREST_PO2: { - VALIDATE_ARG_NUM(0); - int64_t num = *p_inputs[0]; - *r_return = next_power_of_2(num); - } break; - case VisualScriptBuiltinFunc::OBJ_WEAKREF: { - if (p_inputs[0]->get_type() != Variant::OBJECT) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::OBJECT; - - return; - } - - if (p_inputs[0]->is_ref_counted()) { - Ref<RefCounted> r = *p_inputs[0]; - if (!r.is_valid()) { - return; - } - - Ref<WeakRef> wref = memnew(WeakRef); - wref->set_ref(r); - *r_return = wref; - } else { - Object *obj = *p_inputs[0]; - if (!obj) { - return; - } - Ref<WeakRef> wref = memnew(WeakRef); - wref->set_obj(obj); - *r_return = wref; - } - - } break; - case VisualScriptBuiltinFunc::TYPE_CONVERT: { - VALIDATE_ARG_NUM(1); - int type = *p_inputs[1]; - if (type < 0 || type >= Variant::VARIANT_MAX) { - r_error_str = RTR("Invalid type argument to convert(), use TYPE_* constants."); - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::INT; - return; - - } else { - Variant::construct(Variant::Type(type), *r_return, p_inputs, 1, r_error); - } - } break; - case VisualScriptBuiltinFunc::TYPE_OF: { - *r_return = p_inputs[0]->get_type(); - - } break; - case VisualScriptBuiltinFunc::TYPE_EXISTS: { - *r_return = ClassDB::class_exists(*p_inputs[0]); - - } break; - case VisualScriptBuiltinFunc::TEXT_CHAR: { - char32_t result[2] = { *p_inputs[0], 0 }; - - *r_return = String(result); - - } break; - case VisualScriptBuiltinFunc::TEXT_ORD: { - if (p_inputs[0]->get_type() != Variant::STRING) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::STRING; - - return; - } - - String str = p_inputs[0]->operator String(); - - if (str.length() != 1) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::STRING; - *r_return = "Expected a string of length 1 (a character)."; - - return; - } - - *r_return = str.get(0); - - } break; - case VisualScriptBuiltinFunc::TEXT_STR: { - String str = *p_inputs[0]; - - *r_return = str; - - } break; - case VisualScriptBuiltinFunc::TEXT_PRINT: { - String str = *p_inputs[0]; - print_line(str); - - } break; - - case VisualScriptBuiltinFunc::TEXT_PRINTERR: { - String str = *p_inputs[0]; - print_error(str); - - } break; - case VisualScriptBuiltinFunc::TEXT_PRINTRAW: { - String str = *p_inputs[0]; - OS::get_singleton()->print("%s", str.utf8().get_data()); - - } break; - case VisualScriptBuiltinFunc::TEXT_PRINT_VERBOSE: { - String str = *p_inputs[0]; - print_verbose(str); - } break; - case VisualScriptBuiltinFunc::VAR_TO_STR: { - String vars; - VariantWriter::write_to_string(*p_inputs[0], vars); - *r_return = vars; - } break; - case VisualScriptBuiltinFunc::STR_TO_VAR: { - if (p_inputs[0]->get_type() != Variant::STRING) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::STRING; - - return; - } - - VariantParser::StreamString ss; - ss.s = *p_inputs[0]; - - String errs; - int line; - Error err = VariantParser::parse(&ss, *r_return, errs, line); - - if (err != OK) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::STRING; - *r_return = "Parse error at line " + itos(line) + ": " + errs; - return; - } - - } break; - case VisualScriptBuiltinFunc::VAR_TO_BYTES: { - if (p_inputs[1]->get_type() != Variant::BOOL) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 1; - r_error.expected = Variant::BOOL; - return; - } - PackedByteArray barr; - int len; - bool full_objects = *p_inputs[1]; - Error err = encode_variant(*p_inputs[0], nullptr, len, full_objects); - if (err) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::NIL; - r_error_str = "Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID)."; - return; - } - - barr.resize(len); - { - uint8_t *w = barr.ptrw(); - encode_variant(*p_inputs[0], w, len, full_objects); - } - *r_return = barr; - } break; - case VisualScriptBuiltinFunc::BYTES_TO_VAR: { - if (p_inputs[0]->get_type() != Variant::PACKED_BYTE_ARRAY) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::PACKED_BYTE_ARRAY; - return; - } - if (p_inputs[1]->get_type() != Variant::BOOL) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 1; - r_error.expected = Variant::BOOL; - return; - } - - PackedByteArray varr = *p_inputs[0]; - bool allow_objects = *p_inputs[1]; - Variant ret; - { - const uint8_t *r = varr.ptr(); - Error err = decode_variant(ret, r, varr.size(), nullptr, allow_objects); - if (err != OK) { - r_error_str = RTR("Not enough bytes for decoding bytes, or invalid format."); - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::PACKED_BYTE_ARRAY; - return; - } - } - - *r_return = ret; - - } break; - default: { - } - } -} - -class VisualScriptNodeInstanceBuiltinFunc : public VisualScriptNodeInstance { -public: - VisualScriptBuiltinFunc *node = nullptr; - VisualScriptInstance *instance = nullptr; - - VisualScriptBuiltinFunc::BuiltinFunc func; - - //virtual int get_working_memory_size() const override { return 0; } - //virtual bool is_output_port_unsequenced(int p_idx) const { return false; } - //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - VisualScriptBuiltinFunc::exec_func(func, p_inputs, p_outputs[0], r_error, r_error_str); - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptBuiltinFunc::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceBuiltinFunc *instance = memnew(VisualScriptNodeInstanceBuiltinFunc); - instance->node = this; - instance->instance = p_instance; - instance->func = func; - return instance; -} - -void VisualScriptBuiltinFunc::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_func", "which"), &VisualScriptBuiltinFunc::set_func); - ClassDB::bind_method(D_METHOD("get_func"), &VisualScriptBuiltinFunc::get_func); - - String cc; - - for (int i = 0; i < FUNC_MAX; i++) { - if (i > 0) { - cc += ","; - } - cc += func_name[i]; - } - ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, cc), "set_func", "get_func"); - - BIND_ENUM_CONSTANT(MATH_SIN); - BIND_ENUM_CONSTANT(MATH_COS); - BIND_ENUM_CONSTANT(MATH_TAN); - BIND_ENUM_CONSTANT(MATH_SINH); - BIND_ENUM_CONSTANT(MATH_COSH); - BIND_ENUM_CONSTANT(MATH_TANH); - BIND_ENUM_CONSTANT(MATH_ASIN); - BIND_ENUM_CONSTANT(MATH_ACOS); - BIND_ENUM_CONSTANT(MATH_ATAN); - BIND_ENUM_CONSTANT(MATH_ATAN2); - BIND_ENUM_CONSTANT(MATH_SQRT); - BIND_ENUM_CONSTANT(MATH_FMOD); - BIND_ENUM_CONSTANT(MATH_FPOSMOD); - BIND_ENUM_CONSTANT(MATH_FLOOR); - BIND_ENUM_CONSTANT(MATH_CEIL); - BIND_ENUM_CONSTANT(MATH_ROUND); - BIND_ENUM_CONSTANT(MATH_ABS); - BIND_ENUM_CONSTANT(MATH_SIGN); - BIND_ENUM_CONSTANT(MATH_POW); - BIND_ENUM_CONSTANT(MATH_LOG); - BIND_ENUM_CONSTANT(MATH_EXP); - BIND_ENUM_CONSTANT(MATH_ISNAN); - BIND_ENUM_CONSTANT(MATH_ISINF); - BIND_ENUM_CONSTANT(MATH_EASE); - BIND_ENUM_CONSTANT(MATH_STEP_DECIMALS); - BIND_ENUM_CONSTANT(MATH_SNAPPED); - BIND_ENUM_CONSTANT(MATH_LERP); - BIND_ENUM_CONSTANT(MATH_CUBIC_INTERPOLATE); - BIND_ENUM_CONSTANT(MATH_INVERSE_LERP); - BIND_ENUM_CONSTANT(MATH_RANGE_LERP); - BIND_ENUM_CONSTANT(MATH_MOVE_TOWARD); - BIND_ENUM_CONSTANT(MATH_RANDOMIZE); - BIND_ENUM_CONSTANT(MATH_RANDI); - BIND_ENUM_CONSTANT(MATH_RANDF); - BIND_ENUM_CONSTANT(MATH_RANDI_RANGE); - BIND_ENUM_CONSTANT(MATH_RANDF_RANGE); - BIND_ENUM_CONSTANT(MATH_RANDFN); - BIND_ENUM_CONSTANT(MATH_SEED); - BIND_ENUM_CONSTANT(MATH_RANDSEED); - BIND_ENUM_CONSTANT(MATH_DEG2RAD); - BIND_ENUM_CONSTANT(MATH_RAD2DEG); - BIND_ENUM_CONSTANT(MATH_LINEAR2DB); - BIND_ENUM_CONSTANT(MATH_DB2LINEAR); - BIND_ENUM_CONSTANT(MATH_WRAP); - BIND_ENUM_CONSTANT(MATH_WRAPF); - BIND_ENUM_CONSTANT(MATH_PINGPONG); - BIND_ENUM_CONSTANT(LOGIC_MAX); - BIND_ENUM_CONSTANT(LOGIC_MIN); - BIND_ENUM_CONSTANT(LOGIC_CLAMP); - BIND_ENUM_CONSTANT(LOGIC_NEAREST_PO2); - BIND_ENUM_CONSTANT(OBJ_WEAKREF); - BIND_ENUM_CONSTANT(TYPE_CONVERT); - BIND_ENUM_CONSTANT(TYPE_OF); - BIND_ENUM_CONSTANT(TYPE_EXISTS); - BIND_ENUM_CONSTANT(TEXT_CHAR); - BIND_ENUM_CONSTANT(TEXT_STR); - BIND_ENUM_CONSTANT(TEXT_PRINT); - BIND_ENUM_CONSTANT(TEXT_PRINTERR); - BIND_ENUM_CONSTANT(TEXT_PRINTRAW); - BIND_ENUM_CONSTANT(TEXT_PRINT_VERBOSE); - BIND_ENUM_CONSTANT(VAR_TO_STR); - BIND_ENUM_CONSTANT(STR_TO_VAR); - BIND_ENUM_CONSTANT(VAR_TO_BYTES); - BIND_ENUM_CONSTANT(BYTES_TO_VAR); - BIND_ENUM_CONSTANT(MATH_SMOOTHSTEP); - BIND_ENUM_CONSTANT(MATH_POSMOD); - BIND_ENUM_CONSTANT(MATH_LERP_ANGLE); - BIND_ENUM_CONSTANT(TEXT_ORD); - BIND_ENUM_CONSTANT(FUNC_MAX); -} - -VisualScriptBuiltinFunc::VisualScriptBuiltinFunc(VisualScriptBuiltinFunc::BuiltinFunc func) { - this->func = func; -} - -VisualScriptBuiltinFunc::VisualScriptBuiltinFunc() { - func = MATH_SIN; -} - -template <VisualScriptBuiltinFunc::BuiltinFunc func> -static Ref<VisualScriptNode> create_builtin_func_node(const String &p_name) { - Ref<VisualScriptBuiltinFunc> node = memnew(VisualScriptBuiltinFunc(func)); - return node; -} - -void register_visual_script_builtin_func_node() { - VisualScriptLanguage::singleton->add_register_func("functions/built_in/sin", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_SIN>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/cos", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_COS>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/tan", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_TAN>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/sinh", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_SINH>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/cosh", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_COSH>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/tanh", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_TANH>); - - VisualScriptLanguage::singleton->add_register_func("functions/built_in/asin", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_ASIN>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/acos", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_ACOS>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/atan", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_ATAN>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/atan2", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_ATAN2>); - - VisualScriptLanguage::singleton->add_register_func("functions/built_in/sqrt", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_SQRT>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/fmod", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_FMOD>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/fposmod", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_FPOSMOD>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/posmod", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_POSMOD>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/floor", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_FLOOR>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/ceil", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_CEIL>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/round", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_ROUND>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/abs", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_ABS>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/sign", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_SIGN>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/pow", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_POW>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/log", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_LOG>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/exp", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_EXP>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/isnan", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_ISNAN>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/isinf", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_ISINF>); - - VisualScriptLanguage::singleton->add_register_func("functions/built_in/ease", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_EASE>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/step_decimals", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_STEP_DECIMALS>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/snapped", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_SNAPPED>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/lerp", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_LERP>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/cubic_interpolate", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_CUBIC_INTERPOLATE>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/lerp_angle", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_LERP_ANGLE>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/inverse_lerp", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_INVERSE_LERP>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/range_lerp", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANGE_LERP>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/smoothstep", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_SMOOTHSTEP>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/move_toward", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_MOVE_TOWARD>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/randomize", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDOMIZE>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/randi", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDI>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/randf", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDF>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/randi_range", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDI_RANGE>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/randf_range", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDF_RANGE>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/randfn", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDFN>); - - VisualScriptLanguage::singleton->add_register_func("functions/built_in/seed", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_SEED>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/randseed", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDSEED>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/deg2rad", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_DEG2RAD>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/rad2deg", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RAD2DEG>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/linear2db", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_LINEAR2DB>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/db2linear", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_DB2LINEAR>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/wrapi", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_WRAP>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/wrapf", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_WRAPF>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/pingpong", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_PINGPONG>); - - VisualScriptLanguage::singleton->add_register_func("functions/built_in/max", create_builtin_func_node<VisualScriptBuiltinFunc::LOGIC_MAX>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/min", create_builtin_func_node<VisualScriptBuiltinFunc::LOGIC_MIN>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/clamp", create_builtin_func_node<VisualScriptBuiltinFunc::LOGIC_CLAMP>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/nearest_po2", create_builtin_func_node<VisualScriptBuiltinFunc::LOGIC_NEAREST_PO2>); - - VisualScriptLanguage::singleton->add_register_func("functions/built_in/weakref", create_builtin_func_node<VisualScriptBuiltinFunc::OBJ_WEAKREF>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/convert", create_builtin_func_node<VisualScriptBuiltinFunc::TYPE_CONVERT>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/typeof", create_builtin_func_node<VisualScriptBuiltinFunc::TYPE_OF>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/type_exists", create_builtin_func_node<VisualScriptBuiltinFunc::TYPE_EXISTS>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/char", create_builtin_func_node<VisualScriptBuiltinFunc::TEXT_CHAR>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/ord", create_builtin_func_node<VisualScriptBuiltinFunc::TEXT_ORD>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/str", create_builtin_func_node<VisualScriptBuiltinFunc::TEXT_STR>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/print", create_builtin_func_node<VisualScriptBuiltinFunc::TEXT_PRINT>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/printerr", create_builtin_func_node<VisualScriptBuiltinFunc::TEXT_PRINTERR>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/printraw", create_builtin_func_node<VisualScriptBuiltinFunc::TEXT_PRINTRAW>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/print_verbose", create_builtin_func_node<VisualScriptBuiltinFunc::TEXT_PRINT_VERBOSE>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/var2str", create_builtin_func_node<VisualScriptBuiltinFunc::VAR_TO_STR>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/str2var", create_builtin_func_node<VisualScriptBuiltinFunc::STR_TO_VAR>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/var2bytes", create_builtin_func_node<VisualScriptBuiltinFunc::VAR_TO_BYTES>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/bytes2var", create_builtin_func_node<VisualScriptBuiltinFunc::BYTES_TO_VAR>); -} diff --git a/modules/visual_script/visual_script_builtin_funcs.h b/modules/visual_script/visual_script_builtin_funcs.h deleted file mode 100644 index 18935b9995..0000000000 --- a/modules/visual_script/visual_script_builtin_funcs.h +++ /dev/null @@ -1,153 +0,0 @@ -/*************************************************************************/ -/* visual_script_builtin_funcs.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef VISUAL_SCRIPT_BUILTIN_FUNCS_H -#define VISUAL_SCRIPT_BUILTIN_FUNCS_H - -#include "visual_script.h" - -class VisualScriptBuiltinFunc : public VisualScriptNode { - GDCLASS(VisualScriptBuiltinFunc, VisualScriptNode); - -public: - enum BuiltinFunc { - MATH_SIN, - MATH_COS, - MATH_TAN, - MATH_SINH, - MATH_COSH, - MATH_TANH, - MATH_ASIN, - MATH_ACOS, - MATH_ATAN, - MATH_ATAN2, - MATH_SQRT, - MATH_FMOD, - MATH_FPOSMOD, - MATH_FLOOR, - MATH_CEIL, - MATH_ROUND, - MATH_ABS, - MATH_SIGN, - MATH_POW, - MATH_LOG, - MATH_EXP, - MATH_ISNAN, - MATH_ISINF, - MATH_EASE, - MATH_STEP_DECIMALS, - MATH_SNAPPED, - MATH_LERP, - MATH_CUBIC_INTERPOLATE, - MATH_INVERSE_LERP, - MATH_RANGE_LERP, - MATH_MOVE_TOWARD, - MATH_RANDOMIZE, - MATH_RANDI, - MATH_RANDF, - MATH_RANDI_RANGE, - MATH_RANDF_RANGE, - MATH_RANDFN, - MATH_SEED, - MATH_RANDSEED, - MATH_DEG2RAD, - MATH_RAD2DEG, - MATH_LINEAR2DB, - MATH_DB2LINEAR, - MATH_WRAP, - MATH_WRAPF, - MATH_PINGPONG, - LOGIC_MAX, - LOGIC_MIN, - LOGIC_CLAMP, - LOGIC_NEAREST_PO2, - OBJ_WEAKREF, - TYPE_CONVERT, - TYPE_OF, - TYPE_EXISTS, - TEXT_CHAR, - TEXT_STR, - TEXT_PRINT, - TEXT_PRINTERR, - TEXT_PRINTRAW, - TEXT_PRINT_VERBOSE, - VAR_TO_STR, - STR_TO_VAR, - VAR_TO_BYTES, - BYTES_TO_VAR, - MATH_SMOOTHSTEP, - MATH_POSMOD, - MATH_LERP_ANGLE, - TEXT_ORD, - FUNC_MAX - }; - - static int get_func_argument_count(BuiltinFunc p_func); - static String get_func_name(BuiltinFunc p_func); - static void exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Callable::CallError &r_error, String &r_error_str); - static BuiltinFunc find_function(const String &p_string); - -private: - static const char *func_name[FUNC_MAX]; - BuiltinFunc func; - -protected: - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - //virtual String get_text() const; - virtual String get_category() const override { return "functions"; } - - void set_func(BuiltinFunc p_which); - BuiltinFunc get_func(); - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptBuiltinFunc(VisualScriptBuiltinFunc::BuiltinFunc func); - VisualScriptBuiltinFunc(); -}; - -VARIANT_ENUM_CAST(VisualScriptBuiltinFunc::BuiltinFunc) - -void register_visual_script_builtin_func_node(); - -#endif // VISUAL_SCRIPT_BUILTIN_FUNCS_H diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp deleted file mode 100644 index e0f6436094..0000000000 --- a/modules/visual_script/visual_script_expression.cpp +++ /dev/null @@ -1,1570 +0,0 @@ -/*************************************************************************/ -/* visual_script_expression.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "visual_script_expression.h" - -bool VisualScriptExpression::_set(const StringName &p_name, const Variant &p_value) { - if (String(p_name) == "expression") { - expression = p_value; - expression_dirty = true; - ports_changed_notify(); - return true; - } - - if (String(p_name) == "out_type") { - output_type = Variant::Type(int(p_value)); - expression_dirty = true; - ports_changed_notify(); - return true; - } - if (String(p_name) == "sequenced") { - sequenced = p_value; - ports_changed_notify(); - return true; - } - - if (String(p_name) == "input_count") { - int from = inputs.size(); - inputs.resize(int(p_value)); - for (int i = from; i < inputs.size(); i++) { - inputs.write[i].name = String::chr('a' + i); - if (from == 0) { - inputs.write[i].type = output_type; - } else { - inputs.write[i].type = inputs[from - 1].type; - } - } - expression_dirty = true; - ports_changed_notify(); - notify_property_list_changed(); - return true; - } - - if (String(p_name).begins_with("input_")) { - int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int(); - ERR_FAIL_INDEX_V(idx, inputs.size(), false); - - String what = String(p_name).get_slice("/", 1); - - if (what == "type") { - inputs.write[idx].type = Variant::Type(int(p_value)); - } else if (what == "name") { - inputs.write[idx].name = p_value; - } else { - return false; - } - - expression_dirty = true; - ports_changed_notify(); - return true; - } - - return false; -} - -bool VisualScriptExpression::_get(const StringName &p_name, Variant &r_ret) const { - if (String(p_name) == "expression") { - r_ret = expression; - return true; - } - - if (String(p_name) == "out_type") { - r_ret = output_type; - return true; - } - - if (String(p_name) == "sequenced") { - r_ret = sequenced; - return true; - } - - if (String(p_name) == "input_count") { - r_ret = inputs.size(); - return true; - } - - if (String(p_name).begins_with("input_")) { - int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int(); - ERR_FAIL_INDEX_V(idx, inputs.size(), false); - - String what = String(p_name).get_slice("/", 1); - - if (what == "type") { - r_ret = inputs[idx].type; - } else if (what == "name") { - r_ret = inputs[idx].name; - } else { - return false; - } - - return true; - } - - return false; -} - -void VisualScriptExpression::_get_property_list(List<PropertyInfo> *p_list) const { - String argt = "Any"; - for (int i = 1; i < Variant::VARIANT_MAX; i++) { - argt += "," + Variant::get_type_name(Variant::Type(i)); - } - - p_list->push_back(PropertyInfo(Variant::STRING, "expression", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); - p_list->push_back(PropertyInfo(Variant::INT, "out_type", PROPERTY_HINT_ENUM, argt)); - p_list->push_back(PropertyInfo(Variant::INT, "input_count", PROPERTY_HINT_RANGE, "0,64,1")); - p_list->push_back(PropertyInfo(Variant::BOOL, "sequenced")); - - for (int i = 0; i < inputs.size(); i++) { - p_list->push_back(PropertyInfo(Variant::INT, "input_" + itos(i) + "/type", PROPERTY_HINT_ENUM, argt)); - p_list->push_back(PropertyInfo(Variant::STRING, "input_" + itos(i) + "/name")); - } -} - -int VisualScriptExpression::get_output_sequence_port_count() const { - return sequenced ? 1 : 0; -} - -bool VisualScriptExpression::has_input_sequence_port() const { - return sequenced; -} - -String VisualScriptExpression::get_output_sequence_port_text(int p_port) const { - return String(); -} - -int VisualScriptExpression::get_input_value_port_count() const { - return inputs.size(); -} - -int VisualScriptExpression::get_output_value_port_count() const { - return 1; -} - -PropertyInfo VisualScriptExpression::get_input_value_port_info(int p_idx) const { - return PropertyInfo(inputs[p_idx].type, inputs[p_idx].name); -} - -PropertyInfo VisualScriptExpression::get_output_value_port_info(int p_idx) const { - return PropertyInfo(output_type, "result"); -} - -String VisualScriptExpression::get_caption() const { - return RTR("Expression"); -} - -String VisualScriptExpression::get_text() const { - return expression; -} - -Error VisualScriptExpression::_get_token(Token &r_token) { - while (true) { -#define GET_CHAR() (str_ofs >= expression.length() ? 0 : expression[str_ofs++]) - - char32_t cchar = GET_CHAR(); - if (cchar == 0) { - r_token.type = TK_EOF; - return OK; - } - - switch (cchar) { - case 0: { - r_token.type = TK_EOF; - return OK; - } break; - case '{': { - r_token.type = TK_CURLY_BRACKET_OPEN; - return OK; - }; - case '}': { - r_token.type = TK_CURLY_BRACKET_CLOSE; - return OK; - }; - case '[': { - r_token.type = TK_BRACKET_OPEN; - return OK; - }; - case ']': { - r_token.type = TK_BRACKET_CLOSE; - return OK; - }; - case '(': { - r_token.type = TK_PARENTHESIS_OPEN; - return OK; - }; - case ')': { - r_token.type = TK_PARENTHESIS_CLOSE; - return OK; - }; - case ',': { - r_token.type = TK_COMMA; - return OK; - }; - case ':': { - r_token.type = TK_COLON; - return OK; - }; - case '.': { - r_token.type = TK_PERIOD; - return OK; - }; - case '=': { - cchar = GET_CHAR(); - if (cchar == '=') { - r_token.type = TK_OP_EQUAL; - } else { - _set_error("Expected '='"); - r_token.type = TK_ERROR; - return ERR_PARSE_ERROR; - } - return OK; - }; - case '!': { - if (expression[str_ofs] == '=') { - r_token.type = TK_OP_NOT_EQUAL; - str_ofs++; - } else { - r_token.type = TK_OP_NOT; - } - return OK; - }; - case '>': { - if (expression[str_ofs] == '=') { - r_token.type = TK_OP_GREATER_EQUAL; - str_ofs++; - } else if (expression[str_ofs] == '>') { - r_token.type = TK_OP_SHIFT_RIGHT; - str_ofs++; - } else { - r_token.type = TK_OP_GREATER; - } - return OK; - }; - case '<': { - if (expression[str_ofs] == '=') { - r_token.type = TK_OP_LESS_EQUAL; - str_ofs++; - } else if (expression[str_ofs] == '<') { - r_token.type = TK_OP_SHIFT_LEFT; - str_ofs++; - } else { - r_token.type = TK_OP_LESS; - } - return OK; - }; - case '+': { - r_token.type = TK_OP_ADD; - return OK; - }; - case '-': { - r_token.type = TK_OP_SUB; - return OK; - }; - case '/': { - r_token.type = TK_OP_DIV; - return OK; - }; - case '*': { - r_token.type = TK_OP_MUL; - return OK; - }; - case '%': { - r_token.type = TK_OP_MOD; - return OK; - }; - case '&': { - if (expression[str_ofs] == '&') { - r_token.type = TK_OP_AND; - str_ofs++; - } else { - r_token.type = TK_OP_BIT_AND; - } - return OK; - }; - case '|': { - if (expression[str_ofs] == '|') { - r_token.type = TK_OP_OR; - str_ofs++; - } else { - r_token.type = TK_OP_BIT_OR; - } - return OK; - }; - case '^': { - r_token.type = TK_OP_BIT_XOR; - - return OK; - }; - case '~': { - r_token.type = TK_OP_BIT_INVERT; - - return OK; - }; - case '"': { - String str; - char32_t prev = 0; - while (true) { - char32_t ch = GET_CHAR(); - - if (ch == 0) { - _set_error("Unterminated String"); - r_token.type = TK_ERROR; - return ERR_PARSE_ERROR; - } else if (ch == '"') { - break; - } else if (ch == '\\') { - //escaped characters... - - char32_t next = GET_CHAR(); - if (next == 0) { - _set_error("Unterminated String"); - r_token.type = TK_ERROR; - return ERR_PARSE_ERROR; - } - char32_t res = 0; - - switch (next) { - case 'b': - res = 8; - break; - case 't': - res = 9; - break; - case 'n': - res = 10; - break; - case 'f': - res = 12; - break; - case 'r': - res = 13; - break; - case 'U': - case 'u': { - // Hexadecimal sequence. - int hex_len = (next == 'U') ? 6 : 4; - for (int j = 0; j < hex_len; j++) { - char32_t c = GET_CHAR(); - - if (c == 0) { - _set_error("Unterminated String"); - r_token.type = TK_ERROR; - return ERR_PARSE_ERROR; - } - if (!is_hex_digit(c)) { - _set_error("Malformed hex constant in string"); - r_token.type = TK_ERROR; - return ERR_PARSE_ERROR; - } - char32_t v; - if (is_digit(c)) { - v = c - '0'; - } else if (c >= 'a' && c <= 'f') { - v = c - 'a'; - v += 10; - } else if (c >= 'A' && c <= 'F') { - v = c - 'A'; - v += 10; - } else { - ERR_PRINT("Bug parsing hex constant."); - v = 0; - } - - res <<= 4; - res |= v; - } - - } break; - default: { - res = next; - } break; - } - - // Parse UTF-16 pair. - if ((res & 0xfffffc00) == 0xd800) { - if (prev == 0) { - prev = res; - continue; - } else { - _set_error("Invalid UTF-16 sequence in string, unpaired lead surrogate"); - r_token.type = TK_ERROR; - return ERR_PARSE_ERROR; - } - } else if ((res & 0xfffffc00) == 0xdc00) { - if (prev == 0) { - _set_error("Invalid UTF-16 sequence in string, unpaired trail surrogate"); - r_token.type = TK_ERROR; - return ERR_PARSE_ERROR; - } else { - res = (prev << 10UL) + res - ((0xd800 << 10UL) + 0xdc00 - 0x10000); - prev = 0; - } - } - if (prev != 0) { - _set_error("Invalid UTF-16 sequence in string, unpaired lead surrogate"); - r_token.type = TK_ERROR; - return ERR_PARSE_ERROR; - } - str += res; - } else { - if (prev != 0) { - _set_error("Invalid UTF-16 sequence in string, unpaired lead surrogate"); - r_token.type = TK_ERROR; - return ERR_PARSE_ERROR; - } - str += ch; - } - } - if (prev != 0) { - _set_error("Invalid UTF-16 sequence in string, unpaired lead surrogate"); - r_token.type = TK_ERROR; - return ERR_PARSE_ERROR; - } - - r_token.type = TK_CONSTANT; - r_token.value = str; - return OK; - - } break; - default: { - if (cchar <= 32) { - break; - } - - if (is_digit(cchar)) { - //a number - - String num; -#define READING_SIGN 0 -#define READING_INT 1 -#define READING_DEC 2 -#define READING_EXP 3 -#define READING_DONE 4 - int reading = READING_INT; - - char32_t c = cchar; - bool exp_sign = false; - bool exp_beg = false; - bool is_float = false; - - while (true) { - switch (reading) { - case READING_INT: { - if (is_digit(c)) { - //pass - } else if (c == '.') { - reading = READING_DEC; - is_float = true; - } else if (c == 'e') { - reading = READING_EXP; - } else { - reading = READING_DONE; - } - - } break; - case READING_DEC: { - if (is_digit(c)) { - } else if (c == 'e') { - reading = READING_EXP; - - } else { - reading = READING_DONE; - } - - } break; - case READING_EXP: { - if (is_digit(c)) { - exp_beg = true; - - } else if ((c == '-' || c == '+') && !exp_sign && !exp_beg) { - if (c == '-') { - is_float = true; - } - exp_sign = true; - - } else { - reading = READING_DONE; - } - } break; - } - - if (reading == READING_DONE) { - break; - } - num += String::chr(c); - c = GET_CHAR(); - } - - str_ofs--; - - r_token.type = TK_CONSTANT; - - if (is_float) { - r_token.value = num.to_float(); - } else { - r_token.value = num.to_int(); - } - return OK; - - } else if (is_ascii_char(cchar) || cchar == '_') { - String id; - bool first = true; - - while (is_ascii_char(cchar) || cchar == '_' || (!first && is_digit(cchar))) { - id += String::chr(cchar); - cchar = GET_CHAR(); - first = false; - } - - str_ofs--; //go back one - - if (id == "in") { - r_token.type = TK_OP_IN; - } else if (id == "null") { - r_token.type = TK_CONSTANT; - r_token.value = Variant(); - } else if (id == "true") { - r_token.type = TK_CONSTANT; - r_token.value = true; - } else if (id == "false") { - r_token.type = TK_CONSTANT; - r_token.value = false; - } else if (id == "PI") { - r_token.type = TK_CONSTANT; - r_token.value = Math_PI; - } else if (id == "TAU") { - r_token.type = TK_CONSTANT; - r_token.value = Math_TAU; - } else if (id == "INF") { - r_token.type = TK_CONSTANT; - r_token.value = INFINITY; - } else if (id == "NAN") { - r_token.type = TK_CONSTANT; - r_token.value = NAN; - } else if (id == "not") { - r_token.type = TK_OP_NOT; - } else if (id == "or") { - r_token.type = TK_OP_OR; - } else if (id == "and") { - r_token.type = TK_OP_AND; - } else if (id == "self") { - r_token.type = TK_SELF; - } else { - for (int i = 0; i < Variant::VARIANT_MAX; i++) { - if (id == Variant::get_type_name(Variant::Type(i))) { - r_token.type = TK_BASIC_TYPE; - r_token.value = i; - return OK; - } - } - - VisualScriptBuiltinFunc::BuiltinFunc bifunc = VisualScriptBuiltinFunc::find_function(id); - if (bifunc != VisualScriptBuiltinFunc::FUNC_MAX) { - r_token.type = TK_BUILTIN_FUNC; - r_token.value = bifunc; - return OK; - } - - r_token.type = TK_IDENTIFIER; - r_token.value = id; - } - - return OK; - } else { - _set_error("Unexpected character."); - r_token.type = TK_ERROR; - return ERR_PARSE_ERROR; - } - } - } - } - - r_token.type = TK_ERROR; - return ERR_PARSE_ERROR; -} - -const char *VisualScriptExpression::token_name[TK_MAX] = { - "CURLY BRACKET OPEN", - "CURLY BRACKET CLOSE", - "BRACKET OPEN", - "BRACKET CLOSE", - "PARENTHESIS OPEN", - "PARENTHESIS CLOSE", - "IDENTIFIER", - "BUILTIN FUNC", - "SELF", - "CONSTANT", - "BASIC TYPE", - "COLON", - "COMMA", - "PERIOD", - "OP IN", - "OP EQUAL", - "OP NOT EQUAL", - "OP LESS", - "OP LESS EQUAL", - "OP GREATER", - "OP GREATER EQUAL", - "OP AND", - "OP OR", - "OP NOT", - "OP ADD", - "OP SUB", - "OP MUL", - "OP DIV", - "OP MOD", - "OP SHIFT LEFT", - "OP SHIFT RIGHT", - "OP BIT AND", - "OP BIT OR", - "OP BIT XOR", - "OP BIT INVERT", - "EOF", - "ERROR" -}; - -VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() { - Vector<Expression> expression; - - while (true) { - //keep appending stuff to expression - ENode *expr = nullptr; - - Token tk; - _get_token(tk); - if (error_set) { - return nullptr; - } - - switch (tk.type) { - case TK_CURLY_BRACKET_OPEN: { - //a dictionary - DictionaryNode *dn = alloc_node<DictionaryNode>(); - - while (true) { - int cofs = str_ofs; - _get_token(tk); - if (tk.type == TK_CURLY_BRACKET_CLOSE) { - break; - } - str_ofs = cofs; //revert - //parse an expression - ENode *expr2 = _parse_expression(); - if (!expr2) { - return nullptr; - } - dn->dict.push_back(expr2); - - _get_token(tk); - if (tk.type != TK_COLON) { - _set_error("Expected ':'"); - return nullptr; - } - - expr2 = _parse_expression(); - if (!expr2) { - return nullptr; - } - - dn->dict.push_back(expr2); - - cofs = str_ofs; - _get_token(tk); - if (tk.type == TK_COMMA) { - //all good - } else if (tk.type == TK_CURLY_BRACKET_CLOSE) { - str_ofs = cofs; - } else { - _set_error("Expected ',' or '}'"); - } - } - - expr = dn; - } break; - case TK_BRACKET_OPEN: { - //an array - - ArrayNode *an = alloc_node<ArrayNode>(); - - while (true) { - int cofs = str_ofs; - _get_token(tk); - if (tk.type == TK_BRACKET_CLOSE) { - break; - } - str_ofs = cofs; //revert - //parse an expression - ENode *expr2 = _parse_expression(); - if (!expr2) { - return nullptr; - } - an->array.push_back(expr2); - - cofs = str_ofs; - _get_token(tk); - if (tk.type == TK_COMMA) { - //all good - } else if (tk.type == TK_BRACKET_CLOSE) { - str_ofs = cofs; - } else { - _set_error("Expected ',' or ']'"); - } - } - - expr = an; - } break; - case TK_PARENTHESIS_OPEN: { - //a suexpression - ENode *e = _parse_expression(); - if (error_set) { - return nullptr; - } - _get_token(tk); - if (tk.type != TK_PARENTHESIS_CLOSE) { - _set_error("Expected ')'"); - return nullptr; - } - - expr = e; - - } break; - case TK_IDENTIFIER: { - String what = tk.value; - int index = -1; - for (int i = 0; i < inputs.size(); i++) { - if (what == inputs[i].name) { - index = i; - break; - } - } - - if (index != -1) { - InputNode *input = alloc_node<InputNode>(); - input->index = index; - expr = input; - } else { - _set_error("Invalid input identifier '" + what + "'. For script variables, use self (locals are for inputs)." + what); - return nullptr; - } - } break; - case TK_SELF: { - SelfNode *self = alloc_node<SelfNode>(); - expr = self; - } break; - case TK_CONSTANT: { - ConstantNode *constant = alloc_node<ConstantNode>(); - constant->value = tk.value; - expr = constant; - } break; - case TK_BASIC_TYPE: { - //constructor.. - - Variant::Type bt = Variant::Type(int(tk.value)); - _get_token(tk); - if (tk.type != TK_PARENTHESIS_OPEN) { - _set_error("Expected '('"); - return nullptr; - } - - ConstructorNode *constructor = alloc_node<ConstructorNode>(); - constructor->data_type = bt; - - while (true) { - int cofs = str_ofs; - _get_token(tk); - if (tk.type == TK_PARENTHESIS_CLOSE) { - break; - } - str_ofs = cofs; //revert - //parse an expression - ENode *expr2 = _parse_expression(); - if (!expr2) { - return nullptr; - } - - constructor->arguments.push_back(expr2); - - cofs = str_ofs; - _get_token(tk); - if (tk.type == TK_COMMA) { - //all good - } else if (tk.type == TK_PARENTHESIS_CLOSE) { - str_ofs = cofs; - } else { - _set_error("Expected ',' or ')'"); - } - } - - expr = constructor; - - } break; - case TK_BUILTIN_FUNC: { - //builtin function - - _get_token(tk); - if (tk.type != TK_PARENTHESIS_OPEN) { - _set_error("Expected '('"); - return nullptr; - } - - BuiltinFuncNode *bifunc = alloc_node<BuiltinFuncNode>(); - bifunc->func = VisualScriptBuiltinFunc::BuiltinFunc(int(tk.value)); - - while (true) { - int cofs = str_ofs; - _get_token(tk); - if (tk.type == TK_PARENTHESIS_CLOSE) { - break; - } - str_ofs = cofs; //revert - //parse an expression - ENode *expr2 = _parse_expression(); - if (!expr2) { - return nullptr; - } - - bifunc->arguments.push_back(expr2); - - cofs = str_ofs; - _get_token(tk); - if (tk.type == TK_COMMA) { - //all good - } else if (tk.type == TK_PARENTHESIS_CLOSE) { - str_ofs = cofs; - } else { - _set_error("Expected ',' or ')'"); - } - } - - int expected_args = VisualScriptBuiltinFunc::get_func_argument_count(bifunc->func); - if (bifunc->arguments.size() != expected_args) { - _set_error("Builtin func '" + VisualScriptBuiltinFunc::get_func_name(bifunc->func) + "' expects " + itos(expected_args) + " arguments."); - } - - expr = bifunc; - - } break; - case TK_OP_SUB: { - Expression e; - e.is_op = true; - e.op = Variant::OP_NEGATE; - expression.push_back(e); - continue; - } break; - case TK_OP_NOT: { - Expression e; - e.is_op = true; - e.op = Variant::OP_NOT; - expression.push_back(e); - continue; - } break; - - default: { - _set_error("Expected expression."); - return nullptr; - } break; - } - - //before going to operators, must check indexing! - - while (true) { - int cofs2 = str_ofs; - _get_token(tk); - if (error_set) { - return nullptr; - } - - bool done = false; - - switch (tk.type) { - case TK_BRACKET_OPEN: { - //value indexing - - IndexNode *index = alloc_node<IndexNode>(); - index->base = expr; - - ENode *what = _parse_expression(); - if (!what) { - return nullptr; - } - - index->index = what; - - _get_token(tk); - if (tk.type != TK_BRACKET_CLOSE) { - _set_error("Expected ']' at end of index."); - return nullptr; - } - expr = index; - - } break; - case TK_PERIOD: { - //named indexing or function call - _get_token(tk); - if (tk.type != TK_IDENTIFIER) { - _set_error("Expected identifier after '.'"); - return nullptr; - } - - StringName identifier = tk.value; - - int cofs = str_ofs; - _get_token(tk); - if (tk.type == TK_PARENTHESIS_OPEN) { - //function call - CallNode *func_call = alloc_node<CallNode>(); - func_call->method = identifier; - func_call->base = expr; - - while (true) { - int cofs3 = str_ofs; - _get_token(tk); - if (tk.type == TK_PARENTHESIS_CLOSE) { - break; - } - str_ofs = cofs3; //revert - //parse an expression - ENode *expr2 = _parse_expression(); - if (!expr2) { - return nullptr; - } - - func_call->arguments.push_back(expr2); - - cofs3 = str_ofs; - _get_token(tk); - if (tk.type == TK_COMMA) { - //all good - } else if (tk.type == TK_PARENTHESIS_CLOSE) { - str_ofs = cofs3; - } else { - _set_error("Expected ',' or ')'"); - } - } - - expr = func_call; - } else { - //named indexing - str_ofs = cofs; - - NamedIndexNode *index = alloc_node<NamedIndexNode>(); - index->base = expr; - index->name = identifier; - expr = index; - } - - } break; - default: { - str_ofs = cofs2; - done = true; - } break; - } - - if (done) { - break; - } - } - - //push expression - { - Expression e; - e.is_op = false; - e.node = expr; - expression.push_back(e); - } - - //ok finally look for an operator - - int cofs = str_ofs; - _get_token(tk); - if (error_set) { - return nullptr; - } - - Variant::Operator op = Variant::OP_MAX; - - switch (tk.type) { - case TK_OP_IN: - op = Variant::OP_IN; - break; - case TK_OP_EQUAL: - op = Variant::OP_EQUAL; - break; - case TK_OP_NOT_EQUAL: - op = Variant::OP_NOT_EQUAL; - break; - case TK_OP_LESS: - op = Variant::OP_LESS; - break; - case TK_OP_LESS_EQUAL: - op = Variant::OP_LESS_EQUAL; - break; - case TK_OP_GREATER: - op = Variant::OP_GREATER; - break; - case TK_OP_GREATER_EQUAL: - op = Variant::OP_GREATER_EQUAL; - break; - case TK_OP_AND: - op = Variant::OP_AND; - break; - case TK_OP_OR: - op = Variant::OP_OR; - break; - case TK_OP_NOT: - op = Variant::OP_NOT; - break; - case TK_OP_ADD: - op = Variant::OP_ADD; - break; - case TK_OP_SUB: - op = Variant::OP_SUBTRACT; - break; - case TK_OP_MUL: - op = Variant::OP_MULTIPLY; - break; - case TK_OP_DIV: - op = Variant::OP_DIVIDE; - break; - case TK_OP_MOD: - op = Variant::OP_MODULE; - break; - case TK_OP_SHIFT_LEFT: - op = Variant::OP_SHIFT_LEFT; - break; - case TK_OP_SHIFT_RIGHT: - op = Variant::OP_SHIFT_RIGHT; - break; - case TK_OP_BIT_AND: - op = Variant::OP_BIT_AND; - break; - case TK_OP_BIT_OR: - op = Variant::OP_BIT_OR; - break; - case TK_OP_BIT_XOR: - op = Variant::OP_BIT_XOR; - break; - case TK_OP_BIT_INVERT: - op = Variant::OP_BIT_NEGATE; - break; - default: { - }; - } - - if (op == Variant::OP_MAX) { //stop appending stuff - str_ofs = cofs; - break; - } - - //push operator and go on - { - Expression e; - e.is_op = true; - e.op = op; - expression.push_back(e); - } - } - - /* Reduce the set of expressions and place them in an operator tree, respecting precedence */ - - while (expression.size() > 1) { - int next_op = -1; - int min_priority = 0xFFFFF; - bool is_unary = false; - - for (int i = 0; i < expression.size(); i++) { - if (!expression[i].is_op) { - continue; - } - - int priority; - - bool unary = false; - - switch (expression[i].op) { - case Variant::OP_BIT_NEGATE: - priority = 0; - unary = true; - break; - case Variant::OP_NEGATE: - priority = 1; - unary = true; - break; - - case Variant::OP_MULTIPLY: - priority = 2; - break; - case Variant::OP_DIVIDE: - priority = 2; - break; - case Variant::OP_MODULE: - priority = 2; - break; - - case Variant::OP_ADD: - priority = 3; - break; - case Variant::OP_SUBTRACT: - priority = 3; - break; - - case Variant::OP_SHIFT_LEFT: - priority = 4; - break; - case Variant::OP_SHIFT_RIGHT: - priority = 4; - break; - - case Variant::OP_BIT_AND: - priority = 5; - break; - case Variant::OP_BIT_XOR: - priority = 6; - break; - case Variant::OP_BIT_OR: - priority = 7; - break; - - case Variant::OP_LESS: - priority = 8; - break; - case Variant::OP_LESS_EQUAL: - priority = 8; - break; - case Variant::OP_GREATER: - priority = 8; - break; - case Variant::OP_GREATER_EQUAL: - priority = 8; - break; - - case Variant::OP_EQUAL: - priority = 8; - break; - case Variant::OP_NOT_EQUAL: - priority = 8; - break; - - case Variant::OP_IN: - priority = 10; - break; - - case Variant::OP_NOT: - priority = 11; - unary = true; - break; - case Variant::OP_AND: - priority = 12; - break; - case Variant::OP_OR: - priority = 13; - break; - - default: { - _set_error("Parser bug, invalid operator in expression: " + itos(expression[i].op)); - return nullptr; - } - } - - if (priority < min_priority) { - // < is used for left to right (default) - // <= is used for right to left - - next_op = i; - min_priority = priority; - is_unary = unary; - } - } - - if (next_op == -1) { - _set_error("Yet another parser bug...."); - ERR_FAIL_V(nullptr); - } - - // OK! create operator.. - if (is_unary) { - int expr_pos = next_op; - while (expression[expr_pos].is_op) { - expr_pos++; - if (expr_pos == expression.size()) { - //can happen.. - _set_error("Unexpected end of expression..."); - return nullptr; - } - } - - //consecutively do unary operators - for (int i = expr_pos - 1; i >= next_op; i--) { - OperatorNode *op = alloc_node<OperatorNode>(); - op->op = expression[i].op; - op->nodes[0] = expression[i + 1].node; - op->nodes[1] = nullptr; - expression.write[i].is_op = false; - expression.write[i].node = op; - expression.remove_at(i + 1); - } - - } else { - if (next_op < 1 || next_op >= (expression.size() - 1)) { - _set_error("Parser bug..."); - ERR_FAIL_V(nullptr); - } - - OperatorNode *op = alloc_node<OperatorNode>(); - op->op = expression[next_op].op; - - if (expression[next_op - 1].is_op) { - _set_error("Parser bug..."); - ERR_FAIL_V(nullptr); - } - - if (expression[next_op + 1].is_op) { - // this is not invalid and can really appear - // but it becomes invalid anyway because no binary op - // can be followed by a unary op in a valid combination, - // due to how precedence works, unaries will always disappear first - - _set_error("Unexpected two consecutive operators."); - return nullptr; - } - - op->nodes[0] = expression[next_op - 1].node; //expression goes as left - op->nodes[1] = expression[next_op + 1].node; //next expression goes as right - - //replace all 3 nodes by this operator and make it an expression - expression.write[next_op - 1].node = op; - expression.remove_at(next_op); - expression.remove_at(next_op); - } - } - - return expression[0].node; -} - -bool VisualScriptExpression::_compile_expression() { - if (!expression_dirty) { - return error_set; - } - - if (nodes) { - memdelete(nodes); - nodes = nullptr; - root = nullptr; - } - - error_str = String(); - error_set = false; - str_ofs = 0; - - root = _parse_expression(); - - if (error_set) { - root = nullptr; - if (nodes) { - memdelete(nodes); - } - nodes = nullptr; - return true; - } - - expression_dirty = false; - return false; -} - -class VisualScriptNodeInstanceExpression : public VisualScriptNodeInstance { -public: - VisualScriptInstance *instance = nullptr; - VisualScriptExpression *expression = nullptr; - - //virtual int get_working_memory_size() const override { return 0; } - //execute by parsing the tree directly - virtual bool _execute(const Variant **p_inputs, VisualScriptExpression::ENode *p_node, Variant &r_ret, String &r_error_str, Callable::CallError &ce) { - switch (p_node->type) { - case VisualScriptExpression::ENode::TYPE_INPUT: { - const VisualScriptExpression::InputNode *in = static_cast<const VisualScriptExpression::InputNode *>(p_node); - r_ret = *p_inputs[in->index]; - } break; - case VisualScriptExpression::ENode::TYPE_CONSTANT: { - const VisualScriptExpression::ConstantNode *c = static_cast<const VisualScriptExpression::ConstantNode *>(p_node); - r_ret = c->value; - - } break; - case VisualScriptExpression::ENode::TYPE_SELF: { - r_ret = instance->get_owner_ptr(); - } break; - case VisualScriptExpression::ENode::TYPE_OPERATOR: { - const VisualScriptExpression::OperatorNode *op = static_cast<const VisualScriptExpression::OperatorNode *>(p_node); - - Variant a; - bool ret = _execute(p_inputs, op->nodes[0], a, r_error_str, ce); - if (ret) { - return true; - } - - Variant b; - - if (op->nodes[1]) { - ret = _execute(p_inputs, op->nodes[1], b, r_error_str, ce); - if (ret) { - return true; - } - } - - bool valid = true; - Variant::evaluate(op->op, a, b, r_ret, valid); - if (!valid) { - r_error_str = "Invalid operands to operator " + Variant::get_operator_name(op->op) + ": " + Variant::get_type_name(a.get_type()) + " and " + Variant::get_type_name(b.get_type()) + "."; - return true; - } - - } break; - case VisualScriptExpression::ENode::TYPE_INDEX: { - const VisualScriptExpression::IndexNode *index = static_cast<const VisualScriptExpression::IndexNode *>(p_node); - - Variant base; - bool ret = _execute(p_inputs, index->base, base, r_error_str, ce); - if (ret) { - return true; - } - - Variant idx; - - ret = _execute(p_inputs, index->index, idx, r_error_str, ce); - if (ret) { - return true; - } - - bool valid; - r_ret = base.get(idx, &valid); - if (!valid) { - r_error_str = "Invalid index of type " + Variant::get_type_name(idx.get_type()) + " for base of type " + Variant::get_type_name(base.get_type()) + "."; - return true; - } - - } break; - case VisualScriptExpression::ENode::TYPE_NAMED_INDEX: { - const VisualScriptExpression::NamedIndexNode *index = static_cast<const VisualScriptExpression::NamedIndexNode *>(p_node); - - Variant base; - bool ret = _execute(p_inputs, index->base, base, r_error_str, ce); - if (ret) { - return true; - } - - bool valid; - r_ret = base.get_named(index->name, valid); - if (!valid) { - r_error_str = "Invalid index '" + String(index->name) + "' for base of type " + Variant::get_type_name(base.get_type()) + "."; - return true; - } - - } break; - case VisualScriptExpression::ENode::TYPE_ARRAY: { - const VisualScriptExpression::ArrayNode *array = static_cast<const VisualScriptExpression::ArrayNode *>(p_node); - - Array arr; - arr.resize(array->array.size()); - for (int i = 0; i < array->array.size(); i++) { - Variant value; - bool ret = _execute(p_inputs, array->array[i], value, r_error_str, ce); - if (ret) { - return true; - } - arr[i] = value; - } - - r_ret = arr; - - } break; - case VisualScriptExpression::ENode::TYPE_DICTIONARY: { - const VisualScriptExpression::DictionaryNode *dictionary = static_cast<const VisualScriptExpression::DictionaryNode *>(p_node); - - Dictionary d; - for (int i = 0; i < dictionary->dict.size(); i += 2) { - Variant key; - bool ret = _execute(p_inputs, dictionary->dict[i + 0], key, r_error_str, ce); - if (ret) { - return true; - } - - Variant value; - ret = _execute(p_inputs, dictionary->dict[i + 1], value, r_error_str, ce); - if (ret) { - return true; - } - - d[key] = value; - } - - r_ret = d; - } break; - case VisualScriptExpression::ENode::TYPE_CONSTRUCTOR: { - const VisualScriptExpression::ConstructorNode *constructor = static_cast<const VisualScriptExpression::ConstructorNode *>(p_node); - - Vector<Variant> arr; - Vector<const Variant *> argp; - arr.resize(constructor->arguments.size()); - argp.resize(constructor->arguments.size()); - - for (int i = 0; i < constructor->arguments.size(); i++) { - Variant value; - bool ret = _execute(p_inputs, constructor->arguments[i], value, r_error_str, ce); - if (ret) { - return true; - } - arr.write[i] = value; - argp.write[i] = &arr[i]; - } - - Variant::construct(constructor->data_type, r_ret, (const Variant **)argp.ptr(), argp.size(), ce); - - if (ce.error != Callable::CallError::CALL_OK) { - r_error_str = "Invalid arguments to construct '" + Variant::get_type_name(constructor->data_type) + "'."; - return true; - } - - } break; - case VisualScriptExpression::ENode::TYPE_BUILTIN_FUNC: { - const VisualScriptExpression::BuiltinFuncNode *bifunc = static_cast<const VisualScriptExpression::BuiltinFuncNode *>(p_node); - - Vector<Variant> arr; - Vector<const Variant *> argp; - arr.resize(bifunc->arguments.size()); - argp.resize(bifunc->arguments.size()); - - for (int i = 0; i < bifunc->arguments.size(); i++) { - Variant value; - bool ret = _execute(p_inputs, bifunc->arguments[i], value, r_error_str, ce); - if (ret) { - return true; - } - arr.write[i] = value; - argp.write[i] = &arr[i]; - } - - VisualScriptBuiltinFunc::exec_func(bifunc->func, (const Variant **)argp.ptr(), &r_ret, ce, r_error_str); - - if (ce.error != Callable::CallError::CALL_OK) { - r_error_str = "Builtin Call Failed. " + r_error_str; - return true; - } - - } break; - case VisualScriptExpression::ENode::TYPE_CALL: { - const VisualScriptExpression::CallNode *call = static_cast<const VisualScriptExpression::CallNode *>(p_node); - - Variant base; - bool ret = _execute(p_inputs, call->base, base, r_error_str, ce); - if (ret) { - return true; - } - - Vector<Variant> arr; - Vector<const Variant *> argp; - arr.resize(call->arguments.size()); - argp.resize(call->arguments.size()); - - for (int i = 0; i < call->arguments.size(); i++) { - Variant value; - bool ret2 = _execute(p_inputs, call->arguments[i], value, r_error_str, ce); - if (ret2) { - return true; - } - arr.write[i] = value; - argp.write[i] = &arr[i]; - } - - base.callp(call->method, (const Variant **)argp.ptr(), argp.size(), r_ret, ce); - - if (ce.error != Callable::CallError::CALL_OK) { - r_error_str = "On call to '" + String(call->method) + "':"; - return true; - } - - } break; - } - return false; - } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - if (!expression->root || expression->error_set) { - r_error_str = expression->error_str; - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - return 0; - } - - bool error = _execute(p_inputs, expression->root, *p_outputs[0], r_error_str, r_error); - if (error && r_error.error == Callable::CallError::CALL_OK) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - } - -#ifdef DEBUG_ENABLED - if (!error && expression->output_type != Variant::NIL && !Variant::can_convert_strict(p_outputs[0]->get_type(), expression->output_type)) { - r_error_str += "Can't convert expression result from " + Variant::get_type_name(p_outputs[0]->get_type()) + " to " + Variant::get_type_name(expression->output_type) + "."; - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - } -#endif - - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptExpression::instantiate(VisualScriptInstance *p_instance) { - _compile_expression(); - VisualScriptNodeInstanceExpression *instance = memnew(VisualScriptNodeInstanceExpression); - instance->instance = p_instance; - instance->expression = this; - return instance; -} - -void VisualScriptExpression::reset_state() { - if (nodes) { - memdelete(nodes); - nodes = nullptr; - root = nullptr; - } - - error_str = String(); - error_set = false; - str_ofs = 0; - inputs.clear(); -} - -VisualScriptExpression::VisualScriptExpression() { -} - -VisualScriptExpression::~VisualScriptExpression() { - if (nodes) { - memdelete(nodes); - } -} - -void register_visual_script_expression_node() { - VisualScriptLanguage::singleton->add_register_func("operators/expression", create_node_generic<VisualScriptExpression>); -} diff --git a/modules/visual_script/visual_script_expression.h b/modules/visual_script/visual_script_expression.h deleted file mode 100644 index 7e10f98f36..0000000000 --- a/modules/visual_script/visual_script_expression.h +++ /dev/null @@ -1,284 +0,0 @@ -/*************************************************************************/ -/* visual_script_expression.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef VISUAL_SCRIPT_EXPRESSION_H -#define VISUAL_SCRIPT_EXPRESSION_H - -#include "visual_script.h" -#include "visual_script_builtin_funcs.h" - -class VisualScriptExpression : public VisualScriptNode { - GDCLASS(VisualScriptExpression, VisualScriptNode); - friend class VisualScriptNodeInstanceExpression; - - struct Input { - Variant::Type type = Variant::NIL; - String name; - }; - - Vector<Input> inputs; - Variant::Type output_type = Variant::NIL; - - String expression; - - bool sequenced = false; - int str_ofs = 0; - bool expression_dirty = true; - - bool _compile_expression(); - - enum TokenType { - TK_CURLY_BRACKET_OPEN, - TK_CURLY_BRACKET_CLOSE, - TK_BRACKET_OPEN, - TK_BRACKET_CLOSE, - TK_PARENTHESIS_OPEN, - TK_PARENTHESIS_CLOSE, - TK_IDENTIFIER, - TK_BUILTIN_FUNC, - TK_SELF, - TK_CONSTANT, - TK_BASIC_TYPE, - TK_COLON, - TK_COMMA, - TK_PERIOD, - TK_OP_IN, - TK_OP_EQUAL, - TK_OP_NOT_EQUAL, - TK_OP_LESS, - TK_OP_LESS_EQUAL, - TK_OP_GREATER, - TK_OP_GREATER_EQUAL, - TK_OP_AND, - TK_OP_OR, - TK_OP_NOT, - TK_OP_ADD, - TK_OP_SUB, - TK_OP_MUL, - TK_OP_DIV, - TK_OP_MOD, - TK_OP_SHIFT_LEFT, - TK_OP_SHIFT_RIGHT, - TK_OP_BIT_AND, - TK_OP_BIT_OR, - TK_OP_BIT_XOR, - TK_OP_BIT_INVERT, - TK_EOF, - TK_ERROR, - TK_MAX - }; - - static const char *token_name[TK_MAX]; - struct Token { - TokenType type; - Variant value; - }; - - void _set_error(const String &p_err) { - if (error_set) { - return; - } - error_str = p_err; - error_set = true; - } - - Error _get_token(Token &r_token); - - String error_str; - bool error_set = true; - - struct ENode { - enum Type { - TYPE_INPUT, - TYPE_CONSTANT, - TYPE_SELF, - TYPE_OPERATOR, - TYPE_INDEX, - TYPE_NAMED_INDEX, - TYPE_ARRAY, - TYPE_DICTIONARY, - TYPE_CONSTRUCTOR, - TYPE_BUILTIN_FUNC, - TYPE_CALL - }; - - ENode *next = nullptr; - - Type type = Type::TYPE_SELF; - - virtual ~ENode() { - if (next) { - memdelete(next); - } - } - }; - - struct Expression { - bool is_op = false; - union { - Variant::Operator op; - ENode *node = nullptr; - }; - }; - - ENode *_parse_expression(); - - struct InputNode : public ENode { - int index = 0; - InputNode() { - type = TYPE_INPUT; - } - }; - - struct ConstantNode : public ENode { - Variant value; - ConstantNode() { - type = TYPE_CONSTANT; - } - }; - - struct OperatorNode : public ENode { - Variant::Operator op = Variant::Operator::OP_ADD; - - ENode *nodes[2] = { nullptr, nullptr }; - - OperatorNode() { - type = TYPE_OPERATOR; - } - }; - - struct SelfNode : public ENode { - SelfNode() { - type = TYPE_SELF; - } - }; - - struct IndexNode : public ENode { - ENode *base = nullptr; - ENode *index = nullptr; - - IndexNode() { - type = TYPE_INDEX; - } - }; - - struct NamedIndexNode : public ENode { - ENode *base = nullptr; - StringName name; - - NamedIndexNode() { - type = TYPE_NAMED_INDEX; - } - }; - - struct ConstructorNode : public ENode { - Variant::Type data_type = Variant::Type::NIL; - Vector<ENode *> arguments; - - ConstructorNode() { - type = TYPE_CONSTRUCTOR; - } - }; - - struct CallNode : public ENode { - ENode *base = nullptr; - StringName method; - Vector<ENode *> arguments; - - CallNode() { - type = TYPE_CALL; - } - }; - - struct ArrayNode : public ENode { - Vector<ENode *> array; - ArrayNode() { - type = TYPE_ARRAY; - } - }; - - struct DictionaryNode : public ENode { - Vector<ENode *> dict; - DictionaryNode() { - type = TYPE_DICTIONARY; - } - }; - - struct BuiltinFuncNode : public ENode { - VisualScriptBuiltinFunc::BuiltinFunc func = VisualScriptBuiltinFunc::BuiltinFunc::BYTES_TO_VAR; - Vector<ENode *> arguments; - BuiltinFuncNode() { - type = TYPE_BUILTIN_FUNC; - } - }; - - template <class T> - T *alloc_node() { - T *node = memnew(T); - node->next = nodes; - nodes = node; - return node; - } - - ENode *root = nullptr; - ENode *nodes = nullptr; - -protected: - bool _set(const StringName &p_name, const Variant &p_value); - bool _get(const StringName &p_name, Variant &r_ret) const; - void _get_property_list(List<PropertyInfo> *p_list) const; - -public: - virtual void reset_state() override; - - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_text() const override; - virtual String get_category() const override { return "operators"; } - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptExpression(); - ~VisualScriptExpression(); -}; - -void register_visual_script_expression_node(); - -#endif // VISUAL_SCRIPT_EXPRESSION_H diff --git a/modules/visual_script/visual_script_flow_control.cpp b/modules/visual_script/visual_script_flow_control.cpp deleted file mode 100644 index 19bbd834cc..0000000000 --- a/modules/visual_script/visual_script_flow_control.cpp +++ /dev/null @@ -1,880 +0,0 @@ -/*************************************************************************/ -/* visual_script_flow_control.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "visual_script_flow_control.h" - -#include "core/config/project_settings.h" -#include "core/io/resource_loader.h" -#include "core/os/keyboard.h" - -////////////////////////////////////////// -////////////////RETURN//////////////////// -////////////////////////////////////////// - -int VisualScriptReturn::get_output_sequence_port_count() const { - return 0; -} - -bool VisualScriptReturn::has_input_sequence_port() const { - return true; -} - -int VisualScriptReturn::get_input_value_port_count() const { - return with_value ? 1 : 0; -} - -int VisualScriptReturn::get_output_value_port_count() const { - return 0; -} - -String VisualScriptReturn::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptReturn::get_input_value_port_info(int p_idx) const { - PropertyInfo pinfo; - pinfo.name = "result"; - pinfo.type = type; - return pinfo; -} - -PropertyInfo VisualScriptReturn::get_output_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -String VisualScriptReturn::get_caption() const { - return RTR("Return"); -} - -String VisualScriptReturn::get_text() const { - return get_name(); -} - -void VisualScriptReturn::set_return_type(Variant::Type p_type) { - if (type == p_type) { - return; - } - type = p_type; - ports_changed_notify(); -} - -Variant::Type VisualScriptReturn::get_return_type() const { - return type; -} - -void VisualScriptReturn::set_enable_return_value(bool p_enable) { - if (with_value == p_enable) { - return; - } - - with_value = p_enable; - ports_changed_notify(); -} - -bool VisualScriptReturn::is_return_value_enabled() const { - return with_value; -} - -void VisualScriptReturn::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_return_type", "type"), &VisualScriptReturn::set_return_type); - ClassDB::bind_method(D_METHOD("get_return_type"), &VisualScriptReturn::get_return_type); - ClassDB::bind_method(D_METHOD("set_enable_return_value", "enable"), &VisualScriptReturn::set_enable_return_value); - ClassDB::bind_method(D_METHOD("is_return_value_enabled"), &VisualScriptReturn::is_return_value_enabled); - - String argt = "Any"; - for (int i = 1; i < Variant::VARIANT_MAX; i++) { - argt += "," + Variant::get_type_name(Variant::Type(i)); - } - - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "return_enabled"), "set_enable_return_value", "is_return_value_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "return_type", PROPERTY_HINT_ENUM, argt), "set_return_type", "get_return_type"); -} - -class VisualScriptNodeInstanceReturn : public VisualScriptNodeInstance { -public: - VisualScriptReturn *node = nullptr; - VisualScriptInstance *instance = nullptr; - bool with_value = false; - - virtual int get_working_memory_size() const override { return 1; } - //virtual bool is_output_port_unsequenced(int p_idx) const { return false; } - //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - if (with_value) { - *p_working_mem = *p_inputs[0]; - return STEP_EXIT_FUNCTION_BIT; - } else { - *p_working_mem = Variant(); - return 0; - } - } -}; - -VisualScriptNodeInstance *VisualScriptReturn::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceReturn *instance = memnew(VisualScriptNodeInstanceReturn); - instance->node = this; - instance->instance = p_instance; - instance->with_value = with_value; - return instance; -} - -VisualScriptReturn::VisualScriptReturn() { - with_value = false; - type = Variant::NIL; -} - -template <bool with_value> -static Ref<VisualScriptNode> create_return_node(const String &p_name) { - Ref<VisualScriptReturn> node; - node.instantiate(); - node->set_enable_return_value(with_value); - return node; -} - -////////////////////////////////////////// -////////////////CONDITION///////////////// -////////////////////////////////////////// - -int VisualScriptCondition::get_output_sequence_port_count() const { - return 3; -} - -bool VisualScriptCondition::has_input_sequence_port() const { - return true; -} - -int VisualScriptCondition::get_input_value_port_count() const { - return 1; -} - -int VisualScriptCondition::get_output_value_port_count() const { - return 0; -} - -String VisualScriptCondition::get_output_sequence_port_text(int p_port) const { - if (p_port == 0) { - return "true"; - } else if (p_port == 1) { - return "false"; - } else { - return "done"; - } -} - -PropertyInfo VisualScriptCondition::get_input_value_port_info(int p_idx) const { - PropertyInfo pinfo; - pinfo.name = "cond"; - pinfo.type = Variant::BOOL; - return pinfo; -} - -PropertyInfo VisualScriptCondition::get_output_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -String VisualScriptCondition::get_caption() const { - return RTR("Condition"); -} - -String VisualScriptCondition::get_text() const { - return RTR("if (cond) is:"); -} - -void VisualScriptCondition::_bind_methods() { -} - -class VisualScriptNodeInstanceCondition : public VisualScriptNodeInstance { -public: - VisualScriptCondition *node = nullptr; - VisualScriptInstance *instance = nullptr; - - //virtual int get_working_memory_size() const override { return 1; } - //virtual bool is_output_port_unsequenced(int p_idx) const { return false; } - //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - if (p_start_mode == START_MODE_CONTINUE_SEQUENCE) { - return 2; - } else if (p_inputs[0]->operator bool()) { - return 0 | STEP_FLAG_PUSH_STACK_BIT; - } else { - return 1 | STEP_FLAG_PUSH_STACK_BIT; - } - } -}; - -VisualScriptNodeInstance *VisualScriptCondition::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceCondition *instance = memnew(VisualScriptNodeInstanceCondition); - instance->node = this; - instance->instance = p_instance; - return instance; -} - -VisualScriptCondition::VisualScriptCondition() { -} - -////////////////////////////////////////// -////////////////WHILE///////////////// -////////////////////////////////////////// - -int VisualScriptWhile::get_output_sequence_port_count() const { - return 2; -} - -bool VisualScriptWhile::has_input_sequence_port() const { - return true; -} - -int VisualScriptWhile::get_input_value_port_count() const { - return 1; -} - -int VisualScriptWhile::get_output_value_port_count() const { - return 0; -} - -String VisualScriptWhile::get_output_sequence_port_text(int p_port) const { - if (p_port == 0) { - return "repeat"; - } else { - return "exit"; - } -} - -PropertyInfo VisualScriptWhile::get_input_value_port_info(int p_idx) const { - PropertyInfo pinfo; - pinfo.name = "cond"; - pinfo.type = Variant::BOOL; - return pinfo; -} - -PropertyInfo VisualScriptWhile::get_output_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -String VisualScriptWhile::get_caption() const { - return RTR("While"); -} - -String VisualScriptWhile::get_text() const { - return RTR("while (cond):"); -} - -void VisualScriptWhile::_bind_methods() { -} - -class VisualScriptNodeInstanceWhile : public VisualScriptNodeInstance { -public: - VisualScriptWhile *node = nullptr; - VisualScriptInstance *instance = nullptr; - - //virtual int get_working_memory_size() const override { return 1; } - //virtual bool is_output_port_unsequenced(int p_idx) const { return false; } - //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - bool keep_going = p_inputs[0]->operator bool(); - - if (keep_going) { - return 0 | STEP_FLAG_PUSH_STACK_BIT; - } else { - return 1; - } - } -}; - -VisualScriptNodeInstance *VisualScriptWhile::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceWhile *instance = memnew(VisualScriptNodeInstanceWhile); - instance->node = this; - instance->instance = p_instance; - return instance; -} - -VisualScriptWhile::VisualScriptWhile() { -} - -////////////////////////////////////////// -////////////////ITERATOR///////////////// -////////////////////////////////////////// - -int VisualScriptIterator::get_output_sequence_port_count() const { - return 2; -} - -bool VisualScriptIterator::has_input_sequence_port() const { - return true; -} - -int VisualScriptIterator::get_input_value_port_count() const { - return 1; -} - -int VisualScriptIterator::get_output_value_port_count() const { - return 1; -} - -String VisualScriptIterator::get_output_sequence_port_text(int p_port) const { - if (p_port == 0) { - return "each"; - } else { - return "exit"; - } -} - -PropertyInfo VisualScriptIterator::get_input_value_port_info(int p_idx) const { - PropertyInfo pinfo; - pinfo.name = "input"; - pinfo.type = Variant::NIL; - return pinfo; -} - -PropertyInfo VisualScriptIterator::get_output_value_port_info(int p_idx) const { - PropertyInfo pinfo; - pinfo.name = "elem"; - pinfo.type = Variant::NIL; - return pinfo; -} - -String VisualScriptIterator::get_caption() const { - return RTR("Iterator"); -} - -String VisualScriptIterator::get_text() const { - return RTR("for (elem) in (input):"); -} - -void VisualScriptIterator::_bind_methods() { -} - -class VisualScriptNodeInstanceIterator : public VisualScriptNodeInstance { -public: - VisualScriptIterator *node = nullptr; - VisualScriptInstance *instance = nullptr; - - virtual int get_working_memory_size() const override { return 2; } - //virtual bool is_output_port_unsequenced(int p_idx) const { return false; } - //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - if (p_start_mode == START_MODE_BEGIN_SEQUENCE) { - p_working_mem[0] = *p_inputs[0]; - bool valid; - bool can_iter = p_inputs[0]->iter_init(p_working_mem[1], valid); - - if (!valid) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = RTR("Input type not iterable:") + " " + Variant::get_type_name(p_inputs[0]->get_type()); - return 0; - } - - if (!can_iter) { - return 1; //nothing to iterate - } - - *p_outputs[0] = p_working_mem[0].iter_get(p_working_mem[1], valid); - - if (!valid) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = RTR("Iterator became invalid"); - return 0; - } - - } else { //continue sequence - - bool valid; - bool can_iter = p_working_mem[0].iter_next(p_working_mem[1], valid); - - if (!valid) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = RTR("Iterator became invalid:") + " " + Variant::get_type_name(p_inputs[0]->get_type()); - return 0; - } - - if (!can_iter) { - return 1; //nothing to iterate - } - - *p_outputs[0] = p_working_mem[0].iter_get(p_working_mem[1], valid); - - if (!valid) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = RTR("Iterator became invalid"); - return 0; - } - } - - return 0 | STEP_FLAG_PUSH_STACK_BIT; //go around - } -}; - -VisualScriptNodeInstance *VisualScriptIterator::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceIterator *instance = memnew(VisualScriptNodeInstanceIterator); - instance->node = this; - instance->instance = p_instance; - return instance; -} - -VisualScriptIterator::VisualScriptIterator() { -} - -////////////////////////////////////////// -////////////////SEQUENCE///////////////// -////////////////////////////////////////// - -int VisualScriptSequence::get_output_sequence_port_count() const { - return steps; -} - -bool VisualScriptSequence::has_input_sequence_port() const { - return true; -} - -int VisualScriptSequence::get_input_value_port_count() const { - return 0; -} - -int VisualScriptSequence::get_output_value_port_count() const { - return 1; -} - -String VisualScriptSequence::get_output_sequence_port_text(int p_port) const { - return itos(p_port + 1); -} - -PropertyInfo VisualScriptSequence::get_input_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -PropertyInfo VisualScriptSequence::get_output_value_port_info(int p_idx) const { - return PropertyInfo(Variant::INT, "current"); -} - -String VisualScriptSequence::get_caption() const { - return RTR("Sequence"); -} - -String VisualScriptSequence::get_text() const { - return RTR("in order:"); -} - -void VisualScriptSequence::set_steps(int p_steps) { - ERR_FAIL_COND(p_steps < 1); - if (steps == p_steps) { - return; - } - - steps = p_steps; - ports_changed_notify(); -} - -int VisualScriptSequence::get_steps() const { - return steps; -} - -void VisualScriptSequence::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_steps", "steps"), &VisualScriptSequence::set_steps); - ClassDB::bind_method(D_METHOD("get_steps"), &VisualScriptSequence::get_steps); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "steps", PROPERTY_HINT_RANGE, "1,64,1"), "set_steps", "get_steps"); -} - -class VisualScriptNodeInstanceSequence : public VisualScriptNodeInstance { -public: - VisualScriptSequence *node = nullptr; - VisualScriptInstance *instance = nullptr; - int steps = 0; - - virtual int get_working_memory_size() const override { return 1; } - //virtual bool is_output_port_unsequenced(int p_idx) const { return false; } - //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - if (p_start_mode == START_MODE_BEGIN_SEQUENCE) { - p_working_mem[0] = 0; - } - - int step = p_working_mem[0]; - - *p_outputs[0] = step; - - if (step + 1 == steps) { - return step; - } else { - p_working_mem[0] = step + 1; - return step | STEP_FLAG_PUSH_STACK_BIT; - } - } -}; - -VisualScriptNodeInstance *VisualScriptSequence::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceSequence *instance = memnew(VisualScriptNodeInstanceSequence); - instance->node = this; - instance->instance = p_instance; - instance->steps = steps; - return instance; -} - -VisualScriptSequence::VisualScriptSequence() { - steps = 1; -} - -////////////////////////////////////////// -////////////////EVENT TYPE FILTER/////////// -////////////////////////////////////////// - -int VisualScriptSwitch::get_output_sequence_port_count() const { - return case_values.size() + 1; -} - -bool VisualScriptSwitch::has_input_sequence_port() const { - return true; -} - -int VisualScriptSwitch::get_input_value_port_count() const { - return case_values.size() + 1; -} - -int VisualScriptSwitch::get_output_value_port_count() const { - return 0; -} - -String VisualScriptSwitch::get_output_sequence_port_text(int p_port) const { - if (p_port == case_values.size()) { - return "done"; - } - - return String(); -} - -PropertyInfo VisualScriptSwitch::get_input_value_port_info(int p_idx) const { - if (p_idx < case_values.size()) { - return PropertyInfo(case_values[p_idx].type, " ="); - } else { - return PropertyInfo(Variant::NIL, "input"); - } -} - -PropertyInfo VisualScriptSwitch::get_output_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -String VisualScriptSwitch::get_caption() const { - return RTR("Switch"); -} - -String VisualScriptSwitch::get_text() const { - return RTR("'input' is:"); -} - -class VisualScriptNodeInstanceSwitch : public VisualScriptNodeInstance { -public: - VisualScriptInstance *instance = nullptr; - int case_count = 0; - - //virtual int get_working_memory_size() const override { return 0; } - //virtual bool is_output_port_unsequenced(int p_idx) const { return false; } - //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return false; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - if (p_start_mode == START_MODE_CONTINUE_SEQUENCE) { - return case_count; //exit - } - - for (int i = 0; i < case_count; i++) { - if (*p_inputs[i] == *p_inputs[case_count]) { - return i | STEP_FLAG_PUSH_STACK_BIT; - } - } - - return case_count; - } -}; - -VisualScriptNodeInstance *VisualScriptSwitch::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceSwitch *instance = memnew(VisualScriptNodeInstanceSwitch); - instance->instance = p_instance; - instance->case_count = case_values.size(); - return instance; -} - -bool VisualScriptSwitch::_set(const StringName &p_name, const Variant &p_value) { - if (String(p_name) == "case_count") { - case_values.resize(p_value); - notify_property_list_changed(); - ports_changed_notify(); - return true; - } - - if (String(p_name).begins_with("case/")) { - int idx = String(p_name).get_slice("/", 1).to_int(); - ERR_FAIL_INDEX_V(idx, case_values.size(), false); - - case_values.write[idx].type = Variant::Type(int(p_value)); - notify_property_list_changed(); - ports_changed_notify(); - - return true; - } - - return false; -} - -bool VisualScriptSwitch::_get(const StringName &p_name, Variant &r_ret) const { - if (String(p_name) == "case_count") { - r_ret = case_values.size(); - return true; - } - - if (String(p_name).begins_with("case/")) { - int idx = String(p_name).get_slice("/", 1).to_int(); - ERR_FAIL_INDEX_V(idx, case_values.size(), false); - - r_ret = case_values[idx].type; - return true; - } - - return false; -} - -void VisualScriptSwitch::_get_property_list(List<PropertyInfo> *p_list) const { - p_list->push_back(PropertyInfo(Variant::INT, "case_count", PROPERTY_HINT_RANGE, "0,128")); - - String argt = "Any"; - for (int i = 1; i < Variant::VARIANT_MAX; i++) { - argt += "," + Variant::get_type_name(Variant::Type(i)); - } - - for (int i = 0; i < case_values.size(); i++) { - p_list->push_back(PropertyInfo(Variant::INT, "case/" + itos(i), PROPERTY_HINT_ENUM, argt)); - } -} - -void VisualScriptSwitch::reset_state() { - case_values.clear(); -} - -void VisualScriptSwitch::_bind_methods() { -} - -VisualScriptSwitch::VisualScriptSwitch() { -} - -////////////////////////////////////////// -////////////////TYPE CAST/////////// -////////////////////////////////////////// - -int VisualScriptTypeCast::get_output_sequence_port_count() const { - return 2; -} - -bool VisualScriptTypeCast::has_input_sequence_port() const { - return true; -} - -int VisualScriptTypeCast::get_input_value_port_count() const { - return 1; -} - -int VisualScriptTypeCast::get_output_value_port_count() const { - return 1; -} - -String VisualScriptTypeCast::get_output_sequence_port_text(int p_port) const { - return p_port == 0 ? "yes" : "no"; -} - -PropertyInfo VisualScriptTypeCast::get_input_value_port_info(int p_idx) const { - return PropertyInfo(Variant::OBJECT, "instance"); -} - -PropertyInfo VisualScriptTypeCast::get_output_value_port_info(int p_idx) const { - return PropertyInfo(Variant::OBJECT, "", PROPERTY_HINT_TYPE_STRING, get_base_type()); -} - -String VisualScriptTypeCast::get_caption() const { - return RTR("Type Cast"); -} - -String VisualScriptTypeCast::get_text() const { - if (!script.is_empty()) { - return vformat(RTR("Is %s?"), script.get_file()); - } else { - return vformat(RTR("Is %s?"), base_type); - } -} - -void VisualScriptTypeCast::set_base_type(const StringName &p_type) { - if (base_type == p_type) { - return; - } - - base_type = p_type; - notify_property_list_changed(); - ports_changed_notify(); -} - -StringName VisualScriptTypeCast::get_base_type() const { - return base_type; -} - -void VisualScriptTypeCast::set_base_script(const String &p_path) { - if (script == p_path) { - return; - } - - script = p_path; - notify_property_list_changed(); - ports_changed_notify(); -} - -String VisualScriptTypeCast::get_base_script() const { - return script; -} - -VisualScriptTypeCast::TypeGuess VisualScriptTypeCast::guess_output_type(TypeGuess *p_inputs, int p_output) const { - TypeGuess tg; - tg.type = Variant::OBJECT; - if (!script.is_empty()) { - tg.script = ResourceLoader::load(script); - } - //if (!tg.script.is_valid()) { - // tg.gdclass = base_type; - //} - - return tg; -} - -class VisualScriptNodeInstanceTypeCast : public VisualScriptNodeInstance { -public: - VisualScriptInstance *instance = nullptr; - StringName base_type; - String script; - - //virtual int get_working_memory_size() const override { return 0; } - //virtual bool is_output_port_unsequenced(int p_idx) const { return false; } - //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return false; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - Object *obj = *p_inputs[0]; - - *p_outputs[0] = Variant(); - - if (!obj) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = "Instance is null"; - return 0; - } - - if (!script.is_empty()) { - Ref<Script> obj_script = obj->get_script(); - if (!obj_script.is_valid()) { - return 1; //well, definitely not the script because object we got has no script. - } - - if (!ResourceCache::has(script)) { - //if the script is not in use by anyone, we can safely assume whatever we got is not casting to it. - return 1; - } - Ref<Script> cast_script = ResourceCache::get_ref(script); - if (!cast_script.is_valid()) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = "Script path is not a script: " + script; - return 1; - } - - while (obj_script.is_valid()) { - if (cast_script == obj_script) { - *p_outputs[0] = *p_inputs[0]; //copy - return 0; // it is the script, yey - } - - obj_script = obj_script->get_base_script(); - } - - return 1; //not found sorry - } - - if (ClassDB::is_parent_class(obj->get_class_name(), base_type)) { - *p_outputs[0] = *p_inputs[0]; //copy - return 0; - } else { - return 1; - } - } -}; - -VisualScriptNodeInstance *VisualScriptTypeCast::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceTypeCast *instance = memnew(VisualScriptNodeInstanceTypeCast); - instance->instance = p_instance; - instance->base_type = base_type; - instance->script = script; - return instance; -} - -void VisualScriptTypeCast::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_base_type", "type"), &VisualScriptTypeCast::set_base_type); - ClassDB::bind_method(D_METHOD("get_base_type"), &VisualScriptTypeCast::get_base_type); - - ClassDB::bind_method(D_METHOD("set_base_script", "path"), &VisualScriptTypeCast::set_base_script); - ClassDB::bind_method(D_METHOD("get_base_script"), &VisualScriptTypeCast::get_base_script); - - List<String> script_extensions; - for (int i = 0; i > ScriptServer::get_language_count(); i++) { - ScriptServer::get_language(i)->get_recognized_extensions(&script_extensions); - } - - String script_ext_hint; - for (const String &E : script_extensions) { - if (!script_ext_hint.is_empty()) { - script_ext_hint += ","; - } - script_ext_hint += "*." + E; - } - - ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_type", PROPERTY_HINT_TYPE_STRING, "Object"), "set_base_type", "get_base_type"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_script", PROPERTY_HINT_FILE, script_ext_hint), "set_base_script", "get_base_script"); -} - -VisualScriptTypeCast::VisualScriptTypeCast() { - base_type = "Object"; -} - -void register_visual_script_flow_control_nodes() { - VisualScriptLanguage::singleton->add_register_func("flow_control/return", create_return_node<false>); - VisualScriptLanguage::singleton->add_register_func("flow_control/return_with_value", create_return_node<true>); - VisualScriptLanguage::singleton->add_register_func("flow_control/condition", create_node_generic<VisualScriptCondition>); - VisualScriptLanguage::singleton->add_register_func("flow_control/while", create_node_generic<VisualScriptWhile>); - VisualScriptLanguage::singleton->add_register_func("flow_control/iterator", create_node_generic<VisualScriptIterator>); - VisualScriptLanguage::singleton->add_register_func("flow_control/sequence", create_node_generic<VisualScriptSequence>); - VisualScriptLanguage::singleton->add_register_func("flow_control/switch", create_node_generic<VisualScriptSwitch>); - //VisualScriptLanguage::singleton->add_register_func("flow_control/input", create_node_generic<VisualScriptInputFilter>); - VisualScriptLanguage::singleton->add_register_func("flow_control/type_cast", create_node_generic<VisualScriptTypeCast>); -} diff --git a/modules/visual_script/visual_script_flow_control.h b/modules/visual_script/visual_script_flow_control.h deleted file mode 100644 index 7ffdf3df65..0000000000 --- a/modules/visual_script/visual_script_flow_control.h +++ /dev/null @@ -1,268 +0,0 @@ -/*************************************************************************/ -/* visual_script_flow_control.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef VISUAL_SCRIPT_FLOW_CONTROL_H -#define VISUAL_SCRIPT_FLOW_CONTROL_H - -#include "visual_script.h" - -class VisualScriptReturn : public VisualScriptNode { - GDCLASS(VisualScriptReturn, VisualScriptNode); - - Variant::Type type; - bool with_value; - -protected: - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_text() const override; - virtual String get_category() const override { return "flow_control"; } - - void set_return_type(Variant::Type); - Variant::Type get_return_type() const; - - void set_enable_return_value(bool p_enable); - bool is_return_value_enabled() const; - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptReturn(); -}; - -class VisualScriptCondition : public VisualScriptNode { - GDCLASS(VisualScriptCondition, VisualScriptNode); - -protected: - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_text() const override; - virtual String get_category() const override { return "flow_control"; } - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptCondition(); -}; - -class VisualScriptWhile : public VisualScriptNode { - GDCLASS(VisualScriptWhile, VisualScriptNode); - -protected: - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_text() const override; - virtual String get_category() const override { return "flow_control"; } - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptWhile(); -}; - -class VisualScriptIterator : public VisualScriptNode { - GDCLASS(VisualScriptIterator, VisualScriptNode); - -protected: - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_text() const override; - virtual String get_category() const override { return "flow_control"; } - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptIterator(); -}; - -class VisualScriptSequence : public VisualScriptNode { - GDCLASS(VisualScriptSequence, VisualScriptNode); - - int steps; - -protected: - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_text() const override; - virtual String get_category() const override { return "flow_control"; } - - void set_steps(int p_steps); - int get_steps() const; - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptSequence(); -}; - -class VisualScriptSwitch : public VisualScriptNode { - GDCLASS(VisualScriptSwitch, VisualScriptNode); - - struct Case { - Variant::Type type; - Case() { type = Variant::NIL; } - }; - - Vector<Case> case_values; - - friend class VisualScriptNodeInstanceSwitch; - -protected: - bool _set(const StringName &p_name, const Variant &p_value); - bool _get(const StringName &p_name, Variant &r_ret) const; - void _get_property_list(List<PropertyInfo> *p_list) const; - - static void _bind_methods(); - -public: - virtual void reset_state() override; - - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - virtual bool has_mixed_input_and_sequence_ports() const override { return true; } - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_text() const override; - virtual String get_category() const override { return "flow_control"; } - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptSwitch(); -}; - -class VisualScriptTypeCast : public VisualScriptNode { - GDCLASS(VisualScriptTypeCast, VisualScriptNode); - - StringName base_type; - String script; - -protected: - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_text() const override; - virtual String get_category() const override { return "flow_control"; } - - void set_base_type(const StringName &p_type); - StringName get_base_type() const; - - void set_base_script(const String &p_path); - String get_base_script() const; - - virtual TypeGuess guess_output_type(TypeGuess *p_inputs, int p_output) const override; - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptTypeCast(); -}; - -void register_visual_script_flow_control_nodes(); - -#endif // VISUAL_SCRIPT_FLOW_CONTROL_H diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp deleted file mode 100644 index e79d3bae8a..0000000000 --- a/modules/visual_script/visual_script_func_nodes.cpp +++ /dev/null @@ -1,2444 +0,0 @@ -/*************************************************************************/ -/* visual_script_func_nodes.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "visual_script_func_nodes.h" - -#include "core/config/engine.h" -#include "core/io/resource_loader.h" -#include "core/os/os.h" -#include "core/templates/local_vector.h" -#include "scene/main/node.h" -#include "scene/main/scene_tree.h" -#include "visual_script_nodes.h" - -////////////////////////////////////////// -////////////////CALL////////////////////// -////////////////////////////////////////// - -int VisualScriptFunctionCall::get_output_sequence_port_count() const { - if ((method_cache.flags & METHOD_FLAG_CONST && call_mode != CALL_MODE_INSTANCE) || (call_mode == CALL_MODE_BASIC_TYPE && Variant::is_builtin_method_const(basic_type, function))) { - return 0; - } else { - return 1; - } -} - -bool VisualScriptFunctionCall::has_input_sequence_port() const { - return !((method_cache.flags & METHOD_FLAG_CONST && call_mode != CALL_MODE_INSTANCE) || (call_mode == CALL_MODE_BASIC_TYPE && Variant::is_builtin_method_const(basic_type, function))); -} -#ifdef TOOLS_ENABLED - -static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) { - if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene) { - return nullptr; - } - - Ref<Script> scr = p_current_node->get_script(); - - if (scr.is_valid() && scr == script) { - return p_current_node; - } - - for (int i = 0; i < p_current_node->get_child_count(); i++) { - Node *n = _find_script_node(p_edited_scene, p_current_node->get_child(i), script); - if (n) { - return n; - } - } - - return nullptr; -} - -#endif -Node *VisualScriptFunctionCall::_get_base_node() const { -#ifdef TOOLS_ENABLED - Ref<Script> script = get_visual_script(); - if (!script.is_valid()) { - return nullptr; - } - - MainLoop *main_loop = OS::get_singleton()->get_main_loop(); - SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop); - - if (!scene_tree) { - return nullptr; - } - - Node *edited_scene = scene_tree->get_edited_scene_root(); - - if (!edited_scene) { - return nullptr; - } - - Node *script_node = _find_script_node(edited_scene, edited_scene, script); - - if (!script_node) { - return nullptr; - } - - if (!script_node->has_node(base_path)) { - return nullptr; - } - - Node *path_to = script_node->get_node(base_path); - - return path_to; -#else - - return nullptr; -#endif -} - -StringName VisualScriptFunctionCall::_get_base_type() const { - if (call_mode == CALL_MODE_SELF && get_visual_script().is_valid()) { - return get_visual_script()->get_instance_base_type(); - } else if (call_mode == CALL_MODE_NODE_PATH && get_visual_script().is_valid()) { - Node *path = _get_base_node(); - if (path) { - return path->get_class(); - } - } - - return base_type; -} - -int VisualScriptFunctionCall::get_input_value_port_count() const { - if (call_mode == CALL_MODE_BASIC_TYPE) { - Vector<Variant::Type> types; - int argc = Variant::get_builtin_method_argument_count(basic_type, function); - for (int i = 0; i < argc; i++) { - types.push_back(Variant::get_builtin_method_argument_type(basic_type, function, i)); - } - return types.size() + (rpc_call_mode >= RPC_RELIABLE_TO_ID ? 1 : 0) + 1; - - } else { - MethodBind *mb = ClassDB::get_method(_get_base_type(), function); - if (mb) { - int defaulted_args = mb->get_argument_count() < use_default_args ? mb->get_argument_count() : use_default_args; - return mb->get_argument_count() + (call_mode == CALL_MODE_INSTANCE ? 1 : 0) + (rpc_call_mode >= RPC_RELIABLE_TO_ID ? 1 : 0) - defaulted_args; - } - - int defaulted_args = method_cache.arguments.size() < use_default_args ? method_cache.arguments.size() : use_default_args; - return method_cache.arguments.size() + (call_mode == CALL_MODE_INSTANCE ? 1 : 0) + (rpc_call_mode >= RPC_RELIABLE_TO_ID ? 1 : 0) - defaulted_args; - } -} - -int VisualScriptFunctionCall::get_output_value_port_count() const { - if (call_mode == CALL_MODE_BASIC_TYPE) { - bool returns = Variant::has_builtin_method_return_value(basic_type, function); - return returns ? 1 : 0; - - } else { - int ret; - MethodBind *mb = ClassDB::get_method(_get_base_type(), function); - if (mb) { - ret = mb->has_return() ? 1 : 0; - } else { - ret = 1; //it is assumed that script always returns something - } - - if (call_mode == CALL_MODE_INSTANCE) { - ret++; - } - - return ret; - } -} - -String VisualScriptFunctionCall::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptFunctionCall::get_input_value_port_info(int p_idx) const { - if (call_mode == CALL_MODE_INSTANCE || call_mode == CALL_MODE_BASIC_TYPE) { - if (p_idx == 0) { - PropertyInfo pi; - pi.type = (call_mode == CALL_MODE_INSTANCE ? Variant::OBJECT : basic_type); - pi.name = (call_mode == CALL_MODE_INSTANCE ? String("instance") : Variant::get_type_name(basic_type).to_lower()); - return pi; - } else { - p_idx--; - } - } - - if (rpc_call_mode >= RPC_RELIABLE_TO_ID) { - if (p_idx == 0) { - return PropertyInfo(Variant::INT, "peer_id"); - } else { - p_idx--; - } - } - -#ifdef DEBUG_METHODS_ENABLED - - if (call_mode == CALL_MODE_BASIC_TYPE) { - return PropertyInfo(Variant::get_builtin_method_argument_type(basic_type, function, p_idx), Variant::get_builtin_method_argument_name(basic_type, function, p_idx)); - } else { - MethodBind *mb = ClassDB::get_method(_get_base_type(), function); - if (mb) { - return mb->get_argument_info(p_idx); - } - - if (p_idx >= 0 && p_idx < method_cache.arguments.size()) { - return method_cache.arguments[p_idx]; - } - - return PropertyInfo(); - } -#else - return PropertyInfo(); -#endif -} - -PropertyInfo VisualScriptFunctionCall::get_output_value_port_info(int p_idx) const { -#ifdef DEBUG_METHODS_ENABLED - - if (call_mode == CALL_MODE_BASIC_TYPE) { - return PropertyInfo(Variant::get_builtin_method_return_type(basic_type, function), ""); - } else { - if (call_mode == CALL_MODE_INSTANCE) { - if (p_idx == 0) { - return PropertyInfo(Variant::OBJECT, "pass", PROPERTY_HINT_TYPE_STRING, get_base_type()); - } else { - p_idx--; - } - } - - PropertyInfo ret; - - /*MethodBind *mb = ClassDB::get_method(_get_base_type(),function); - if (mb) { - ret = mb->get_argument_info(-1); - } else {*/ - - ret = method_cache.return_val; - - //} - - if (call_mode == CALL_MODE_INSTANCE) { - ret.name = "return"; - } else { - ret.name = ""; - } - return ret; - } -#else - return PropertyInfo(); -#endif -} - -String VisualScriptFunctionCall::get_caption() const { - return " " + String(function) + "()"; -} - -String VisualScriptFunctionCall::get_text() const { - String text; - - if (call_mode == CALL_MODE_BASIC_TYPE) { - text = vformat(RTR("On %s"), Variant::get_type_name(basic_type)); - } else if (call_mode == CALL_MODE_INSTANCE) { - text = vformat(RTR("On %s"), base_type); - } else if (call_mode == CALL_MODE_NODE_PATH) { - text = "[" + String(base_path.simplified()) + "]"; - } else if (call_mode == CALL_MODE_SELF) { - text = RTR("On Self"); - } else if (call_mode == CALL_MODE_SINGLETON) { - text = String(singleton) + ":" + String(function) + "()"; - } - - if (rpc_call_mode) { - text += " RPC"; - if (rpc_call_mode == RPC_UNRELIABLE || rpc_call_mode == RPC_UNRELIABLE_TO_ID) { - text += " UNREL"; - } - } - - return text; -} - -void VisualScriptFunctionCall::set_basic_type(Variant::Type p_type) { - if (basic_type == p_type) { - return; - } - basic_type = p_type; - - notify_property_list_changed(); - ports_changed_notify(); -} - -Variant::Type VisualScriptFunctionCall::get_basic_type() const { - return basic_type; -} - -void VisualScriptFunctionCall::set_base_type(const StringName &p_type) { - if (base_type == p_type) { - return; - } - - base_type = p_type; - notify_property_list_changed(); - ports_changed_notify(); -} - -StringName VisualScriptFunctionCall::get_base_type() const { - return base_type; -} - -void VisualScriptFunctionCall::set_base_script(const String &p_path) { - if (base_script == p_path) { - return; - } - - base_script = p_path; - notify_property_list_changed(); - ports_changed_notify(); -} - -String VisualScriptFunctionCall::get_base_script() const { - return base_script; -} - -void VisualScriptFunctionCall::set_singleton(const StringName &p_type) { - if (singleton == p_type) { - return; - } - - singleton = p_type; - Object *obj = Engine::get_singleton()->get_singleton_object(singleton); - if (obj) { - base_type = obj->get_class(); - } - - notify_property_list_changed(); - ports_changed_notify(); -} - -StringName VisualScriptFunctionCall::get_singleton() const { - return singleton; -} - -void VisualScriptFunctionCall::_update_method_cache() { - StringName type; - Ref<Script> script; - - if (call_mode == CALL_MODE_NODE_PATH) { - Node *node = _get_base_node(); - if (node) { - type = node->get_class(); - base_type = type; //cache, too - script = node->get_script(); - } - } else if (call_mode == CALL_MODE_SELF) { - if (get_visual_script().is_valid()) { - type = get_visual_script()->get_instance_base_type(); - base_type = type; //cache, too - script = get_visual_script(); - } - - } else if (call_mode == CALL_MODE_SINGLETON) { - Object *obj = Engine::get_singleton()->get_singleton_object(singleton); - if (obj) { - type = obj->get_class(); - script = obj->get_script(); - } - - } else if (call_mode == CALL_MODE_INSTANCE) { - type = base_type; - if (!base_script.is_empty()) { - if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) { - ScriptServer::edit_request_func(base_script); //make sure it's loaded - } - - if (ResourceCache::has(base_script)) { - script = ResourceCache::get_ref(base_script); - } else { - return; - } - } - } - - MethodBind *mb = ClassDB::get_method(type, function); - if (mb) { - use_default_args = mb->get_default_argument_count(); - method_cache = MethodInfo(); - for (int i = 0; i < mb->get_argument_count(); i++) { -#ifdef DEBUG_METHODS_ENABLED - method_cache.arguments.push_back(mb->get_argument_info(i)); -#else - method_cache.arguments.push_back(PropertyInfo()); -#endif - } - - if (mb->is_const()) { - method_cache.flags |= METHOD_FLAG_CONST; - } - -#ifdef DEBUG_METHODS_ENABLED - - method_cache.return_val = mb->get_return_info(); -#endif - - if (mb->is_vararg()) { - //for vararg just give it 10 arguments (should be enough for most use cases) - for (int i = 0; i < 10; i++) { - method_cache.arguments.push_back(PropertyInfo(Variant::NIL, "arg" + itos(i))); - use_default_args++; - } - } - } else if (script.is_valid() && script->has_method(function)) { - method_cache = script->get_method_info(function); - use_default_args = method_cache.default_arguments.size(); - } -} - -void VisualScriptFunctionCall::set_function(const StringName &p_type) { - if (function == p_type) { - return; - } - - function = p_type; - - if (call_mode == CALL_MODE_BASIC_TYPE) { - use_default_args = Variant::get_builtin_method_default_arguments(basic_type, function).size(); - } else { - //update all caches - - _update_method_cache(); - } - - notify_property_list_changed(); - ports_changed_notify(); -} - -StringName VisualScriptFunctionCall::get_function() const { - return function; -} - -void VisualScriptFunctionCall::set_base_path(const NodePath &p_type) { - if (base_path == p_type) { - return; - } - - base_path = p_type; - notify_property_list_changed(); - ports_changed_notify(); -} - -NodePath VisualScriptFunctionCall::get_base_path() const { - return base_path; -} - -void VisualScriptFunctionCall::set_call_mode(CallMode p_mode) { - if (call_mode == p_mode) { - return; - } - - call_mode = p_mode; - notify_property_list_changed(); - ports_changed_notify(); -} - -VisualScriptFunctionCall::CallMode VisualScriptFunctionCall::get_call_mode() const { - return call_mode; -} - -void VisualScriptFunctionCall::set_use_default_args(int p_amount) { - if (use_default_args == p_amount) { - return; - } - - use_default_args = p_amount; - ports_changed_notify(); -} - -void VisualScriptFunctionCall::set_rpc_call_mode(VisualScriptFunctionCall::RPCCallMode p_mode) { - if (rpc_call_mode == p_mode) { - return; - } - rpc_call_mode = p_mode; - ports_changed_notify(); - notify_property_list_changed(); -} - -VisualScriptFunctionCall::RPCCallMode VisualScriptFunctionCall::get_rpc_call_mode() const { - return rpc_call_mode; -} - -int VisualScriptFunctionCall::get_use_default_args() const { - return use_default_args; -} - -void VisualScriptFunctionCall::set_validate(bool p_amount) { - validate = p_amount; -} - -bool VisualScriptFunctionCall::get_validate() const { - return validate; -} - -void VisualScriptFunctionCall::_set_argument_cache(const Dictionary &p_cache) { - //so everything works in case all else fails - method_cache = MethodInfo::from_dict(p_cache); -} - -Dictionary VisualScriptFunctionCall::_get_argument_cache() const { - return method_cache; -} - -void VisualScriptFunctionCall::_validate_property(PropertyInfo &p_property) const { - if (p_property.name == "base_type") { - if (call_mode != CALL_MODE_INSTANCE) { - p_property.usage = PROPERTY_USAGE_NO_EDITOR; - } - } - - if (p_property.name == "base_script") { - if (call_mode != CALL_MODE_INSTANCE) { - p_property.usage = PROPERTY_USAGE_NONE; - } - } - - if (p_property.name == "basic_type") { - if (call_mode != CALL_MODE_BASIC_TYPE) { - p_property.usage = PROPERTY_USAGE_NONE; - } - } - - if (p_property.name == "singleton") { - if (call_mode != CALL_MODE_SINGLETON) { - p_property.usage = PROPERTY_USAGE_NONE; - } else { - List<Engine::Singleton> names; - Engine::get_singleton()->get_singletons(&names); - p_property.hint = PROPERTY_HINT_ENUM; - String sl; - for (const Engine::Singleton &E : names) { - if (!sl.is_empty()) { - sl += ","; - } - sl += E.name; - } - p_property.hint_string = sl; - } - } - - if (p_property.name == "node_path") { - if (call_mode != CALL_MODE_NODE_PATH) { - p_property.usage = PROPERTY_USAGE_NONE; - } else { - Node *bnode = _get_base_node(); - if (bnode) { - p_property.hint_string = bnode->get_path(); //convert to long string - } - } - } - - if (p_property.name == "function") { - if (call_mode == CALL_MODE_BASIC_TYPE) { - p_property.hint = PROPERTY_HINT_METHOD_OF_VARIANT_TYPE; - p_property.hint_string = Variant::get_type_name(basic_type); - - } else if (call_mode == CALL_MODE_SELF && get_visual_script().is_valid()) { - p_property.hint = PROPERTY_HINT_METHOD_OF_SCRIPT; - p_property.hint_string = itos(get_visual_script()->get_instance_id()); - } else if (call_mode == CALL_MODE_SINGLETON) { - Object *obj = Engine::get_singleton()->get_singleton_object(singleton); - if (obj) { - p_property.hint = PROPERTY_HINT_METHOD_OF_INSTANCE; - p_property.hint_string = itos(obj->get_instance_id()); - } else { - p_property.hint = PROPERTY_HINT_METHOD_OF_BASE_TYPE; - p_property.hint_string = base_type; //should be cached - } - } else if (call_mode == CALL_MODE_INSTANCE) { - p_property.hint = PROPERTY_HINT_METHOD_OF_BASE_TYPE; - p_property.hint_string = base_type; - - if (!base_script.is_empty()) { - if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) { - ScriptServer::edit_request_func(base_script); //make sure it's loaded - } - - if (ResourceCache::has(base_script)) { - Ref<Script> script = ResourceCache::get_ref(base_script); - if (script.is_valid()) { - p_property.hint = PROPERTY_HINT_METHOD_OF_SCRIPT; - p_property.hint_string = itos(script->get_instance_id()); - } - } - } - - } else if (call_mode == CALL_MODE_NODE_PATH) { - Node *node = _get_base_node(); - if (node) { - p_property.hint = PROPERTY_HINT_METHOD_OF_INSTANCE; - p_property.hint_string = itos(node->get_instance_id()); - } else { - p_property.hint = PROPERTY_HINT_METHOD_OF_BASE_TYPE; - p_property.hint_string = get_base_type(); - } - } - } - - if (p_property.name == "use_default_args") { - p_property.hint = PROPERTY_HINT_RANGE; - - int mc = 0; - - if (call_mode == CALL_MODE_BASIC_TYPE) { - mc = Variant::get_builtin_method_default_arguments(basic_type, function).size(); - } else { - MethodBind *mb = ClassDB::get_method(_get_base_type(), function); - if (mb) { - mc = mb->get_default_argument_count(); - } - } - - if (mc == 0) { - p_property.usage = PROPERTY_USAGE_NONE; //do not show - } else { - p_property.hint_string = "0," + itos(mc) + ",1"; - } - } - - if (p_property.name == "rpc_call_mode") { - if (call_mode == CALL_MODE_BASIC_TYPE) { - p_property.usage = PROPERTY_USAGE_NONE; - } - } -} - -void VisualScriptFunctionCall::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_base_type", "base_type"), &VisualScriptFunctionCall::set_base_type); - ClassDB::bind_method(D_METHOD("get_base_type"), &VisualScriptFunctionCall::get_base_type); - - ClassDB::bind_method(D_METHOD("set_base_script", "base_script"), &VisualScriptFunctionCall::set_base_script); - ClassDB::bind_method(D_METHOD("get_base_script"), &VisualScriptFunctionCall::get_base_script); - - ClassDB::bind_method(D_METHOD("set_basic_type", "basic_type"), &VisualScriptFunctionCall::set_basic_type); - ClassDB::bind_method(D_METHOD("get_basic_type"), &VisualScriptFunctionCall::get_basic_type); - - ClassDB::bind_method(D_METHOD("set_singleton", "singleton"), &VisualScriptFunctionCall::set_singleton); - ClassDB::bind_method(D_METHOD("get_singleton"), &VisualScriptFunctionCall::get_singleton); - - ClassDB::bind_method(D_METHOD("set_function", "function"), &VisualScriptFunctionCall::set_function); - ClassDB::bind_method(D_METHOD("get_function"), &VisualScriptFunctionCall::get_function); - - ClassDB::bind_method(D_METHOD("set_call_mode", "mode"), &VisualScriptFunctionCall::set_call_mode); - ClassDB::bind_method(D_METHOD("get_call_mode"), &VisualScriptFunctionCall::get_call_mode); - - ClassDB::bind_method(D_METHOD("set_base_path", "base_path"), &VisualScriptFunctionCall::set_base_path); - ClassDB::bind_method(D_METHOD("get_base_path"), &VisualScriptFunctionCall::get_base_path); - - ClassDB::bind_method(D_METHOD("set_use_default_args", "amount"), &VisualScriptFunctionCall::set_use_default_args); - ClassDB::bind_method(D_METHOD("get_use_default_args"), &VisualScriptFunctionCall::get_use_default_args); - - ClassDB::bind_method(D_METHOD("_set_argument_cache", "argument_cache"), &VisualScriptFunctionCall::_set_argument_cache); - ClassDB::bind_method(D_METHOD("_get_argument_cache"), &VisualScriptFunctionCall::_get_argument_cache); - - ClassDB::bind_method(D_METHOD("set_rpc_call_mode", "mode"), &VisualScriptFunctionCall::set_rpc_call_mode); - ClassDB::bind_method(D_METHOD("get_rpc_call_mode"), &VisualScriptFunctionCall::get_rpc_call_mode); - - ClassDB::bind_method(D_METHOD("set_validate", "enable"), &VisualScriptFunctionCall::set_validate); - ClassDB::bind_method(D_METHOD("get_validate"), &VisualScriptFunctionCall::get_validate); - - String bt; - for (int i = 0; i < Variant::VARIANT_MAX; i++) { - if (i > 0) { - bt += ","; - } - - bt += Variant::get_type_name(Variant::Type(i)); - } - - List<String> script_extensions; - for (int i = 0; i < ScriptServer::get_language_count(); i++) { - ScriptServer::get_language(i)->get_recognized_extensions(&script_extensions); - } - - String script_ext_hint; - for (const String &E : script_extensions) { - if (!script_ext_hint.is_empty()) { - script_ext_hint += ","; - } - script_ext_hint += "*." + E; - } - - ADD_PROPERTY(PropertyInfo(Variant::INT, "call_mode", PROPERTY_HINT_ENUM, "Self,Node Path,Instance,Basic Type,Singleton"), "set_call_mode", "get_call_mode"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_type", PROPERTY_HINT_TYPE_STRING, "Object"), "set_base_type", "get_base_type"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_script", PROPERTY_HINT_FILE, script_ext_hint), "set_base_script", "get_base_script"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "singleton"), "set_singleton", "get_singleton"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "basic_type", PROPERTY_HINT_ENUM, bt), "set_basic_type", "get_basic_type"); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_path", PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE), "set_base_path", "get_base_path"); - ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "argument_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_argument_cache", "_get_argument_cache"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "function"), "set_function", "get_function"); //when set, if loaded properly, will override argument count. - ADD_PROPERTY(PropertyInfo(Variant::INT, "use_default_args"), "set_use_default_args", "get_use_default_args"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "validate"), "set_validate", "get_validate"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "rpc_call_mode", PROPERTY_HINT_ENUM, "Disabled,Reliable,Unreliable,ReliableToID,UnreliableToID"), "set_rpc_call_mode", "get_rpc_call_mode"); //when set, if loaded properly, will override argument count. - - BIND_ENUM_CONSTANT(CALL_MODE_SELF); - BIND_ENUM_CONSTANT(CALL_MODE_NODE_PATH); - BIND_ENUM_CONSTANT(CALL_MODE_INSTANCE); - BIND_ENUM_CONSTANT(CALL_MODE_BASIC_TYPE); - BIND_ENUM_CONSTANT(CALL_MODE_SINGLETON); - - BIND_ENUM_CONSTANT(RPC_DISABLED); - BIND_ENUM_CONSTANT(RPC_RELIABLE); - BIND_ENUM_CONSTANT(RPC_UNRELIABLE); - BIND_ENUM_CONSTANT(RPC_RELIABLE_TO_ID); - BIND_ENUM_CONSTANT(RPC_UNRELIABLE_TO_ID); -} - -class VisualScriptNodeInstanceFunctionCall : public VisualScriptNodeInstance { -public: - VisualScriptFunctionCall::CallMode call_mode; - NodePath node_path; - int input_args = 0; - bool validate = false; - int returns = 0; - VisualScriptFunctionCall::RPCCallMode rpc_mode; - StringName function; - StringName singleton; - - VisualScriptFunctionCall *node = nullptr; - VisualScriptInstance *instance = nullptr; - - //virtual int get_working_memory_size() const override { return 0; } - //virtual bool is_output_port_unsequenced(int p_idx) const { return false; } - //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; } - - _FORCE_INLINE_ bool call_rpc(Object *p_base, const Variant **p_args, int p_argcount) { - if (!p_base) { - return false; - } - - Node *node = Object::cast_to<Node>(p_base); - if (!node) { - return false; - } - - int to_id = 0; - //bool reliable = true; - - if (rpc_mode >= VisualScriptFunctionCall::RPC_RELIABLE_TO_ID) { - to_id = *p_args[0]; - p_args += 1; - p_argcount -= 1; - //if (rpc_mode == VisualScriptFunctionCall::RPC_UNRELIABLE_TO_ID) { - //reliable = false; - //} - } - //else if (rpc_mode == VisualScriptFunctionCall::RPC_UNRELIABLE) { - //reliable = false; - //} - - // TODO reliable? - node->rpcp(to_id, function, p_args, p_argcount); - - return true; - } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - switch (call_mode) { - case VisualScriptFunctionCall::CALL_MODE_SELF: { - Object *object = instance->get_owner_ptr(); - - if (rpc_mode) { - call_rpc(object, p_inputs, input_args); - } else if (returns) { - *p_outputs[0] = object->callp(function, p_inputs, input_args, r_error); - } else { - object->callp(function, p_inputs, input_args, r_error); - } - } break; - case VisualScriptFunctionCall::CALL_MODE_NODE_PATH: { - Node *node = Object::cast_to<Node>(instance->get_owner_ptr()); - if (!node) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = "Base object is not a Node!"; - return 0; - } - - Node *another = node->get_node(node_path); - if (!another) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = "Path does not lead Node!"; - return 0; - } - - if (rpc_mode) { - call_rpc(node, p_inputs, input_args); - } else if (returns) { - *p_outputs[0] = another->callp(function, p_inputs, input_args, r_error); - } else { - another->callp(function, p_inputs, input_args, r_error); - } - - } break; - case VisualScriptFunctionCall::CALL_MODE_INSTANCE: - case VisualScriptFunctionCall::CALL_MODE_BASIC_TYPE: { - Variant v = *p_inputs[0]; - - if (rpc_mode) { - Object *obj = v; - if (obj) { - call_rpc(obj, p_inputs + 1, input_args - 1); - } - } else if (returns) { - if (call_mode == VisualScriptFunctionCall::CALL_MODE_INSTANCE) { - if (returns >= 2) { - v.callp(function, p_inputs + 1, input_args, *p_outputs[1], r_error); - } else if (returns == 1) { - Variant ret; - v.callp(function, p_inputs + 1, input_args, ret, r_error); - } else { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = "Invalid returns count for call_mode == CALL_MODE_INSTANCE"; - return 0; - } - } else { - v.callp(function, p_inputs + 1, input_args, *p_outputs[0], r_error); - } - } else { - Variant ret; - v.callp(function, p_inputs + 1, input_args, ret, r_error); - } - - if (call_mode == VisualScriptFunctionCall::CALL_MODE_INSTANCE) { - *p_outputs[0] = *p_inputs[0]; - } - - } break; - case VisualScriptFunctionCall::CALL_MODE_SINGLETON: { - Object *object = Engine::get_singleton()->get_singleton_object(singleton); - if (!object) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = "Invalid singleton name: '" + String(singleton) + "'"; - return 0; - } - - if (rpc_mode) { - call_rpc(object, p_inputs, input_args); - } else if (returns) { - *p_outputs[0] = object->callp(function, p_inputs, input_args, r_error); - } else { - object->callp(function, p_inputs, input_args, r_error); - } - } break; - } - - if (!validate) { - //ignore call errors if validation is disabled - r_error.error = Callable::CallError::CALL_OK; - r_error_str = String(); - } - - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptFunctionCall::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceFunctionCall *instance = memnew(VisualScriptNodeInstanceFunctionCall); - instance->node = this; - instance->instance = p_instance; - instance->singleton = singleton; - instance->function = function; - instance->call_mode = call_mode; - instance->returns = get_output_value_port_count(); - instance->node_path = base_path; - instance->input_args = get_input_value_port_count() - ((call_mode == CALL_MODE_BASIC_TYPE || call_mode == CALL_MODE_INSTANCE) ? 1 : 0); - instance->rpc_mode = rpc_call_mode; - instance->validate = validate; - return instance; -} - -VisualScriptFunctionCall::TypeGuess VisualScriptFunctionCall::guess_output_type(TypeGuess *p_inputs, int p_output) const { - if (p_output == 0 && call_mode == CALL_MODE_INSTANCE) { - return p_inputs[0]; - } - - return VisualScriptNode::guess_output_type(p_inputs, p_output); -} - -VisualScriptFunctionCall::VisualScriptFunctionCall() { - validate = true; - call_mode = CALL_MODE_SELF; - basic_type = Variant::NIL; - use_default_args = 0; - base_type = "Object"; - rpc_call_mode = RPC_DISABLED; -} - -template <VisualScriptFunctionCall::CallMode cmode> -static Ref<VisualScriptNode> create_function_call_node(const String &p_name) { - Ref<VisualScriptFunctionCall> node; - node.instantiate(); - node->set_call_mode(cmode); - return node; -} - -////////////////////////////////////////// -////////////////SET////////////////////// -////////////////////////////////////////// - -int VisualScriptPropertySet::get_output_sequence_port_count() const { - return 1; -} - -bool VisualScriptPropertySet::has_input_sequence_port() const { - return true; -} - -Node *VisualScriptPropertySet::_get_base_node() const { -#ifdef TOOLS_ENABLED - Ref<Script> script = get_visual_script(); - if (!script.is_valid()) { - return nullptr; - } - - MainLoop *main_loop = OS::get_singleton()->get_main_loop(); - - SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop); - - if (!scene_tree) { - return nullptr; - } - - Node *edited_scene = scene_tree->get_edited_scene_root(); - - if (!edited_scene) { - return nullptr; - } - - Node *script_node = _find_script_node(edited_scene, edited_scene, script); - - if (!script_node) { - return nullptr; - } - - if (!script_node->has_node(base_path)) { - return nullptr; - } - - Node *path_to = script_node->get_node(base_path); - - return path_to; -#else - - return nullptr; -#endif -} - -StringName VisualScriptPropertySet::_get_base_type() const { - if (call_mode == CALL_MODE_SELF && get_visual_script().is_valid()) { - return get_visual_script()->get_instance_base_type(); - } else if (call_mode == CALL_MODE_NODE_PATH && get_visual_script().is_valid()) { - Node *path = _get_base_node(); - if (path) { - return path->get_class(); - } - } - - return base_type; -} - -int VisualScriptPropertySet::get_input_value_port_count() const { - int pc = (call_mode == CALL_MODE_BASIC_TYPE || call_mode == CALL_MODE_INSTANCE) ? 2 : 1; - - return pc; -} - -int VisualScriptPropertySet::get_output_value_port_count() const { - return (call_mode == CALL_MODE_BASIC_TYPE || call_mode == CALL_MODE_INSTANCE) ? 1 : 0; -} - -String VisualScriptPropertySet::get_output_sequence_port_text(int p_port) const { - return String(); -} - -void VisualScriptPropertySet::_adjust_input_index(PropertyInfo &pinfo) const { - if (index != StringName()) { - Variant v; - Callable::CallError ce; - Variant::construct(pinfo.type, v, nullptr, 0, ce); - Variant i = v.get(index); - pinfo.type = i.get_type(); - } -} - -PropertyInfo VisualScriptPropertySet::get_input_value_port_info(int p_idx) const { - if (call_mode == CALL_MODE_INSTANCE || call_mode == CALL_MODE_BASIC_TYPE) { - if (p_idx == 0) { - PropertyInfo pi; - pi.type = (call_mode == CALL_MODE_INSTANCE ? Variant::OBJECT : basic_type); - pi.name = "instance"; - return pi; - } - } - - List<PropertyInfo> props; - ClassDB::get_property_list(_get_base_type(), &props, false); - for (const PropertyInfo &E : props) { - if (E.name == property) { - String detail_prop_name = property; - if (index != StringName()) { - detail_prop_name += "." + String(index); - } - PropertyInfo pinfo = PropertyInfo(E.type, detail_prop_name, E.hint, E.hint_string); - _adjust_input_index(pinfo); - return pinfo; - } - } - - PropertyInfo pinfo = type_cache; - _adjust_input_index(pinfo); - return pinfo; -} - -PropertyInfo VisualScriptPropertySet::get_output_value_port_info(int p_idx) const { - if (call_mode == CALL_MODE_BASIC_TYPE) { - return PropertyInfo(basic_type, "pass"); - } else if (call_mode == CALL_MODE_INSTANCE) { - return PropertyInfo(Variant::OBJECT, "pass", PROPERTY_HINT_TYPE_STRING, get_base_type()); - } else { - return PropertyInfo(); - } -} - -String VisualScriptPropertySet::get_caption() const { - static const LocalVector<String> opname = { - RTR("Set %s"), - RTR("Add %s"), - RTR("Subtract %s"), - RTR("Multiply %s"), - RTR("Divide %s"), - RTR("Mod %s"), - RTR("ShiftLeft %s"), - RTR("ShiftRight %s"), - RTR("BitAnd %s"), - RTR("BitOr %s"), - RTR("BitXor %s"), - }; - - String prop = property; - if (index != StringName()) { - prop += "." + String(index); - } - - return vformat(opname[assign_op], prop); -} - -String VisualScriptPropertySet::get_text() const { - if (!has_input_sequence_port()) { - return ""; - } - if (call_mode == CALL_MODE_BASIC_TYPE) { - return vformat(RTR("On %s"), Variant::get_type_name(basic_type)); - } else if (call_mode == CALL_MODE_INSTANCE) { - return vformat(RTR("On %s"), base_type); - } else if (call_mode == CALL_MODE_NODE_PATH) { - return " [" + String(base_path.simplified()) + "]"; - } else { - return RTR("On Self"); - } -} - -void VisualScriptPropertySet::_update_base_type() { - //cache it because this information may not be available on load - if (call_mode == CALL_MODE_NODE_PATH) { - Node *node = _get_base_node(); - if (node) { - base_type = node->get_class(); - } - } else if (call_mode == CALL_MODE_SELF) { - if (get_visual_script().is_valid()) { - base_type = get_visual_script()->get_instance_base_type(); - } - } -} - -void VisualScriptPropertySet::set_basic_type(Variant::Type p_type) { - if (basic_type == p_type) { - return; - } - basic_type = p_type; - - notify_property_list_changed(); - _update_base_type(); - ports_changed_notify(); -} - -Variant::Type VisualScriptPropertySet::get_basic_type() const { - return basic_type; -} - -void VisualScriptPropertySet::set_base_type(const StringName &p_type) { - if (base_type == p_type) { - return; - } - - base_type = p_type; - notify_property_list_changed(); - ports_changed_notify(); -} - -StringName VisualScriptPropertySet::get_base_type() const { - return base_type; -} - -void VisualScriptPropertySet::set_base_script(const String &p_path) { - if (base_script == p_path) { - return; - } - - base_script = p_path; - notify_property_list_changed(); - ports_changed_notify(); -} - -String VisualScriptPropertySet::get_base_script() const { - return base_script; -} - -void VisualScriptPropertySet::_update_cache() { - if (!Object::cast_to<SceneTree>(OS::get_singleton()->get_main_loop())) { - return; - } - - if (!Engine::get_singleton()->is_editor_hint()) { //only update cache if editor exists, it's pointless otherwise - return; - } - - if (call_mode == CALL_MODE_BASIC_TYPE) { - //not super efficient.. - - Variant v; - Callable::CallError ce; - Variant::construct(basic_type, v, nullptr, 0, ce); - - List<PropertyInfo> pinfo; - v.get_property_list(&pinfo); - - for (const PropertyInfo &E : pinfo) { - if (E.name == property) { - type_cache = E; - } - } - - } else { - StringName type; - Ref<Script> script; - Node *node = nullptr; - - if (call_mode == CALL_MODE_NODE_PATH) { - node = _get_base_node(); - if (node) { - type = node->get_class(); - base_type = type; //cache, too - script = node->get_script(); - } - } else if (call_mode == CALL_MODE_SELF) { - if (get_visual_script().is_valid()) { - type = get_visual_script()->get_instance_base_type(); - base_type = type; //cache, too - script = get_visual_script(); - } - } else if (call_mode == CALL_MODE_INSTANCE) { - type = base_type; - if (!base_script.is_empty()) { - if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) { - ScriptServer::edit_request_func(base_script); //make sure it's loaded - } - - if (ResourceCache::has(base_script)) { - script = ResourceCache::get_ref(base_script); - } else { - return; - } - } - } - - List<PropertyInfo> pinfo; - - if (node) { - node->get_property_list(&pinfo); - } else { - ClassDB::get_property_list(type, &pinfo); - } - - if (script.is_valid()) { - script->get_script_property_list(&pinfo); - } - - for (const PropertyInfo &E : pinfo) { - if (E.name == property) { - type_cache = E; - return; - } - } - } -} - -void VisualScriptPropertySet::set_property(const StringName &p_type) { - if (property == p_type) { - return; - } - - property = p_type; - index = StringName(); - _update_cache(); - notify_property_list_changed(); - ports_changed_notify(); -} - -StringName VisualScriptPropertySet::get_property() const { - return property; -} - -void VisualScriptPropertySet::set_base_path(const NodePath &p_type) { - if (base_path == p_type) { - return; - } - - base_path = p_type; - _update_base_type(); - notify_property_list_changed(); - ports_changed_notify(); -} - -NodePath VisualScriptPropertySet::get_base_path() const { - return base_path; -} - -void VisualScriptPropertySet::set_call_mode(CallMode p_mode) { - if (call_mode == p_mode) { - return; - } - - call_mode = p_mode; - _update_base_type(); - notify_property_list_changed(); - ports_changed_notify(); -} - -VisualScriptPropertySet::CallMode VisualScriptPropertySet::get_call_mode() const { - return call_mode; -} - -void VisualScriptPropertySet::_set_type_cache(const Dictionary &p_type) { - type_cache = PropertyInfo::from_dict(p_type); -} - -Dictionary VisualScriptPropertySet::_get_type_cache() const { - return type_cache; -} - -void VisualScriptPropertySet::set_index(const StringName &p_type) { - if (index == p_type) { - return; - } - index = p_type; - _update_cache(); - notify_property_list_changed(); - ports_changed_notify(); -} - -StringName VisualScriptPropertySet::get_index() const { - return index; -} - -void VisualScriptPropertySet::set_assign_op(AssignOp p_op) { - ERR_FAIL_INDEX(p_op, ASSIGN_OP_MAX); - if (assign_op == p_op) { - return; - } - - assign_op = p_op; - _update_cache(); - notify_property_list_changed(); - ports_changed_notify(); -} - -VisualScriptPropertySet::AssignOp VisualScriptPropertySet::get_assign_op() const { - return assign_op; -} - -void VisualScriptPropertySet::_validate_property(PropertyInfo &p_property) const { - if (p_property.name == "base_type") { - if (call_mode != CALL_MODE_INSTANCE) { - p_property.usage = PROPERTY_USAGE_NO_EDITOR; - } - } - - if (p_property.name == "base_script") { - if (call_mode != CALL_MODE_INSTANCE) { - p_property.usage = PROPERTY_USAGE_NONE; - } - } - - if (p_property.name == "basic_type") { - if (call_mode != CALL_MODE_BASIC_TYPE) { - p_property.usage = PROPERTY_USAGE_NONE; - } - } - - if (p_property.name == "node_path") { - if (call_mode != CALL_MODE_NODE_PATH) { - p_property.usage = PROPERTY_USAGE_NONE; - } else { - Node *bnode = _get_base_node(); - if (bnode) { - p_property.hint_string = bnode->get_path(); //convert to long string - } - } - } - - if (p_property.name == "property") { - if (call_mode == CALL_MODE_BASIC_TYPE) { - p_property.hint = PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE; - p_property.hint_string = Variant::get_type_name(basic_type); - - } else if (call_mode == CALL_MODE_SELF && get_visual_script().is_valid()) { - p_property.hint = PROPERTY_HINT_PROPERTY_OF_SCRIPT; - p_property.hint_string = itos(get_visual_script()->get_instance_id()); - } else if (call_mode == CALL_MODE_INSTANCE) { - p_property.hint = PROPERTY_HINT_PROPERTY_OF_BASE_TYPE; - p_property.hint_string = base_type; - - if (!base_script.is_empty()) { - if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) { - ScriptServer::edit_request_func(base_script); //make sure it's loaded - } - - if (ResourceCache::has(base_script)) { - Ref<Script> script = ResourceCache::get_ref(base_script); - if (script.is_valid()) { - p_property.hint = PROPERTY_HINT_PROPERTY_OF_SCRIPT; - p_property.hint_string = itos(script->get_instance_id()); - } - } - } - - } else if (call_mode == CALL_MODE_NODE_PATH) { - Node *node = _get_base_node(); - if (node) { - p_property.hint = PROPERTY_HINT_PROPERTY_OF_INSTANCE; - p_property.hint_string = itos(node->get_instance_id()); - } else { - p_property.hint = PROPERTY_HINT_PROPERTY_OF_BASE_TYPE; - p_property.hint_string = get_base_type(); - } - } - } - - if (p_property.name == "index") { - Callable::CallError ce; - Variant v; - Variant::construct(type_cache.type, v, nullptr, 0, ce); - List<PropertyInfo> plist; - v.get_property_list(&plist); - String options = ""; - for (const PropertyInfo &E : plist) { - options += "," + E.name; - } - - p_property.hint = PROPERTY_HINT_ENUM; - p_property.hint_string = options; - p_property.type = Variant::STRING; - if (options.is_empty()) { - p_property.usage = PROPERTY_USAGE_NONE; //hide if type has no usable index - } - } -} - -void VisualScriptPropertySet::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_base_type", "base_type"), &VisualScriptPropertySet::set_base_type); - ClassDB::bind_method(D_METHOD("get_base_type"), &VisualScriptPropertySet::get_base_type); - - ClassDB::bind_method(D_METHOD("set_base_script", "base_script"), &VisualScriptPropertySet::set_base_script); - ClassDB::bind_method(D_METHOD("get_base_script"), &VisualScriptPropertySet::get_base_script); - - ClassDB::bind_method(D_METHOD("set_basic_type", "basic_type"), &VisualScriptPropertySet::set_basic_type); - ClassDB::bind_method(D_METHOD("get_basic_type"), &VisualScriptPropertySet::get_basic_type); - - ClassDB::bind_method(D_METHOD("_set_type_cache", "type_cache"), &VisualScriptPropertySet::_set_type_cache); - ClassDB::bind_method(D_METHOD("_get_type_cache"), &VisualScriptPropertySet::_get_type_cache); - - ClassDB::bind_method(D_METHOD("set_property", "property"), &VisualScriptPropertySet::set_property); - ClassDB::bind_method(D_METHOD("get_property"), &VisualScriptPropertySet::get_property); - - ClassDB::bind_method(D_METHOD("set_call_mode", "mode"), &VisualScriptPropertySet::set_call_mode); - ClassDB::bind_method(D_METHOD("get_call_mode"), &VisualScriptPropertySet::get_call_mode); - - ClassDB::bind_method(D_METHOD("set_base_path", "base_path"), &VisualScriptPropertySet::set_base_path); - ClassDB::bind_method(D_METHOD("get_base_path"), &VisualScriptPropertySet::get_base_path); - - ClassDB::bind_method(D_METHOD("set_index", "index"), &VisualScriptPropertySet::set_index); - ClassDB::bind_method(D_METHOD("get_index"), &VisualScriptPropertySet::get_index); - - ClassDB::bind_method(D_METHOD("set_assign_op", "assign_op"), &VisualScriptPropertySet::set_assign_op); - ClassDB::bind_method(D_METHOD("get_assign_op"), &VisualScriptPropertySet::get_assign_op); - - String bt; - for (int i = 0; i < Variant::VARIANT_MAX; i++) { - if (i > 0) { - bt += ","; - } - - bt += Variant::get_type_name(Variant::Type(i)); - } - - List<String> script_extensions; - for (int i = 0; i < ScriptServer::get_language_count(); i++) { - ScriptServer::get_language(i)->get_recognized_extensions(&script_extensions); - } - - String script_ext_hint; - for (const String &E : script_extensions) { - if (!script_ext_hint.is_empty()) { - script_ext_hint += ","; - } - script_ext_hint += "*." + E; - } - - ADD_PROPERTY(PropertyInfo(Variant::INT, "set_mode", PROPERTY_HINT_ENUM, "Self,Node Path,Instance,Basic Type"), "set_call_mode", "get_call_mode"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_type", PROPERTY_HINT_TYPE_STRING, "Object"), "set_base_type", "get_base_type"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_script", PROPERTY_HINT_FILE, script_ext_hint), "set_base_script", "get_base_script"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "type_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_type_cache", "_get_type_cache"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "basic_type", PROPERTY_HINT_ENUM, bt), "set_basic_type", "get_basic_type"); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_path", PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE), "set_base_path", "get_base_path"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "property"), "set_property", "get_property"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "index"), "set_index", "get_index"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "assign_op", PROPERTY_HINT_ENUM, "Assign,Add,Sub,Mul,Div,Mod,ShiftLeft,ShiftRight,BitAnd,BitOr,Bitxor"), "set_assign_op", "get_assign_op"); - - BIND_ENUM_CONSTANT(CALL_MODE_SELF); - BIND_ENUM_CONSTANT(CALL_MODE_NODE_PATH); - BIND_ENUM_CONSTANT(CALL_MODE_INSTANCE); - BIND_ENUM_CONSTANT(CALL_MODE_BASIC_TYPE); - - BIND_ENUM_CONSTANT(ASSIGN_OP_NONE); - BIND_ENUM_CONSTANT(ASSIGN_OP_ADD); - BIND_ENUM_CONSTANT(ASSIGN_OP_SUB); - BIND_ENUM_CONSTANT(ASSIGN_OP_MUL); - BIND_ENUM_CONSTANT(ASSIGN_OP_DIV); - BIND_ENUM_CONSTANT(ASSIGN_OP_MOD); - BIND_ENUM_CONSTANT(ASSIGN_OP_SHIFT_LEFT); - BIND_ENUM_CONSTANT(ASSIGN_OP_SHIFT_RIGHT); - BIND_ENUM_CONSTANT(ASSIGN_OP_BIT_AND); - BIND_ENUM_CONSTANT(ASSIGN_OP_BIT_OR); - BIND_ENUM_CONSTANT(ASSIGN_OP_BIT_XOR); -} - -class VisualScriptNodeInstancePropertySet : public VisualScriptNodeInstance { -public: - VisualScriptPropertySet::CallMode call_mode; - NodePath node_path; - StringName property; - - VisualScriptPropertySet *node = nullptr; - VisualScriptInstance *instance = nullptr; - VisualScriptPropertySet::AssignOp assign_op; - StringName index; - bool needs_get = false; - - //virtual int get_working_memory_size() const override { return 0; } - //virtual bool is_output_port_unsequenced(int p_idx) const { return false; } - //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; } - - _FORCE_INLINE_ void _process_get(Variant &source, const Variant &p_argument, bool &valid) { - if (index != StringName() && assign_op == VisualScriptPropertySet::ASSIGN_OP_NONE) { - source.set_named(index, p_argument, valid); - } else { - Variant value; - if (index != StringName()) { - value = source.get_named(index, valid); - } else { - value = source; - } - - switch (assign_op) { - case VisualScriptPropertySet::ASSIGN_OP_NONE: { - //should never get here - } break; - case VisualScriptPropertySet::ASSIGN_OP_ADD: { - value = Variant::evaluate(Variant::OP_ADD, value, p_argument); - } break; - case VisualScriptPropertySet::ASSIGN_OP_SUB: { - value = Variant::evaluate(Variant::OP_SUBTRACT, value, p_argument); - } break; - case VisualScriptPropertySet::ASSIGN_OP_MUL: { - value = Variant::evaluate(Variant::OP_MULTIPLY, value, p_argument); - } break; - case VisualScriptPropertySet::ASSIGN_OP_DIV: { - value = Variant::evaluate(Variant::OP_DIVIDE, value, p_argument); - } break; - case VisualScriptPropertySet::ASSIGN_OP_MOD: { - value = Variant::evaluate(Variant::OP_MODULE, value, p_argument); - } break; - case VisualScriptPropertySet::ASSIGN_OP_SHIFT_LEFT: { - value = Variant::evaluate(Variant::OP_SHIFT_LEFT, value, p_argument); - } break; - case VisualScriptPropertySet::ASSIGN_OP_SHIFT_RIGHT: { - value = Variant::evaluate(Variant::OP_SHIFT_RIGHT, value, p_argument); - } break; - case VisualScriptPropertySet::ASSIGN_OP_BIT_AND: { - value = Variant::evaluate(Variant::OP_BIT_AND, value, p_argument); - } break; - case VisualScriptPropertySet::ASSIGN_OP_BIT_OR: { - value = Variant::evaluate(Variant::OP_BIT_OR, value, p_argument); - } break; - case VisualScriptPropertySet::ASSIGN_OP_BIT_XOR: { - value = Variant::evaluate(Variant::OP_BIT_XOR, value, p_argument); - } break; - default: { - } - } - - if (index != StringName()) { - source.set_named(index, value, valid); - } else { - source = value; - } - } - } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - switch (call_mode) { - case VisualScriptPropertySet::CALL_MODE_SELF: { - Object *object = instance->get_owner_ptr(); - - bool valid; - - if (needs_get) { - Variant value = object->get(property, &valid); - _process_get(value, *p_inputs[0], valid); - object->set(property, value, &valid); - } else { - object->set(property, *p_inputs[0], &valid); - } - - if (!valid) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = "Invalid set value '" + String(*p_inputs[0]) + "' on property '" + String(property) + "' of type " + object->get_class(); - } - } break; - case VisualScriptPropertySet::CALL_MODE_NODE_PATH: { - Node *node = Object::cast_to<Node>(instance->get_owner_ptr()); - if (!node) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = "Base object is not a Node!"; - return 0; - } - - Node *another = node->get_node(node_path); - if (!another) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = "Path does not lead Node!"; - return 0; - } - - bool valid; - - if (needs_get) { - Variant value = another->get(property, &valid); - _process_get(value, *p_inputs[0], valid); - another->set(property, value, &valid); - } else { - another->set(property, *p_inputs[0], &valid); - } - - if (!valid) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = "Invalid set value '" + String(*p_inputs[0]) + "' on property '" + String(property) + "' of type " + another->get_class(); - } - - } break; - case VisualScriptPropertySet::CALL_MODE_INSTANCE: - case VisualScriptPropertySet::CALL_MODE_BASIC_TYPE: { - Variant v = *p_inputs[0]; - - bool valid; - - if (needs_get) { - Variant value = v.get_named(property, valid); - _process_get(value, *p_inputs[1], valid); - v.set_named(property, value, valid); - - } else { - v.set_named(property, *p_inputs[1], valid); - } - - if (!valid) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = "Invalid set value '" + String(*p_inputs[1]) + "' (" + Variant::get_type_name(p_inputs[1]->get_type()) + ") on property '" + String(property) + "' of type " + Variant::get_type_name(v.get_type()); - } - - *p_outputs[0] = v; - - } break; - } - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptPropertySet::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstancePropertySet *instance = memnew(VisualScriptNodeInstancePropertySet); - instance->node = this; - instance->instance = p_instance; - instance->property = property; - instance->call_mode = call_mode; - instance->node_path = base_path; - instance->assign_op = assign_op; - instance->index = index; - instance->needs_get = index != StringName() || assign_op != ASSIGN_OP_NONE; - return instance; -} - -VisualScriptPropertySet::TypeGuess VisualScriptPropertySet::guess_output_type(TypeGuess *p_inputs, int p_output) const { - if (p_output == 0 && call_mode == CALL_MODE_INSTANCE) { - return p_inputs[0]; - } - - return VisualScriptNode::guess_output_type(p_inputs, p_output); -} - -VisualScriptPropertySet::VisualScriptPropertySet() { - assign_op = ASSIGN_OP_NONE; - call_mode = CALL_MODE_SELF; - base_type = "Object"; - basic_type = Variant::NIL; -} - -template <VisualScriptPropertySet::CallMode cmode> -static Ref<VisualScriptNode> create_property_set_node(const String &p_name) { - Ref<VisualScriptPropertySet> node; - node.instantiate(); - node->set_call_mode(cmode); - return node; -} - -////////////////////////////////////////// -////////////////GET////////////////////// -////////////////////////////////////////// - -int VisualScriptPropertyGet::get_output_sequence_port_count() const { - return 0; // (call_mode==CALL_MODE_SELF || call_mode==CALL_MODE_NODE_PATH)?0:1; -} - -bool VisualScriptPropertyGet::has_input_sequence_port() const { - return false; //(call_mode==CALL_MODE_SELF || call_mode==CALL_MODE_NODE_PATH)?false:true; -} - -void VisualScriptPropertyGet::_update_base_type() { - //cache it because this information may not be available on load - if (call_mode == CALL_MODE_NODE_PATH) { - Node *node = _get_base_node(); - if (node) { - base_type = node->get_class(); - } - } else if (call_mode == CALL_MODE_SELF) { - if (get_visual_script().is_valid()) { - base_type = get_visual_script()->get_instance_base_type(); - } - } -} - -Node *VisualScriptPropertyGet::_get_base_node() const { -#ifdef TOOLS_ENABLED - Ref<Script> script = get_visual_script(); - if (!script.is_valid()) { - return nullptr; - } - - MainLoop *main_loop = OS::get_singleton()->get_main_loop(); - - SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop); - - if (!scene_tree) { - return nullptr; - } - - Node *edited_scene = scene_tree->get_edited_scene_root(); - - if (!edited_scene) { - return nullptr; - } - - Node *script_node = _find_script_node(edited_scene, edited_scene, script); - - if (!script_node) { - return nullptr; - } - - if (!script_node->has_node(base_path)) { - return nullptr; - } - - Node *path_to = script_node->get_node(base_path); - - return path_to; -#else - - return nullptr; -#endif -} - -StringName VisualScriptPropertyGet::_get_base_type() const { - if (call_mode == CALL_MODE_SELF && get_visual_script().is_valid()) { - return get_visual_script()->get_instance_base_type(); - } else if (call_mode == CALL_MODE_NODE_PATH && get_visual_script().is_valid()) { - Node *path = _get_base_node(); - if (path) { - return path->get_class(); - } - } - - return base_type; -} - -int VisualScriptPropertyGet::get_input_value_port_count() const { - return (call_mode == CALL_MODE_BASIC_TYPE || call_mode == CALL_MODE_INSTANCE) ? 1 : 0; -} - -int VisualScriptPropertyGet::get_output_value_port_count() const { - int pc = (call_mode == CALL_MODE_BASIC_TYPE || call_mode == CALL_MODE_INSTANCE) ? 2 : 1; - - return pc; -} - -String VisualScriptPropertyGet::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptPropertyGet::get_input_value_port_info(int p_idx) const { - if (call_mode == CALL_MODE_INSTANCE || call_mode == CALL_MODE_BASIC_TYPE) { - if (p_idx == 0) { - PropertyInfo pi; - pi.type = (call_mode == CALL_MODE_INSTANCE ? Variant::OBJECT : basic_type); - pi.name = (call_mode == CALL_MODE_INSTANCE ? String("instance") : Variant::get_type_name(basic_type).to_lower()); - return pi; - } - } - return PropertyInfo(); -} - -PropertyInfo VisualScriptPropertyGet::get_output_value_port_info(int p_idx) const { - if (call_mode == CALL_MODE_BASIC_TYPE && p_idx == 0) { - return PropertyInfo(basic_type, "pass"); - } else if (call_mode == CALL_MODE_INSTANCE && p_idx == 0) { - return PropertyInfo(Variant::OBJECT, "pass", PROPERTY_HINT_TYPE_STRING, get_base_type()); - } else { - List<PropertyInfo> props; - ClassDB::get_property_list(_get_base_type(), &props, false); - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - if (E->get().name == property) { - PropertyInfo pinfo = PropertyInfo(E->get().type, String(property) + "." + String(index), E->get().hint, E->get().hint_string); - _adjust_input_index(pinfo); - return pinfo; - } - } - } - - PropertyInfo pinfo = PropertyInfo(type_cache, "value"); - _adjust_input_index(pinfo); - return pinfo; -} - -String VisualScriptPropertyGet::get_caption() const { - String prop = property; - if (index != StringName()) { - prop += "." + String(index); - } - - return vformat(RTR("Get %s"), prop); -} - -String VisualScriptPropertyGet::get_text() const { - if (call_mode == CALL_MODE_BASIC_TYPE) { - return vformat(RTR("On %s"), Variant::get_type_name(basic_type)); - } else if (call_mode == CALL_MODE_INSTANCE) { - return vformat(RTR("On %s"), base_type); - } else if (call_mode == CALL_MODE_NODE_PATH) { - return " [" + String(base_path.simplified()) + "]"; - } else { - return RTR("On Self"); - } -} - -void VisualScriptPropertyGet::set_base_type(const StringName &p_type) { - if (base_type == p_type) { - return; - } - - base_type = p_type; - notify_property_list_changed(); - ports_changed_notify(); -} - -StringName VisualScriptPropertyGet::get_base_type() const { - return base_type; -} - -void VisualScriptPropertyGet::set_base_script(const String &p_path) { - if (base_script == p_path) { - return; - } - - base_script = p_path; - notify_property_list_changed(); - ports_changed_notify(); -} - -String VisualScriptPropertyGet::get_base_script() const { - return base_script; -} - -void VisualScriptPropertyGet::_update_cache() { - if (call_mode == CALL_MODE_BASIC_TYPE) { - //not super efficient.. - - Variant v; - Callable::CallError ce; - Variant::construct(basic_type, v, nullptr, 0, ce); - - List<PropertyInfo> pinfo; - v.get_property_list(&pinfo); - - for (const PropertyInfo &E : pinfo) { - if (E.name == property) { - type_cache = E.type; - return; - } - } - - } else { - StringName type; - Ref<Script> script; - Node *node = nullptr; - - if (call_mode == CALL_MODE_NODE_PATH) { - node = _get_base_node(); - if (node) { - type = node->get_class(); - base_type = type; //cache, too - script = node->get_script(); - } - } else if (call_mode == CALL_MODE_SELF) { - if (get_visual_script().is_valid()) { - type = get_visual_script()->get_instance_base_type(); - base_type = type; //cache, too - script = get_visual_script(); - } - } else if (call_mode == CALL_MODE_INSTANCE) { - type = base_type; - if (!base_script.is_empty()) { - if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) { - ScriptServer::edit_request_func(base_script); //make sure it's loaded - } - - if (ResourceCache::has(base_script)) { - script = ResourceCache::get_ref(base_script); - } else { - return; - } - } - } - - bool valid = false; - - Variant::Type type_ret; - - type_ret = ClassDB::get_property_type(base_type, property, &valid); - - if (valid) { - type_cache = type_ret; - return; //all dandy - } - - if (node) { - Variant prop = node->get(property, &valid); - if (valid) { - type_cache = prop.get_type(); - return; //all dandy again - } - } - - if (script.is_valid()) { - type_ret = script->get_static_property_type(property, &valid); - - if (valid) { - type_cache = type_ret; - return; //all dandy - } - } - } -} - -void VisualScriptPropertyGet::set_property(const StringName &p_type) { - if (property == p_type) { - return; - } - - property = p_type; - - _update_cache(); - notify_property_list_changed(); - ports_changed_notify(); -} - -StringName VisualScriptPropertyGet::get_property() const { - return property; -} - -void VisualScriptPropertyGet::set_base_path(const NodePath &p_type) { - if (base_path == p_type) { - return; - } - - base_path = p_type; - notify_property_list_changed(); - _update_base_type(); - ports_changed_notify(); -} - -NodePath VisualScriptPropertyGet::get_base_path() const { - return base_path; -} - -void VisualScriptPropertyGet::set_call_mode(CallMode p_mode) { - if (call_mode == p_mode) { - return; - } - - call_mode = p_mode; - notify_property_list_changed(); - _update_base_type(); - ports_changed_notify(); -} - -VisualScriptPropertyGet::CallMode VisualScriptPropertyGet::get_call_mode() const { - return call_mode; -} - -void VisualScriptPropertyGet::set_basic_type(Variant::Type p_type) { - if (basic_type == p_type) { - return; - } - basic_type = p_type; - - notify_property_list_changed(); - ports_changed_notify(); -} - -Variant::Type VisualScriptPropertyGet::get_basic_type() const { - return basic_type; -} - -void VisualScriptPropertyGet::_set_type_cache(Variant::Type p_type) { - type_cache = p_type; -} - -Variant::Type VisualScriptPropertyGet::_get_type_cache() const { - return type_cache; -} - -void VisualScriptPropertyGet::_adjust_input_index(PropertyInfo &pinfo) const { - if (index != StringName()) { - Variant v; - Callable::CallError ce; - Variant::construct(pinfo.type, v, nullptr, 0, ce); - Variant i = v.get(index); - pinfo.type = i.get_type(); - pinfo.name = String(property) + "." + index; - } else { - pinfo.name = String(property); - } -} - -void VisualScriptPropertyGet::set_index(const StringName &p_type) { - if (index == p_type) { - return; - } - index = p_type; - _update_cache(); - notify_property_list_changed(); - ports_changed_notify(); -} - -StringName VisualScriptPropertyGet::get_index() const { - return index; -} - -void VisualScriptPropertyGet::_validate_property(PropertyInfo &p_property) const { - if (p_property.name == "base_type") { - if (call_mode != CALL_MODE_INSTANCE) { - p_property.usage = PROPERTY_USAGE_NO_EDITOR; - } - } - - if (p_property.name == "base_script") { - if (call_mode != CALL_MODE_INSTANCE) { - p_property.usage = PROPERTY_USAGE_NONE; - } - } - - if (p_property.name == "basic_type") { - if (call_mode != CALL_MODE_BASIC_TYPE) { - p_property.usage = PROPERTY_USAGE_NONE; - } - } - - if (p_property.name == "node_path") { - if (call_mode != CALL_MODE_NODE_PATH) { - p_property.usage = PROPERTY_USAGE_NONE; - } else { - Node *bnode = _get_base_node(); - if (bnode) { - p_property.hint_string = bnode->get_path(); //convert to long string - } - } - } - - if (p_property.name == "property") { - if (call_mode == CALL_MODE_BASIC_TYPE) { - p_property.hint = PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE; - p_property.hint_string = Variant::get_type_name(basic_type); - - } else if (call_mode == CALL_MODE_SELF && get_visual_script().is_valid()) { - p_property.hint = PROPERTY_HINT_PROPERTY_OF_SCRIPT; - p_property.hint_string = itos(get_visual_script()->get_instance_id()); - } else if (call_mode == CALL_MODE_INSTANCE) { - p_property.hint = PROPERTY_HINT_PROPERTY_OF_BASE_TYPE; - p_property.hint_string = base_type; - - if (!base_script.is_empty()) { - if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) { - ScriptServer::edit_request_func(base_script); //make sure it's loaded - } - - if (ResourceCache::has(base_script)) { - Ref<Script> script = ResourceCache::get_ref(base_script); - if (script.is_valid()) { - p_property.hint = PROPERTY_HINT_PROPERTY_OF_SCRIPT; - p_property.hint_string = itos(script->get_instance_id()); - } - } - } - } else if (call_mode == CALL_MODE_NODE_PATH) { - Node *node = _get_base_node(); - if (node) { - p_property.hint = PROPERTY_HINT_PROPERTY_OF_INSTANCE; - p_property.hint_string = itos(node->get_instance_id()); - } else { - p_property.hint = PROPERTY_HINT_PROPERTY_OF_BASE_TYPE; - p_property.hint_string = get_base_type(); - } - } - } - - if (p_property.name == "index") { - Callable::CallError ce; - Variant v; - Variant::construct(type_cache, v, nullptr, 0, ce); - List<PropertyInfo> plist; - v.get_property_list(&plist); - String options = ""; - for (const PropertyInfo &E : plist) { - options += "," + E.name; - } - - p_property.hint = PROPERTY_HINT_ENUM; - p_property.hint_string = options; - p_property.type = Variant::STRING; - if (options.is_empty()) { - p_property.usage = PROPERTY_USAGE_NONE; //hide if type has no usable index - } - } -} - -void VisualScriptPropertyGet::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_base_type", "base_type"), &VisualScriptPropertyGet::set_base_type); - ClassDB::bind_method(D_METHOD("get_base_type"), &VisualScriptPropertyGet::get_base_type); - - ClassDB::bind_method(D_METHOD("set_base_script", "base_script"), &VisualScriptPropertyGet::set_base_script); - ClassDB::bind_method(D_METHOD("get_base_script"), &VisualScriptPropertyGet::get_base_script); - - ClassDB::bind_method(D_METHOD("set_basic_type", "basic_type"), &VisualScriptPropertyGet::set_basic_type); - ClassDB::bind_method(D_METHOD("get_basic_type"), &VisualScriptPropertyGet::get_basic_type); - - ClassDB::bind_method(D_METHOD("_set_type_cache", "type_cache"), &VisualScriptPropertyGet::_set_type_cache); - ClassDB::bind_method(D_METHOD("_get_type_cache"), &VisualScriptPropertyGet::_get_type_cache); - - ClassDB::bind_method(D_METHOD("set_property", "property"), &VisualScriptPropertyGet::set_property); - ClassDB::bind_method(D_METHOD("get_property"), &VisualScriptPropertyGet::get_property); - - ClassDB::bind_method(D_METHOD("set_call_mode", "mode"), &VisualScriptPropertyGet::set_call_mode); - ClassDB::bind_method(D_METHOD("get_call_mode"), &VisualScriptPropertyGet::get_call_mode); - - ClassDB::bind_method(D_METHOD("set_base_path", "base_path"), &VisualScriptPropertyGet::set_base_path); - ClassDB::bind_method(D_METHOD("get_base_path"), &VisualScriptPropertyGet::get_base_path); - - ClassDB::bind_method(D_METHOD("set_index", "index"), &VisualScriptPropertyGet::set_index); - ClassDB::bind_method(D_METHOD("get_index"), &VisualScriptPropertyGet::get_index); - - String bt; - for (int i = 0; i < Variant::VARIANT_MAX; i++) { - if (i > 0) { - bt += ","; - } - - bt += Variant::get_type_name(Variant::Type(i)); - } - - List<String> script_extensions; - for (int i = 0; i < ScriptServer::get_language_count(); i++) { - ScriptServer::get_language(i)->get_recognized_extensions(&script_extensions); - } - - String script_ext_hint; - for (const String &E : script_extensions) { - if (!script_ext_hint.is_empty()) { - script_ext_hint += ","; - } - script_ext_hint += "." + E; - } - - ADD_PROPERTY(PropertyInfo(Variant::INT, "set_mode", PROPERTY_HINT_ENUM, "Self,Node Path,Instance,Basic Type"), "set_call_mode", "get_call_mode"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_type", PROPERTY_HINT_TYPE_STRING, "Object"), "set_base_type", "get_base_type"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_script", PROPERTY_HINT_FILE, script_ext_hint), "set_base_script", "get_base_script"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "type_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_type_cache", "_get_type_cache"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "basic_type", PROPERTY_HINT_ENUM, bt), "set_basic_type", "get_basic_type"); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_path", PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE), "set_base_path", "get_base_path"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "property"), "set_property", "get_property"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "index", PROPERTY_HINT_ENUM), "set_index", "get_index"); - - BIND_ENUM_CONSTANT(CALL_MODE_SELF); - BIND_ENUM_CONSTANT(CALL_MODE_NODE_PATH); - BIND_ENUM_CONSTANT(CALL_MODE_INSTANCE); - BIND_ENUM_CONSTANT(CALL_MODE_BASIC_TYPE); -} - -class VisualScriptNodeInstancePropertyGet : public VisualScriptNodeInstance { -public: - VisualScriptPropertyGet::CallMode call_mode; - NodePath node_path; - StringName property; - StringName index; - - VisualScriptPropertyGet *node = nullptr; - VisualScriptInstance *instance = nullptr; - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - switch (call_mode) { - case VisualScriptPropertyGet::CALL_MODE_SELF: { - Object *object = instance->get_owner_ptr(); - - bool valid; - - *p_outputs[0] = object->get(property, &valid); - - if (index != StringName()) { - *p_outputs[0] = p_outputs[0]->get_named(index, valid); - } - - if (!valid) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = RTR("Invalid index property name."); - return 0; - } - } break; - case VisualScriptPropertyGet::CALL_MODE_NODE_PATH: { - Node *node = Object::cast_to<Node>(instance->get_owner_ptr()); - if (!node) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = RTR("Base object is not a Node!"); - return 0; - } - - Node *another = node->get_node(node_path); - if (!another) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = RTR("Path does not lead Node!"); - return 0; - } - - bool valid; - - *p_outputs[0] = another->get(property, &valid); - - if (index != StringName()) { - *p_outputs[0] = p_outputs[0]->get_named(index, valid); - } - - if (!valid) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = vformat(RTR("Invalid index property name '%s' in node %s."), String(property), another->get_name()); - return 0; - } - - } break; - default: { - bool valid; - Variant v = *p_inputs[0]; - - *p_outputs[1] = v.get(property, &valid); - if (index != StringName()) { - *p_outputs[1] = p_outputs[1]->get_named(index, valid); - } - - if (!valid) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = RTR("Invalid index property name."); - } - - *p_outputs[0] = v; - }; - } - - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptPropertyGet::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstancePropertyGet *instance = memnew(VisualScriptNodeInstancePropertyGet); - instance->node = this; - instance->instance = p_instance; - instance->property = property; - instance->call_mode = call_mode; - instance->node_path = base_path; - instance->index = index; - - return instance; -} - -VisualScriptPropertyGet::VisualScriptPropertyGet() { - call_mode = CALL_MODE_SELF; - base_type = "Object"; - basic_type = Variant::NIL; - type_cache = Variant::NIL; -} - -template <VisualScriptPropertyGet::CallMode cmode> -static Ref<VisualScriptNode> create_property_get_node(const String &p_name) { - Ref<VisualScriptPropertyGet> node; - node.instantiate(); - node->set_call_mode(cmode); - return node; -} - -////////////////////////////////////////// -////////////////EMIT////////////////////// -////////////////////////////////////////// - -int VisualScriptEmitSignal::get_output_sequence_port_count() const { - return 1; -} - -bool VisualScriptEmitSignal::has_input_sequence_port() const { - return true; -} - -int VisualScriptEmitSignal::get_input_value_port_count() const { - Ref<VisualScript> vs = get_visual_script(); - if (vs.is_valid()) { - if (!vs->has_custom_signal(name)) { - return 0; - } - - return vs->custom_signal_get_argument_count(name); - } - - return 0; -} - -int VisualScriptEmitSignal::get_output_value_port_count() const { - return 0; -} - -String VisualScriptEmitSignal::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptEmitSignal::get_input_value_port_info(int p_idx) const { - Ref<VisualScript> vs = get_visual_script(); - if (vs.is_valid()) { - if (!vs->has_custom_signal(name)) { - return PropertyInfo(); - } - - return PropertyInfo(vs->custom_signal_get_argument_type(name, p_idx), vs->custom_signal_get_argument_name(name, p_idx)); - } - - return PropertyInfo(); -} - -PropertyInfo VisualScriptEmitSignal::get_output_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -String VisualScriptEmitSignal::get_caption() const { - return vformat(RTR("Emit %s"), name); -} - -void VisualScriptEmitSignal::set_signal(const StringName &p_type) { - if (name == p_type) { - return; - } - - name = p_type; - - notify_property_list_changed(); - ports_changed_notify(); -} - -StringName VisualScriptEmitSignal::get_signal() const { - return name; -} - -void VisualScriptEmitSignal::_validate_property(PropertyInfo &p_property) const { - if (p_property.name == "signal") { - p_property.hint = PROPERTY_HINT_ENUM; - - List<StringName> sigs; - List<MethodInfo> base_sigs; - - Ref<VisualScript> vs = get_visual_script(); - if (vs.is_valid()) { - vs->get_custom_signal_list(&sigs); - ClassDB::get_signal_list(vs->get_instance_base_type(), &base_sigs); - } - - String ml; - for (const StringName &E : sigs) { - if (!ml.is_empty()) { - ml += ","; - } - ml += E; - } - for (const MethodInfo &E : base_sigs) { - if (!ml.is_empty()) { - ml += ","; - } - ml += E.name; - } - - p_property.hint_string = ml; - } -} - -void VisualScriptEmitSignal::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_signal", "name"), &VisualScriptEmitSignal::set_signal); - ClassDB::bind_method(D_METHOD("get_signal"), &VisualScriptEmitSignal::get_signal); - - ADD_PROPERTY(PropertyInfo(Variant::STRING, "signal"), "set_signal", "get_signal"); -} - -class VisualScriptNodeInstanceEmitSignal : public VisualScriptNodeInstance { -public: - VisualScriptEmitSignal *node = nullptr; - VisualScriptInstance *instance = nullptr; - int argcount = 0; - StringName name; - - //virtual int get_working_memory_size() const override { return 0; } - //virtual bool is_output_port_unsequenced(int p_idx) const { return false; } - //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - Object *obj = instance->get_owner_ptr(); - - obj->emit_signalp(name, p_inputs, argcount); - - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptEmitSignal::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceEmitSignal *instance = memnew(VisualScriptNodeInstanceEmitSignal); - instance->node = this; - instance->instance = p_instance; - instance->name = name; - instance->argcount = get_input_value_port_count(); - return instance; -} - -VisualScriptEmitSignal::VisualScriptEmitSignal() { -} - -static Ref<VisualScriptNode> create_basic_type_call_node(const String &p_name) { - Vector<String> path = p_name.split("/"); - ERR_FAIL_COND_V(path.size() < 4, Ref<VisualScriptNode>()); - String base_type = path[2]; - String method = path[3]; - - Ref<VisualScriptFunctionCall> node; - node.instantiate(); - - Variant::Type type = Variant::VARIANT_MAX; - - for (int i = 0; i < Variant::VARIANT_MAX; i++) { - if (Variant::get_type_name(Variant::Type(i)) == base_type) { - type = Variant::Type(i); - break; - } - } - - ERR_FAIL_COND_V(type == Variant::VARIANT_MAX, Ref<VisualScriptNode>()); - - node->set_call_mode(VisualScriptFunctionCall::CALL_MODE_BASIC_TYPE); - node->set_basic_type(type); - node->set_function(method); - - return node; -} - -void register_visual_script_func_nodes() { - VisualScriptLanguage::singleton->add_register_func("functions/call", create_node_generic<VisualScriptFunctionCall>); - VisualScriptLanguage::singleton->add_register_func("functions/set", create_node_generic<VisualScriptPropertySet>); - VisualScriptLanguage::singleton->add_register_func("functions/get", create_node_generic<VisualScriptPropertyGet>); - - //VisualScriptLanguage::singleton->add_register_func("functions/call_script/call_self",create_script_call_node<VisualScriptScriptCall::CALL_MODE_SELF>); - //VisualScriptLanguage::singleton->add_register_func("functions/call_script/call_node",create_script_call_node<VisualScriptScriptCall::CALL_MODE_NODE_PATH>); - VisualScriptLanguage::singleton->add_register_func("functions/emit_signal", create_node_generic<VisualScriptEmitSignal>); - - for (int i = 0; i < Variant::VARIANT_MAX; i++) { - Variant::Type t = Variant::Type(i); - String type_name = Variant::get_type_name(t); - Callable::CallError ce; - Variant vt; - Variant::construct(t, vt, nullptr, 0, ce); - List<MethodInfo> ml; - vt.get_method_list(&ml); - - for (const MethodInfo &E : ml) { - VisualScriptLanguage::singleton->add_register_func("functions/by_type/" + type_name + "/" + E.name, create_basic_type_call_node); - } - } -} diff --git a/modules/visual_script/visual_script_func_nodes.h b/modules/visual_script/visual_script_func_nodes.h deleted file mode 100644 index 70f601307b..0000000000 --- a/modules/visual_script/visual_script_func_nodes.h +++ /dev/null @@ -1,363 +0,0 @@ -/*************************************************************************/ -/* visual_script_func_nodes.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef VISUAL_SCRIPT_FUNC_NODES_H -#define VISUAL_SCRIPT_FUNC_NODES_H - -#include "visual_script.h" - -class VisualScriptFunctionCall : public VisualScriptNode { - GDCLASS(VisualScriptFunctionCall, VisualScriptNode); - -public: - enum CallMode { - CALL_MODE_SELF, - CALL_MODE_NODE_PATH, - CALL_MODE_INSTANCE, - CALL_MODE_BASIC_TYPE, - CALL_MODE_SINGLETON, - }; - - enum RPCCallMode { - RPC_DISABLED, - RPC_RELIABLE, - RPC_UNRELIABLE, - RPC_RELIABLE_TO_ID, - RPC_UNRELIABLE_TO_ID - }; - -private: - CallMode call_mode; - StringName base_type; - String base_script; - Variant::Type basic_type; - NodePath base_path; - StringName function; - int use_default_args; - RPCCallMode rpc_call_mode; - StringName singleton; - bool validate; - - Node *_get_base_node() const; - StringName _get_base_type() const; - - MethodInfo method_cache; - void _update_method_cache(); - - void _set_argument_cache(const Dictionary &p_cache); - Dictionary _get_argument_cache() const; - -protected: - void _validate_property(PropertyInfo &p_property) const; - - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_text() const override; - virtual String get_category() const override { return "functions"; } - - void set_basic_type(Variant::Type p_type); - Variant::Type get_basic_type() const; - - void set_base_type(const StringName &p_type); - StringName get_base_type() const; - - void set_base_script(const String &p_path); - String get_base_script() const; - - void set_singleton(const StringName &p_type); - StringName get_singleton() const; - - void set_function(const StringName &p_type); - StringName get_function() const; - - void set_base_path(const NodePath &p_type); - NodePath get_base_path() const; - - void set_call_mode(CallMode p_mode); - CallMode get_call_mode() const; - - void set_use_default_args(int p_amount); - int get_use_default_args() const; - - void set_validate(bool p_amount); - bool get_validate() const; - - void set_rpc_call_mode(RPCCallMode p_mode); - RPCCallMode get_rpc_call_mode() const; - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - virtual TypeGuess guess_output_type(TypeGuess *p_inputs, int p_output) const override; - - VisualScriptFunctionCall(); -}; - -VARIANT_ENUM_CAST(VisualScriptFunctionCall::CallMode); -VARIANT_ENUM_CAST(VisualScriptFunctionCall::RPCCallMode); - -class VisualScriptPropertySet : public VisualScriptNode { - GDCLASS(VisualScriptPropertySet, VisualScriptNode); - -public: - enum CallMode { - CALL_MODE_SELF, - CALL_MODE_NODE_PATH, - CALL_MODE_INSTANCE, - CALL_MODE_BASIC_TYPE, - - }; - - enum AssignOp { - ASSIGN_OP_NONE, - ASSIGN_OP_ADD, - ASSIGN_OP_SUB, - ASSIGN_OP_MUL, - ASSIGN_OP_DIV, - ASSIGN_OP_MOD, - ASSIGN_OP_SHIFT_LEFT, - ASSIGN_OP_SHIFT_RIGHT, - ASSIGN_OP_BIT_AND, - ASSIGN_OP_BIT_OR, - ASSIGN_OP_BIT_XOR, - ASSIGN_OP_MAX - }; - -private: - PropertyInfo type_cache; - - CallMode call_mode; - Variant::Type basic_type; - StringName base_type; - String base_script; - NodePath base_path; - StringName property; - StringName index; - AssignOp assign_op; - - Node *_get_base_node() const; - StringName _get_base_type() const; - - void _update_base_type(); - - void _update_cache(); - - void _set_type_cache(const Dictionary &p_type); - Dictionary _get_type_cache() const; - - void _adjust_input_index(PropertyInfo &pinfo) const; - -protected: - void _validate_property(PropertyInfo &p_property) const; - - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_text() const override; - virtual String get_category() const override { return "functions"; } - - void set_base_type(const StringName &p_type); - StringName get_base_type() const; - - void set_base_script(const String &p_path); - String get_base_script() const; - - void set_basic_type(Variant::Type p_type); - Variant::Type get_basic_type() const; - - void set_property(const StringName &p_type); - StringName get_property() const; - - void set_base_path(const NodePath &p_type); - NodePath get_base_path() const; - - void set_call_mode(CallMode p_mode); - CallMode get_call_mode() const; - - void set_index(const StringName &p_type); - StringName get_index() const; - - void set_assign_op(AssignOp p_op); - AssignOp get_assign_op() const; - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - virtual TypeGuess guess_output_type(TypeGuess *p_inputs, int p_output) const override; - - VisualScriptPropertySet(); -}; - -VARIANT_ENUM_CAST(VisualScriptPropertySet::CallMode); -VARIANT_ENUM_CAST(VisualScriptPropertySet::AssignOp); - -class VisualScriptPropertyGet : public VisualScriptNode { - GDCLASS(VisualScriptPropertyGet, VisualScriptNode); - -public: - enum CallMode { - CALL_MODE_SELF, - CALL_MODE_NODE_PATH, - CALL_MODE_INSTANCE, - CALL_MODE_BASIC_TYPE, - - }; - -private: - Variant::Type type_cache; - - CallMode call_mode; - Variant::Type basic_type; - StringName base_type; - String base_script; - NodePath base_path; - StringName property; - StringName index; - - void _update_base_type(); - Node *_get_base_node() const; - StringName _get_base_type() const; - - void _update_cache(); - - void _set_type_cache(Variant::Type p_type); - Variant::Type _get_type_cache() const; - - void _adjust_input_index(PropertyInfo &pinfo) const; - -protected: - void _validate_property(PropertyInfo &p_property) const; - - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_text() const override; - virtual String get_category() const override { return "functions"; } - - void set_base_type(const StringName &p_type); - StringName get_base_type() const; - - void set_base_script(const String &p_path); - String get_base_script() const; - - void set_basic_type(Variant::Type p_type); - Variant::Type get_basic_type() const; - - void set_property(const StringName &p_type); - StringName get_property() const; - - void set_base_path(const NodePath &p_type); - NodePath get_base_path() const; - - void set_call_mode(CallMode p_mode); - CallMode get_call_mode() const; - - void set_index(const StringName &p_type); - StringName get_index() const; - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptPropertyGet(); -}; - -VARIANT_ENUM_CAST(VisualScriptPropertyGet::CallMode); - -class VisualScriptEmitSignal : public VisualScriptNode { - GDCLASS(VisualScriptEmitSignal, VisualScriptNode); - -private: - StringName name; - -protected: - void _validate_property(PropertyInfo &p_property) const; - - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - //virtual String get_text() const; - virtual String get_category() const override { return "functions"; } - - void set_signal(const StringName &p_type); - StringName get_signal() const; - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptEmitSignal(); -}; - -void register_visual_script_func_nodes(); - -#endif // VISUAL_SCRIPT_FUNC_NODES_H diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp deleted file mode 100644 index f02a79a617..0000000000 --- a/modules/visual_script/visual_script_nodes.cpp +++ /dev/null @@ -1,4072 +0,0 @@ -/*************************************************************************/ -/* visual_script_nodes.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "visual_script_nodes.h" - -#include "core/config/engine.h" -#include "core/config/project_settings.h" -#include "core/core_constants.h" -#include "core/input/input.h" -#include "core/os/os.h" -#include "scene/main/node.h" -#include "scene/main/scene_tree.h" - -////////////////////////////////////////// -////////////////FUNCTION////////////////// -////////////////////////////////////////// - -bool VisualScriptFunction::_set(const StringName &p_name, const Variant &p_value) { - if (p_name == "argument_count") { - int new_argc = p_value; - int argc = arguments.size(); - if (argc == new_argc) { - return true; - } - - arguments.resize(new_argc); - - for (int i = argc; i < new_argc; i++) { - arguments.write[i].name = "arg" + itos(i + 1); - arguments.write[i].type = Variant::NIL; - } - ports_changed_notify(); - notify_property_list_changed(); - return true; - } - if (String(p_name).begins_with("argument_")) { - int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int() - 1; - ERR_FAIL_INDEX_V(idx, arguments.size(), false); - String what = String(p_name).get_slice("/", 1); - if (what == "type") { - Variant::Type new_type = Variant::Type(int(p_value)); - arguments.write[idx].type = new_type; - ports_changed_notify(); - - return true; - } - - if (what == "name") { - arguments.write[idx].name = p_value; - ports_changed_notify(); - return true; - } - } - - if (p_name == "stack/stackless") { - set_stack_less(p_value); - return true; - } - - if (p_name == "stack/size") { - stack_size = p_value; - return true; - } - - if (p_name == "rpc/mode") { - rpc_mode = MultiplayerAPI::RPCMode(int(p_value)); - return true; - } - - if (p_name == "sequenced/sequenced") { - sequenced = p_value; - ports_changed_notify(); - return true; - } - - return false; -} - -bool VisualScriptFunction::_get(const StringName &p_name, Variant &r_ret) const { - if (p_name == "argument_count") { - r_ret = arguments.size(); - return true; - } - if (String(p_name).begins_with("argument_")) { - int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int() - 1; - ERR_FAIL_INDEX_V(idx, arguments.size(), false); - String what = String(p_name).get_slice("/", 1); - if (what == "type") { - r_ret = arguments[idx].type; - return true; - } - if (what == "name") { - r_ret = arguments[idx].name; - return true; - } - } - - if (p_name == "stack/stackless") { - r_ret = stack_less; - return true; - } - - if (p_name == "stack/size") { - r_ret = stack_size; - return true; - } - - if (p_name == "rpc/mode") { - r_ret = rpc_mode; - return true; - } - - if (p_name == "sequenced/sequenced") { - r_ret = sequenced; - return true; - } - - return false; -} - -void VisualScriptFunction::_get_property_list(List<PropertyInfo> *p_list) const { - p_list->push_back(PropertyInfo(Variant::INT, "argument_count", PROPERTY_HINT_RANGE, "0,256")); - String argt = "Any"; - for (int i = 1; i < Variant::VARIANT_MAX; i++) { - argt += "," + Variant::get_type_name(Variant::Type(i)); - } - - for (int i = 0; i < arguments.size(); i++) { - p_list->push_back(PropertyInfo(Variant::INT, "argument_" + itos(i + 1) + "/type", PROPERTY_HINT_ENUM, argt)); - p_list->push_back(PropertyInfo(Variant::STRING, "argument_" + itos(i + 1) + "/name")); - } - - p_list->push_back(PropertyInfo(Variant::BOOL, "sequenced/sequenced")); - - if (!stack_less) { - p_list->push_back(PropertyInfo(Variant::INT, "stack/size", PROPERTY_HINT_RANGE, "1,100000")); - } - p_list->push_back(PropertyInfo(Variant::BOOL, "stack/stackless")); - p_list->push_back(PropertyInfo(Variant::INT, "rpc/mode", PROPERTY_HINT_ENUM, "Disabled,Any,Authority")); -} - -int VisualScriptFunction::get_output_sequence_port_count() const { - return 1; -} - -bool VisualScriptFunction::has_input_sequence_port() const { - return false; -} - -int VisualScriptFunction::get_input_value_port_count() const { - return 0; -} - -int VisualScriptFunction::get_output_value_port_count() const { - return arguments.size(); -} - -String VisualScriptFunction::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptFunction::get_input_value_port_info(int p_idx) const { - ERR_FAIL_V(PropertyInfo()); -} - -PropertyInfo VisualScriptFunction::get_output_value_port_info(int p_idx) const { - // Need to check it without ERR_FAIL_COND, to prevent warnings from appearing on node creation via dragging. - if (p_idx < 0 || p_idx >= arguments.size()) { - return PropertyInfo(); - } - PropertyInfo out; - out.type = arguments[p_idx].type; - out.name = arguments[p_idx].name; - out.hint = arguments[p_idx].hint; - out.hint_string = arguments[p_idx].hint_string; - return out; -} - -String VisualScriptFunction::get_caption() const { - return RTR("Function"); -} - -String VisualScriptFunction::get_text() const { - return get_name(); //use name as function name I guess -} - -void VisualScriptFunction::add_argument(Variant::Type p_type, const String &p_name, int p_index, const PropertyHint p_hint, const String &p_hint_string) { - Argument arg; - arg.name = p_name; - arg.type = p_type; - arg.hint = p_hint; - arg.hint_string = p_hint_string; - if (p_index >= 0) { - arguments.insert(p_index, arg); - } else { - arguments.push_back(arg); - } - - ports_changed_notify(); -} - -void VisualScriptFunction::set_argument_type(int p_argidx, Variant::Type p_type) { - ERR_FAIL_INDEX(p_argidx, arguments.size()); - - arguments.write[p_argidx].type = p_type; - ports_changed_notify(); -} - -Variant::Type VisualScriptFunction::get_argument_type(int p_argidx) const { - ERR_FAIL_INDEX_V(p_argidx, arguments.size(), Variant::NIL); - return arguments[p_argidx].type; -} - -void VisualScriptFunction::set_argument_name(int p_argidx, const String &p_name) { - ERR_FAIL_INDEX(p_argidx, arguments.size()); - - arguments.write[p_argidx].name = p_name; - ports_changed_notify(); -} - -String VisualScriptFunction::get_argument_name(int p_argidx) const { - ERR_FAIL_INDEX_V(p_argidx, arguments.size(), String()); - return arguments[p_argidx].name; -} - -void VisualScriptFunction::remove_argument(int p_argidx) { - ERR_FAIL_INDEX(p_argidx, arguments.size()); - - arguments.remove_at(p_argidx); - ports_changed_notify(); -} - -int VisualScriptFunction::get_argument_count() const { - return arguments.size(); -} - -void VisualScriptFunction::set_rpc_mode(MultiplayerAPI::RPCMode p_mode) { - rpc_mode = p_mode; -} - -MultiplayerAPI::RPCMode VisualScriptFunction::get_rpc_mode() const { - return rpc_mode; -} - -class VisualScriptNodeInstanceFunction : public VisualScriptNodeInstance { -public: - VisualScriptFunction *node = nullptr; - VisualScriptInstance *instance = nullptr; - - //virtual int get_working_memory_size() const override { return 0; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - int ac = node->get_argument_count(); - - for (int i = 0; i < ac; i++) { -#ifdef DEBUG_ENABLED - Variant::Type expected = node->get_argument_type(i); - if (expected != Variant::NIL) { - if (!Variant::can_convert_strict(p_inputs[i]->get_type(), expected)) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.expected = expected; - r_error.argument = i; - return 0; - } - } -#endif - - *p_outputs[i] = *p_inputs[i]; - } - - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptFunction::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceFunction *instance = memnew(VisualScriptNodeInstanceFunction); - instance->node = this; - instance->instance = p_instance; - return instance; -} - -void VisualScriptFunction::reset_state() { - arguments.clear(); - stack_size = 256; - stack_less = false; - sequenced = true; - rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; -} - -VisualScriptFunction::VisualScriptFunction() { - stack_size = 256; - stack_less = false; - sequenced = true; - rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; -} - -void VisualScriptFunction::set_stack_less(bool p_enable) { - stack_less = p_enable; - notify_property_list_changed(); -} - -bool VisualScriptFunction::is_stack_less() const { - return stack_less; -} - -void VisualScriptFunction::set_sequenced(bool p_enable) { - sequenced = p_enable; -} - -bool VisualScriptFunction::is_sequenced() const { - return sequenced; -} - -void VisualScriptFunction::set_stack_size(int p_size) { - ERR_FAIL_COND(p_size < 1 || p_size > 100000); - stack_size = p_size; -} - -int VisualScriptFunction::get_stack_size() const { - return stack_size; -} - -////////////////////////////////////////// -/////////////////LISTS//////////////////// -////////////////////////////////////////// - -int VisualScriptLists::get_output_sequence_port_count() const { - if (sequenced) { - return 1; - } - return 0; -} - -bool VisualScriptLists::has_input_sequence_port() const { - return sequenced; -} - -String VisualScriptLists::get_output_sequence_port_text(int p_port) const { - return ""; -} - -int VisualScriptLists::get_input_value_port_count() const { - return inputports.size(); -} - -int VisualScriptLists::get_output_value_port_count() const { - return outputports.size(); -} - -PropertyInfo VisualScriptLists::get_input_value_port_info(int p_idx) const { - ERR_FAIL_INDEX_V(p_idx, inputports.size(), PropertyInfo()); - - PropertyInfo pi; - pi.name = inputports[p_idx].name; - pi.type = inputports[p_idx].type; - return pi; -} - -PropertyInfo VisualScriptLists::get_output_value_port_info(int p_idx) const { - ERR_FAIL_INDEX_V(p_idx, outputports.size(), PropertyInfo()); - - PropertyInfo pi; - pi.name = outputports[p_idx].name; - pi.type = outputports[p_idx].type; - return pi; -} - -bool VisualScriptLists::is_input_port_editable() const { - return ((flags & INPUT_EDITABLE) == INPUT_EDITABLE); -} - -bool VisualScriptLists::is_input_port_name_editable() const { - return ((flags & INPUT_NAME_EDITABLE) == INPUT_NAME_EDITABLE); -} - -bool VisualScriptLists::is_input_port_type_editable() const { - return ((flags & INPUT_TYPE_EDITABLE) == INPUT_TYPE_EDITABLE); -} - -bool VisualScriptLists::is_output_port_editable() const { - return ((flags & OUTPUT_EDITABLE) == OUTPUT_EDITABLE); -} - -bool VisualScriptLists::is_output_port_name_editable() const { - return ((flags & INPUT_NAME_EDITABLE) == INPUT_NAME_EDITABLE); -} - -bool VisualScriptLists::is_output_port_type_editable() const { - return ((flags & INPUT_TYPE_EDITABLE) == INPUT_TYPE_EDITABLE); -} - -// for the inspector -bool VisualScriptLists::_set(const StringName &p_name, const Variant &p_value) { - if (p_name == "input_count" && is_input_port_editable()) { - int new_argc = p_value; - int argc = inputports.size(); - if (argc == new_argc) { - return true; - } - - inputports.resize(new_argc); - - for (int i = argc; i < new_argc; i++) { - inputports.write[i].name = "arg" + itos(i + 1); - inputports.write[i].type = Variant::NIL; - } - ports_changed_notify(); - notify_property_list_changed(); - return true; - } - if (String(p_name).begins_with("input_") && is_input_port_editable()) { - int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int() - 1; - ERR_FAIL_INDEX_V(idx, inputports.size(), false); - String what = String(p_name).get_slice("/", 1); - if (what == "type") { - Variant::Type new_type = Variant::Type(int(p_value)); - inputports.write[idx].type = new_type; - ports_changed_notify(); - - return true; - } - - if (what == "name") { - inputports.write[idx].name = p_value; - ports_changed_notify(); - return true; - } - } - - if (p_name == "output_count" && is_output_port_editable()) { - int new_argc = p_value; - int argc = outputports.size(); - if (argc == new_argc) { - return true; - } - - outputports.resize(new_argc); - - for (int i = argc; i < new_argc; i++) { - outputports.write[i].name = "arg" + itos(i + 1); - outputports.write[i].type = Variant::NIL; - } - ports_changed_notify(); - notify_property_list_changed(); - return true; - } - if (String(p_name).begins_with("output_") && is_output_port_editable()) { - int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int() - 1; - ERR_FAIL_INDEX_V(idx, outputports.size(), false); - String what = String(p_name).get_slice("/", 1); - if (what == "type") { - Variant::Type new_type = Variant::Type(int(p_value)); - outputports.write[idx].type = new_type; - ports_changed_notify(); - - return true; - } - - if (what == "name") { - outputports.write[idx].name = p_value; - ports_changed_notify(); - return true; - } - } - - if (p_name == "sequenced/sequenced") { - sequenced = p_value; - ports_changed_notify(); - return true; - } - - return false; -} - -bool VisualScriptLists::_get(const StringName &p_name, Variant &r_ret) const { - if (p_name == "input_count" && is_input_port_editable()) { - r_ret = inputports.size(); - return true; - } - if (String(p_name).begins_with("input_") && is_input_port_editable()) { - int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int() - 1; - ERR_FAIL_INDEX_V(idx, inputports.size(), false); - String what = String(p_name).get_slice("/", 1); - if (what == "type") { - r_ret = inputports[idx].type; - return true; - } - if (what == "name") { - r_ret = inputports[idx].name; - return true; - } - } - - if (p_name == "output_count" && is_output_port_editable()) { - r_ret = outputports.size(); - return true; - } - if (String(p_name).begins_with("output_") && is_output_port_editable()) { - int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int() - 1; - ERR_FAIL_INDEX_V(idx, outputports.size(), false); - String what = String(p_name).get_slice("/", 1); - if (what == "type") { - r_ret = outputports[idx].type; - return true; - } - if (what == "name") { - r_ret = outputports[idx].name; - return true; - } - } - - if (p_name == "sequenced/sequenced") { - r_ret = sequenced; - return true; - } - - return false; -} - -void VisualScriptLists::_get_property_list(List<PropertyInfo> *p_list) const { - if (is_input_port_editable()) { - p_list->push_back(PropertyInfo(Variant::INT, "input_count", PROPERTY_HINT_RANGE, "0,256")); - String argt = "Any"; - for (int i = 1; i < Variant::VARIANT_MAX; i++) { - argt += "," + Variant::get_type_name(Variant::Type(i)); - } - - for (int i = 0; i < inputports.size(); i++) { - p_list->push_back(PropertyInfo(Variant::INT, "input_" + itos(i + 1) + "/type", PROPERTY_HINT_ENUM, argt)); - p_list->push_back(PropertyInfo(Variant::STRING, "input_" + itos(i + 1) + "/name")); - } - } - - if (is_output_port_editable()) { - p_list->push_back(PropertyInfo(Variant::INT, "output_count", PROPERTY_HINT_RANGE, "0,256")); - String argt = "Any"; - for (int i = 1; i < Variant::VARIANT_MAX; i++) { - argt += "," + Variant::get_type_name(Variant::Type(i)); - } - - for (int i = 0; i < outputports.size(); i++) { - p_list->push_back(PropertyInfo(Variant::INT, "output_" + itos(i + 1) + "/type", PROPERTY_HINT_ENUM, argt)); - p_list->push_back(PropertyInfo(Variant::STRING, "output_" + itos(i + 1) + "/name")); - } - } - p_list->push_back(PropertyInfo(Variant::BOOL, "sequenced/sequenced")); -} - -// input data port interaction -void VisualScriptLists::add_input_data_port(Variant::Type p_type, const String &p_name, int p_index) { - if (!is_input_port_editable()) { - return; - } - - Port inp; - inp.name = p_name; - inp.type = p_type; - if (p_index >= 0) { - inputports.insert(p_index, inp); - } else { - inputports.push_back(inp); - } - - ports_changed_notify(); - notify_property_list_changed(); -} - -void VisualScriptLists::set_input_data_port_type(int p_idx, Variant::Type p_type) { - if (!is_input_port_type_editable()) { - return; - } - - ERR_FAIL_INDEX(p_idx, inputports.size()); - - inputports.write[p_idx].type = p_type; - ports_changed_notify(); - notify_property_list_changed(); -} - -void VisualScriptLists::set_input_data_port_name(int p_idx, const String &p_name) { - if (!is_input_port_name_editable()) { - return; - } - - ERR_FAIL_INDEX(p_idx, inputports.size()); - - inputports.write[p_idx].name = p_name; - ports_changed_notify(); - notify_property_list_changed(); -} - -void VisualScriptLists::remove_input_data_port(int p_argidx) { - if (!is_input_port_editable()) { - return; - } - - ERR_FAIL_INDEX(p_argidx, inputports.size()); - - inputports.remove_at(p_argidx); - - ports_changed_notify(); - notify_property_list_changed(); -} - -// output data port interaction -void VisualScriptLists::add_output_data_port(Variant::Type p_type, const String &p_name, int p_index) { - if (!is_output_port_editable()) { - return; - } - - Port out; - out.name = p_name; - out.type = p_type; - if (p_index >= 0) { - outputports.insert(p_index, out); - } else { - outputports.push_back(out); - } - - ports_changed_notify(); - notify_property_list_changed(); -} - -void VisualScriptLists::set_output_data_port_type(int p_idx, Variant::Type p_type) { - if (!is_output_port_type_editable()) { - return; - } - - ERR_FAIL_INDEX(p_idx, outputports.size()); - - outputports.write[p_idx].type = p_type; - ports_changed_notify(); - notify_property_list_changed(); -} - -void VisualScriptLists::set_output_data_port_name(int p_idx, const String &p_name) { - if (!is_output_port_name_editable()) { - return; - } - - ERR_FAIL_INDEX(p_idx, outputports.size()); - - outputports.write[p_idx].name = p_name; - ports_changed_notify(); - notify_property_list_changed(); -} - -void VisualScriptLists::remove_output_data_port(int p_argidx) { - if (!is_output_port_editable()) { - return; - } - - ERR_FAIL_INDEX(p_argidx, outputports.size()); - - outputports.remove_at(p_argidx); - - ports_changed_notify(); - notify_property_list_changed(); -} - -// sequences -void VisualScriptLists::set_sequenced(bool p_enable) { - if (sequenced == p_enable) { - return; - } - sequenced = p_enable; - ports_changed_notify(); -} - -bool VisualScriptLists::is_sequenced() const { - return sequenced; -} - -void VisualScriptLists::reset_state() { - inputports.clear(); - outputports.clear(); - sequenced = false; - flags = 0; -} - -VisualScriptLists::VisualScriptLists() { - // initialize - sequenced = false; - flags = 0; -} - -void VisualScriptLists::_bind_methods() { - ClassDB::bind_method(D_METHOD("add_input_data_port", "type", "name", "index"), &VisualScriptLists::add_input_data_port); - ClassDB::bind_method(D_METHOD("set_input_data_port_name", "index", "name"), &VisualScriptLists::set_input_data_port_name); - ClassDB::bind_method(D_METHOD("set_input_data_port_type", "index", "type"), &VisualScriptLists::set_input_data_port_type); - ClassDB::bind_method(D_METHOD("remove_input_data_port", "index"), &VisualScriptLists::remove_input_data_port); - - ClassDB::bind_method(D_METHOD("add_output_data_port", "type", "name", "index"), &VisualScriptLists::add_output_data_port); - ClassDB::bind_method(D_METHOD("set_output_data_port_name", "index", "name"), &VisualScriptLists::set_output_data_port_name); - ClassDB::bind_method(D_METHOD("set_output_data_port_type", "index", "type"), &VisualScriptLists::set_output_data_port_type); - ClassDB::bind_method(D_METHOD("remove_output_data_port", "index"), &VisualScriptLists::remove_output_data_port); -} - -////////////////////////////////////////// -//////////////COMPOSEARRAY//////////////// -////////////////////////////////////////// - -int VisualScriptComposeArray::get_output_sequence_port_count() const { - if (sequenced) { - return 1; - } - return 0; -} - -bool VisualScriptComposeArray::has_input_sequence_port() const { - return sequenced; -} - -String VisualScriptComposeArray::get_output_sequence_port_text(int p_port) const { - return ""; -} - -int VisualScriptComposeArray::get_input_value_port_count() const { - return inputports.size(); -} - -int VisualScriptComposeArray::get_output_value_port_count() const { - return 1; -} - -PropertyInfo VisualScriptComposeArray::get_input_value_port_info(int p_idx) const { - ERR_FAIL_INDEX_V(p_idx, inputports.size(), PropertyInfo()); - - PropertyInfo pi; - pi.name = inputports[p_idx].name; - pi.type = inputports[p_idx].type; - return pi; -} - -PropertyInfo VisualScriptComposeArray::get_output_value_port_info(int p_idx) const { - PropertyInfo pi; - pi.name = "out"; - pi.type = Variant::ARRAY; - return pi; -} - -String VisualScriptComposeArray::get_caption() const { - return RTR("Compose Array"); -} - -String VisualScriptComposeArray::get_text() const { - return ""; -} - -class VisualScriptComposeArrayNode : public VisualScriptNodeInstance { -public: - int input_count = 0; - virtual int get_working_memory_size() const override { return 0; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - if (input_count > 0) { - Array arr; - for (int i = 0; i < input_count; i++) { - arr.push_back((*p_inputs[i])); - } - Variant va = Variant(arr); - - *p_outputs[0] = va; - } - - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptComposeArray::instantiate(VisualScriptInstance *p_instance) { - VisualScriptComposeArrayNode *instance = memnew(VisualScriptComposeArrayNode); - instance->input_count = inputports.size(); - return instance; -} - -VisualScriptComposeArray::VisualScriptComposeArray() { - // initialize stuff here - sequenced = false; - flags = INPUT_EDITABLE; -} - -////////////////////////////////////////// -////////////////OPERATOR////////////////// -////////////////////////////////////////// - -int VisualScriptOperator::get_output_sequence_port_count() const { - return 0; -} - -bool VisualScriptOperator::has_input_sequence_port() const { - return false; -} - -int VisualScriptOperator::get_input_value_port_count() const { - return (op == Variant::OP_BIT_NEGATE || op == Variant::OP_NOT || op == Variant::OP_NEGATE || op == Variant::OP_POSITIVE) ? 1 : 2; -} - -int VisualScriptOperator::get_output_value_port_count() const { - return 1; -} - -String VisualScriptOperator::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptOperator::get_input_value_port_info(int p_idx) const { - static const Variant::Type port_types[Variant::OP_MAX][2] = { - { Variant::NIL, Variant::NIL }, //OP_EQUAL, - { Variant::NIL, Variant::NIL }, //OP_NOT_EQUAL, - { Variant::NIL, Variant::NIL }, //OP_LESS, - { Variant::NIL, Variant::NIL }, //OP_LESS_EQUAL, - { Variant::NIL, Variant::NIL }, //OP_GREATER, - { Variant::NIL, Variant::NIL }, //OP_GREATER_EQUAL, - //mathematic - { Variant::NIL, Variant::NIL }, //OP_ADD, - { Variant::NIL, Variant::NIL }, //OP_SUBTRACT, - { Variant::NIL, Variant::NIL }, //OP_MULTIPLY, - { Variant::NIL, Variant::NIL }, //OP_DIVIDE, - { Variant::NIL, Variant::NIL }, //OP_NEGATE, - { Variant::NIL, Variant::NIL }, //OP_POSITIVE, - { Variant::INT, Variant::INT }, //OP_MODULE, - //bitwise - { Variant::INT, Variant::INT }, //OP_SHIFT_LEFT, - { Variant::INT, Variant::INT }, //OP_SHIFT_RIGHT, - { Variant::INT, Variant::INT }, //OP_BIT_AND, - { Variant::INT, Variant::INT }, //OP_BIT_OR, - { Variant::INT, Variant::INT }, //OP_BIT_XOR, - { Variant::INT, Variant::INT }, //OP_BIT_NEGATE, - //logic - { Variant::BOOL, Variant::BOOL }, //OP_AND, - { Variant::BOOL, Variant::BOOL }, //OP_OR, - { Variant::BOOL, Variant::BOOL }, //OP_XOR, - { Variant::BOOL, Variant::BOOL }, //OP_NOT, - //containment - { Variant::NIL, Variant::NIL } //OP_IN, - }; - - ERR_FAIL_INDEX_V(p_idx, 2, PropertyInfo()); - - PropertyInfo pinfo; - pinfo.name = p_idx == 0 ? "A" : "B"; - pinfo.type = port_types[op][p_idx]; - if (pinfo.type == Variant::NIL) { - pinfo.type = typed; - } - return pinfo; -} - -PropertyInfo VisualScriptOperator::get_output_value_port_info(int p_idx) const { - static const Variant::Type port_types[Variant::OP_MAX] = { - //comparison - Variant::BOOL, //OP_EQUAL, - Variant::BOOL, //OP_NOT_EQUAL, - Variant::BOOL, //OP_LESS, - Variant::BOOL, //OP_LESS_EQUAL, - Variant::BOOL, //OP_GREATER, - Variant::BOOL, //OP_GREATER_EQUAL, - //mathematic - Variant::NIL, //OP_ADD, - Variant::NIL, //OP_SUBTRACT, - Variant::NIL, //OP_MULTIPLY, - Variant::NIL, //OP_DIVIDE, - Variant::NIL, //OP_NEGATE, - Variant::NIL, //OP_POSITIVE, - Variant::INT, //OP_MODULE, - //bitwise - Variant::INT, //OP_SHIFT_LEFT, - Variant::INT, //OP_SHIFT_RIGHT, - Variant::INT, //OP_BIT_AND, - Variant::INT, //OP_BIT_OR, - Variant::INT, //OP_BIT_XOR, - Variant::INT, //OP_BIT_NEGATE, - //logic - Variant::BOOL, //OP_AND, - Variant::BOOL, //OP_OR, - Variant::BOOL, //OP_XOR, - Variant::BOOL, //OP_NOT, - //containment - Variant::BOOL //OP_IN, - }; - - PropertyInfo pinfo; - pinfo.name = ""; - pinfo.type = port_types[op]; - if (pinfo.type == Variant::NIL) { - pinfo.type = typed; - } - return pinfo; -} - -String VisualScriptOperator::get_caption() const { - switch (op) { - // comparison - case Variant::OP_EQUAL: - return U"A = B"; - case Variant::OP_NOT_EQUAL: - return U"A \u2260 B"; - case Variant::OP_LESS: - return U"A < B"; - case Variant::OP_LESS_EQUAL: - return U"A \u2264 B"; - case Variant::OP_GREATER: - return U"A > B"; - case Variant::OP_GREATER_EQUAL: - return U"A \u2265 B"; - - // mathematic - case Variant::OP_ADD: - return U"A + B"; - case Variant::OP_SUBTRACT: - return U"A - B"; - case Variant::OP_MULTIPLY: - return U"A \u00D7 B"; - case Variant::OP_DIVIDE: - return U"A \u00F7 B"; - case Variant::OP_NEGATE: - return U"\u00AC A"; - case Variant::OP_POSITIVE: - return U"+ A"; - case Variant::OP_MODULE: - return U"A mod B"; - - // bitwise - case Variant::OP_SHIFT_LEFT: - return U"A << B"; - case Variant::OP_SHIFT_RIGHT: - return U"A >> B"; - case Variant::OP_BIT_AND: - return U"A & B"; - case Variant::OP_BIT_OR: - return U"A | B"; - case Variant::OP_BIT_XOR: - return U"A ^ B"; - case Variant::OP_BIT_NEGATE: - return U"~A"; - - // logic - case Variant::OP_AND: - return U"A and B"; - case Variant::OP_OR: - return U"A or B"; - case Variant::OP_XOR: - return U"A xor B"; - case Variant::OP_NOT: - return U"not A"; - case Variant::OP_IN: - return U"A in B"; - - default: { - ERR_FAIL_V_MSG( - U"Unknown node", - U"Unknown node type encountered, caption not available."); - } - } -} - -String VisualScriptOperator::get_operator_name(Variant::Operator p_op) { - switch (p_op) { - // comparison - case Variant::OP_EQUAL: - return "Are Equal"; - case Variant::OP_NOT_EQUAL: - return "Are Not Equal"; - case Variant::OP_LESS: - return "Less Than"; - case Variant::OP_LESS_EQUAL: - return "Less Than or Equal"; - case Variant::OP_GREATER: - return "Greater Than"; - case Variant::OP_GREATER_EQUAL: - return "Greater Than or Equal"; - - // mathematic - case Variant::OP_ADD: - return "Add"; - case Variant::OP_SUBTRACT: - return "Subtract"; - case Variant::OP_MULTIPLY: - return "Multiply"; - case Variant::OP_DIVIDE: - return "Divide"; - case Variant::OP_NEGATE: - return "Negate"; - case Variant::OP_POSITIVE: - return "Positive"; - case Variant::OP_MODULE: - return "Remainder"; - - // bitwise - case Variant::OP_SHIFT_LEFT: - return "Bit Shift Left"; - case Variant::OP_SHIFT_RIGHT: - return "Bit Shift Right"; - case Variant::OP_BIT_AND: - return "Bit And"; - case Variant::OP_BIT_OR: - return "Bit Or"; - case Variant::OP_BIT_XOR: - return "Bit Xor"; - case Variant::OP_BIT_NEGATE: - return "Bit Negate"; - - // logic - case Variant::OP_AND: - return "And"; - case Variant::OP_OR: - return "Or"; - case Variant::OP_XOR: - return "Xor"; - case Variant::OP_NOT: - return "Not"; - case Variant::OP_IN: - return "In"; - - default: { - ERR_FAIL_INDEX_V(p_op, Variant::OP_MAX, ""); - return "Unknown Operator"; - } - } -} - -void VisualScriptOperator::set_operator(Variant::Operator p_op) { - if (op == p_op) { - return; - } - op = p_op; - ports_changed_notify(); -} - -Variant::Operator VisualScriptOperator::get_operator() const { - return op; -} - -void VisualScriptOperator::set_typed(Variant::Type p_op) { - if (typed == p_op) { - return; - } - - typed = p_op; - ports_changed_notify(); -} - -Variant::Type VisualScriptOperator::get_typed() const { - return typed; -} - -void VisualScriptOperator::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualScriptOperator::set_operator); - ClassDB::bind_method(D_METHOD("get_operator"), &VisualScriptOperator::get_operator); - - ClassDB::bind_method(D_METHOD("set_typed", "type"), &VisualScriptOperator::set_typed); - ClassDB::bind_method(D_METHOD("get_typed"), &VisualScriptOperator::get_typed); - - String types; - for (int i = 0; i < Variant::OP_MAX; i++) { - if (i > 0) { - types += ","; - } - types += get_operator_name(static_cast<Variant::Operator>(i)); - } - - String argt = "Any"; - for (int i = 1; i < Variant::VARIANT_MAX; i++) { - argt += "," + Variant::get_type_name(Variant::Type(i)); - } - - ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, types), "set_operator", "get_operator"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt), "set_typed", "get_typed"); -} - -class VisualScriptNodeInstanceOperator : public VisualScriptNodeInstance { -public: - bool unary = false; - Variant::Operator op; - - //virtual int get_working_memory_size() const override { return 0; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - bool valid; - if (unary) { - Variant::evaluate(op, *p_inputs[0], Variant(), *p_outputs[0], valid); - } else { - Variant::evaluate(op, *p_inputs[0], *p_inputs[1], *p_outputs[0], valid); - } - - if (!valid) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - if (p_outputs[0]->get_type() == Variant::STRING) { - r_error_str = *p_outputs[0]; - } else { - if (unary) { - r_error_str = String(Variant::get_operator_name(op)) + ": " + RTR("Invalid argument of type:") + " " + Variant::get_type_name(p_inputs[0]->get_type()); - } else { - r_error_str = String(Variant::get_operator_name(op)) + ": " + RTR("Invalid arguments:") + " A: " + Variant::get_type_name(p_inputs[0]->get_type()) + ", B: " + Variant::get_type_name(p_inputs[1]->get_type()); - } - } - } - - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptOperator::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceOperator *instance = memnew(VisualScriptNodeInstanceOperator); - instance->unary = get_input_value_port_count() == 1; - instance->op = op; - return instance; -} - -VisualScriptOperator::VisualScriptOperator() { - op = Variant::OP_ADD; - typed = Variant::NIL; -} - -template <Variant::Operator OP> -static Ref<VisualScriptNode> create_op_node(const String &p_name) { - Ref<VisualScriptOperator> node; - node.instantiate(); - node->set_operator(OP); - return node; -} - -////////////////////////////////////////// -////////////////OPERATOR////////////////// -////////////////////////////////////////// - -int VisualScriptSelect::get_output_sequence_port_count() const { - return 0; -} - -bool VisualScriptSelect::has_input_sequence_port() const { - return false; -} - -int VisualScriptSelect::get_input_value_port_count() const { - return 3; -} - -int VisualScriptSelect::get_output_value_port_count() const { - return 1; -} - -String VisualScriptSelect::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptSelect::get_input_value_port_info(int p_idx) const { - if (p_idx == 0) { - return PropertyInfo(Variant::BOOL, "cond"); - } else if (p_idx == 1) { - return PropertyInfo(typed, "a"); - } else { - return PropertyInfo(typed, "b"); - } -} - -PropertyInfo VisualScriptSelect::get_output_value_port_info(int p_idx) const { - return PropertyInfo(typed, "out"); -} - -String VisualScriptSelect::get_caption() const { - return RTR("Select"); -} - -String VisualScriptSelect::get_text() const { - return RTR("a if cond, else b"); -} - -void VisualScriptSelect::set_typed(Variant::Type p_op) { - if (typed == p_op) { - return; - } - - typed = p_op; - ports_changed_notify(); -} - -Variant::Type VisualScriptSelect::get_typed() const { - return typed; -} - -void VisualScriptSelect::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_typed", "type"), &VisualScriptSelect::set_typed); - ClassDB::bind_method(D_METHOD("get_typed"), &VisualScriptSelect::get_typed); - - String argt = "Any"; - for (int i = 1; i < Variant::VARIANT_MAX; i++) { - argt += "," + Variant::get_type_name(Variant::Type(i)); - } - - ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt), "set_typed", "get_typed"); -} - -class VisualScriptNodeInstanceSelect : public VisualScriptNodeInstance { -public: - //virtual int get_working_memory_size() const override { return 0; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - bool cond = *p_inputs[0]; - if (cond) { - *p_outputs[0] = *p_inputs[1]; - } else { - *p_outputs[0] = *p_inputs[2]; - } - - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptSelect::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceSelect *instance = memnew(VisualScriptNodeInstanceSelect); - return instance; -} - -VisualScriptSelect::VisualScriptSelect() { - typed = Variant::NIL; -} - -////////////////////////////////////////// -////////////////VARIABLE GET////////////////// -////////////////////////////////////////// - -int VisualScriptVariableGet::get_output_sequence_port_count() const { - return 0; -} - -bool VisualScriptVariableGet::has_input_sequence_port() const { - return false; -} - -int VisualScriptVariableGet::get_input_value_port_count() const { - return 0; -} - -int VisualScriptVariableGet::get_output_value_port_count() const { - return 1; -} - -String VisualScriptVariableGet::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptVariableGet::get_input_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -PropertyInfo VisualScriptVariableGet::get_output_value_port_info(int p_idx) const { - PropertyInfo pinfo; - pinfo.name = "value"; - if (get_visual_script().is_valid() && get_visual_script()->has_variable(variable)) { - PropertyInfo vinfo = get_visual_script()->get_variable_info(variable); - pinfo.type = vinfo.type; - pinfo.hint = vinfo.hint; - pinfo.hint_string = vinfo.hint_string; - } - return pinfo; -} - -String VisualScriptVariableGet::get_caption() const { - return vformat(RTR("Get %s"), variable); -} - -void VisualScriptVariableGet::set_variable(StringName p_variable) { - if (variable == p_variable) { - return; - } - variable = p_variable; - ports_changed_notify(); -} - -StringName VisualScriptVariableGet::get_variable() const { - return variable; -} - -void VisualScriptVariableGet::_validate_property(PropertyInfo &p_property) const { - if (p_property.name == "var_name" && get_visual_script().is_valid()) { - Ref<VisualScript> vs = get_visual_script(); - List<StringName> vars; - vs->get_variable_list(&vars); - - String vhint; - for (const StringName &E : vars) { - if (!vhint.is_empty()) { - vhint += ","; - } - - vhint += E.operator String(); - } - - p_property.hint = PROPERTY_HINT_ENUM; - p_property.hint_string = vhint; - } -} - -void VisualScriptVariableGet::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_variable", "name"), &VisualScriptVariableGet::set_variable); - ClassDB::bind_method(D_METHOD("get_variable"), &VisualScriptVariableGet::get_variable); - - ADD_PROPERTY(PropertyInfo(Variant::STRING, "var_name"), "set_variable", "get_variable"); -} - -class VisualScriptNodeInstanceVariableGet : public VisualScriptNodeInstance { -public: - VisualScriptVariableGet *node = nullptr; - VisualScriptInstance *instance = nullptr; - StringName variable; - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - if (!instance->get_variable(variable, p_outputs[0])) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = RTR("VariableGet not found in script:") + " '" + String(variable) + "'"; - return 0; - } - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptVariableGet::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceVariableGet *instance = memnew(VisualScriptNodeInstanceVariableGet); - instance->node = this; - instance->instance = p_instance; - instance->variable = variable; - return instance; -} - -VisualScriptVariableGet::VisualScriptVariableGet() { -} - -////////////////////////////////////////// -////////////////VARIABLE SET////////////////// -////////////////////////////////////////// - -int VisualScriptVariableSet::get_output_sequence_port_count() const { - return 1; -} - -bool VisualScriptVariableSet::has_input_sequence_port() const { - return true; -} - -int VisualScriptVariableSet::get_input_value_port_count() const { - return 1; -} - -int VisualScriptVariableSet::get_output_value_port_count() const { - return 0; -} - -String VisualScriptVariableSet::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptVariableSet::get_input_value_port_info(int p_idx) const { - PropertyInfo pinfo; - pinfo.name = "set"; - if (get_visual_script().is_valid() && get_visual_script()->has_variable(variable)) { - PropertyInfo vinfo = get_visual_script()->get_variable_info(variable); - pinfo.type = vinfo.type; - pinfo.hint = vinfo.hint; - pinfo.hint_string = vinfo.hint_string; - } - return pinfo; -} - -PropertyInfo VisualScriptVariableSet::get_output_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -String VisualScriptVariableSet::get_caption() const { - return vformat(RTR("Set %s"), variable); -} - -void VisualScriptVariableSet::set_variable(StringName p_variable) { - if (variable == p_variable) { - return; - } - variable = p_variable; - ports_changed_notify(); -} - -StringName VisualScriptVariableSet::get_variable() const { - return variable; -} - -void VisualScriptVariableSet::_validate_property(PropertyInfo &p_property) const { - if (p_property.name == "var_name" && get_visual_script().is_valid()) { - Ref<VisualScript> vs = get_visual_script(); - List<StringName> vars; - vs->get_variable_list(&vars); - - String vhint; - for (const StringName &E : vars) { - if (!vhint.is_empty()) { - vhint += ","; - } - - vhint += E.operator String(); - } - - p_property.hint = PROPERTY_HINT_ENUM; - p_property.hint_string = vhint; - } -} - -void VisualScriptVariableSet::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_variable", "name"), &VisualScriptVariableSet::set_variable); - ClassDB::bind_method(D_METHOD("get_variable"), &VisualScriptVariableSet::get_variable); - - ADD_PROPERTY(PropertyInfo(Variant::STRING, "var_name"), "set_variable", "get_variable"); -} - -class VisualScriptNodeInstanceVariableSet : public VisualScriptNodeInstance { -public: - VisualScriptVariableSet *node = nullptr; - VisualScriptInstance *instance = nullptr; - StringName variable; - - //virtual int get_working_memory_size() const override { return 0; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - if (!instance->set_variable(variable, *p_inputs[0])) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = RTR("VariableSet not found in script:") + " '" + String(variable) + "'"; - } - - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptVariableSet::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceVariableSet *instance = memnew(VisualScriptNodeInstanceVariableSet); - instance->node = this; - instance->instance = p_instance; - instance->variable = variable; - return instance; -} - -VisualScriptVariableSet::VisualScriptVariableSet() { -} - -////////////////////////////////////////// -////////////////CONSTANT////////////////// -////////////////////////////////////////// - -int VisualScriptConstant::get_output_sequence_port_count() const { - return 0; -} - -bool VisualScriptConstant::has_input_sequence_port() const { - return false; -} - -int VisualScriptConstant::get_input_value_port_count() const { - return 0; -} - -int VisualScriptConstant::get_output_value_port_count() const { - return 1; -} - -String VisualScriptConstant::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptConstant::get_input_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -PropertyInfo VisualScriptConstant::get_output_value_port_info(int p_idx) const { - PropertyInfo pinfo; - pinfo.name = String(value); - pinfo.type = type; - return pinfo; -} - -String VisualScriptConstant::get_caption() const { - return RTR("Constant"); -} - -void VisualScriptConstant::set_constant_type(Variant::Type p_type) { - if (type == p_type) { - return; - } - - type = p_type; - Callable::CallError ce; - Variant::construct(type, value, nullptr, 0, ce); - ports_changed_notify(); - notify_property_list_changed(); -} - -Variant::Type VisualScriptConstant::get_constant_type() const { - return type; -} - -void VisualScriptConstant::set_constant_value(Variant p_value) { - if (value == p_value) { - return; - } - - value = p_value; - ports_changed_notify(); -} - -Variant VisualScriptConstant::get_constant_value() const { - return value; -} - -void VisualScriptConstant::_validate_property(PropertyInfo &p_property) const { - if (p_property.name == "value") { - p_property.type = type; - if (type == Variant::NIL) { - p_property.usage = PROPERTY_USAGE_NONE; //do not save if nil - } - } -} - -void VisualScriptConstant::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_constant_type", "type"), &VisualScriptConstant::set_constant_type); - ClassDB::bind_method(D_METHOD("get_constant_type"), &VisualScriptConstant::get_constant_type); - - ClassDB::bind_method(D_METHOD("set_constant_value", "value"), &VisualScriptConstant::set_constant_value); - ClassDB::bind_method(D_METHOD("get_constant_value"), &VisualScriptConstant::get_constant_value); - - String argt = "Null"; - for (int i = 1; i < Variant::VARIANT_MAX; i++) { - argt += "," + Variant::get_type_name(Variant::Type(i)); - } - - ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt), "set_constant_type", "get_constant_type"); - ADD_PROPERTY(PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT | PROPERTY_USAGE_DEFAULT), "set_constant_value", "get_constant_value"); -} - -class VisualScriptNodeInstanceConstant : public VisualScriptNodeInstance { -public: - Variant constant; - //virtual int get_working_memory_size() const override { return 0; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - *p_outputs[0] = constant; - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptConstant::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceConstant *instance = memnew(VisualScriptNodeInstanceConstant); - instance->constant = value; - return instance; -} - -VisualScriptConstant::VisualScriptConstant() { - type = Variant::NIL; -} - -////////////////////////////////////////// -////////////////PRELOAD////////////////// -////////////////////////////////////////// - -int VisualScriptPreload::get_output_sequence_port_count() const { - return 0; -} - -bool VisualScriptPreload::has_input_sequence_port() const { - return false; -} - -int VisualScriptPreload::get_input_value_port_count() const { - return 0; -} - -int VisualScriptPreload::get_output_value_port_count() const { - return 1; -} - -String VisualScriptPreload::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptPreload::get_input_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -PropertyInfo VisualScriptPreload::get_output_value_port_info(int p_idx) const { - PropertyInfo pinfo; - pinfo.type = Variant::OBJECT; - if (preload.is_valid()) { - pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE; - pinfo.hint_string = preload->get_class(); - if (preload->get_path().is_resource_file()) { - pinfo.name = preload->get_path(); - } else if (!preload->get_name().is_empty()) { - pinfo.name = preload->get_name(); - } else { - pinfo.name = preload->get_class(); - } - } else { - pinfo.name = "<empty>"; - } - - return pinfo; -} - -String VisualScriptPreload::get_caption() const { - return RTR("Preload"); -} - -void VisualScriptPreload::set_preload(const Ref<Resource> &p_preload) { - if (preload == p_preload) { - return; - } - - preload = p_preload; - ports_changed_notify(); -} - -Ref<Resource> VisualScriptPreload::get_preload() const { - return preload; -} - -void VisualScriptPreload::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_preload", "resource"), &VisualScriptPreload::set_preload); - ClassDB::bind_method(D_METHOD("get_preload"), &VisualScriptPreload::get_preload); - - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource"), "set_preload", "get_preload"); -} - -class VisualScriptNodeInstancePreload : public VisualScriptNodeInstance { -public: - Ref<Resource> preload; - //virtual int get_working_memory_size() const override { return 0; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - *p_outputs[0] = preload; - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptPreload::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstancePreload *instance = memnew(VisualScriptNodeInstancePreload); - instance->preload = preload; - return instance; -} - -VisualScriptPreload::VisualScriptPreload() { -} - -////////////////////////////////////////// -////////////////INDEX//////////////////// -////////////////////////////////////////// - -int VisualScriptIndexGet::get_output_sequence_port_count() const { - return 0; -} - -bool VisualScriptIndexGet::has_input_sequence_port() const { - return false; -} - -int VisualScriptIndexGet::get_input_value_port_count() const { - return 2; -} - -int VisualScriptIndexGet::get_output_value_port_count() const { - return 1; -} - -String VisualScriptIndexGet::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptIndexGet::get_input_value_port_info(int p_idx) const { - if (p_idx == 0) { - return PropertyInfo(Variant::NIL, "base"); - } else { - return PropertyInfo(Variant::NIL, "index"); - } -} - -PropertyInfo VisualScriptIndexGet::get_output_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -String VisualScriptIndexGet::get_caption() const { - return RTR("Get Index"); -} - -class VisualScriptNodeInstanceIndexGet : public VisualScriptNodeInstance { -public: - //virtual int get_working_memory_size() const override { return 0; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - bool valid; - *p_outputs[0] = p_inputs[0]->get(*p_inputs[1], &valid); - - if (!valid) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = "Invalid get: " + p_inputs[0]->get_construct_string(); - } - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptIndexGet::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceIndexGet *instance = memnew(VisualScriptNodeInstanceIndexGet); - return instance; -} - -VisualScriptIndexGet::VisualScriptIndexGet() { -} - -////////////////////////////////////////// -////////////////INDEXSET////////////////// -////////////////////////////////////////// - -int VisualScriptIndexSet::get_output_sequence_port_count() const { - return 1; -} - -bool VisualScriptIndexSet::has_input_sequence_port() const { - return true; -} - -int VisualScriptIndexSet::get_input_value_port_count() const { - return 3; -} - -int VisualScriptIndexSet::get_output_value_port_count() const { - return 0; -} - -String VisualScriptIndexSet::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptIndexSet::get_input_value_port_info(int p_idx) const { - if (p_idx == 0) { - return PropertyInfo(Variant::NIL, "base"); - } else if (p_idx == 1) { - return PropertyInfo(Variant::NIL, "index"); - - } else { - return PropertyInfo(Variant::NIL, "value"); - } -} - -PropertyInfo VisualScriptIndexSet::get_output_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -String VisualScriptIndexSet::get_caption() const { - return RTR("Set Index"); -} - -class VisualScriptNodeInstanceIndexSet : public VisualScriptNodeInstance { -public: - //virtual int get_working_memory_size() const override { return 0; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - bool valid; - ((Variant *)p_inputs[0])->set(*p_inputs[1], *p_inputs[2], &valid); - - if (!valid) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = "Invalid set: " + p_inputs[1]->get_construct_string(); - } - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptIndexSet::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceIndexSet *instance = memnew(VisualScriptNodeInstanceIndexSet); - return instance; -} - -VisualScriptIndexSet::VisualScriptIndexSet() { -} - -////////////////////////////////////////// -////////////////GLOBALCONSTANT/////////// -////////////////////////////////////////// - -int VisualScriptGlobalConstant::get_output_sequence_port_count() const { - return 0; -} - -bool VisualScriptGlobalConstant::has_input_sequence_port() const { - return false; -} - -int VisualScriptGlobalConstant::get_input_value_port_count() const { - return 0; -} - -int VisualScriptGlobalConstant::get_output_value_port_count() const { - return 1; -} - -String VisualScriptGlobalConstant::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptGlobalConstant::get_input_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -PropertyInfo VisualScriptGlobalConstant::get_output_value_port_info(int p_idx) const { - String name = CoreConstants::get_global_constant_name(index); - return PropertyInfo(Variant::INT, name); -} - -String VisualScriptGlobalConstant::get_caption() const { - return RTR("Global Constant"); -} - -void VisualScriptGlobalConstant::set_global_constant(int p_which) { - index = p_which; - notify_property_list_changed(); - ports_changed_notify(); -} - -int VisualScriptGlobalConstant::get_global_constant() { - return index; -} - -class VisualScriptNodeInstanceGlobalConstant : public VisualScriptNodeInstance { -public: - int index = 0; - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - *p_outputs[0] = CoreConstants::get_global_constant_value(index); - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptGlobalConstant::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceGlobalConstant *instance = memnew(VisualScriptNodeInstanceGlobalConstant); - instance->index = index; - return instance; -} - -void VisualScriptGlobalConstant::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_global_constant", "index"), &VisualScriptGlobalConstant::set_global_constant); - ClassDB::bind_method(D_METHOD("get_global_constant"), &VisualScriptGlobalConstant::get_global_constant); - - String cc; - - for (int i = 0; i < CoreConstants::get_global_constant_count(); i++) { - if (i > 0) { - cc += ","; - } - cc += CoreConstants::get_global_constant_name(i); - } - ADD_PROPERTY(PropertyInfo(Variant::INT, "constant", PROPERTY_HINT_ENUM, cc), "set_global_constant", "get_global_constant"); -} - -VisualScriptGlobalConstant::VisualScriptGlobalConstant() { - index = 0; -} - -////////////////////////////////////////// -////////////////CLASSCONSTANT/////////// -////////////////////////////////////////// - -int VisualScriptClassConstant::get_output_sequence_port_count() const { - return 0; -} - -bool VisualScriptClassConstant::has_input_sequence_port() const { - return false; -} - -int VisualScriptClassConstant::get_input_value_port_count() const { - return 0; -} - -int VisualScriptClassConstant::get_output_value_port_count() const { - return 1; -} - -String VisualScriptClassConstant::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptClassConstant::get_input_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -PropertyInfo VisualScriptClassConstant::get_output_value_port_info(int p_idx) const { - if (name == "") { - return PropertyInfo(Variant::INT, String(base_type)); - } else { - return PropertyInfo(Variant::INT, String(base_type) + "." + String(name)); - } -} - -String VisualScriptClassConstant::get_caption() const { - return RTR("Class Constant"); -} - -void VisualScriptClassConstant::set_class_constant(const StringName &p_which) { - name = p_which; - notify_property_list_changed(); - ports_changed_notify(); -} - -StringName VisualScriptClassConstant::get_class_constant() { - return name; -} - -void VisualScriptClassConstant::set_base_type(const StringName &p_which) { - base_type = p_which; - List<String> constants; - ClassDB::get_integer_constant_list(base_type, &constants, true); - if (constants.size() > 0) { - bool found_name = false; - for (const String &E : constants) { - if (E == name) { - found_name = true; - break; - } - } - if (!found_name) { - name = constants[0]; - } - } else { - name = ""; - } - notify_property_list_changed(); - ports_changed_notify(); -} - -StringName VisualScriptClassConstant::get_base_type() { - return base_type; -} - -class VisualScriptNodeInstanceClassConstant : public VisualScriptNodeInstance { -public: - int value = 0; - bool valid = false; - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - if (!valid) { - r_error_str = "Invalid constant name, pick a valid class constant."; - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - } - - *p_outputs[0] = value; - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptClassConstant::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceClassConstant *instance = memnew(VisualScriptNodeInstanceClassConstant); - instance->value = ClassDB::get_integer_constant(base_type, name, &instance->valid); - return instance; -} - -void VisualScriptClassConstant::_validate_property(PropertyInfo &p_property) const { - if (p_property.name == "constant") { - List<String> constants; - ClassDB::get_integer_constant_list(base_type, &constants, true); - - p_property.hint_string = ""; - for (const String &E : constants) { - if (!p_property.hint_string.is_empty()) { - p_property.hint_string += ","; - } - p_property.hint_string += E; - } - } -} - -void VisualScriptClassConstant::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_class_constant", "name"), &VisualScriptClassConstant::set_class_constant); - ClassDB::bind_method(D_METHOD("get_class_constant"), &VisualScriptClassConstant::get_class_constant); - - ClassDB::bind_method(D_METHOD("set_base_type", "name"), &VisualScriptClassConstant::set_base_type); - ClassDB::bind_method(D_METHOD("get_base_type"), &VisualScriptClassConstant::get_base_type); - - ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_type", PROPERTY_HINT_TYPE_STRING, "Object"), "set_base_type", "get_base_type"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "constant", PROPERTY_HINT_ENUM, ""), "set_class_constant", "get_class_constant"); -} - -VisualScriptClassConstant::VisualScriptClassConstant() { - base_type = "Object"; -} - -////////////////////////////////////////// -////////////////BASICTYPECONSTANT/////////// -////////////////////////////////////////// - -int VisualScriptBasicTypeConstant::get_output_sequence_port_count() const { - return 0; -} - -bool VisualScriptBasicTypeConstant::has_input_sequence_port() const { - return false; -} - -int VisualScriptBasicTypeConstant::get_input_value_port_count() const { - return 0; -} - -int VisualScriptBasicTypeConstant::get_output_value_port_count() const { - return 1; -} - -String VisualScriptBasicTypeConstant::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptBasicTypeConstant::get_input_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -PropertyInfo VisualScriptBasicTypeConstant::get_output_value_port_info(int p_idx) const { - return PropertyInfo(type, "value"); -} - -String VisualScriptBasicTypeConstant::get_caption() const { - return RTR("Basic Constant"); -} - -String VisualScriptBasicTypeConstant::get_text() const { - if (name == "") { - return Variant::get_type_name(type); - } else { - return Variant::get_type_name(type) + "." + String(name); - } -} - -void VisualScriptBasicTypeConstant::set_basic_type_constant(const StringName &p_which) { - name = p_which; - notify_property_list_changed(); - ports_changed_notify(); -} - -StringName VisualScriptBasicTypeConstant::get_basic_type_constant() const { - return name; -} - -void VisualScriptBasicTypeConstant::set_basic_type(Variant::Type p_which) { - type = p_which; - - List<StringName> constants; - Variant::get_constants_for_type(type, &constants); - if (constants.size() > 0) { - bool found_name = false; - for (const StringName &E : constants) { - if (E == name) { - found_name = true; - break; - } - } - if (!found_name) { - name = constants[0]; - } - } else { - name = ""; - } - notify_property_list_changed(); - ports_changed_notify(); -} - -Variant::Type VisualScriptBasicTypeConstant::get_basic_type() const { - return type; -} - -class VisualScriptNodeInstanceBasicTypeConstant : public VisualScriptNodeInstance { -public: - Variant value; - bool valid = false; - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - if (!valid) { - r_error_str = "Invalid constant name, pick a valid basic type constant."; - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - } - - *p_outputs[0] = value; - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptBasicTypeConstant::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceBasicTypeConstant *instance = memnew(VisualScriptNodeInstanceBasicTypeConstant); - instance->value = Variant::get_constant_value(type, name, &instance->valid); - return instance; -} - -void VisualScriptBasicTypeConstant::_validate_property(PropertyInfo &p_property) const { - if (p_property.name == "constant") { - List<StringName> constants; - Variant::get_constants_for_type(type, &constants); - - if (constants.size() == 0) { - p_property.usage = PROPERTY_USAGE_NONE; - return; - } - p_property.hint_string = ""; - for (const StringName &E : constants) { - if (!p_property.hint_string.is_empty()) { - p_property.hint_string += ","; - } - p_property.hint_string += String(E); - } - } -} - -void VisualScriptBasicTypeConstant::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_basic_type", "name"), &VisualScriptBasicTypeConstant::set_basic_type); - ClassDB::bind_method(D_METHOD("get_basic_type"), &VisualScriptBasicTypeConstant::get_basic_type); - - ClassDB::bind_method(D_METHOD("set_basic_type_constant", "name"), &VisualScriptBasicTypeConstant::set_basic_type_constant); - ClassDB::bind_method(D_METHOD("get_basic_type_constant"), &VisualScriptBasicTypeConstant::get_basic_type_constant); - - String argt = "Null"; - for (int i = 1; i < Variant::VARIANT_MAX; i++) { - argt += "," + Variant::get_type_name(Variant::Type(i)); - } - - ADD_PROPERTY(PropertyInfo(Variant::INT, "basic_type", PROPERTY_HINT_ENUM, argt), "set_basic_type", "get_basic_type"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "constant", PROPERTY_HINT_ENUM, ""), "set_basic_type_constant", "get_basic_type_constant"); -} - -VisualScriptBasicTypeConstant::VisualScriptBasicTypeConstant() { - type = Variant::NIL; -} - -////////////////////////////////////////// -////////////////MATHCONSTANT/////////// -////////////////////////////////////////// - -const char *VisualScriptMathConstant::const_name[MATH_CONSTANT_MAX] = { - "One", - "PI", - "PI/2", - "TAU", - "E", - "Sqrt2", - "INF", - "NAN" -}; - -double VisualScriptMathConstant::const_value[MATH_CONSTANT_MAX] = { - 1.0, - Math_PI, - Math_PI * 0.5, - Math_TAU, - 2.71828182845904523536, - Math::sqrt(2.0), - INFINITY, - NAN -}; - -int VisualScriptMathConstant::get_output_sequence_port_count() const { - return 0; -} - -bool VisualScriptMathConstant::has_input_sequence_port() const { - return false; -} - -int VisualScriptMathConstant::get_input_value_port_count() const { - return 0; -} - -int VisualScriptMathConstant::get_output_value_port_count() const { - return 1; -} - -String VisualScriptMathConstant::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptMathConstant::get_input_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -PropertyInfo VisualScriptMathConstant::get_output_value_port_info(int p_idx) const { - return PropertyInfo(Variant::FLOAT, const_name[constant]); -} - -String VisualScriptMathConstant::get_caption() const { - return RTR("Math Constant"); -} - -void VisualScriptMathConstant::set_math_constant(MathConstant p_which) { - constant = p_which; - notify_property_list_changed(); - ports_changed_notify(); -} - -VisualScriptMathConstant::MathConstant VisualScriptMathConstant::get_math_constant() { - return constant; -} - -class VisualScriptNodeInstanceMathConstant : public VisualScriptNodeInstance { -public: - float value = 0.0f; - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - *p_outputs[0] = value; - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptMathConstant::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceMathConstant *instance = memnew(VisualScriptNodeInstanceMathConstant); - instance->value = const_value[constant]; - return instance; -} - -void VisualScriptMathConstant::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_math_constant", "which"), &VisualScriptMathConstant::set_math_constant); - ClassDB::bind_method(D_METHOD("get_math_constant"), &VisualScriptMathConstant::get_math_constant); - - String cc; - - for (int i = 0; i < MATH_CONSTANT_MAX; i++) { - if (i > 0) { - cc += ","; - } - cc += const_name[i]; - } - ADD_PROPERTY(PropertyInfo(Variant::INT, "constant", PROPERTY_HINT_ENUM, cc), "set_math_constant", "get_math_constant"); - - BIND_ENUM_CONSTANT(MATH_CONSTANT_ONE); - BIND_ENUM_CONSTANT(MATH_CONSTANT_PI); - BIND_ENUM_CONSTANT(MATH_CONSTANT_HALF_PI); - BIND_ENUM_CONSTANT(MATH_CONSTANT_TAU); - BIND_ENUM_CONSTANT(MATH_CONSTANT_E); - BIND_ENUM_CONSTANT(MATH_CONSTANT_SQRT2); - BIND_ENUM_CONSTANT(MATH_CONSTANT_INF); - BIND_ENUM_CONSTANT(MATH_CONSTANT_NAN); - BIND_ENUM_CONSTANT(MATH_CONSTANT_MAX); -} - -VisualScriptMathConstant::VisualScriptMathConstant() { - constant = MATH_CONSTANT_ONE; -} - -////////////////////////////////////////// -////////////////ENGINESINGLETON/////////// -////////////////////////////////////////// - -int VisualScriptEngineSingleton::get_output_sequence_port_count() const { - return 0; -} - -bool VisualScriptEngineSingleton::has_input_sequence_port() const { - return false; -} - -int VisualScriptEngineSingleton::get_input_value_port_count() const { - return 0; -} - -int VisualScriptEngineSingleton::get_output_value_port_count() const { - return 1; -} - -String VisualScriptEngineSingleton::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptEngineSingleton::get_input_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -PropertyInfo VisualScriptEngineSingleton::get_output_value_port_info(int p_idx) const { - return PropertyInfo(Variant::OBJECT, singleton); -} - -String VisualScriptEngineSingleton::get_caption() const { - return RTR("Get Engine Singleton"); -} - -void VisualScriptEngineSingleton::set_singleton(const String &p_string) { - singleton = p_string; - - notify_property_list_changed(); - ports_changed_notify(); -} - -String VisualScriptEngineSingleton::get_singleton() { - return singleton; -} - -class VisualScriptNodeInstanceEngineSingleton : public VisualScriptNodeInstance { -public: - Object *singleton = nullptr; - - //virtual int get_working_memory_size() const override { return 0; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - *p_outputs[0] = singleton; - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptEngineSingleton::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceEngineSingleton *instance = memnew(VisualScriptNodeInstanceEngineSingleton); - instance->singleton = Engine::get_singleton()->get_singleton_object(singleton); - return instance; -} - -VisualScriptEngineSingleton::TypeGuess VisualScriptEngineSingleton::guess_output_type(TypeGuess *p_inputs, int p_output) const { - Object *obj = Engine::get_singleton()->get_singleton_object(singleton); - TypeGuess tg; - tg.type = Variant::OBJECT; - if (obj) { - tg.gdclass = obj->get_class(); - tg.script = obj->get_script(); - } - - return tg; -} - -void VisualScriptEngineSingleton::_validate_property(PropertyInfo &p_property) const { - String cc; - - List<Engine::Singleton> singletons; - - Engine::get_singleton()->get_singletons(&singletons); - - for (const Engine::Singleton &E : singletons) { - if (E.name == "VS" || E.name == "PS" || E.name == "PS2D" || E.name == "AS" || E.name == "TS" || E.name == "SS" || E.name == "SS2D") { - continue; //skip these, too simple named - } - - if (!cc.is_empty()) { - cc += ","; - } - cc += E.name; - } - - p_property.hint = PROPERTY_HINT_ENUM; - p_property.hint_string = cc; -} - -void VisualScriptEngineSingleton::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_singleton", "name"), &VisualScriptEngineSingleton::set_singleton); - ClassDB::bind_method(D_METHOD("get_singleton"), &VisualScriptEngineSingleton::get_singleton); - - ADD_PROPERTY(PropertyInfo(Variant::STRING, "constant"), "set_singleton", "get_singleton"); -} - -VisualScriptEngineSingleton::VisualScriptEngineSingleton() { - singleton = String(); -} - -////////////////////////////////////////// -////////////////GETNODE/////////// -////////////////////////////////////////// - -int VisualScriptSceneNode::get_output_sequence_port_count() const { - return 0; -} - -bool VisualScriptSceneNode::has_input_sequence_port() const { - return false; -} - -int VisualScriptSceneNode::get_input_value_port_count() const { - return 0; -} - -int VisualScriptSceneNode::get_output_value_port_count() const { - return 1; -} - -String VisualScriptSceneNode::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptSceneNode::get_input_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -PropertyInfo VisualScriptSceneNode::get_output_value_port_info(int p_idx) const { - return PropertyInfo(Variant::OBJECT, path.simplified()); -} - -String VisualScriptSceneNode::get_caption() const { - return RTR("Get Scene Node"); -} - -void VisualScriptSceneNode::set_node_path(const NodePath &p_path) { - path = p_path; - notify_property_list_changed(); - ports_changed_notify(); -} - -NodePath VisualScriptSceneNode::get_node_path() { - return path; -} - -class VisualScriptNodeInstanceSceneNode : public VisualScriptNodeInstance { -public: - VisualScriptSceneNode *node = nullptr; - VisualScriptInstance *instance = nullptr; - NodePath path; - - //virtual int get_working_memory_size() const override { return 0; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - Node *node = Object::cast_to<Node>(instance->get_owner_ptr()); - if (!node) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = "Base object is not a Node!"; - return 0; - } - - Node *another = node->get_node(path); - if (!another) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = "Path does not lead Node!"; - return 0; - } - - *p_outputs[0] = another; - - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptSceneNode::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceSceneNode *instance = memnew(VisualScriptNodeInstanceSceneNode); - instance->node = this; - instance->instance = p_instance; - instance->path = path; - return instance; -} - -#ifdef TOOLS_ENABLED - -static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) { - if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene) { - return nullptr; - } - - Ref<Script> scr = p_current_node->get_script(); - - if (scr.is_valid() && scr == script) { - return p_current_node; - } - - for (int i = 0; i < p_current_node->get_child_count(); i++) { - Node *n = _find_script_node(p_edited_scene, p_current_node->get_child(i), script); - if (n) { - return n; - } - } - - return nullptr; -} - -#endif - -VisualScriptSceneNode::TypeGuess VisualScriptSceneNode::guess_output_type(TypeGuess *p_inputs, int p_output) const { - VisualScriptSceneNode::TypeGuess tg; - tg.type = Variant::OBJECT; - tg.gdclass = SNAME("Node"); - -#ifdef TOOLS_ENABLED - Ref<Script> script = get_visual_script(); - if (!script.is_valid()) { - return tg; - } - - MainLoop *main_loop = OS::get_singleton()->get_main_loop(); - SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop); - - if (!scene_tree) { - return tg; - } - - Node *edited_scene = scene_tree->get_edited_scene_root(); - - if (!edited_scene) { - return tg; - } - - Node *script_node = _find_script_node(edited_scene, edited_scene, script); - - if (!script_node) { - return tg; - } - - Node *another = script_node->get_node(path); - - if (another) { - tg.gdclass = another->get_class(); - tg.script = another->get_script(); - } -#endif - return tg; -} - -void VisualScriptSceneNode::_validate_property(PropertyInfo &p_property) const { -#ifdef TOOLS_ENABLED - if (p_property.name == "node_path") { - Ref<Script> script = get_visual_script(); - if (!script.is_valid()) { - return; - } - - MainLoop *main_loop = OS::get_singleton()->get_main_loop(); - SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop); - - if (!scene_tree) { - return; - } - - Node *edited_scene = scene_tree->get_edited_scene_root(); - - if (!edited_scene) { - return; - } - - Node *script_node = _find_script_node(edited_scene, edited_scene, script); - - if (!script_node) { - return; - } - - p_property.hint_string = script_node->get_path(); - } -#endif -} - -void VisualScriptSceneNode::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_node_path", "path"), &VisualScriptSceneNode::set_node_path); - ClassDB::bind_method(D_METHOD("get_node_path"), &VisualScriptSceneNode::get_node_path); - - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_path", PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE), "set_node_path", "get_node_path"); -} - -VisualScriptSceneNode::VisualScriptSceneNode() { - path = String("."); -} - -////////////////////////////////////////// -////////////////SceneTree/////////// -////////////////////////////////////////// - -int VisualScriptSceneTree::get_output_sequence_port_count() const { - return 0; -} - -bool VisualScriptSceneTree::has_input_sequence_port() const { - return false; -} - -int VisualScriptSceneTree::get_input_value_port_count() const { - return 0; -} - -int VisualScriptSceneTree::get_output_value_port_count() const { - return 1; -} - -String VisualScriptSceneTree::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptSceneTree::get_input_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -PropertyInfo VisualScriptSceneTree::get_output_value_port_info(int p_idx) const { - return PropertyInfo(Variant::OBJECT, "Scene Tree", PROPERTY_HINT_TYPE_STRING, "SceneTree"); -} - -String VisualScriptSceneTree::get_caption() const { - return RTR("Get Scene Tree"); -} - -class VisualScriptNodeInstanceSceneTree : public VisualScriptNodeInstance { -public: - VisualScriptSceneTree *node = nullptr; - VisualScriptInstance *instance = nullptr; - - //virtual int get_working_memory_size() const override { return 0; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - Node *node = Object::cast_to<Node>(instance->get_owner_ptr()); - if (!node) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = "Base object is not a Node!"; - return 0; - } - - SceneTree *tree = node->get_tree(); - if (!tree) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = "Attempt to get SceneTree while node is not in the active tree."; - return 0; - } - - *p_outputs[0] = tree; - - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptSceneTree::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceSceneTree *instance = memnew(VisualScriptNodeInstanceSceneTree); - instance->node = this; - instance->instance = p_instance; - return instance; -} - -VisualScriptSceneTree::TypeGuess VisualScriptSceneTree::guess_output_type(TypeGuess *p_inputs, int p_output) const { - TypeGuess tg; - tg.type = Variant::OBJECT; - tg.gdclass = SNAME("SceneTree"); - return tg; -} - -void VisualScriptSceneTree::_validate_property(PropertyInfo &p_property) const { -} - -void VisualScriptSceneTree::_bind_methods() { -} - -VisualScriptSceneTree::VisualScriptSceneTree() { -} - -////////////////////////////////////////// -////////////////RESPATH/////////// -////////////////////////////////////////// - -int VisualScriptResourcePath::get_output_sequence_port_count() const { - return 0; -} - -bool VisualScriptResourcePath::has_input_sequence_port() const { - return false; -} - -int VisualScriptResourcePath::get_input_value_port_count() const { - return 0; -} - -int VisualScriptResourcePath::get_output_value_port_count() const { - return 1; -} - -String VisualScriptResourcePath::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptResourcePath::get_input_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -PropertyInfo VisualScriptResourcePath::get_output_value_port_info(int p_idx) const { - return PropertyInfo(Variant::STRING, path); -} - -String VisualScriptResourcePath::get_caption() const { - return RTR("Resource Path"); -} - -void VisualScriptResourcePath::set_resource_path(const String &p_path) { - path = p_path; - notify_property_list_changed(); - ports_changed_notify(); -} - -String VisualScriptResourcePath::get_resource_path() { - return path; -} - -class VisualScriptNodeInstanceResourcePath : public VisualScriptNodeInstance { -public: - String path; - - //virtual int get_working_memory_size() const override { return 0; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - *p_outputs[0] = path; - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptResourcePath::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceResourcePath *instance = memnew(VisualScriptNodeInstanceResourcePath); - instance->path = path; - return instance; -} - -void VisualScriptResourcePath::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_resource_path", "path"), &VisualScriptResourcePath::set_resource_path); - ClassDB::bind_method(D_METHOD("get_resource_path"), &VisualScriptResourcePath::get_resource_path); - - ADD_PROPERTY(PropertyInfo(Variant::STRING, "path", PROPERTY_HINT_FILE), "set_resource_path", "get_resource_path"); -} - -VisualScriptResourcePath::VisualScriptResourcePath() { - path = ""; -} - -////////////////////////////////////////// -////////////////SELF/////////// -////////////////////////////////////////// - -int VisualScriptSelf::get_output_sequence_port_count() const { - return 0; -} - -bool VisualScriptSelf::has_input_sequence_port() const { - return false; -} - -int VisualScriptSelf::get_input_value_port_count() const { - return 0; -} - -int VisualScriptSelf::get_output_value_port_count() const { - return 1; -} - -String VisualScriptSelf::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptSelf::get_input_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -PropertyInfo VisualScriptSelf::get_output_value_port_info(int p_idx) const { - StringName type_name; - if (get_visual_script().is_valid()) { - type_name = get_visual_script()->get_instance_base_type(); - } else { - type_name = SNAME("instance"); - } - - return PropertyInfo(Variant::OBJECT, type_name); -} - -String VisualScriptSelf::get_caption() const { - return RTR("Get Self"); -} - -class VisualScriptNodeInstanceSelf : public VisualScriptNodeInstance { -public: - VisualScriptInstance *instance = nullptr; - - //virtual int get_working_memory_size() const override { return 0; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - *p_outputs[0] = instance->get_owner_ptr(); - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptSelf::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceSelf *instance = memnew(VisualScriptNodeInstanceSelf); - instance->instance = p_instance; - return instance; -} - -VisualScriptSelf::TypeGuess VisualScriptSelf::guess_output_type(TypeGuess *p_inputs, int p_output) const { - VisualScriptSceneNode::TypeGuess tg; - tg.type = Variant::OBJECT; - tg.gdclass = SNAME("Object"); - - Ref<Script> script = get_visual_script(); - if (!script.is_valid()) { - return tg; - } - - tg.gdclass = script->get_instance_base_type(); - tg.script = script; - - return tg; -} - -void VisualScriptSelf::_bind_methods() { -} - -VisualScriptSelf::VisualScriptSelf() { -} - -////////////////////////////////////////// -////////////////CUSTOM (SCRIPTED)/////////// -////////////////////////////////////////// - -int VisualScriptCustomNode::get_output_sequence_port_count() const { - int ret; - if (GDVIRTUAL_CALL(_get_output_sequence_port_count, ret)) { - return ret; - } - return 0; -} - -bool VisualScriptCustomNode::has_input_sequence_port() const { - bool ret; - if (GDVIRTUAL_CALL(_has_input_sequence_port, ret)) { - return ret; - } - return false; -} - -int VisualScriptCustomNode::get_input_value_port_count() const { - int ret; - if (GDVIRTUAL_CALL(_get_input_value_port_count, ret)) { - return ret; - } - return 0; -} - -int VisualScriptCustomNode::get_output_value_port_count() const { - int ret; - if (GDVIRTUAL_CALL(_get_output_value_port_count, ret)) { - return ret; - } - return 0; -} - -String VisualScriptCustomNode::get_output_sequence_port_text(int p_port) const { - String ret; - if (GDVIRTUAL_CALL(_get_output_sequence_port_text, p_port, ret)) { - return ret; - } - - return String(); -} - -PropertyInfo VisualScriptCustomNode::get_input_value_port_info(int p_idx) const { - PropertyInfo info; - { - int type; - if (GDVIRTUAL_CALL(_get_input_value_port_type, p_idx, type)) { - info.type = Variant::Type(type); - } - } - { - String name; - if (GDVIRTUAL_CALL(_get_input_value_port_name, p_idx, name)) { - info.name = name; - } - } - { - int hint; - if (GDVIRTUAL_CALL(_get_input_value_port_hint, p_idx, hint)) { - info.hint = PropertyHint(hint); - } - } - - { - String hint_string; - if (GDVIRTUAL_CALL(_get_input_value_port_hint_string, p_idx, hint_string)) { - info.hint_string = hint_string; - } - } - - return info; -} - -PropertyInfo VisualScriptCustomNode::get_output_value_port_info(int p_idx) const { - PropertyInfo info; - { - int type; - if (GDVIRTUAL_CALL(_get_output_value_port_type, p_idx, type)) { - info.type = Variant::Type(type); - } - } - { - String name; - if (GDVIRTUAL_CALL(_get_output_value_port_name, p_idx, name)) { - info.name = name; - } - } - { - int hint; - if (GDVIRTUAL_CALL(_get_output_value_port_hint, p_idx, hint)) { - info.hint = PropertyHint(hint); - } - } - - { - String hint_string; - if (GDVIRTUAL_CALL(_get_output_value_port_hint_string, p_idx, hint_string)) { - info.hint_string = hint_string; - } - } - return info; -} - -VisualScriptCustomNode::TypeGuess VisualScriptCustomNode::guess_output_type(TypeGuess *p_inputs, int p_output) const { - TypeGuess tg; - PropertyInfo pi = VisualScriptCustomNode::get_output_value_port_info(p_output); - tg.type = pi.type; - if (pi.type == Variant::OBJECT) { - if (pi.hint == PROPERTY_HINT_RESOURCE_TYPE) { - if (pi.hint_string.is_resource_file()) { - tg.script = ResourceLoader::load(pi.hint_string); - } else if (ClassDB::class_exists(pi.hint_string)) { - tg.gdclass = pi.hint_string; - } - } - } - return tg; -} - -String VisualScriptCustomNode::get_caption() const { - String ret; - if (GDVIRTUAL_CALL(_get_caption, ret)) { - return ret; - } - return RTR("CustomNode"); -} - -String VisualScriptCustomNode::get_text() const { - String ret; - if (GDVIRTUAL_CALL(_get_text, ret)) { - return ret; - } - return ""; -} - -String VisualScriptCustomNode::get_category() const { - String ret; - if (GDVIRTUAL_CALL(_get_category, ret)) { - return ret; - } - return "Custom"; -} - -class VisualScriptNodeInstanceCustomNode : public VisualScriptNodeInstance { -public: - VisualScriptInstance *instance = nullptr; - VisualScriptCustomNode *node = nullptr; - int in_count = 0; - int out_count = 0; - int work_mem_size = 0; - - virtual int get_working_memory_size() const override { return work_mem_size; } - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - if (GDVIRTUAL_IS_OVERRIDDEN_PTR(node, _step)) { - Array in_values; - Array out_values; - Array work_mem; - - in_values.resize(in_count); - - for (int i = 0; i < in_count; i++) { - in_values[i] = *p_inputs[i]; - } - - out_values.resize(out_count); - - work_mem.resize(work_mem_size); - - for (int i = 0; i < work_mem_size; i++) { - work_mem[i] = p_working_mem[i]; - } - - int ret_out; - - Variant ret; - GDVIRTUAL_CALL_PTR(node, _step, in_values, out_values, p_start_mode, work_mem, ret); - if (ret.get_type() == Variant::STRING) { - r_error_str = ret; - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - return 0; - } else if (ret.is_num()) { - ret_out = ret; - } else { - r_error_str = RTR("Invalid return value from _step(), must be integer (seq out), or string (error)."); - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - return 0; - } - - for (int i = 0; i < out_count; i++) { - if (i < out_values.size()) { - *p_outputs[i] = out_values[i]; - } - } - - for (int i = 0; i < work_mem_size; i++) { - if (i < work_mem.size()) { - p_working_mem[i] = work_mem[i]; - } - } - - return ret_out; - } else { - r_error_str = RTR("Custom node has no _step() method, can't process graph."); - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - } - - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptCustomNode::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceCustomNode *instance = memnew(VisualScriptNodeInstanceCustomNode); - instance->instance = p_instance; - instance->node = this; - instance->in_count = get_input_value_port_count(); - instance->out_count = get_output_value_port_count(); - - instance->work_mem_size = 0; - GDVIRTUAL_CALL(_get_working_memory_size, instance->work_mem_size); - - return instance; -} - -void VisualScriptCustomNode::_script_changed() { - call_deferred(SNAME("ports_changed_notify")); -} - -void VisualScriptCustomNode::_bind_methods() { - GDVIRTUAL_BIND(_get_output_sequence_port_count); - GDVIRTUAL_BIND(_has_input_sequence_port); - GDVIRTUAL_BIND(_get_output_sequence_port_text, "seq_idx"); - - GDVIRTUAL_BIND(_get_input_value_port_count); - GDVIRTUAL_BIND(_get_input_value_port_type, "input_idx"); - GDVIRTUAL_BIND(_get_input_value_port_name, "input_idx"); - GDVIRTUAL_BIND(_get_input_value_port_hint, "input_idx"); - GDVIRTUAL_BIND(_get_input_value_port_hint_string, "input_idx"); - - GDVIRTUAL_BIND(_get_output_value_port_count); - GDVIRTUAL_BIND(_get_output_value_port_type, "output_idx"); - GDVIRTUAL_BIND(_get_output_value_port_name, "output_idx"); - GDVIRTUAL_BIND(_get_output_value_port_hint, "output_idx"); - GDVIRTUAL_BIND(_get_output_value_port_hint_string, "output_idx"); - - GDVIRTUAL_BIND(_get_caption); - GDVIRTUAL_BIND(_get_text); - GDVIRTUAL_BIND(_get_category); - - GDVIRTUAL_BIND(_get_working_memory_size); - - GDVIRTUAL_BIND(_step, "inputs", "outputs", "start_mode", "working_mem"); - - BIND_ENUM_CONSTANT(START_MODE_BEGIN_SEQUENCE); - BIND_ENUM_CONSTANT(START_MODE_CONTINUE_SEQUENCE); - BIND_ENUM_CONSTANT(START_MODE_RESUME_YIELD); - - BIND_CONSTANT(STEP_PUSH_STACK_BIT); - BIND_CONSTANT(STEP_GO_BACK_BIT); - BIND_CONSTANT(STEP_NO_ADVANCE_BIT); - BIND_CONSTANT(STEP_EXIT_FUNCTION_BIT); - BIND_CONSTANT(STEP_YIELD_BIT); -} - -VisualScriptCustomNode::VisualScriptCustomNode() { - connect("script_changed", callable_mp(this, &VisualScriptCustomNode::_script_changed)); -} - -////////////////////////////////////////// -////////////////SUBCALL/////////// -////////////////////////////////////////// - -int VisualScriptSubCall::get_output_sequence_port_count() const { - return 1; -} - -bool VisualScriptSubCall::has_input_sequence_port() const { - return true; -} - -int VisualScriptSubCall::get_input_value_port_count() const { - Ref<Script> script = get_script(); - - if (script.is_valid() && script->has_method(VisualScriptLanguage::singleton->_subcall)) { - MethodInfo mi = script->get_method_info(VisualScriptLanguage::singleton->_subcall); - return mi.arguments.size(); - } - - return 0; -} - -int VisualScriptSubCall::get_output_value_port_count() const { - return 1; -} - -String VisualScriptSubCall::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptSubCall::get_input_value_port_info(int p_idx) const { - Ref<Script> script = get_script(); - if (script.is_valid() && script->has_method(VisualScriptLanguage::singleton->_subcall)) { - MethodInfo mi = script->get_method_info(VisualScriptLanguage::singleton->_subcall); - return mi.arguments[p_idx]; - } - - return PropertyInfo(); -} - -PropertyInfo VisualScriptSubCall::get_output_value_port_info(int p_idx) const { - Ref<Script> script = get_script(); - if (script.is_valid() && script->has_method(VisualScriptLanguage::singleton->_subcall)) { - MethodInfo mi = script->get_method_info(VisualScriptLanguage::singleton->_subcall); - return mi.return_val; - } - return PropertyInfo(); -} - -String VisualScriptSubCall::get_caption() const { - return RTR("SubCall"); -} - -String VisualScriptSubCall::get_text() const { - Ref<Script> script = get_script(); - if (script.is_valid()) { - if (!script->get_name().is_empty()) { - return script->get_name(); - } - if (script->get_path().is_resource_file()) { - return script->get_path().get_file(); - } - return script->get_class(); - } - return ""; -} - -String VisualScriptSubCall::get_category() const { - return "custom"; -} - -class VisualScriptNodeInstanceSubCall : public VisualScriptNodeInstance { -public: - VisualScriptInstance *instance = nullptr; - VisualScriptSubCall *subcall = nullptr; - int input_args = 0; - bool valid = false; - - //virtual int get_working_memory_size() const override { return 0; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - if (!valid) { - r_error_str = "Node requires a script with a _subcall(<args>) method to work."; - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - return 0; - } - *p_outputs[0] = subcall->callp(VisualScriptLanguage::singleton->_subcall, p_inputs, input_args, r_error); - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptSubCall::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceSubCall *instance = memnew(VisualScriptNodeInstanceSubCall); - instance->instance = p_instance; - Ref<Script> script = get_script(); - if (script.is_valid() && script->has_method(VisualScriptLanguage::singleton->_subcall)) { - instance->valid = true; - instance->input_args = get_input_value_port_count(); - } else { - instance->valid = false; - } - return instance; -} - -void VisualScriptSubCall::_bind_methods() { - // Since this is script only, registering virtual function is no longer valid. Will have to go in docs. -} - -VisualScriptSubCall::VisualScriptSubCall() { -} - -////////////////////////////////////////// -////////////////Comment/////////// -////////////////////////////////////////// - -int VisualScriptComment::get_output_sequence_port_count() const { - return 0; -} - -bool VisualScriptComment::has_input_sequence_port() const { - return false; -} - -int VisualScriptComment::get_input_value_port_count() const { - return 0; -} - -int VisualScriptComment::get_output_value_port_count() const { - return 0; -} - -String VisualScriptComment::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptComment::get_input_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -PropertyInfo VisualScriptComment::get_output_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -String VisualScriptComment::get_caption() const { - return title; -} - -String VisualScriptComment::get_text() const { - return description; -} - -void VisualScriptComment::set_title(const String &p_title) { - if (title == p_title) { - return; - } - title = p_title; - ports_changed_notify(); -} - -String VisualScriptComment::get_title() const { - return title; -} - -void VisualScriptComment::set_description(const String &p_description) { - if (description == p_description) { - return; - } - description = p_description; - ports_changed_notify(); -} - -String VisualScriptComment::get_description() const { - return description; -} - -void VisualScriptComment::set_size(const Size2 &p_size) { - if (size == p_size) { - return; - } - size = p_size; - ports_changed_notify(); -} - -Size2 VisualScriptComment::get_size() const { - return size; -} - -String VisualScriptComment::get_category() const { - return "data"; -} - -class VisualScriptNodeInstanceComment : public VisualScriptNodeInstance { -public: - VisualScriptInstance *instance = nullptr; - - //virtual int get_working_memory_size() const override { return 0; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptComment::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceComment *instance = memnew(VisualScriptNodeInstanceComment); - instance->instance = p_instance; - return instance; -} - -void VisualScriptComment::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_title", "title"), &VisualScriptComment::set_title); - ClassDB::bind_method(D_METHOD("get_title"), &VisualScriptComment::get_title); - - ClassDB::bind_method(D_METHOD("set_description", "description"), &VisualScriptComment::set_description); - ClassDB::bind_method(D_METHOD("get_description"), &VisualScriptComment::get_description); - - ClassDB::bind_method(D_METHOD("set_size", "size"), &VisualScriptComment::set_size); - ClassDB::bind_method(D_METHOD("get_size"), &VisualScriptComment::get_size); - - ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "description", PROPERTY_HINT_MULTILINE_TEXT), "set_description", "get_description"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size"); -} - -VisualScriptComment::VisualScriptComment() { - title = "Comment"; - size = Size2(150, 150); -} - -////////////////////////////////////////// -////////////////Constructor/////////// -////////////////////////////////////////// - -int VisualScriptConstructor::get_output_sequence_port_count() const { - return 0; -} - -bool VisualScriptConstructor::has_input_sequence_port() const { - return false; -} - -int VisualScriptConstructor::get_input_value_port_count() const { - return constructor.arguments.size(); -} - -int VisualScriptConstructor::get_output_value_port_count() const { - return 1; -} - -String VisualScriptConstructor::get_output_sequence_port_text(int p_port) const { - return ""; -} - -PropertyInfo VisualScriptConstructor::get_input_value_port_info(int p_idx) const { - return constructor.arguments[p_idx]; -} - -PropertyInfo VisualScriptConstructor::get_output_value_port_info(int p_idx) const { - return PropertyInfo(type, "value"); -} - -String VisualScriptConstructor::get_caption() const { - return vformat(RTR("Construct %s"), Variant::get_type_name(type)); -} - -String VisualScriptConstructor::get_category() const { - return "functions"; -} - -void VisualScriptConstructor::set_constructor_type(Variant::Type p_type) { - if (type == p_type) { - return; - } - - type = p_type; - ports_changed_notify(); -} - -Variant::Type VisualScriptConstructor::get_constructor_type() const { - return type; -} - -void VisualScriptConstructor::set_constructor(const Dictionary &p_info) { - constructor = MethodInfo::from_dict(p_info); - ports_changed_notify(); -} - -Dictionary VisualScriptConstructor::get_constructor() const { - return constructor; -} - -class VisualScriptNodeInstanceConstructor : public VisualScriptNodeInstance { -public: - VisualScriptInstance *instance = nullptr; - Variant::Type type; - int argcount = 0; - - //virtual int get_working_memory_size() const override { return 0; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - Callable::CallError ce; - Variant::construct(type, *p_outputs[0], p_inputs, argcount, ce); - if (ce.error != Callable::CallError::CALL_OK) { - r_error_str = "Invalid arguments for constructor"; - } - - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptConstructor::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceConstructor *instance = memnew(VisualScriptNodeInstanceConstructor); - instance->instance = p_instance; - instance->type = type; - instance->argcount = constructor.arguments.size(); - return instance; -} - -void VisualScriptConstructor::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_constructor_type", "type"), &VisualScriptConstructor::set_constructor_type); - ClassDB::bind_method(D_METHOD("get_constructor_type"), &VisualScriptConstructor::get_constructor_type); - - ClassDB::bind_method(D_METHOD("set_constructor", "constructor"), &VisualScriptConstructor::set_constructor); - ClassDB::bind_method(D_METHOD("get_constructor"), &VisualScriptConstructor::get_constructor); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "set_constructor_type", "get_constructor_type"); - ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "constructor", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "set_constructor", "get_constructor"); -} - -VisualScriptConstructor::VisualScriptConstructor() { - type = Variant::NIL; -} - -static HashMap<String, Pair<Variant::Type, MethodInfo>> constructor_map; - -static Ref<VisualScriptNode> create_constructor_node(const String &p_name) { - ERR_FAIL_COND_V(!constructor_map.has(p_name), Ref<VisualScriptNode>()); - - Ref<VisualScriptConstructor> vsc; - vsc.instantiate(); - vsc->set_constructor_type(constructor_map[p_name].first); - vsc->set_constructor(constructor_map[p_name].second); - - return vsc; -} - -////////////////////////////////////////// -////////////////LocalVar/////////// -////////////////////////////////////////// - -int VisualScriptLocalVar::get_output_sequence_port_count() const { - return 0; -} - -bool VisualScriptLocalVar::has_input_sequence_port() const { - return false; -} - -int VisualScriptLocalVar::get_input_value_port_count() const { - return 0; -} - -int VisualScriptLocalVar::get_output_value_port_count() const { - return 1; -} - -String VisualScriptLocalVar::get_output_sequence_port_text(int p_port) const { - return ""; -} - -PropertyInfo VisualScriptLocalVar::get_input_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -PropertyInfo VisualScriptLocalVar::get_output_value_port_info(int p_idx) const { - return PropertyInfo(type, name); -} - -String VisualScriptLocalVar::get_caption() const { - return RTR("Get Local Var"); -} - -String VisualScriptLocalVar::get_category() const { - return "data"; -} - -void VisualScriptLocalVar::set_var_name(const StringName &p_name) { - if (name == p_name) { - return; - } - - name = p_name; - ports_changed_notify(); -} - -StringName VisualScriptLocalVar::get_var_name() const { - return name; -} - -void VisualScriptLocalVar::set_var_type(Variant::Type p_type) { - type = p_type; - ports_changed_notify(); -} - -Variant::Type VisualScriptLocalVar::get_var_type() const { - return type; -} - -class VisualScriptNodeInstanceLocalVar : public VisualScriptNodeInstance { -public: - VisualScriptInstance *instance = nullptr; - StringName name; - - virtual int get_working_memory_size() const override { return 1; } - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - *p_outputs[0] = *p_working_mem; - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptLocalVar::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceLocalVar *instance = memnew(VisualScriptNodeInstanceLocalVar); - instance->instance = p_instance; - instance->name = name; - - return instance; -} - -void VisualScriptLocalVar::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_var_name", "name"), &VisualScriptLocalVar::set_var_name); - ClassDB::bind_method(D_METHOD("get_var_name"), &VisualScriptLocalVar::get_var_name); - - ClassDB::bind_method(D_METHOD("set_var_type", "type"), &VisualScriptLocalVar::set_var_type); - ClassDB::bind_method(D_METHOD("get_var_type"), &VisualScriptLocalVar::get_var_type); - - String argt = "Any"; - for (int i = 1; i < Variant::VARIANT_MAX; i++) { - argt += "," + Variant::get_type_name(Variant::Type(i)); - } - - ADD_PROPERTY(PropertyInfo(Variant::STRING, "var_name"), "set_var_name", "get_var_name"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt), "set_var_type", "get_var_type"); -} - -VisualScriptLocalVar::VisualScriptLocalVar() { - name = "new_local"; - type = Variant::NIL; -} - -////////////////////////////////////////// -////////////////LocalVar/////////// -////////////////////////////////////////// - -int VisualScriptLocalVarSet::get_output_sequence_port_count() const { - return 1; -} - -bool VisualScriptLocalVarSet::has_input_sequence_port() const { - return true; -} - -int VisualScriptLocalVarSet::get_input_value_port_count() const { - return 1; -} - -int VisualScriptLocalVarSet::get_output_value_port_count() const { - return 1; -} - -String VisualScriptLocalVarSet::get_output_sequence_port_text(int p_port) const { - return ""; -} - -PropertyInfo VisualScriptLocalVarSet::get_input_value_port_info(int p_idx) const { - return PropertyInfo(type, "set"); -} - -PropertyInfo VisualScriptLocalVarSet::get_output_value_port_info(int p_idx) const { - return PropertyInfo(type, "get"); -} - -String VisualScriptLocalVarSet::get_caption() const { - return RTR("Set Local Var"); -} - -String VisualScriptLocalVarSet::get_text() const { - return name; -} - -String VisualScriptLocalVarSet::get_category() const { - return "data"; -} - -void VisualScriptLocalVarSet::set_var_name(const StringName &p_name) { - if (name == p_name) { - return; - } - - name = p_name; - ports_changed_notify(); -} - -StringName VisualScriptLocalVarSet::get_var_name() const { - return name; -} - -void VisualScriptLocalVarSet::set_var_type(Variant::Type p_type) { - type = p_type; - ports_changed_notify(); -} - -Variant::Type VisualScriptLocalVarSet::get_var_type() const { - return type; -} - -class VisualScriptNodeInstanceLocalVarSet : public VisualScriptNodeInstance { -public: - VisualScriptInstance *instance = nullptr; - StringName name; - - virtual int get_working_memory_size() const override { return 1; } - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - *p_working_mem = *p_inputs[0]; - *p_outputs[0] = *p_working_mem; - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptLocalVarSet::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceLocalVarSet *instance = memnew(VisualScriptNodeInstanceLocalVarSet); - instance->instance = p_instance; - instance->name = name; - - return instance; -} - -void VisualScriptLocalVarSet::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_var_name", "name"), &VisualScriptLocalVarSet::set_var_name); - ClassDB::bind_method(D_METHOD("get_var_name"), &VisualScriptLocalVarSet::get_var_name); - - ClassDB::bind_method(D_METHOD("set_var_type", "type"), &VisualScriptLocalVarSet::set_var_type); - ClassDB::bind_method(D_METHOD("get_var_type"), &VisualScriptLocalVarSet::get_var_type); - - String argt = "Any"; - for (int i = 1; i < Variant::VARIANT_MAX; i++) { - argt += "," + Variant::get_type_name(Variant::Type(i)); - } - - ADD_PROPERTY(PropertyInfo(Variant::STRING, "var_name"), "set_var_name", "get_var_name"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt), "set_var_type", "get_var_type"); -} - -VisualScriptLocalVarSet::VisualScriptLocalVarSet() { - name = "new_local"; - type = Variant::NIL; -} - -////////////////////////////////////////// -////////////////LocalVar/////////// -////////////////////////////////////////// - -int VisualScriptInputAction::get_output_sequence_port_count() const { - return 0; -} - -bool VisualScriptInputAction::has_input_sequence_port() const { - return false; -} - -int VisualScriptInputAction::get_input_value_port_count() const { - return 0; -} - -int VisualScriptInputAction::get_output_value_port_count() const { - return 1; -} - -String VisualScriptInputAction::get_output_sequence_port_text(int p_port) const { - return ""; -} - -PropertyInfo VisualScriptInputAction::get_input_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -PropertyInfo VisualScriptInputAction::get_output_value_port_info(int p_idx) const { - String mstr; - switch (mode) { - case MODE_PRESSED: { - mstr = "pressed"; - } break; - case MODE_RELEASED: { - mstr = "not pressed"; - } break; - case MODE_JUST_PRESSED: { - mstr = "just pressed"; - } break; - case MODE_JUST_RELEASED: { - mstr = "just released"; - } break; - } - - return PropertyInfo(Variant::BOOL, mstr); -} - -String VisualScriptInputAction::get_caption() const { - return vformat(RTR("Action %s"), name); -} - -String VisualScriptInputAction::get_category() const { - return "data"; -} - -void VisualScriptInputAction::set_action_name(const StringName &p_name) { - if (name == p_name) { - return; - } - - name = p_name; - ports_changed_notify(); -} - -StringName VisualScriptInputAction::get_action_name() const { - return name; -} - -void VisualScriptInputAction::set_action_mode(Mode p_mode) { - if (mode == p_mode) { - return; - } - - mode = p_mode; - ports_changed_notify(); -} - -VisualScriptInputAction::Mode VisualScriptInputAction::get_action_mode() const { - return mode; -} - -class VisualScriptNodeInstanceInputAction : public VisualScriptNodeInstance { -public: - VisualScriptInstance *instance = nullptr; - StringName action; - VisualScriptInputAction::Mode mode; - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - switch (mode) { - case VisualScriptInputAction::MODE_PRESSED: { - *p_outputs[0] = Input::get_singleton()->is_action_pressed(action); - } break; - case VisualScriptInputAction::MODE_RELEASED: { - *p_outputs[0] = !Input::get_singleton()->is_action_pressed(action); - } break; - case VisualScriptInputAction::MODE_JUST_PRESSED: { - *p_outputs[0] = Input::get_singleton()->is_action_just_pressed(action); - } break; - case VisualScriptInputAction::MODE_JUST_RELEASED: { - *p_outputs[0] = Input::get_singleton()->is_action_just_released(action); - } break; - } - - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptInputAction::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceInputAction *instance = memnew(VisualScriptNodeInstanceInputAction); - instance->instance = p_instance; - instance->action = name; - instance->mode = mode; - - return instance; -} - -void VisualScriptInputAction::_validate_property(PropertyInfo &p_property) const { - if (p_property.name == "action") { - p_property.hint = PROPERTY_HINT_ENUM; - String actions; - - List<PropertyInfo> pinfo; - ProjectSettings::get_singleton()->get_property_list(&pinfo); - Vector<String> al; - - for (const PropertyInfo &pi : pinfo) { - if (!pi.name.begins_with("input/")) { - continue; - } - - String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length()); - - al.push_back(name); - } - - al.sort(); - - for (int i = 0; i < al.size(); i++) { - if (!actions.is_empty()) { - actions += ","; - } - actions += al[i]; - } - - p_property.hint_string = actions; - } -} - -void VisualScriptInputAction::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_action_name", "name"), &VisualScriptInputAction::set_action_name); - ClassDB::bind_method(D_METHOD("get_action_name"), &VisualScriptInputAction::get_action_name); - - ClassDB::bind_method(D_METHOD("set_action_mode", "mode"), &VisualScriptInputAction::set_action_mode); - ClassDB::bind_method(D_METHOD("get_action_mode"), &VisualScriptInputAction::get_action_mode); - - ADD_PROPERTY(PropertyInfo(Variant::STRING, "action"), "set_action_name", "get_action_name"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Pressed,Released,JustPressed,JustReleased"), "set_action_mode", "get_action_mode"); - - BIND_ENUM_CONSTANT(MODE_PRESSED); - BIND_ENUM_CONSTANT(MODE_RELEASED); - BIND_ENUM_CONSTANT(MODE_JUST_PRESSED); - BIND_ENUM_CONSTANT(MODE_JUST_RELEASED); -} - -VisualScriptInputAction::VisualScriptInputAction() { - name = ""; - mode = MODE_PRESSED; -} - -////////////////////////////////////////// -////////////////Constructor/////////// -////////////////////////////////////////// - -int VisualScriptDeconstruct::get_output_sequence_port_count() const { - return 0; -} - -bool VisualScriptDeconstruct::has_input_sequence_port() const { - return false; -} - -int VisualScriptDeconstruct::get_input_value_port_count() const { - return 1; -} - -int VisualScriptDeconstruct::get_output_value_port_count() const { - return elements.size(); -} - -String VisualScriptDeconstruct::get_output_sequence_port_text(int p_port) const { - return ""; -} - -PropertyInfo VisualScriptDeconstruct::get_input_value_port_info(int p_idx) const { - return PropertyInfo(type, "value"); -} - -PropertyInfo VisualScriptDeconstruct::get_output_value_port_info(int p_idx) const { - return PropertyInfo(elements[p_idx].type, elements[p_idx].name); -} - -String VisualScriptDeconstruct::get_caption() const { - return vformat(RTR("Deconstruct %s"), Variant::get_type_name(type)); -} - -String VisualScriptDeconstruct::get_category() const { - return "functions"; -} - -void VisualScriptDeconstruct::_update_elements() { - elements.clear(); - Variant v; - Callable::CallError ce; - Variant::construct(type, v, nullptr, 0, ce); - - List<PropertyInfo> pinfo; - v.get_property_list(&pinfo); - - for (const PropertyInfo &E : pinfo) { - Element e; - e.name = E.name; - e.type = E.type; - elements.push_back(e); - } -} - -void VisualScriptDeconstruct::set_deconstruct_type(Variant::Type p_type) { - if (type == p_type) { - return; - } - - type = p_type; - _update_elements(); - ports_changed_notify(); - notify_property_list_changed(); //to make input appear/disappear -} - -Variant::Type VisualScriptDeconstruct::get_deconstruct_type() const { - return type; -} - -void VisualScriptDeconstruct::_set_elem_cache(const Array &p_elements) { - ERR_FAIL_COND(p_elements.size() % 2 == 1); - elements.resize(p_elements.size() / 2); - for (int i = 0; i < elements.size(); i++) { - elements.write[i].name = p_elements[i * 2 + 0]; - elements.write[i].type = Variant::Type(int(p_elements[i * 2 + 1])); - } -} - -Array VisualScriptDeconstruct::_get_elem_cache() const { - Array ret; - for (int i = 0; i < elements.size(); i++) { - ret.push_back(elements[i].name); - ret.push_back(elements[i].type); - } - return ret; -} - -class VisualScriptNodeInstanceDeconstruct : public VisualScriptNodeInstance { -public: - VisualScriptInstance *instance = nullptr; - Vector<StringName> outputs; - - //virtual int get_working_memory_size() const override { return 0; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - Variant in = *p_inputs[0]; - - for (int i = 0; i < outputs.size(); i++) { - bool valid; - *p_outputs[i] = in.get(outputs[i], &valid); - if (!valid) { - r_error_str = "Can't obtain element '" + String(outputs[i]) + "' from " + Variant::get_type_name(in.get_type()); - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - return 0; - } - } - - return 0; - } -}; - -VisualScriptNodeInstance *VisualScriptDeconstruct::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceDeconstruct *instance = memnew(VisualScriptNodeInstanceDeconstruct); - instance->instance = p_instance; - instance->outputs.resize(elements.size()); - for (int i = 0; i < elements.size(); i++) { - instance->outputs.write[i] = elements[i].name; - } - - return instance; -} - -void VisualScriptDeconstruct::_validate_property(PropertyInfo &p_property) const { -} - -void VisualScriptDeconstruct::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_deconstruct_type", "type"), &VisualScriptDeconstruct::set_deconstruct_type); - ClassDB::bind_method(D_METHOD("get_deconstruct_type"), &VisualScriptDeconstruct::get_deconstruct_type); - - ClassDB::bind_method(D_METHOD("_set_elem_cache", "_cache"), &VisualScriptDeconstruct::_set_elem_cache); - ClassDB::bind_method(D_METHOD("_get_elem_cache"), &VisualScriptDeconstruct::_get_elem_cache); - - String argt = "Any"; - for (int i = 1; i < Variant::VARIANT_MAX; i++) { - argt += "," + Variant::get_type_name(Variant::Type(i)); - } - - ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt), "set_deconstruct_type", "get_deconstruct_type"); - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "elem_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_elem_cache", "_get_elem_cache"); -} - -VisualScriptDeconstruct::VisualScriptDeconstruct() { - type = Variant::NIL; -} - -template <Variant::Type T> -static Ref<VisualScriptNode> create_node_deconst_typed(const String &p_name) { - Ref<VisualScriptDeconstruct> node; - node.instantiate(); - node->set_deconstruct_type(T); - return node; -} - -void register_visual_script_nodes() { - VisualScriptLanguage::singleton->add_register_func("data/set_variable", create_node_generic<VisualScriptVariableSet>); - VisualScriptLanguage::singleton->add_register_func("data/get_variable", create_node_generic<VisualScriptVariableGet>); - VisualScriptLanguage::singleton->add_register_func("data/engine_singleton", create_node_generic<VisualScriptEngineSingleton>); - VisualScriptLanguage::singleton->add_register_func("data/scene_node", create_node_generic<VisualScriptSceneNode>); - VisualScriptLanguage::singleton->add_register_func("data/scene_tree", create_node_generic<VisualScriptSceneTree>); - VisualScriptLanguage::singleton->add_register_func("data/resource_path", create_node_generic<VisualScriptResourcePath>); - VisualScriptLanguage::singleton->add_register_func("data/self", create_node_generic<VisualScriptSelf>); - VisualScriptLanguage::singleton->add_register_func("data/comment", create_node_generic<VisualScriptComment>); - VisualScriptLanguage::singleton->add_register_func("data/get_local_variable", create_node_generic<VisualScriptLocalVar>); - VisualScriptLanguage::singleton->add_register_func("data/set_local_variable", create_node_generic<VisualScriptLocalVarSet>); - VisualScriptLanguage::singleton->add_register_func("data/preload", create_node_generic<VisualScriptPreload>); - VisualScriptLanguage::singleton->add_register_func("data/action", create_node_generic<VisualScriptInputAction>); - - VisualScriptLanguage::singleton->add_register_func("constants/constant", create_node_generic<VisualScriptConstant>); - VisualScriptLanguage::singleton->add_register_func("constants/math_constant", create_node_generic<VisualScriptMathConstant>); - VisualScriptLanguage::singleton->add_register_func("constants/class_constant", create_node_generic<VisualScriptClassConstant>); - VisualScriptLanguage::singleton->add_register_func("constants/global_constant", create_node_generic<VisualScriptGlobalConstant>); - VisualScriptLanguage::singleton->add_register_func("constants/basic_type_constant", create_node_generic<VisualScriptBasicTypeConstant>); - - VisualScriptLanguage::singleton->add_register_func("custom/custom_node", create_node_generic<VisualScriptCustomNode>); - VisualScriptLanguage::singleton->add_register_func("custom/sub_call", create_node_generic<VisualScriptSubCall>); - - VisualScriptLanguage::singleton->add_register_func("index/get_index", create_node_generic<VisualScriptIndexGet>); - VisualScriptLanguage::singleton->add_register_func("index/set_index", create_node_generic<VisualScriptIndexSet>); - - VisualScriptLanguage::singleton->add_register_func("operators/compare/equal", create_op_node<Variant::OP_EQUAL>); - VisualScriptLanguage::singleton->add_register_func("operators/compare/not_equal", create_op_node<Variant::OP_NOT_EQUAL>); - VisualScriptLanguage::singleton->add_register_func("operators/compare/less", create_op_node<Variant::OP_LESS>); - VisualScriptLanguage::singleton->add_register_func("operators/compare/less_equal", create_op_node<Variant::OP_LESS_EQUAL>); - VisualScriptLanguage::singleton->add_register_func("operators/compare/greater", create_op_node<Variant::OP_GREATER>); - VisualScriptLanguage::singleton->add_register_func("operators/compare/greater_equal", create_op_node<Variant::OP_GREATER_EQUAL>); - //mathematic - VisualScriptLanguage::singleton->add_register_func("operators/math/add", create_op_node<Variant::OP_ADD>); - VisualScriptLanguage::singleton->add_register_func("operators/math/subtract", create_op_node<Variant::OP_SUBTRACT>); - VisualScriptLanguage::singleton->add_register_func("operators/math/multiply", create_op_node<Variant::OP_MULTIPLY>); - VisualScriptLanguage::singleton->add_register_func("operators/math/divide", create_op_node<Variant::OP_DIVIDE>); - VisualScriptLanguage::singleton->add_register_func("operators/math/negate", create_op_node<Variant::OP_NEGATE>); - VisualScriptLanguage::singleton->add_register_func("operators/math/positive", create_op_node<Variant::OP_POSITIVE>); - VisualScriptLanguage::singleton->add_register_func("operators/math/remainder", create_op_node<Variant::OP_MODULE>); - //bitwise - VisualScriptLanguage::singleton->add_register_func("operators/bitwise/shift_left", create_op_node<Variant::OP_SHIFT_LEFT>); - VisualScriptLanguage::singleton->add_register_func("operators/bitwise/shift_right", create_op_node<Variant::OP_SHIFT_RIGHT>); - VisualScriptLanguage::singleton->add_register_func("operators/bitwise/bit_and", create_op_node<Variant::OP_BIT_AND>); - VisualScriptLanguage::singleton->add_register_func("operators/bitwise/bit_or", create_op_node<Variant::OP_BIT_OR>); - VisualScriptLanguage::singleton->add_register_func("operators/bitwise/bit_xor", create_op_node<Variant::OP_BIT_XOR>); - VisualScriptLanguage::singleton->add_register_func("operators/bitwise/bit_negate", create_op_node<Variant::OP_BIT_NEGATE>); - //logic - VisualScriptLanguage::singleton->add_register_func("operators/logic/and", create_op_node<Variant::OP_AND>); - VisualScriptLanguage::singleton->add_register_func("operators/logic/or", create_op_node<Variant::OP_OR>); - VisualScriptLanguage::singleton->add_register_func("operators/logic/xor", create_op_node<Variant::OP_XOR>); - VisualScriptLanguage::singleton->add_register_func("operators/logic/not", create_op_node<Variant::OP_NOT>); - VisualScriptLanguage::singleton->add_register_func("operators/logic/in", create_op_node<Variant::OP_IN>); - VisualScriptLanguage::singleton->add_register_func("operators/logic/select", create_node_generic<VisualScriptSelect>); - - VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR2), create_node_deconst_typed<Variant::Type::VECTOR2>); - VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR2I), create_node_deconst_typed<Variant::Type::VECTOR2I>); - VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR3), create_node_deconst_typed<Variant::Type::VECTOR3>); - VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR3I), create_node_deconst_typed<Variant::Type::VECTOR3I>); - VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR4), create_node_deconst_typed<Variant::Type::VECTOR4>); - VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR4I), create_node_deconst_typed<Variant::Type::VECTOR4I>); - VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::COLOR), create_node_deconst_typed<Variant::Type::COLOR>); - VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::RECT2), create_node_deconst_typed<Variant::Type::RECT2>); - VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::RECT2I), create_node_deconst_typed<Variant::Type::RECT2I>); - VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::TRANSFORM2D), create_node_deconst_typed<Variant::Type::TRANSFORM2D>); - VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::PLANE), create_node_deconst_typed<Variant::Type::PLANE>); - VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::QUATERNION), create_node_deconst_typed<Variant::Type::QUATERNION>); - VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::AABB), create_node_deconst_typed<Variant::Type::AABB>); - VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::BASIS), create_node_deconst_typed<Variant::Type::BASIS>); - VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::TRANSFORM3D), create_node_deconst_typed<Variant::Type::TRANSFORM3D>); - VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::PROJECTION), create_node_deconst_typed<Variant::Type::PROJECTION>); - VisualScriptLanguage::singleton->add_register_func("functions/compose_array", create_node_generic<VisualScriptComposeArray>); - - for (int i = 1; i < Variant::VARIANT_MAX; i++) { - List<MethodInfo> constructors; - Variant::get_constructor_list(Variant::Type(i), &constructors); - - for (const MethodInfo &E : constructors) { - if (E.arguments.size() > 0) { - String name = "functions/constructors/" + Variant::get_type_name(Variant::Type(i)) + "("; - for (int j = 0; j < E.arguments.size(); j++) { - if (j > 0) { - name += ", "; - } - if (E.arguments.size() == 1) { - name += Variant::get_type_name(E.arguments[j].type); - } else { - name += E.arguments[j].name; - } - } - name += ")"; - VisualScriptLanguage::singleton->add_register_func(name, create_constructor_node); - Pair<Variant::Type, MethodInfo> pair; - pair.first = Variant::Type(i); - pair.second = E; - constructor_map[name] = pair; - } - } - } -} - -void unregister_visual_script_nodes() { - constructor_map.clear(); -} diff --git a/modules/visual_script/visual_script_nodes.h b/modules/visual_script/visual_script_nodes.h deleted file mode 100644 index 72a99b9fd2..0000000000 --- a/modules/visual_script/visual_script_nodes.h +++ /dev/null @@ -1,1092 +0,0 @@ -/*************************************************************************/ -/* visual_script_nodes.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef VISUAL_SCRIPT_NODES_H -#define VISUAL_SCRIPT_NODES_H - -#include "core/object/gdvirtual.gen.inc" -#include "core/object/script_language.h" -#include "scene/main/multiplayer_api.h" -#include "visual_script.h" - -class VisualScriptFunction : public VisualScriptNode { - GDCLASS(VisualScriptFunction, VisualScriptNode); - - struct Argument { - String name; - Variant::Type type; - PropertyHint hint; - String hint_string; - }; - - Vector<Argument> arguments; - - bool stack_less; - int stack_size; - MultiplayerAPI::RPCMode rpc_mode; - bool sequenced; - -protected: - bool _set(const StringName &p_name, const Variant &p_value); - bool _get(const StringName &p_name, Variant &r_ret) const; - void _get_property_list(List<PropertyInfo> *p_list) const; - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_text() const override; - virtual String get_category() const override { return "flow_control"; } - - void add_argument(Variant::Type p_type, const String &p_name, int p_index = -1, const PropertyHint p_hint = PROPERTY_HINT_NONE, const String &p_hint_string = String("")); - void set_argument_type(int p_argidx, Variant::Type p_type); - Variant::Type get_argument_type(int p_argidx) const; - void set_argument_name(int p_argidx, const String &p_name); - String get_argument_name(int p_argidx) const; - void remove_argument(int p_argidx); - int get_argument_count() const; - - void set_stack_less(bool p_enable); - bool is_stack_less() const; - - void set_sequenced(bool p_enable); - bool is_sequenced() const; - - void set_stack_size(int p_size); - int get_stack_size() const; - - void set_rpc_mode(MultiplayerAPI::RPCMode p_mode); - MultiplayerAPI::RPCMode get_rpc_mode() const; - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - virtual void reset_state() override; - - VisualScriptFunction(); -}; - -class VisualScriptLists : public VisualScriptNode { - GDCLASS(VisualScriptLists, VisualScriptNode) - - struct Port { - String name; - Variant::Type type; - }; - -protected: - Vector<Port> inputports; - Vector<Port> outputports; - - enum { - OUTPUT_EDITABLE = 0x0001, - OUTPUT_NAME_EDITABLE = 0x0002, - OUTPUT_TYPE_EDITABLE = 0x0004, - INPUT_EDITABLE = 0x0008, - INPUT_NAME_EDITABLE = 0x000F, - INPUT_TYPE_EDITABLE = 0x0010, - }; - - int flags; - - bool sequenced; - - bool _set(const StringName &p_name, const Variant &p_value); - bool _get(const StringName &p_name, Variant &r_ret) const; - void _get_property_list(List<PropertyInfo> *p_list) const; - - static void _bind_methods(); - -public: - virtual void reset_state() override; - - virtual bool is_output_port_editable() const; - virtual bool is_output_port_name_editable() const; - virtual bool is_output_port_type_editable() const; - - virtual bool is_input_port_editable() const; - virtual bool is_input_port_name_editable() const; - virtual bool is_input_port_type_editable() const; - - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - void add_input_data_port(Variant::Type p_type, const String &p_name, int p_index = -1); - void set_input_data_port_type(int p_idx, Variant::Type p_type); - void set_input_data_port_name(int p_idx, const String &p_name); - void remove_input_data_port(int p_argidx); - - void add_output_data_port(Variant::Type p_type, const String &p_name, int p_index = -1); - void set_output_data_port_type(int p_idx, Variant::Type p_type); - void set_output_data_port_name(int p_idx, const String &p_name); - void remove_output_data_port(int p_argidx); - - void set_sequenced(bool p_enable); - bool is_sequenced() const; - - VisualScriptLists(); -}; - -class VisualScriptComposeArray : public VisualScriptLists { - GDCLASS(VisualScriptComposeArray, VisualScriptLists) - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_text() const override; - virtual String get_category() const override { return "functions"; } - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptComposeArray(); -}; - -class VisualScriptOperator : public VisualScriptNode { - GDCLASS(VisualScriptOperator, VisualScriptNode); - - Variant::Type typed; - Variant::Operator op; - -protected: - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_category() const override { return "operators"; } - - void set_operator(Variant::Operator p_op); - Variant::Operator get_operator() const; - - void set_typed(Variant::Type p_op); - Variant::Type get_typed() const; - - static String get_operator_name(Variant::Operator p_op); - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptOperator(); -}; - -class VisualScriptSelect : public VisualScriptNode { - GDCLASS(VisualScriptSelect, VisualScriptNode); - - Variant::Type typed; - -protected: - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_text() const override; - virtual String get_category() const override { return "operators"; } - - void set_typed(Variant::Type p_op); - Variant::Type get_typed() const; - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptSelect(); -}; - -class VisualScriptVariableGet : public VisualScriptNode { - GDCLASS(VisualScriptVariableGet, VisualScriptNode); - - StringName variable; - -protected: - void _validate_property(PropertyInfo &p_property) const; - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_category() const override { return "data"; } - - void set_variable(StringName p_variable); - StringName get_variable() const; - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptVariableGet(); -}; - -class VisualScriptVariableSet : public VisualScriptNode { - GDCLASS(VisualScriptVariableSet, VisualScriptNode); - - StringName variable; - -protected: - void _validate_property(PropertyInfo &p_property) const; - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_category() const override { return "data"; } - - void set_variable(StringName p_variable); - StringName get_variable() const; - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptVariableSet(); -}; - -class VisualScriptConstant : public VisualScriptNode { - GDCLASS(VisualScriptConstant, VisualScriptNode); - - Variant::Type type; - Variant value; - -protected: - void _validate_property(PropertyInfo &p_property) const; - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_category() const override { return "constants"; } - - void set_constant_type(Variant::Type p_type); - Variant::Type get_constant_type() const; - - void set_constant_value(Variant p_value); - Variant get_constant_value() const; - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptConstant(); -}; - -class VisualScriptPreload : public VisualScriptNode { - GDCLASS(VisualScriptPreload, VisualScriptNode); - - Ref<Resource> preload; - -protected: - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_category() const override { return "data"; } - - void set_preload(const Ref<Resource> &p_preload); - Ref<Resource> get_preload() const; - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptPreload(); -}; - -class VisualScriptIndexGet : public VisualScriptNode { - GDCLASS(VisualScriptIndexGet, VisualScriptNode); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_category() const override { return "operators"; } - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptIndexGet(); -}; - -class VisualScriptIndexSet : public VisualScriptNode { - GDCLASS(VisualScriptIndexSet, VisualScriptNode); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_category() const override { return "operators"; } - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptIndexSet(); -}; - -class VisualScriptGlobalConstant : public VisualScriptNode { - GDCLASS(VisualScriptGlobalConstant, VisualScriptNode); - - int index; - - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_category() const override { return "constants"; } - - void set_global_constant(int p_which); - int get_global_constant(); - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptGlobalConstant(); -}; - -class VisualScriptClassConstant : public VisualScriptNode { - GDCLASS(VisualScriptClassConstant, VisualScriptNode); - - StringName base_type; - StringName name; - -protected: - static void _bind_methods(); - void _validate_property(PropertyInfo &p_property) const; - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_category() const override { return "constants"; } - - void set_class_constant(const StringName &p_which); - StringName get_class_constant(); - - void set_base_type(const StringName &p_which); - StringName get_base_type(); - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptClassConstant(); -}; - -class VisualScriptBasicTypeConstant : public VisualScriptNode { - GDCLASS(VisualScriptBasicTypeConstant, VisualScriptNode); - - Variant::Type type; - StringName name; - -protected: - static void _bind_methods(); - void _validate_property(PropertyInfo &p_property) const; - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_text() const override; - virtual String get_category() const override { return "constants"; } - - void set_basic_type_constant(const StringName &p_which); - StringName get_basic_type_constant() const; - - void set_basic_type(Variant::Type p_which); - Variant::Type get_basic_type() const; - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptBasicTypeConstant(); -}; - -class VisualScriptMathConstant : public VisualScriptNode { - GDCLASS(VisualScriptMathConstant, VisualScriptNode); - -public: - enum MathConstant { - MATH_CONSTANT_ONE, - MATH_CONSTANT_PI, - MATH_CONSTANT_HALF_PI, - MATH_CONSTANT_TAU, - MATH_CONSTANT_E, - MATH_CONSTANT_SQRT2, - MATH_CONSTANT_INF, - MATH_CONSTANT_NAN, - MATH_CONSTANT_MAX - }; - -private: - static const char *const_name[MATH_CONSTANT_MAX]; - static double const_value[MATH_CONSTANT_MAX]; - MathConstant constant; - -protected: - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_category() const override { return "constants"; } - - void set_math_constant(MathConstant p_which); - MathConstant get_math_constant(); - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptMathConstant(); -}; - -VARIANT_ENUM_CAST(VisualScriptMathConstant::MathConstant) - -class VisualScriptEngineSingleton : public VisualScriptNode { - GDCLASS(VisualScriptEngineSingleton, VisualScriptNode); - - String singleton; - -protected: - void _validate_property(PropertyInfo &p_property) const; - - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_category() const override { return "data"; } - - void set_singleton(const String &p_string); - String get_singleton(); - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - virtual TypeGuess guess_output_type(TypeGuess *p_inputs, int p_output) const override; - - VisualScriptEngineSingleton(); -}; - -class VisualScriptSceneNode : public VisualScriptNode { - GDCLASS(VisualScriptSceneNode, VisualScriptNode); - - NodePath path; - -protected: - void _validate_property(PropertyInfo &p_property) const; - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_category() const override { return "data"; } - - void set_node_path(const NodePath &p_path); - NodePath get_node_path(); - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - virtual TypeGuess guess_output_type(TypeGuess *p_inputs, int p_output) const override; - - VisualScriptSceneNode(); -}; - -class VisualScriptSceneTree : public VisualScriptNode { - GDCLASS(VisualScriptSceneTree, VisualScriptNode); - -protected: - void _validate_property(PropertyInfo &p_property) const; - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_category() const override { return "data"; } - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - virtual TypeGuess guess_output_type(TypeGuess *p_inputs, int p_output) const override; - - VisualScriptSceneTree(); -}; - -class VisualScriptResourcePath : public VisualScriptNode { - GDCLASS(VisualScriptResourcePath, VisualScriptNode); - - String path; - -protected: - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_category() const override { return "data"; } - - void set_resource_path(const String &p_path); - String get_resource_path(); - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptResourcePath(); -}; - -class VisualScriptSelf : public VisualScriptNode { - GDCLASS(VisualScriptSelf, VisualScriptNode); - -protected: - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_category() const override { return "data"; } - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - virtual TypeGuess guess_output_type(TypeGuess *p_inputs, int p_output) const override; - - VisualScriptSelf(); -}; - -class VisualScriptCustomNode : public VisualScriptNode { - GDCLASS(VisualScriptCustomNode, VisualScriptNode); - -protected: - static void _bind_methods(); - friend class VisualScriptNodeInstanceCustomNode; - GDVIRTUAL0RC(int, _get_output_sequence_port_count) - GDVIRTUAL0RC(bool, _has_input_sequence_port) - GDVIRTUAL1RC(String, _get_output_sequence_port_text, int) - - GDVIRTUAL0RC(int, _get_input_value_port_count) - GDVIRTUAL1RC(int, _get_input_value_port_type, int) - GDVIRTUAL1RC(String, _get_input_value_port_name, int) - GDVIRTUAL1RC(int, _get_input_value_port_hint, int) - GDVIRTUAL1RC(String, _get_input_value_port_hint_string, int) - - GDVIRTUAL0RC(int, _get_output_value_port_count) - GDVIRTUAL1RC(int, _get_output_value_port_type, int) - GDVIRTUAL1RC(String, _get_output_value_port_name, int) - GDVIRTUAL1RC(int, _get_output_value_port_hint, int) - GDVIRTUAL1RC(String, _get_output_value_port_hint_string, int) - - GDVIRTUAL0RC(String, _get_caption) - GDVIRTUAL0RC(String, _get_text) - GDVIRTUAL0RC(String, _get_category) - - GDVIRTUAL0RC(int, _get_working_memory_size) - - GDVIRTUAL4RC(Variant, _step, Array, Array, int, Array) - -public: - enum StartMode { //replicated for step - START_MODE_BEGIN_SEQUENCE, - START_MODE_CONTINUE_SEQUENCE, - START_MODE_RESUME_YIELD - }; - - enum { //replicated for step - STEP_SHIFT = 1 << 24, - STEP_MASK = STEP_SHIFT - 1, - STEP_PUSH_STACK_BIT = STEP_SHIFT, //push bit to stack - STEP_GO_BACK_BIT = STEP_SHIFT << 1, //go back to previous node - STEP_NO_ADVANCE_BIT = STEP_SHIFT << 2, //do not advance past this node - STEP_EXIT_FUNCTION_BIT = STEP_SHIFT << 3, //return from function - STEP_YIELD_BIT = STEP_SHIFT << 4, //yield (will find VisualScriptFunctionState state in first working memory) - }; - - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_text() const override; - virtual String get_category() const override; - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - virtual TypeGuess guess_output_type(TypeGuess *p_inputs, int p_output) const override; - - void _script_changed(); - - VisualScriptCustomNode(); -}; - -VARIANT_ENUM_CAST(VisualScriptCustomNode::StartMode); - -class VisualScriptSubCall : public VisualScriptNode { - GDCLASS(VisualScriptSubCall, VisualScriptNode); - -protected: - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_text() const override; - virtual String get_category() const override; - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptSubCall(); -}; - -class VisualScriptComment : public VisualScriptNode { - GDCLASS(VisualScriptComment, VisualScriptNode); - - String title; - String description; - Size2 size; - -protected: - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_text() const override; - virtual String get_category() const override; - - void set_title(const String &p_title); - String get_title() const; - - void set_description(const String &p_description); - String get_description() const; - - void set_size(const Size2 &p_size); - Size2 get_size() const; - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptComment(); -}; - -class VisualScriptConstructor : public VisualScriptNode { - GDCLASS(VisualScriptConstructor, VisualScriptNode); - - Variant::Type type; - MethodInfo constructor; - -protected: - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_category() const override; - - void set_constructor_type(Variant::Type p_type); - Variant::Type get_constructor_type() const; - - void set_constructor(const Dictionary &p_info); - Dictionary get_constructor() const; - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptConstructor(); -}; - -class VisualScriptLocalVar : public VisualScriptNode { - GDCLASS(VisualScriptLocalVar, VisualScriptNode); - - StringName name; - Variant::Type type; - -protected: - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_category() const override; - - void set_var_name(const StringName &p_name); - StringName get_var_name() const; - - void set_var_type(Variant::Type p_type); - Variant::Type get_var_type() const; - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptLocalVar(); -}; - -class VisualScriptLocalVarSet : public VisualScriptNode { - GDCLASS(VisualScriptLocalVarSet, VisualScriptNode); - - StringName name; - Variant::Type type; - -protected: - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_text() const override; - virtual String get_category() const override; - - void set_var_name(const StringName &p_name); - StringName get_var_name() const; - - void set_var_type(Variant::Type p_type); - Variant::Type get_var_type() const; - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptLocalVarSet(); -}; - -class VisualScriptInputAction : public VisualScriptNode { - GDCLASS(VisualScriptInputAction, VisualScriptNode); - -public: - enum Mode { - MODE_PRESSED, - MODE_RELEASED, - MODE_JUST_PRESSED, - MODE_JUST_RELEASED, - }; - - StringName name; - Mode mode; - -protected: - void _validate_property(PropertyInfo &p_property) const; - - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_category() const override; - - void set_action_name(const StringName &p_name); - StringName get_action_name() const; - - void set_action_mode(Mode p_mode); - Mode get_action_mode() const; - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptInputAction(); -}; - -VARIANT_ENUM_CAST(VisualScriptInputAction::Mode) - -class VisualScriptDeconstruct : public VisualScriptNode { - GDCLASS(VisualScriptDeconstruct, VisualScriptNode); - - struct Element { - StringName name; - Variant::Type type; - }; - - Vector<Element> elements; - - void _update_elements(); - Variant::Type type; - - void _set_elem_cache(const Array &p_elements); - Array _get_elem_cache() const; - - void _validate_property(PropertyInfo &p_property) const; - -protected: - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_category() const override; - - void set_deconstruct_type(Variant::Type p_type); - Variant::Type get_deconstruct_type() const; - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptDeconstruct(); -}; - -void register_visual_script_nodes(); -void unregister_visual_script_nodes(); - -#endif // VISUAL_SCRIPT_NODES_H diff --git a/modules/visual_script/visual_script_yield_nodes.cpp b/modules/visual_script/visual_script_yield_nodes.cpp deleted file mode 100644 index 05dbe102f5..0000000000 --- a/modules/visual_script/visual_script_yield_nodes.cpp +++ /dev/null @@ -1,598 +0,0 @@ -/*************************************************************************/ -/* visual_script_yield_nodes.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "visual_script_yield_nodes.h" - -#include "core/os/os.h" -#include "scene/main/node.h" -#include "scene/main/scene_tree.h" -#include "visual_script_nodes.h" - -////////////////////////////////////////// -////////////////YIELD/////////// -////////////////////////////////////////// - -int VisualScriptYield::get_output_sequence_port_count() const { - return 1; -} - -bool VisualScriptYield::has_input_sequence_port() const { - return true; -} - -int VisualScriptYield::get_input_value_port_count() const { - return 0; -} - -int VisualScriptYield::get_output_value_port_count() const { - return 0; -} - -String VisualScriptYield::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptYield::get_input_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -PropertyInfo VisualScriptYield::get_output_value_port_info(int p_idx) const { - return PropertyInfo(); -} - -String VisualScriptYield::get_caption() const { - return yield_mode == YIELD_RETURN ? RTR("Yield") : RTR("Wait"); -} - -String VisualScriptYield::get_text() const { - switch (yield_mode) { - case YIELD_RETURN: - return ""; - break; - case YIELD_FRAME: - return RTR("Next Frame"); - break; - case YIELD_PHYSICS_FRAME: - return RTR("Next Physics Frame"); - break; - case YIELD_WAIT: - return vformat(RTR("%s sec(s)"), rtos(wait_time)); - break; - } - - return String(); -} - -class VisualScriptNodeInstanceYield : public VisualScriptNodeInstance { -public: - VisualScriptYield::YieldMode mode; - double wait_time = 0.0; - - virtual int get_working_memory_size() const override { return 1; } //yield needs at least 1 - //virtual bool is_output_port_unsequenced(int p_idx) const { return false; } - //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return false; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - if (p_start_mode == START_MODE_RESUME_YIELD) { - return 0; //resuming yield - } else { - //yield - - SceneTree *tree = Object::cast_to<SceneTree>(OS::get_singleton()->get_main_loop()); - if (!tree) { - r_error_str = "Main Loop is not SceneTree"; - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - return 0; - } - - Ref<VisualScriptFunctionState> state; - state.instantiate(); - - int ret = STEP_YIELD_BIT; - switch (mode) { - case VisualScriptYield::YIELD_RETURN: - ret = STEP_EXIT_FUNCTION_BIT; - break; //return the yield - case VisualScriptYield::YIELD_FRAME: - state->connect_to_signal(tree, "process_frame", Array()); - break; - case VisualScriptYield::YIELD_PHYSICS_FRAME: - state->connect_to_signal(tree, "physics_frame", Array()); - break; - case VisualScriptYield::YIELD_WAIT: - state->connect_to_signal(tree->create_timer(wait_time).ptr(), "timeout", Array()); - break; - } - - *p_working_mem = state; - - return ret; - } - } -}; - -VisualScriptNodeInstance *VisualScriptYield::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceYield *instance = memnew(VisualScriptNodeInstanceYield); - //instance->instance=p_instance; - instance->mode = yield_mode; - instance->wait_time = wait_time; - return instance; -} - -void VisualScriptYield::set_yield_mode(YieldMode p_mode) { - if (yield_mode == p_mode) { - return; - } - yield_mode = p_mode; - ports_changed_notify(); - notify_property_list_changed(); -} - -VisualScriptYield::YieldMode VisualScriptYield::get_yield_mode() { - return yield_mode; -} - -void VisualScriptYield::set_wait_time(double p_time) { - if (wait_time == p_time) { - return; - } - wait_time = p_time; - ports_changed_notify(); -} - -double VisualScriptYield::get_wait_time() { - return wait_time; -} - -void VisualScriptYield::_validate_property(PropertyInfo &p_property) const { - if (p_property.name == "wait_time") { - if (yield_mode != YIELD_WAIT) { - p_property.usage = PROPERTY_USAGE_NONE; - } - } -} - -void VisualScriptYield::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_yield_mode", "mode"), &VisualScriptYield::set_yield_mode); - ClassDB::bind_method(D_METHOD("get_yield_mode"), &VisualScriptYield::get_yield_mode); - - ClassDB::bind_method(D_METHOD("set_wait_time", "sec"), &VisualScriptYield::set_wait_time); - ClassDB::bind_method(D_METHOD("get_wait_time"), &VisualScriptYield::get_wait_time); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Frame,Physics Frame,Time", PROPERTY_USAGE_NO_EDITOR), "set_yield_mode", "get_yield_mode"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "wait_time"), "set_wait_time", "get_wait_time"); - - BIND_ENUM_CONSTANT(YIELD_FRAME); - BIND_ENUM_CONSTANT(YIELD_PHYSICS_FRAME); - BIND_ENUM_CONSTANT(YIELD_WAIT); -} - -VisualScriptYield::VisualScriptYield() { - yield_mode = YIELD_FRAME; - wait_time = 1; -} - -template <VisualScriptYield::YieldMode MODE> -static Ref<VisualScriptNode> create_yield_node(const String &p_name) { - Ref<VisualScriptYield> node; - node.instantiate(); - node->set_yield_mode(MODE); - return node; -} - -/////////////////////////////////////////////////// -////////////////YIELD SIGNAL////////////////////// -////////////////////////////////////////////////// - -int VisualScriptYieldSignal::get_output_sequence_port_count() const { - return 1; -} - -bool VisualScriptYieldSignal::has_input_sequence_port() const { - return true; -} -#ifdef TOOLS_ENABLED - -static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) { - if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene) { - return nullptr; - } - - Ref<Script> scr = p_current_node->get_script(); - - if (scr.is_valid() && scr == script) { - return p_current_node; - } - - for (int i = 0; i < p_current_node->get_child_count(); i++) { - Node *n = _find_script_node(p_edited_scene, p_current_node->get_child(i), script); - if (n) { - return n; - } - } - - return nullptr; -} - -#endif -Node *VisualScriptYieldSignal::_get_base_node() const { -#ifdef TOOLS_ENABLED - Ref<Script> script = get_visual_script(); - if (!script.is_valid()) { - return nullptr; - } - - MainLoop *main_loop = OS::get_singleton()->get_main_loop(); - SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop); - - if (!scene_tree) { - return nullptr; - } - - Node *edited_scene = scene_tree->get_edited_scene_root(); - - if (!edited_scene) { - return nullptr; - } - - Node *script_node = _find_script_node(edited_scene, edited_scene, script); - - if (!script_node) { - return nullptr; - } - - if (!script_node->has_node(base_path)) { - return nullptr; - } - - Node *path_to = script_node->get_node(base_path); - - return path_to; -#else - - return nullptr; -#endif -} - -StringName VisualScriptYieldSignal::_get_base_type() const { - if (call_mode == CALL_MODE_SELF && get_visual_script().is_valid()) { - return get_visual_script()->get_instance_base_type(); - } else if (call_mode == CALL_MODE_NODE_PATH && get_visual_script().is_valid()) { - Node *path = _get_base_node(); - if (path) { - return path->get_class(); - } - } - - return base_type; -} - -int VisualScriptYieldSignal::get_input_value_port_count() const { - if (call_mode == CALL_MODE_INSTANCE) { - return 1; - } else { - return 0; - } -} - -int VisualScriptYieldSignal::get_output_value_port_count() const { - MethodInfo sr; - - if (!ClassDB::get_signal(_get_base_type(), signal, &sr)) { - return 0; - } - - return sr.arguments.size(); -} - -String VisualScriptYieldSignal::get_output_sequence_port_text(int p_port) const { - return String(); -} - -PropertyInfo VisualScriptYieldSignal::get_input_value_port_info(int p_idx) const { - if (call_mode == CALL_MODE_INSTANCE) { - return PropertyInfo(Variant::OBJECT, "instance"); - } else { - return PropertyInfo(); - } -} - -PropertyInfo VisualScriptYieldSignal::get_output_value_port_info(int p_idx) const { - MethodInfo sr; - - if (!ClassDB::get_signal(_get_base_type(), signal, &sr)) { - return PropertyInfo(); //no signal - } - ERR_FAIL_INDEX_V(p_idx, sr.arguments.size(), PropertyInfo()); - return sr.arguments[p_idx]; -} - -String VisualScriptYieldSignal::get_caption() const { - switch (call_mode) { - case CALL_MODE_SELF: { - return RTR("WaitSignal"); - } break; - case CALL_MODE_NODE_PATH: { - return RTR("WaitNodeSignal"); - } break; - case CALL_MODE_INSTANCE: { - return RTR("WaitInstanceSignal"); - } break; - } - return String(); -} - -String VisualScriptYieldSignal::get_text() const { - if (call_mode == CALL_MODE_SELF) { - return " " + String(signal) + "()"; - } else { - return " " + _get_base_type() + "." + String(signal) + "()"; - } -} - -void VisualScriptYieldSignal::set_base_type(const StringName &p_type) { - if (base_type == p_type) { - return; - } - - base_type = p_type; - - notify_property_list_changed(); - ports_changed_notify(); -} - -StringName VisualScriptYieldSignal::get_base_type() const { - return base_type; -} - -void VisualScriptYieldSignal::set_signal(const StringName &p_type) { - if (signal == p_type) { - return; - } - - signal = p_type; - - notify_property_list_changed(); - ports_changed_notify(); -} - -StringName VisualScriptYieldSignal::get_signal() const { - return signal; -} - -void VisualScriptYieldSignal::set_base_path(const NodePath &p_type) { - if (base_path == p_type) { - return; - } - - base_path = p_type; - - notify_property_list_changed(); - ports_changed_notify(); -} - -NodePath VisualScriptYieldSignal::get_base_path() const { - return base_path; -} - -void VisualScriptYieldSignal::set_call_mode(CallMode p_mode) { - if (call_mode == p_mode) { - return; - } - - call_mode = p_mode; - - notify_property_list_changed(); - ports_changed_notify(); -} - -VisualScriptYieldSignal::CallMode VisualScriptYieldSignal::get_call_mode() const { - return call_mode; -} - -void VisualScriptYieldSignal::_validate_property(PropertyInfo &p_property) const { - if (p_property.name == "base_type") { - if (call_mode != CALL_MODE_INSTANCE) { - p_property.usage = PROPERTY_USAGE_NO_EDITOR; - } - } - - if (p_property.name == "node_path") { - if (call_mode != CALL_MODE_NODE_PATH) { - p_property.usage = PROPERTY_USAGE_NONE; - } else { - Node *bnode = _get_base_node(); - if (bnode) { - p_property.hint_string = bnode->get_path(); //convert to long string - } - } - } - - if (p_property.name == "signal") { - p_property.hint = PROPERTY_HINT_ENUM; - - List<MethodInfo> methods; - - ClassDB::get_signal_list(_get_base_type(), &methods); - - List<String> mstring; - for (const MethodInfo &E : methods) { - if (E.name.begins_with("_")) { - continue; - } - mstring.push_back(E.name.get_slice(":", 0)); - } - - mstring.sort(); - - String ml; - for (const String &E : mstring) { - if (!ml.is_empty()) { - ml += ","; - } - ml += E; - } - - p_property.hint_string = ml; - } -} - -void VisualScriptYieldSignal::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_base_type", "base_type"), &VisualScriptYieldSignal::set_base_type); - ClassDB::bind_method(D_METHOD("get_base_type"), &VisualScriptYieldSignal::get_base_type); - - ClassDB::bind_method(D_METHOD("set_signal", "signal"), &VisualScriptYieldSignal::set_signal); - ClassDB::bind_method(D_METHOD("get_signal"), &VisualScriptYieldSignal::get_signal); - - ClassDB::bind_method(D_METHOD("set_call_mode", "mode"), &VisualScriptYieldSignal::set_call_mode); - ClassDB::bind_method(D_METHOD("get_call_mode"), &VisualScriptYieldSignal::get_call_mode); - - ClassDB::bind_method(D_METHOD("set_base_path", "base_path"), &VisualScriptYieldSignal::set_base_path); - ClassDB::bind_method(D_METHOD("get_base_path"), &VisualScriptYieldSignal::get_base_path); - - String bt; - for (int i = 0; i < Variant::VARIANT_MAX; i++) { - if (i > 0) { - bt += ","; - } - - bt += Variant::get_type_name(Variant::Type(i)); - } - - ADD_PROPERTY(PropertyInfo(Variant::INT, "call_mode", PROPERTY_HINT_ENUM, "Self,Node Path,Instance"), "set_call_mode", "get_call_mode"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_type", PROPERTY_HINT_TYPE_STRING, "Object"), "set_base_type", "get_base_type"); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_path", PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE), "set_base_path", "get_base_path"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "signal"), "set_signal", "get_signal"); - - BIND_ENUM_CONSTANT(CALL_MODE_SELF); - BIND_ENUM_CONSTANT(CALL_MODE_NODE_PATH); - BIND_ENUM_CONSTANT(CALL_MODE_INSTANCE); -} - -class VisualScriptNodeInstanceYieldSignal : public VisualScriptNodeInstance { -public: - VisualScriptYieldSignal::CallMode call_mode; - NodePath node_path; - int output_args = 0; - StringName signal; - - VisualScriptYieldSignal *node = nullptr; - VisualScriptInstance *instance = nullptr; - - virtual int get_working_memory_size() const override { return 1; } - //virtual bool is_output_port_unsequenced(int p_idx) const { return false; } - //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; } - - virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override { - if (p_start_mode == START_MODE_RESUME_YIELD) { - return 0; //resuming yield - } else { - //yield - - Object *object = nullptr; - - switch (call_mode) { - case VisualScriptYieldSignal::CALL_MODE_SELF: { - object = instance->get_owner_ptr(); - - } break; - case VisualScriptYieldSignal::CALL_MODE_NODE_PATH: { - Node *node = Object::cast_to<Node>(instance->get_owner_ptr()); - if (!node) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = "Base object is not a Node!"; - return 0; - } - - Node *another = node->get_node(node_path); - if (!another) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = "Path does not lead Node!"; - return 0; - } - - object = another; - - } break; - case VisualScriptYieldSignal::CALL_MODE_INSTANCE: { - object = *p_inputs[0]; - if (!object) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - r_error_str = "Supplied instance input is null."; - return 0; - } - - } break; - } - - Ref<VisualScriptFunctionState> state; - state.instantiate(); - - state->connect_to_signal(object, signal, Array()); - - *p_working_mem = state; - - return STEP_YIELD_BIT; - } - } -}; - -VisualScriptNodeInstance *VisualScriptYieldSignal::instantiate(VisualScriptInstance *p_instance) { - VisualScriptNodeInstanceYieldSignal *instance = memnew(VisualScriptNodeInstanceYieldSignal); - instance->node = this; - instance->instance = p_instance; - instance->signal = signal; - instance->call_mode = call_mode; - instance->node_path = base_path; - instance->output_args = get_output_value_port_count(); - return instance; -} - -VisualScriptYieldSignal::VisualScriptYieldSignal() { - call_mode = CALL_MODE_SELF; - base_type = "Object"; -} - -template <VisualScriptYieldSignal::CallMode cmode> -static Ref<VisualScriptNode> create_yield_signal_node(const String &p_name) { - Ref<VisualScriptYieldSignal> node; - node.instantiate(); - node->set_call_mode(cmode); - return node; -} - -void register_visual_script_yield_nodes() { - VisualScriptLanguage::singleton->add_register_func("functions/wait/wait_frame", create_yield_node<VisualScriptYield::YIELD_FRAME>); - VisualScriptLanguage::singleton->add_register_func("functions/wait/wait_physics_frame", create_yield_node<VisualScriptYield::YIELD_PHYSICS_FRAME>); - VisualScriptLanguage::singleton->add_register_func("functions/wait/wait_time", create_yield_node<VisualScriptYield::YIELD_WAIT>); - - VisualScriptLanguage::singleton->add_register_func("functions/yield", create_yield_node<VisualScriptYield::YIELD_RETURN>); - VisualScriptLanguage::singleton->add_register_func("functions/yield_signal", create_node_generic<VisualScriptYieldSignal>); -} diff --git a/modules/visual_script/visual_script_yield_nodes.h b/modules/visual_script/visual_script_yield_nodes.h deleted file mode 100644 index 248f2b6e94..0000000000 --- a/modules/visual_script/visual_script_yield_nodes.h +++ /dev/null @@ -1,147 +0,0 @@ -/*************************************************************************/ -/* visual_script_yield_nodes.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef VISUAL_SCRIPT_YIELD_NODES_H -#define VISUAL_SCRIPT_YIELD_NODES_H - -#include "visual_script.h" - -class VisualScriptYield : public VisualScriptNode { - GDCLASS(VisualScriptYield, VisualScriptNode); - -public: - enum YieldMode { - YIELD_RETURN, - YIELD_FRAME, - YIELD_PHYSICS_FRAME, - YIELD_WAIT - - }; - -private: - YieldMode yield_mode; - double wait_time; - -protected: - void _validate_property(PropertyInfo &p_property) const; - - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_text() const override; - virtual String get_category() const override { return "functions"; } - - void set_yield_mode(YieldMode p_mode); - YieldMode get_yield_mode(); - - void set_wait_time(double p_time); - double get_wait_time(); - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptYield(); -}; -VARIANT_ENUM_CAST(VisualScriptYield::YieldMode) - -class VisualScriptYieldSignal : public VisualScriptNode { - GDCLASS(VisualScriptYieldSignal, VisualScriptNode); - -public: - enum CallMode { - CALL_MODE_SELF, - CALL_MODE_NODE_PATH, - CALL_MODE_INSTANCE, - - }; - -private: - CallMode call_mode; - StringName base_type; - NodePath base_path; - StringName signal; - - Node *_get_base_node() const; - StringName _get_base_type() const; - -protected: - void _validate_property(PropertyInfo &p_property) const; - - static void _bind_methods(); - -public: - virtual int get_output_sequence_port_count() const override; - virtual bool has_input_sequence_port() const override; - - virtual String get_output_sequence_port_text(int p_port) const override; - - virtual int get_input_value_port_count() const override; - virtual int get_output_value_port_count() const override; - - virtual PropertyInfo get_input_value_port_info(int p_idx) const override; - virtual PropertyInfo get_output_value_port_info(int p_idx) const override; - - virtual String get_caption() const override; - virtual String get_text() const override; - virtual String get_category() const override { return "functions"; } - - void set_base_type(const StringName &p_type); - StringName get_base_type() const; - - void set_signal(const StringName &p_type); - StringName get_signal() const; - - void set_base_path(const NodePath &p_type); - NodePath get_base_path() const; - - void set_call_mode(CallMode p_mode); - CallMode get_call_mode() const; - - virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; - - VisualScriptYieldSignal(); -}; - -VARIANT_ENUM_CAST(VisualScriptYieldSignal::CallMode); - -void register_visual_script_yield_nodes(); - -#endif // VISUAL_SCRIPT_YIELD_NODES_H |