2017-03-05 14:47:28 +00:00
/*************************************************************************/
/* visual_script.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 12:16:55 +00:00
/* https://godotengine.org */
2017-03-05 14:47:28 +00:00
/*************************************************************************/
2022-01-03 20:27:34 +00:00
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
2017-03-05 14:47:28 +00:00
/* */
/* 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. */
/*************************************************************************/
2018-01-04 23:50:27 +00:00
# ifndef VISUAL_SCRIPT_H
# define VISUAL_SCRIPT_H
2016-08-02 22:11:05 +00:00
2020-02-27 02:30:20 +00:00
# include "core/debugger/engine_debugger.h"
# include "core/debugger/script_debugger.h"
2020-11-29 03:42:06 +00:00
# include "core/doc_data.h"
2020-11-07 22:33:38 +00:00
# include "core/object/script_language.h"
2018-09-11 16:13:45 +00:00
# include "core/os/thread.h"
2022-05-19 15:00:06 +00:00
# include "core/templates/rb_set.h"
2016-08-02 22:11:05 +00:00
2016-08-06 01:46:45 +00:00
class VisualScriptInstance ;
2016-08-02 22:11:05 +00:00
class VisualScriptNodeInstance ;
class VisualScript ;
class VisualScriptNode : public Resource {
2019-03-19 18:35:57 +00:00
GDCLASS ( VisualScriptNode , Resource ) ;
2016-08-02 22:11:05 +00:00
2017-03-05 15:44:50 +00:00
friend class VisualScript ;
2016-08-02 22:11:05 +00:00
2020-06-17 15:39:25 +00:00
Ref < VisualScript > script_used ;
2016-08-04 01:06:39 +00:00
Array default_input_values ;
2021-02-08 09:57:18 +00:00
bool breakpoint = false ;
2016-08-04 01:06:39 +00:00
void _set_default_input_values ( Array p_values ) ;
Array _get_default_input_values ( ) const ;
2016-08-25 20:45:20 +00:00
void validate_input_default_values ( ) ;
2016-08-04 01:06:39 +00:00
2017-03-05 15:44:50 +00:00
protected :
2016-08-04 01:06:39 +00:00
void ports_changed_notify ( ) ;
2016-08-02 22:11:05 +00:00
static void _bind_methods ( ) ;
2017-03-05 15:44:50 +00:00
public :
2016-08-02 22:11:05 +00:00
Ref < VisualScript > get_visual_script ( ) const ;
2017-03-05 15:44:50 +00:00
virtual int get_output_sequence_port_count ( ) const = 0 ;
virtual bool has_input_sequence_port ( ) const = 0 ;
2016-08-02 22:11:05 +00:00
2017-03-05 15:44:50 +00:00
virtual String get_output_sequence_port_text ( int p_port ) const = 0 ;
2016-08-02 22:11:05 +00:00
2016-09-01 23:04:17 +00:00
virtual bool has_mixed_input_and_sequence_ports ( ) const { return false ; }
2017-03-05 15:44:50 +00:00
virtual int get_input_value_port_count ( ) const = 0 ;
virtual int get_output_value_port_count ( ) const = 0 ;
2016-08-02 22:11:05 +00:00
2017-03-05 15:44:50 +00:00
virtual PropertyInfo get_input_value_port_info ( int p_idx ) const = 0 ;
virtual PropertyInfo get_output_value_port_info ( int p_idx ) const = 0 ;
2016-08-02 22:11:05 +00:00
2017-03-05 15:44:50 +00:00
void set_default_input_value ( int p_port , const Variant & p_value ) ;
2016-08-04 01:06:39 +00:00
Variant get_default_input_value ( int p_port ) const ;
2017-03-05 15:44:50 +00:00
virtual String get_caption ( ) const = 0 ;
2018-04-29 23:28:31 +00:00
virtual String get_text ( ) const ;
2017-03-05 15:44:50 +00:00
virtual String get_category ( ) const = 0 ;
2016-08-02 22:11:05 +00:00
2020-06-17 15:39:25 +00:00
// Used by editor, this is not really saved.
2016-08-06 22:00:54 +00:00
void set_breakpoint ( bool p_breakpoint ) ;
bool is_breakpoint ( ) const ;
2021-06-17 22:03:09 +00:00
virtual VisualScriptNodeInstance * instantiate ( VisualScriptInstance * p_instance ) = 0 ;
2016-08-02 22:11:05 +00:00
2016-08-31 02:44:14 +00:00
struct TypeGuess {
2021-02-08 09:57:18 +00:00
Variant : : Type type = Variant : : NIL ;
2017-07-01 00:30:17 +00:00
StringName gdclass ;
2016-09-03 17:58:23 +00:00
Ref < Script > script ;
2016-08-31 02:44:14 +00:00
} ;
2017-03-05 15:44:50 +00:00
virtual TypeGuess guess_output_type ( TypeGuess * p_inputs , int p_output ) const ;
2016-08-31 02:44:14 +00:00
2016-08-06 22:00:54 +00:00
VisualScriptNode ( ) ;
2016-08-02 22:11:05 +00:00
} ;
class VisualScriptNodeInstance {
2017-03-05 15:44:50 +00:00
friend class VisualScriptInstance ;
2020-06-17 15:39:25 +00:00
friend class VisualScriptLanguage ; // For debugger.
2016-08-06 01:46:45 +00:00
2020-06-17 15:39:25 +00:00
enum { // Input argument addressing.
2017-03-05 15:44:50 +00:00
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)
2016-08-06 01:46:45 +00:00
} ;
2021-02-08 09:57:18 +00:00
int id = 0 ;
int sequence_index = 0 ;
VisualScriptNodeInstance * * sequence_outputs = nullptr ;
int sequence_output_count = 0 ;
2017-03-05 15:44:50 +00:00
Vector < VisualScriptNodeInstance * > dependencies ;
2021-02-08 09:57:18 +00:00
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 ;
2016-08-06 01:46:45 +00:00
2021-02-08 09:57:18 +00:00
VisualScriptNode * base = nullptr ;
2016-08-06 01:46:45 +00:00
2016-08-02 22:11:05 +00:00
public :
2016-08-07 22:22:33 +00:00
enum StartMode {
START_MODE_BEGIN_SEQUENCE ,
START_MODE_CONTINUE_SEQUENCE ,
START_MODE_RESUME_YIELD
} ;
2016-08-06 01:46:45 +00:00
enum {
2017-03-05 15:44:50 +00:00
STEP_SHIFT = 1 < < 24 ,
STEP_MASK = STEP_SHIFT - 1 ,
2020-06-17 15:39:25 +00:00
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)
2016-08-06 01:46:45 +00:00
2020-06-17 15:39:25 +00:00
FLOW_STACK_PUSHED_BIT = 1 < < 30 , // in flow stack, means bit was pushed (must go back here if end of sequence)
2017-03-05 15:44:50 +00:00
FLOW_STACK_MASK = FLOW_STACK_PUSHED_BIT - 1
2016-08-06 01:46:45 +00:00
} ;
2017-03-05 15:44:50 +00:00
_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 ; }
2016-08-06 01:46:45 +00:00
2017-03-05 15:44:50 +00:00
_FORCE_INLINE_ int get_id ( ) const { return id ; }
2016-08-06 01:46:45 +00:00
virtual int get_working_memory_size ( ) const { return 0 ; }
2016-08-02 22:11:05 +00:00
2020-06-17 15:39:25 +00:00
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.
2016-08-02 22:11:05 +00:00
2017-03-05 15:44:50 +00:00
Ref < VisualScriptNode > get_base_node ( ) { return Ref < VisualScriptNode > ( base ) ; }
2016-08-06 01:46:45 +00:00
VisualScriptNodeInstance ( ) ;
2016-08-02 22:11:05 +00:00
virtual ~ VisualScriptNodeInstance ( ) ;
} ;
class VisualScript : public Script {
2019-03-19 18:35:57 +00:00
GDCLASS ( VisualScript , Script ) ;
2016-08-02 22:11:05 +00:00
RES_BASE_EXTENSION ( " vs " ) ;
public :
struct SequenceConnection {
union {
struct {
uint64_t from_node : 24 ;
uint64_t from_output : 16 ;
uint64_t to_node : 24 ;
} ;
2021-02-08 09:57:18 +00:00
uint64_t id = 0 ;
2016-08-02 22:11:05 +00:00
} ;
2017-03-05 15:44:50 +00:00
bool operator < ( const SequenceConnection & p_connection ) const {
return id < p_connection . id ;
2016-08-02 22:11:05 +00:00
}
} ;
struct DataConnection {
union {
struct {
uint64_t from_node : 24 ;
uint64_t from_port : 8 ;
uint64_t to_node : 24 ;
uint64_t to_port : 8 ;
} ;
2021-02-08 09:57:18 +00:00
uint64_t id = 0 ;
2016-08-02 22:11:05 +00:00
} ;
2017-03-05 15:44:50 +00:00
bool operator < ( const DataConnection & p_connection ) const {
return id < p_connection . id ;
2016-08-02 22:11:05 +00:00
}
} ;
private :
2017-03-05 15:44:50 +00:00
friend class VisualScriptInstance ;
2016-08-02 22:11:05 +00:00
StringName base_type ;
struct Argument {
String name ;
2021-02-08 09:57:18 +00:00
Variant : : Type type = Variant : : Type : : NIL ;
2016-08-02 22:11:05 +00:00
} ;
2020-06-17 15:39:25 +00:00
struct NodeData {
Point2 pos ;
Ref < VisualScriptNode > node ;
} ;
2016-08-02 22:11:05 +00:00
2020-06-17 15:39:25 +00:00
HashMap < int , NodeData > nodes ; // Can be a sparse map.
2016-08-02 22:11:05 +00:00
2022-05-13 13:04:37 +00:00
RBSet < SequenceConnection > sequence_connections ;
RBSet < DataConnection > data_connections ;
2016-08-02 22:11:05 +00:00
2020-06-17 15:39:25 +00:00
Vector2 scroll ;
2016-08-06 22:00:54 +00:00
2020-06-17 15:39:25 +00:00
struct Function {
int func_id ;
Function ( ) { func_id = - 1 ; }
2016-08-02 22:11:05 +00:00
} ;
struct Variable {
PropertyInfo info ;
Variant default_value ;
2021-02-08 09:57:18 +00:00
bool _export = false ;
2020-06-17 15:39:25 +00:00
// Add getter & setter options here.
2016-08-02 22:11:05 +00:00
} ;
2020-06-17 15:39:25 +00:00
HashMap < StringName , Function > functions ;
HashMap < StringName , Variable > variables ;
2022-05-13 13:04:37 +00:00
HashMap < StringName , Vector < Argument > > custom_signals ;
2021-09-03 17:40:47 +00:00
Vector < Multiplayer : : RPCConfig > rpc_functions ;
2016-08-02 22:11:05 +00:00
2022-05-13 13:04:37 +00:00
HashMap < Object * , VisualScriptInstance * > instances ;
2016-08-06 01:46:45 +00:00
2019-07-26 20:00:23 +00:00
bool is_tool_script ;
2016-08-06 01:46:45 +00:00
# ifdef TOOLS_ENABLED
2022-05-13 13:04:37 +00:00
RBSet < PlaceHolderScriptInstance * > placeholders ;
2020-06-17 15:39:25 +00:00
// void _update_placeholder(PlaceHolderScriptInstance *p_placeholder);
2020-07-10 10:34:39 +00:00
virtual void _placeholder_erased ( PlaceHolderScriptInstance * p_placeholder ) override ;
2016-08-06 01:46:45 +00:00
void _update_placeholders ( ) ;
# endif
2017-03-05 15:44:50 +00:00
void _set_variable_info ( const StringName & p_name , const Dictionary & p_info ) ;
Dictionary _get_variable_info ( const StringName & p_name ) const ;
2016-08-02 22:11:05 +00:00
2017-03-05 15:44:50 +00:00
void _set_data ( const Dictionary & p_data ) ;
2016-08-02 22:11:05 +00:00
Dictionary _get_data ( ) const ;
protected :
void _node_ports_changed ( int p_id ) ;
static void _bind_methods ( ) ;
2017-03-05 15:44:50 +00:00
public :
2020-07-10 10:34:39 +00:00
bool inherits_script ( const Ref < Script > & p_script ) const override ;
2020-04-20 22:06:00 +00:00
2020-06-17 15:39:25 +00:00
void set_scroll ( const Vector2 & p_scroll ) ;
Vector2 get_scroll ( ) const ;
void add_function ( const StringName & p_name , int p_func_node_id ) ;
2017-03-05 15:44:50 +00:00
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 ) ;
2016-08-02 22:11:05 +00:00
void get_function_list ( List < StringName > * r_functions ) const ;
2017-03-05 15:44:50 +00:00
int get_function_node_id ( const StringName & p_name ) const ;
2019-07-26 20:00:23 +00:00
void set_tool_enabled ( bool p_enabled ) ;
2017-03-05 15:44:50 +00:00
2020-06-17 15:39:25 +00:00
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 ;
2022-05-13 13:04:37 +00:00
RBSet < int > get_output_sequence_ports_connected ( int from_node ) ;
2020-06-17 15:39:25 +00:00
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 ;
2017-03-05 15:44:50 +00:00
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 ;
2016-08-23 22:29:07 +00:00
void get_variable_list ( List < StringName > * r_variables ) const ;
2017-03-05 15:44:50 +00:00
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 ) ;
2022-05-13 13:04:37 +00:00
RBSet < int > get_output_sequence_ports_connected ( const String & edited_func , int from_node ) ;
2016-08-02 22:11:05 +00:00
void get_custom_signal_list ( List < StringName > * r_custom_signals ) const ;
int get_available_id ( ) const ;
2017-03-05 15:44:50 +00:00
void set_instance_base_type ( const StringName & p_type ) ;
2016-08-02 22:11:05 +00:00
2021-06-17 22:03:09 +00:00
virtual bool can_instantiate ( ) const override ;
2016-08-02 22:11:05 +00:00
2020-07-10 10:34:39 +00:00
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 ;
2016-08-02 22:11:05 +00:00
2020-07-10 10:34:39 +00:00
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 ;
2016-08-02 22:11:05 +00:00
2020-11-29 02:37:57 +00:00
# ifdef TOOLS_ENABLED
2022-03-26 15:48:43 +00:00
virtual Vector < DocData : : ClassDoc > get_documentation ( ) const override {
Vector < DocData : : ClassDoc > docs ;
2020-11-29 02:37:57 +00:00
return docs ;
}
# endif // TOOLS_ENABLED
2020-07-10 10:34:39 +00:00
virtual bool is_tool ( ) const override ;
virtual bool is_valid ( ) const override ;
2016-08-02 22:11:05 +00:00
2020-07-10 10:34:39 +00:00
virtual ScriptLanguage * get_language ( ) const override ;
2016-08-02 22:11:05 +00:00
2020-07-10 10:34:39 +00:00
virtual bool has_script_signal ( const StringName & p_signal ) const override ;
virtual void get_script_signal_list ( List < MethodInfo > * r_signals ) const override ;
2016-08-02 22:11:05 +00:00
2020-07-10 10:34:39 +00:00
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 ;
2016-08-02 22:11:05 +00:00
2020-07-10 10:34:39 +00:00
virtual bool has_method ( const StringName & p_method ) const override ;
virtual MethodInfo get_method_info ( const StringName & p_method ) const override ;
2016-08-08 04:21:22 +00:00
2020-07-10 10:34:39 +00:00
virtual void get_script_property_list ( List < PropertyInfo > * p_list ) const override ;
2016-08-08 04:21:22 +00:00
2020-07-10 10:34:39 +00:00
virtual int get_member_line ( const StringName & p_member ) const override ;
2017-04-15 17:48:10 +00:00
2021-09-03 17:40:47 +00:00
virtual const Vector < Multiplayer : : RPCConfig > get_rpc_methods ( ) const override ;
2020-02-12 10:51:50 +00:00
2016-09-05 21:50:30 +00:00
# ifdef TOOLS_ENABLED
2016-08-31 20:58:51 +00:00
virtual bool are_subnodes_edited ( ) const ;
2016-09-05 21:50:30 +00:00
# endif
2016-08-02 22:11:05 +00:00
VisualScript ( ) ;
~ VisualScript ( ) ;
} ;
2016-08-06 01:46:45 +00:00
class VisualScriptInstance : public ScriptInstance {
2021-02-08 09:57:18 +00:00
Object * owner = nullptr ;
2016-08-06 01:46:45 +00:00
Ref < VisualScript > script ;
2022-05-13 13:04:37 +00:00
HashMap < StringName , Variant > variables ; // Using variable path, not script.
HashMap < int , VisualScriptNodeInstance * > instances ;
2016-08-06 01:46:45 +00:00
struct Function {
2021-02-08 09:57:18 +00:00
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 ;
2016-08-06 01:46:45 +00:00
} ;
2022-05-13 13:04:37 +00:00
HashMap < StringName , Function > functions ;
2016-08-06 01:46:45 +00:00
Vector < Variant > default_values ;
2021-02-08 09:57:18 +00:00
int max_input_args = 0 ;
int max_output_args = 0 ;
2016-08-06 01:46:45 +00:00
2016-08-06 22:00:54 +00:00
StringName source ;
2016-08-06 01:46:45 +00:00
2020-02-19 19:27:19 +00:00
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 ) ;
2016-08-07 22:22:33 +00:00
2020-06-17 15:39:25 +00:00
friend class VisualScriptFunctionState ; // For yield.
friend class VisualScriptLanguage ; // For debugger.
2016-08-06 01:46:45 +00:00
public :
2017-03-05 15:44:50 +00:00
virtual bool set ( const StringName & p_name , const Variant & p_value ) ;
virtual bool get ( const StringName & p_name , Variant & r_ret ) const ;
2016-08-06 01:46:45 +00:00
virtual void get_property_list ( List < PropertyInfo > * p_properties ) const ;
2020-04-01 23:20:12 +00:00
virtual Variant : : Type get_property_type ( const StringName & p_name , bool * r_is_valid = nullptr ) const ;
2016-08-06 01:46:45 +00:00
virtual void get_method_list ( List < MethodInfo > * p_list ) const ;
2017-03-05 15:44:50 +00:00
virtual bool has_method ( const StringName & p_method ) const ;
2022-03-09 13:58:40 +00:00
virtual Variant callp ( const StringName & p_method , const Variant * * p_args , int p_argcount , Callable : : CallError & r_error ) ;
2016-08-06 01:46:45 +00:00
virtual void notification ( int p_notification ) ;
2019-04-10 05:07:40 +00:00
String to_string ( bool * r_valid ) ;
2016-08-06 01:46:45 +00:00
2017-03-05 15:44:50 +00:00
bool set_variable ( const StringName & p_variable , const Variant & p_value ) {
2022-05-13 13:04:37 +00:00
HashMap < StringName , Variant > : : Iterator E = variables . find ( p_variable ) ;
2020-05-14 14:41:43 +00:00
if ( ! E ) {
2016-08-06 01:46:45 +00:00
return false ;
2020-05-14 14:41:43 +00:00
}
2016-08-06 01:46:45 +00:00
2022-05-13 13:04:37 +00:00
E - > value = p_value ;
2016-08-06 01:46:45 +00:00
return true ;
}
2017-03-05 15:44:50 +00:00
bool get_variable ( const StringName & p_variable , Variant * r_variable ) const {
2022-05-13 13:04:37 +00:00
HashMap < StringName , Variant > : : ConstIterator E = variables . find ( p_variable ) ;
2020-05-14 14:41:43 +00:00
if ( ! E ) {
2016-08-06 01:46:45 +00:00
return false ;
2020-05-14 14:41:43 +00:00
}
2016-08-06 01:46:45 +00:00
2022-05-13 13:04:37 +00:00
* r_variable = E - > value ;
2016-08-06 01:46:45 +00:00
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 ; }
2017-03-05 15:44:50 +00:00
void create ( const Ref < VisualScript > & p_script , Object * p_owner ) ;
2016-08-06 01:46:45 +00:00
virtual ScriptLanguage * get_language ( ) ;
2021-09-03 17:40:47 +00:00
virtual const Vector < Multiplayer : : RPCConfig > get_rpc_methods ( ) const ;
2016-08-19 19:48:08 +00:00
2016-08-06 01:46:45 +00:00
VisualScriptInstance ( ) ;
~ VisualScriptInstance ( ) ;
} ;
2021-06-04 16:03:15 +00:00
class VisualScriptFunctionState : public RefCounted {
GDCLASS ( VisualScriptFunctionState , RefCounted ) ;
2017-03-05 15:44:50 +00:00
friend class VisualScriptInstance ;
2016-08-07 22:22:33 +00:00
ObjectID instance_id ;
ObjectID script_id ;
2021-02-08 09:57:18 +00:00
VisualScriptInstance * instance = nullptr ;
2016-08-07 22:22:33 +00:00
StringName function ;
Vector < uint8_t > stack ;
2021-02-08 09:57:18 +00:00
int working_mem_index = 0 ;
int variant_stack_size = 0 ;
VisualScriptNodeInstance * node = nullptr ;
int flow_stack_pos = 0 ;
int pass = 0 ;
2016-08-07 22:22:33 +00:00
2020-02-19 19:27:19 +00:00
Variant _signal_callback ( const Variant * * p_args , int p_argcount , Callable : : CallError & r_error ) ;
2017-03-05 15:44:50 +00:00
2016-08-07 22:22:33 +00:00
protected :
static void _bind_methods ( ) ;
2017-03-05 15:44:50 +00:00
public :
void connect_to_signal ( Object * p_obj , const String & p_signal , Array p_binds ) ;
2016-08-07 22:22:33 +00:00
bool is_valid ( ) const ;
Variant resume ( Array p_args ) ;
VisualScriptFunctionState ( ) ;
~ VisualScriptFunctionState ( ) ;
} ;
2017-03-05 15:44:50 +00:00
typedef Ref < VisualScriptNode > ( * VisualScriptNodeRegisterFunc ) ( const String & p_type ) ;
2016-08-02 22:11:05 +00:00
class VisualScriptLanguage : public ScriptLanguage {
2022-05-13 13:04:37 +00:00
HashMap < String , VisualScriptNodeRegisterFunc > register_funcs ;
2016-08-06 01:46:45 +00:00
2016-08-06 22:00:54 +00:00
struct CallLevel {
2021-02-08 09:57:18 +00:00
Variant * stack = nullptr ;
Variant * * work_mem = nullptr ;
const StringName * function = nullptr ;
VisualScriptInstance * instance = nullptr ;
int * current_id = nullptr ;
2016-08-06 22:00:54 +00:00
} ;
2021-02-08 09:57:18 +00:00
int _debug_parse_err_node = - 1 ;
String _debug_parse_err_file = " " ;
2016-08-06 22:00:54 +00:00
String _debug_error ;
2021-02-08 09:57:18 +00:00
int _debug_call_stack_pos = 0 ;
2016-08-06 22:00:54 +00:00
int _debug_max_call_stack ;
2022-04-04 13:06:57 +00:00
CallLevel * _call_stack = nullptr ;
2016-08-06 01:46:45 +00:00
2016-08-02 22:11:05 +00:00
public :
2021-02-08 09:57:18 +00:00
StringName notification = " _notification " ;
2016-08-08 00:22:14 +00:00
StringName _get_output_port_unsequenced ;
2021-02-08 09:57:18 +00:00
StringName _step = " _step " ;
StringName _subcall = " _subcall " ;
2016-08-02 22:11:05 +00:00
2017-03-05 15:44:50 +00:00
static VisualScriptLanguage * singleton ;
2016-08-02 22:11:05 +00:00
2020-02-26 10:28:13 +00:00
Mutex lock ;
2016-08-06 01:46:45 +00:00
2017-03-05 15:44:50 +00:00
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 ) ;
2016-08-06 22:00:54 +00:00
2017-03-05 15:44:50 +00:00
_FORCE_INLINE_ void enter_function ( VisualScriptInstance * p_instance , const StringName * p_function , Variant * p_stack , Variant * * p_work_mem , int * current_id ) {
2020-05-14 14:41:43 +00:00
if ( Thread : : get_main_id ( ) ! = Thread : : get_caller_id ( ) ) {
2020-06-17 15:39:25 +00:00
return ; // No support for other threads than main for now.
2020-05-14 14:41:43 +00:00
}
2016-08-06 22:00:54 +00:00
2020-05-14 14:41:43 +00:00
if ( EngineDebugger : : get_script_debugger ( ) - > get_lines_left ( ) > 0 & & EngineDebugger : : get_script_debugger ( ) - > get_depth ( ) > = 0 ) {
2020-02-27 02:30:20 +00:00
EngineDebugger : : get_script_debugger ( ) - > set_depth ( EngineDebugger : : get_script_debugger ( ) - > get_depth ( ) + 1 ) ;
2020-05-14 14:41:43 +00:00
}
2016-08-06 22:00:54 +00:00
2017-03-05 15:44:50 +00:00
if ( _debug_call_stack_pos > = _debug_max_call_stack ) {
2020-06-17 15:39:25 +00:00
// Stack overflow.
2022-05-28 21:11:37 +00:00
_debug_error = vformat ( " Stack overflow (stack size: %s). Check for infinite recursion in your script. " , _debug_max_call_stack ) ;
2020-02-27 02:30:20 +00:00
EngineDebugger : : get_script_debugger ( ) - > debug ( this ) ;
2017-03-05 15:44:50 +00:00
return ;
}
2016-08-06 22:00:54 +00:00
2017-03-05 15:44:50 +00:00
_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 + + ;
2016-08-06 22:00:54 +00:00
}
_FORCE_INLINE_ void exit_function ( ) {
2020-05-14 14:41:43 +00:00
if ( Thread : : get_main_id ( ) ! = Thread : : get_caller_id ( ) ) {
2020-06-17 15:39:25 +00:00
return ; // No support for other threads than main for now.
2020-05-14 14:41:43 +00:00
}
2016-08-06 22:00:54 +00:00
2020-05-14 14:41:43 +00:00
if ( EngineDebugger : : get_script_debugger ( ) - > get_lines_left ( ) > 0 & & EngineDebugger : : get_script_debugger ( ) - > get_depth ( ) > = 0 ) {
2020-02-27 02:30:20 +00:00
EngineDebugger : : get_script_debugger ( ) - > set_depth ( EngineDebugger : : get_script_debugger ( ) - > get_depth ( ) - 1 ) ;
2020-05-14 14:41:43 +00:00
}
2016-08-06 22:00:54 +00:00
2017-03-05 15:44:50 +00:00
if ( _debug_call_stack_pos = = 0 ) {
2022-05-28 21:11:37 +00:00
_debug_error = " Stack underflow (engine bug), please report. " ;
2020-02-27 02:30:20 +00:00
EngineDebugger : : get_script_debugger ( ) - > debug ( this ) ;
2017-03-05 15:44:50 +00:00
return ;
}
2016-08-06 22:00:54 +00:00
2017-03-05 15:44:50 +00:00
_debug_call_stack_pos - - ;
2016-08-06 22:00:54 +00:00
}
//////////////////////////////////////
2021-10-11 09:30:59 +00:00
virtual String get_name ( ) const override ;
2016-08-02 22:11:05 +00:00
/* LANGUAGE FUNCTIONS */
2021-10-11 09:30:59 +00:00
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 ;
2016-08-02 22:11:05 +00:00
/* EDITOR FUNCTIONS */
2021-10-11 09:30:59 +00:00
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 ;
2022-05-19 15:00:06 +00:00
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 ;
2021-10-11 09:30:59 +00:00
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 ;
2016-08-02 22:11:05 +00:00
/* DEBUGGER FUNCTIONS */
2021-10-11 09:30:59 +00:00
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 ;
2016-08-02 22:11:05 +00:00
/* LOADER FUNCTIONS */
2021-10-11 09:30:59 +00:00
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 ;
2022-07-04 15:56:34 +00:00
virtual void get_public_annotations ( List < MethodInfo > * p_annotations ) const override ;
2016-08-02 22:11:05 +00:00
2021-10-11 09:30:59 +00:00
virtual void profiling_start ( ) override ;
virtual void profiling_stop ( ) override ;
2016-08-02 22:11:05 +00:00
2021-10-11 09:30:59 +00:00
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 ;
2016-08-02 22:11:05 +00:00
2017-03-05 15:44:50 +00:00
void add_register_func ( const String & p_name , VisualScriptNodeRegisterFunc p_func ) ;
2017-11-15 15:57:24 +00:00
void remove_register_func ( const String & p_name ) ;
2017-03-05 15:44:50 +00:00
Ref < VisualScriptNode > create_node_from_name ( const String & p_name ) ;
2016-08-02 22:11:05 +00:00
void get_registered_node_names ( List < String > * r_names ) ;
VisualScriptLanguage ( ) ;
2016-08-06 01:46:45 +00:00
~ VisualScriptLanguage ( ) ;
2016-08-02 22:11:05 +00:00
} ;
2020-06-17 15:39:25 +00:00
// Aid for registering.
2017-03-05 15:44:50 +00:00
template < class T >
static Ref < VisualScriptNode > create_node_generic ( const String & p_name ) {
2016-08-02 22:11:05 +00:00
Ref < T > node ;
2021-06-17 22:03:09 +00:00
node . instantiate ( ) ;
2016-08-02 22:11:05 +00:00
return node ;
}
2018-01-04 23:50:27 +00:00
# endif // VISUAL_SCRIPT_H