2017-03-05 15:47:28 +01:00
/*************************************************************************/
/* visual_script.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 14:16:55 +02:00
/* https://godotengine.org */
2017-03-05 15:47:28 +01:00
/*************************************************************************/
2021-01-01 20:13:46 +01:00
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
2017-03-05 15:47:28 +01: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-05 00:50:27 +01:00
# ifndef VISUAL_SCRIPT_H
# define VISUAL_SCRIPT_H
2016-08-03 00:11:05 +02:00
2018-09-11 18:13:45 +02:00
# include "core/os/thread.h"
# include "core/script_language.h"
2016-08-03 00:11:05 +02:00
2016-08-06 03:46:45 +02:00
class VisualScriptInstance ;
2016-08-03 00:11:05 +02:00
class VisualScriptNodeInstance ;
class VisualScript ;
class VisualScriptNode : public Resource {
2019-03-19 19:35:57 +01:00
GDCLASS ( VisualScriptNode , Resource ) ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
friend class VisualScript ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
Set < VisualScript * > scripts_used ;
2016-08-04 03:06:39 +02:00
Array default_input_values ;
2016-08-07 00:00:54 +02:00
bool breakpoint ;
2016-08-04 03:06:39 +02:00
void _set_default_input_values ( Array p_values ) ;
Array _get_default_input_values ( ) const ;
2016-08-25 22:45:20 +02:00
void validate_input_default_values ( ) ;
2016-08-04 03:06:39 +02:00
2017-03-05 16:44:50 +01:00
protected :
2016-08-04 03:06:39 +02:00
void ports_changed_notify ( ) ;
2016-08-03 00:11:05 +02:00
static void _bind_methods ( ) ;
2017-03-05 16:44:50 +01:00
public :
2016-08-03 00:11:05 +02:00
Ref < VisualScript > get_visual_script ( ) const ;
2017-03-05 16:44:50 +01:00
virtual int get_output_sequence_port_count ( ) const = 0 ;
virtual bool has_input_sequence_port ( ) const = 0 ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
virtual String get_output_sequence_port_text ( int p_port ) const = 0 ;
2016-08-03 00:11:05 +02:00
2016-09-02 01:04:17 +02:00
virtual bool has_mixed_input_and_sequence_ports ( ) const { return false ; }
2017-03-05 16:44:50 +01:00
virtual int get_input_value_port_count ( ) const = 0 ;
virtual int get_output_value_port_count ( ) const = 0 ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01: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-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
void set_default_input_value ( int p_port , const Variant & p_value ) ;
2016-08-04 03:06:39 +02:00
Variant get_default_input_value ( int p_port ) const ;
2017-03-05 16:44:50 +01:00
virtual String get_caption ( ) const = 0 ;
2018-04-30 01:28:31 +02:00
virtual String get_text ( ) const ;
2017-03-05 16:44:50 +01:00
virtual String get_category ( ) const = 0 ;
2016-08-03 00:11:05 +02:00
2016-08-07 00:00:54 +02:00
//used by editor, this is not really saved
void set_breakpoint ( bool p_breakpoint ) ;
bool is_breakpoint ( ) const ;
2017-03-05 16:44:50 +01:00
virtual VisualScriptNodeInstance * instance ( VisualScriptInstance * p_instance ) = 0 ;
2016-08-03 00:11:05 +02:00
2016-08-31 04:44:14 +02:00
struct TypeGuess {
Variant : : Type type ;
2017-07-01 02:30:17 +02:00
StringName gdclass ;
2016-09-03 19:58:23 +02:00
Ref < Script > script ;
2016-08-31 04:44:14 +02:00
2017-03-05 16:44:50 +01:00
TypeGuess ( ) {
type = Variant : : NIL ;
}
2016-08-31 04:44:14 +02:00
} ;
2017-03-05 16:44:50 +01:00
virtual TypeGuess guess_output_type ( TypeGuess * p_inputs , int p_output ) const ;
2016-08-31 04:44:14 +02:00
2016-08-07 00:00:54 +02:00
VisualScriptNode ( ) ;
2016-08-03 00:11:05 +02:00
} ;
class VisualScriptNodeInstance {
2017-03-05 16:44:50 +01:00
friend class VisualScriptInstance ;
friend class VisualScriptLanguage ; //for debugger
2016-08-06 03:46:45 +02:00
enum { //input argument addressing
2017-03-05 16:44:50 +01: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 03:46:45 +02:00
} ;
int id ;
int sequence_index ;
VisualScriptNodeInstance * * sequence_outputs ;
int sequence_output_count ;
2017-03-05 16:44:50 +01:00
Vector < VisualScriptNodeInstance * > dependencies ;
2016-08-06 03:46:45 +02:00
int * input_ports ;
int input_port_count ;
int * output_ports ;
int output_port_count ;
int working_mem_idx ;
2016-08-31 04:44:14 +02:00
int pass_idx ;
2016-08-06 03:46:45 +02:00
VisualScriptNode * base ;
2016-08-03 00:11:05 +02:00
public :
2016-08-08 00:22:33 +02:00
enum StartMode {
START_MODE_BEGIN_SEQUENCE ,
START_MODE_CONTINUE_SEQUENCE ,
START_MODE_RESUME_YIELD
} ;
2016-08-06 03:46:45 +02:00
enum {
2017-03-05 16:44:50 +01:00
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)
2016-08-06 03:46:45 +02:00
2017-03-05 16:44:50 +01:00
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
2016-08-06 03:46:45 +02:00
} ;
2017-03-05 16:44:50 +01: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 03:46:45 +02:00
2017-03-05 16:44:50 +01:00
_FORCE_INLINE_ int get_id ( ) const { return id ; }
2016-08-06 03:46:45 +02:00
virtual int get_working_memory_size ( ) const { return 0 ; }
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
virtual int step ( const Variant * * p_inputs , Variant * * p_outputs , StartMode p_start_mode , Variant * p_working_mem , Variant : : CallError & r_error , String & r_error_str ) = 0 ; //do a step, return which sequence port to go out
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
Ref < VisualScriptNode > get_base_node ( ) { return Ref < VisualScriptNode > ( base ) ; }
2016-08-06 03:46:45 +02:00
VisualScriptNodeInstance ( ) ;
2016-08-03 00:11:05 +02:00
virtual ~ VisualScriptNodeInstance ( ) ;
} ;
class VisualScript : public Script {
2019-03-19 19:35:57 +01:00
GDCLASS ( VisualScript , Script ) ;
2016-08-03 00:11:05 +02: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 ;
} ;
uint64_t id ;
} ;
2017-03-05 16:44:50 +01:00
bool operator < ( const SequenceConnection & p_connection ) const {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
return id < p_connection . id ;
2016-08-03 00:11:05 +02: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 ;
} ;
uint64_t id ;
} ;
2017-03-05 16:44:50 +01:00
bool operator < ( const DataConnection & p_connection ) const {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
return id < p_connection . id ;
2016-08-03 00:11:05 +02:00
}
} ;
private :
2017-03-05 16:44:50 +01:00
friend class VisualScriptInstance ;
2016-08-03 00:11:05 +02:00
StringName base_type ;
struct Argument {
String name ;
Variant : : Type type ;
} ;
struct Function {
struct NodeData {
Point2 pos ;
Ref < VisualScriptNode > node ;
} ;
2017-03-05 16:44:50 +01:00
Map < int , NodeData > nodes ;
2016-08-03 00:11:05 +02:00
Set < SequenceConnection > sequence_connections ;
Set < DataConnection > data_connections ;
int function_id ;
2016-08-07 00:00:54 +02:00
Vector2 scroll ;
2017-03-05 16:44:50 +01:00
Function ( ) { function_id = - 1 ; }
2016-08-03 00:11:05 +02:00
} ;
struct Variable {
PropertyInfo info ;
Variant default_value ;
2016-08-31 04:44:14 +02:00
bool _export ;
2019-09-13 21:14:12 +02:00
// add getter & setter options here
2016-08-03 00:11:05 +02:00
} ;
2017-03-05 16:44:50 +01:00
Map < StringName , Function > functions ;
Map < StringName , Variable > variables ;
Map < StringName , Vector < Argument > > custom_signals ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
Map < Object * , VisualScriptInstance * > instances ;
2016-08-06 03:46:45 +02:00
2019-07-26 22:00:23 +02:00
bool is_tool_script ;
2016-08-06 03:46:45 +02:00
# ifdef TOOLS_ENABLED
2017-03-05 16:44:50 +01:00
Set < PlaceHolderScriptInstance * > placeholders ;
2016-08-06 03:46:45 +02:00
//void _update_placeholder(PlaceHolderScriptInstance *p_placeholder);
virtual void _placeholder_erased ( PlaceHolderScriptInstance * p_placeholder ) ;
void _update_placeholders ( ) ;
# endif
2017-03-05 16:44:50 +01:00
void _set_variable_info ( const StringName & p_name , const Dictionary & p_info ) ;
Dictionary _get_variable_info ( const StringName & p_name ) const ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
void _set_data ( const Dictionary & p_data ) ;
2016-08-03 00:11:05 +02:00
Dictionary _get_data ( ) const ;
protected :
void _node_ports_changed ( int p_id ) ;
static void _bind_methods ( ) ;
2017-03-05 16:44:50 +01:00
public :
2019-09-13 21:14:12 +02:00
// TODO: Remove it in future when breaking changes are acceptable
StringName get_default_func ( ) const ;
2017-03-05 16:44:50 +01:00
void add_function ( const StringName & p_name ) ;
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 set_function_scroll ( const StringName & p_name , const Vector2 & p_scroll ) ;
Vector2 get_function_scroll ( const StringName & p_name ) const ;
2016-08-03 00:11:05 +02:00
void get_function_list ( List < StringName > * r_functions ) const ;
2017-03-05 16:44:50 +01:00
int get_function_node_id ( const StringName & p_name ) const ;
2019-07-26 22:00:23 +02:00
void set_tool_enabled ( bool p_enabled ) ;
2017-03-05 16:44:50 +01:00
void add_node ( const StringName & p_func , int p_id , const Ref < VisualScriptNode > & p_node , const Point2 & p_pos = Point2 ( ) ) ;
void remove_node ( const StringName & p_func , int p_id ) ;
bool has_node ( const StringName & p_func , int p_id ) const ;
Ref < VisualScriptNode > get_node ( const StringName & p_func , int p_id ) const ;
2017-09-10 15:37:49 +02:00
void set_node_position ( const StringName & p_func , int p_id , const Point2 & p_pos ) ;
Point2 get_node_position ( const StringName & p_func , int p_id ) const ;
2017-03-05 16:44:50 +01:00
void get_node_list ( const StringName & p_func , List < int > * r_nodes ) const ;
void sequence_connect ( const StringName & p_func , int p_from_node , int p_from_output , int p_to_node ) ;
void sequence_disconnect ( const StringName & p_func , int p_from_node , int p_from_output , int p_to_node ) ;
bool has_sequence_connection ( const StringName & p_func , int p_from_node , int p_from_output , int p_to_node ) const ;
void get_sequence_connection_list ( const StringName & p_func , List < SequenceConnection > * r_connection ) const ;
void data_connect ( const StringName & p_func , int p_from_node , int p_from_port , int p_to_node , int p_to_port ) ;
void data_disconnect ( const StringName & p_func , int p_from_node , int p_from_port , int p_to_node , int p_to_port ) ;
bool has_data_connection ( const StringName & p_func , int p_from_node , int p_from_port , int p_to_node , int p_to_port ) const ;
void get_data_connection_list ( const StringName & p_func , List < DataConnection > * r_connection ) const ;
2017-08-12 18:52:50 +02:00
bool is_input_value_port_connected ( const StringName & p_func , int p_node , int p_port ) const ;
bool get_input_value_port_connection_source ( const StringName & p_func , int p_node , int p_port , int * r_node , int * r_port ) const ;
2017-03-05 16:44:50 +01: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-24 00:29:07 +02:00
void get_variable_list ( List < StringName > * r_variables ) const ;
2017-03-05 16:44:50 +01: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 ) ;
2018-05-13 05:34:35 +02:00
Set < int > get_output_sequence_ports_connected ( const String & edited_func , int from_node ) ;
2016-08-03 00:11:05 +02:00
void get_custom_signal_list ( List < StringName > * r_custom_signals ) const ;
int get_available_id ( ) const ;
2017-03-05 16:44:50 +01:00
void set_instance_base_type ( const StringName & p_type ) ;
2016-08-03 00:11:05 +02:00
virtual bool can_instance ( ) const ;
2016-08-25 22:45:20 +02:00
virtual Ref < Script > get_base_script ( ) const ;
2016-08-03 00:11:05 +02:00
virtual StringName get_instance_base_type ( ) const ;
2017-03-05 16:44:50 +01:00
virtual ScriptInstance * instance_create ( Object * p_this ) ;
2016-08-03 00:11:05 +02:00
virtual bool instance_has ( const Object * p_this ) const ;
virtual bool has_source_code ( ) const ;
virtual String get_source_code ( ) const ;
2017-03-05 16:44:50 +01:00
virtual void set_source_code ( const String & p_code ) ;
virtual Error reload ( bool p_keep_state = false ) ;
2016-08-03 00:11:05 +02:00
virtual bool is_tool ( ) const ;
2018-11-27 23:55:37 +01:00
virtual bool is_valid ( ) const ;
2016-08-03 00:11:05 +02:00
virtual ScriptLanguage * get_language ( ) const ;
2017-03-05 16:44:50 +01:00
virtual bool has_script_signal ( const StringName & p_signal ) const ;
2016-08-03 00:11:05 +02:00
virtual void get_script_signal_list ( List < MethodInfo > * r_signals ) const ;
2017-03-05 16:44:50 +01:00
virtual bool get_property_default_value ( const StringName & p_property , Variant & r_value ) const ;
2016-08-19 21:48:08 +02:00
virtual void get_script_method_list ( List < MethodInfo > * p_list ) const ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
virtual bool has_method ( const StringName & p_method ) const ;
virtual MethodInfo get_method_info ( const StringName & p_method ) const ;
2016-08-08 06:21:22 +02:00
2016-08-24 00:29:07 +02:00
virtual void get_script_property_list ( List < PropertyInfo > * p_list ) const ;
2016-08-08 06:21:22 +02:00
2017-04-15 19:48:10 +02:00
virtual int get_member_line ( const StringName & p_member ) const ;
2016-09-05 23:50:30 +02:00
# ifdef TOOLS_ENABLED
2016-08-31 22:58:51 +02:00
virtual bool are_subnodes_edited ( ) const ;
2016-09-05 23:50:30 +02:00
# endif
2016-08-03 00:11:05 +02:00
VisualScript ( ) ;
~ VisualScript ( ) ;
} ;
2016-08-06 03:46:45 +02:00
class VisualScriptInstance : public ScriptInstance {
Object * owner ;
Ref < VisualScript > script ;
2017-03-05 16:44:50 +01:00
Map < StringName , Variant > variables ; //using variable path, not script
Map < int , VisualScriptNodeInstance * > instances ;
2016-08-06 03:46:45 +02:00
struct Function {
int node ;
int max_stack ;
int trash_pos ;
int flow_stack_size ;
2016-08-31 04:44:14 +02:00
int pass_stack_size ;
2016-08-06 03:46:45 +02:00
int node_count ;
int argument_count ;
} ;
2017-03-05 16:44:50 +01:00
Map < StringName , Function > functions ;
2016-08-06 03:46:45 +02:00
Vector < Variant > default_values ;
2017-03-05 16:44:50 +01:00
int max_input_args , max_output_args ;
2016-08-06 03:46:45 +02:00
2016-08-07 00:00:54 +02:00
StringName source ;
2016-08-06 03:46:45 +02:00
2017-03-05 16:44:50 +01:00
void _dependency_step ( VisualScriptNodeInstance * node , int p_pass , int * pass_stack , const Variant * * input_args , Variant * * output_args , Variant * variant_stack , Variant : : 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 , Variant : : CallError & r_error ) ;
2016-08-08 00:22:33 +02:00
2016-08-06 03:46:45 +02:00
//Map<StringName,Function> functions;
2017-03-05 16:44:50 +01:00
friend class VisualScriptFunctionState ; //for yield
friend class VisualScriptLanguage ; //for debugger
2016-08-06 03:46:45 +02:00
public :
2017-03-05 16:44:50 +01: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 03:46:45 +02:00
virtual void get_property_list ( List < PropertyInfo > * p_properties ) const ;
2017-03-05 16:44:50 +01:00
virtual Variant : : Type get_property_type ( const StringName & p_name , bool * r_is_valid = NULL ) const ;
2016-08-06 03:46:45 +02:00
virtual void get_method_list ( List < MethodInfo > * p_list ) const ;
2017-03-05 16:44:50 +01:00
virtual bool has_method ( const StringName & p_method ) const ;
virtual Variant call ( const StringName & p_method , const Variant * * p_args , int p_argcount , Variant : : CallError & r_error ) ;
2016-08-06 03:46:45 +02:00
virtual void notification ( int p_notification ) ;
2019-04-10 07:07:40 +02:00
String to_string ( bool * r_valid ) ;
2016-08-06 03:46:45 +02:00
2017-03-05 16:44:50 +01:00
bool set_variable ( const StringName & p_variable , const Variant & p_value ) {
2016-08-06 03:46:45 +02:00
2017-03-05 16:44:50 +01:00
Map < StringName , Variant > : : Element * E = variables . find ( p_variable ) ;
2016-08-06 03:46:45 +02:00
if ( ! E )
return false ;
2017-03-05 16:44:50 +01:00
E - > get ( ) = p_value ;
2016-08-06 03:46:45 +02:00
return true ;
}
2017-03-05 16:44:50 +01:00
bool get_variable ( const StringName & p_variable , Variant * r_variable ) const {
2016-08-06 03:46:45 +02:00
2017-03-05 16:44:50 +01:00
const Map < StringName , Variant > : : Element * E = variables . find ( p_variable ) ;
2016-08-06 03:46:45 +02:00
if ( ! E )
return false ;
2017-03-05 16:44:50 +01:00
* r_variable = E - > get ( ) ;
2016-08-06 03:46:45 +02: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 16:44:50 +01:00
void create ( const Ref < VisualScript > & p_script , Object * p_owner ) ;
2016-08-06 03:46:45 +02:00
virtual ScriptLanguage * get_language ( ) ;
2018-05-13 07:07:56 +02:00
virtual MultiplayerAPI : : RPCMode get_rpc_mode ( const StringName & p_method ) const ;
virtual MultiplayerAPI : : RPCMode get_rset_mode ( const StringName & p_variable ) const ;
2016-08-19 21:48:08 +02:00
2016-08-06 03:46:45 +02:00
VisualScriptInstance ( ) ;
~ VisualScriptInstance ( ) ;
} ;
2016-08-08 00:22:33 +02:00
class VisualScriptFunctionState : public Reference {
2017-03-05 16:44:50 +01:00
GDCLASS ( VisualScriptFunctionState , Reference ) ;
friend class VisualScriptInstance ;
2016-08-08 00:22:33 +02:00
ObjectID instance_id ;
ObjectID script_id ;
VisualScriptInstance * instance ;
StringName function ;
Vector < uint8_t > stack ;
int working_mem_index ;
int variant_stack_size ;
VisualScriptNodeInstance * node ;
int flow_stack_pos ;
2016-08-31 04:44:14 +02:00
int pass ;
2016-08-08 00:22:33 +02:00
2017-03-05 16:44:50 +01:00
Variant _signal_callback ( const Variant * * p_args , int p_argcount , Variant : : CallError & r_error ) ;
2016-08-08 00:22:33 +02:00
protected :
static void _bind_methods ( ) ;
2017-03-05 16:44:50 +01:00
public :
void connect_to_signal ( Object * p_obj , const String & p_signal , Array p_binds ) ;
2016-08-08 00:22:33 +02:00
bool is_valid ( ) const ;
Variant resume ( Array p_args ) ;
VisualScriptFunctionState ( ) ;
~ VisualScriptFunctionState ( ) ;
} ;
2017-03-05 16:44:50 +01:00
typedef Ref < VisualScriptNode > ( * VisualScriptNodeRegisterFunc ) ( const String & p_type ) ;
2016-08-03 00:11:05 +02:00
class VisualScriptLanguage : public ScriptLanguage {
2017-03-05 16:44:50 +01:00
Map < String , VisualScriptNodeRegisterFunc > register_funcs ;
2016-08-06 03:46:45 +02:00
2016-08-07 00:00:54 +02:00
struct CallLevel {
2017-03-05 16:44:50 +01:00
Variant * stack ;
Variant * * work_mem ;
const StringName * function ;
VisualScriptInstance * instance ;
int * current_id ;
2016-08-07 00:00:54 +02:00
} ;
int _debug_parse_err_node ;
String _debug_parse_err_file ;
String _debug_error ;
int _debug_call_stack_pos ;
int _debug_max_call_stack ;
CallLevel * _call_stack ;
2016-08-06 03:46:45 +02:00
2016-08-03 00:11:05 +02:00
public :
2016-08-06 03:46:45 +02:00
StringName notification ;
2016-08-08 02:22:14 +02:00
StringName _get_output_port_unsequenced ;
StringName _step ;
2016-08-08 06:21:22 +02:00
StringName _subcall ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
static VisualScriptLanguage * singleton ;
2016-08-03 00:11:05 +02:00
2021-01-27 10:43:02 +01:00
Mutex lock ;
2016-08-06 03:46:45 +02:00
2017-03-05 16:44:50 +01: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-07 00:00:54 +02:00
2017-03-05 16:44:50 +01:00
_FORCE_INLINE_ void enter_function ( VisualScriptInstance * p_instance , const StringName * p_function , Variant * p_stack , Variant * * p_work_mem , int * current_id ) {
2016-08-07 00:00:54 +02:00
2017-08-07 12:17:31 +02:00
if ( Thread : : get_main_id ( ) ! = Thread : : get_caller_id ( ) )
2017-03-05 16:44:50 +01:00
return ; //no support for other threads than main for now
2016-08-07 00:00:54 +02:00
2017-03-05 16:44:50 +01:00
if ( ScriptDebugger : : get_singleton ( ) - > get_lines_left ( ) > 0 & & ScriptDebugger : : get_singleton ( ) - > get_depth ( ) > = 0 )
ScriptDebugger : : get_singleton ( ) - > set_depth ( ScriptDebugger : : get_singleton ( ) - > get_depth ( ) + 1 ) ;
2016-08-07 00:00:54 +02:00
2017-03-05 16:44:50 +01:00
if ( _debug_call_stack_pos > = _debug_max_call_stack ) {
//stack overflow
_debug_error = " Stack Overflow (Stack Size: " + itos ( _debug_max_call_stack ) + " ) " ;
ScriptDebugger : : get_singleton ( ) - > debug ( this ) ;
return ;
}
2016-08-07 00:00:54 +02:00
2017-03-05 16:44:50 +01: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-07 00:00:54 +02:00
}
_FORCE_INLINE_ void exit_function ( ) {
2017-08-07 12:17:31 +02:00
if ( Thread : : get_main_id ( ) ! = Thread : : get_caller_id ( ) )
2017-03-05 16:44:50 +01:00
return ; //no support for other threads than main for now
2016-08-07 00:00:54 +02:00
2017-03-05 16:44:50 +01:00
if ( ScriptDebugger : : get_singleton ( ) - > get_lines_left ( ) > 0 & & ScriptDebugger : : get_singleton ( ) - > get_depth ( ) > = 0 )
ScriptDebugger : : get_singleton ( ) - > set_depth ( ScriptDebugger : : get_singleton ( ) - > get_depth ( ) - 1 ) ;
2016-08-07 00:00:54 +02:00
2017-03-05 16:44:50 +01:00
if ( _debug_call_stack_pos = = 0 ) {
2016-08-07 00:00:54 +02:00
2017-03-05 16:44:50 +01:00
_debug_error = " Stack Underflow (Engine Bug) " ;
ScriptDebugger : : get_singleton ( ) - > debug ( this ) ;
return ;
}
2016-08-07 00:00:54 +02:00
2017-03-05 16:44:50 +01:00
_debug_call_stack_pos - - ;
2016-08-07 00:00:54 +02:00
}
//////////////////////////////////////
2016-08-03 00:11:05 +02:00
virtual String get_name ( ) const ;
/* LANGUAGE FUNCTIONS */
virtual void init ( ) ;
virtual String get_type ( ) const ;
virtual String get_extension ( ) const ;
2017-03-05 16:44:50 +01:00
virtual Error execute_file ( const String & p_path ) ;
2016-08-03 00:11:05 +02:00
virtual void finish ( ) ;
/* EDITOR FUNCTIONS */
virtual void get_reserved_words ( List < String > * p_words ) const ;
virtual void get_comment_delimiters ( List < String > * p_delimiters ) const ;
virtual void get_string_delimiters ( List < String > * p_delimiters ) const ;
2017-03-05 16:44:50 +01:00
virtual Ref < Script > get_template ( const String & p_class_name , const String & p_base_class_name ) const ;
2017-06-13 22:03:08 +02:00
virtual bool is_using_templates ( ) ;
virtual void make_template ( const String & p_class_name , const String & p_base_class_name , Ref < Script > & p_script ) ;
2018-07-01 18:17:40 +02:00
virtual bool validate ( const String & p_script , int & r_line_error , int & r_col_error , String & r_test_error , const String & p_path = " " , List < String > * r_functions = NULL , List < ScriptLanguage : : Warning > * r_warnings = NULL , Set < int > * r_safe_lines = NULL ) const ;
2016-08-03 00:11:05 +02:00
virtual Script * create_script ( ) const ;
virtual bool has_named_classes ( ) const ;
2017-10-24 01:54:47 +02:00
virtual bool supports_builtin_mode ( ) const ;
2017-03-05 16:44:50 +01:00
virtual int find_function ( const String & p_function , const String & p_code ) const ;
virtual String make_function ( const String & p_class , const String & p_name , const PoolStringArray & p_args ) const ;
virtual void auto_indent_code ( String & p_code , int p_from_line , int p_to_line ) const ;
virtual void add_global_constant ( const StringName & p_variable , const Variant & p_value ) ;
2016-08-03 00:11:05 +02:00
/* DEBUGGER FUNCTIONS */
virtual String debug_get_error ( ) const ;
virtual int debug_get_stack_level_count ( ) const ;
virtual int debug_get_stack_level_line ( int p_level ) const ;
virtual String debug_get_stack_level_function ( int p_level ) const ;
virtual String debug_get_stack_level_source ( int p_level ) const ;
2017-03-05 16:44:50 +01:00
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 ) ;
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 ) ;
virtual void debug_get_globals ( List < String > * p_locals , List < Variant > * p_values , int p_max_subitems = - 1 , int p_max_depth = - 1 ) ;
virtual String debug_parse_stack_level_expression ( int p_level , const String & p_expression , int p_max_subitems = - 1 , int p_max_depth = - 1 ) ;
2016-08-03 00:11:05 +02:00
virtual void reload_all_scripts ( ) ;
2017-03-05 16:44:50 +01:00
virtual void reload_tool_script ( const Ref < Script > & p_script , bool p_soft_reload ) ;
2016-08-03 00:11:05 +02:00
/* LOADER FUNCTIONS */
virtual void get_recognized_extensions ( List < String > * p_extensions ) const ;
virtual void get_public_functions ( List < MethodInfo > * p_functions ) const ;
2017-03-05 16:44:50 +01:00
virtual void get_public_constants ( List < Pair < String , Variant > > * p_constants ) const ;
2016-08-03 00:11:05 +02:00
virtual void profiling_start ( ) ;
virtual void profiling_stop ( ) ;
2017-03-05 16:44:50 +01:00
virtual int profiling_get_accumulated_data ( ProfilingInfo * p_info_arr , int p_info_max ) ;
virtual int profiling_get_frame_data ( ProfilingInfo * p_info_arr , int p_info_max ) ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
void add_register_func ( const String & p_name , VisualScriptNodeRegisterFunc p_func ) ;
2017-11-15 16:57:24 +01:00
void remove_register_func ( const String & p_name ) ;
2017-03-05 16:44:50 +01:00
Ref < VisualScriptNode > create_node_from_name ( const String & p_name ) ;
2016-08-03 00:11:05 +02:00
void get_registered_node_names ( List < String > * r_names ) ;
VisualScriptLanguage ( ) ;
2016-08-06 03:46:45 +02:00
~ VisualScriptLanguage ( ) ;
2016-08-03 00:11:05 +02:00
} ;
//aid for registering
2017-03-05 16:44:50 +01:00
template < class T >
static Ref < VisualScriptNode > create_node_generic ( const String & p_name ) {
2016-08-03 00:11:05 +02:00
Ref < T > node ;
node . instance ( ) ;
return node ;
}
2018-01-05 00:50:27 +01:00
# endif // VISUAL_SCRIPT_H