2017-03-05 15:47:28 +01:00
/*************************************************************************/
/* visual_script_func_nodes.cpp */
/*************************************************************************/
/* 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
/*************************************************************************/
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
2017-04-08 00:11:42 +02:00
/* Copyright (c) 2014-2017 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. */
/*************************************************************************/
2016-08-03 00:11:05 +02:00
# include "visual_script_func_nodes.h"
2017-03-05 15:47:28 +01:00
2017-03-05 16:44:50 +01:00
# include "io/resource_loader.h"
2016-08-03 00:11:05 +02:00
# include "os/os.h"
2017-07-22 12:47:04 +02:00
# include "project_settings.h"
2016-08-03 00:11:05 +02:00
# include "scene/main/node.h"
2017-06-27 03:58:03 +02:00
# include "scene/main/scene_tree.h"
2016-08-03 00:11:05 +02:00
# include "visual_script_nodes.h"
//////////////////////////////////////////
////////////////CALL//////////////////////
//////////////////////////////////////////
int VisualScriptFunctionCall : : get_output_sequence_port_count ( ) const {
2017-03-05 16:44:50 +01:00
if ( method_cache . flags & METHOD_FLAG_CONST | | call_mode = = CALL_MODE_BASIC_TYPE )
2016-08-31 04:44:14 +02:00
return 0 ;
else
return 1 ;
2016-08-03 00:11:05 +02:00
}
2017-03-05 16:44:50 +01:00
bool VisualScriptFunctionCall : : has_input_sequence_port ( ) const {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
if ( method_cache . flags & METHOD_FLAG_CONST | | call_mode = = CALL_MODE_BASIC_TYPE )
2016-08-31 04:44:14 +02:00
return false ;
else
return true ;
2016-08-03 00:11:05 +02:00
}
# ifdef TOOLS_ENABLED
2017-03-05 16:44:50 +01:00
static Node * _find_script_node ( Node * p_edited_scene , Node * p_current_node , const Ref < Script > & script ) {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
if ( p_edited_scene ! = p_current_node & & p_current_node - > get_owner ( ) ! = p_edited_scene )
2016-08-03 00:11:05 +02:00
return NULL ;
Ref < Script > scr = p_current_node - > get_script ( ) ;
2017-03-05 16:44:50 +01:00
if ( scr . is_valid ( ) & & scr = = script )
2016-08-03 00:11:05 +02:00
return p_current_node ;
2017-03-05 16:44:50 +01:00
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 ) ;
2016-08-03 00:11:05 +02:00
if ( n )
return n ;
}
return NULL ;
}
# endif
Node * VisualScriptFunctionCall : : _get_base_node ( ) const {
# ifdef TOOLS_ENABLED
Ref < Script > script = get_visual_script ( ) ;
if ( ! script . is_valid ( ) )
return NULL ;
2017-03-05 16:44:50 +01:00
MainLoop * main_loop = OS : : get_singleton ( ) - > get_main_loop ( ) ;
2017-08-24 22:58:51 +02:00
SceneTree * scene_tree = Object : : cast_to < SceneTree > ( main_loop ) ;
2016-08-03 00:11:05 +02:00
if ( ! scene_tree )
return NULL ;
Node * edited_scene = scene_tree - > get_edited_scene_root ( ) ;
if ( ! edited_scene )
return NULL ;
2017-03-05 16:44:50 +01:00
Node * script_node = _find_script_node ( edited_scene , edited_scene , script ) ;
2016-08-03 00:11:05 +02:00
if ( ! script_node )
return NULL ;
if ( ! script_node - > has_node ( base_path ) )
return NULL ;
Node * path_to = script_node - > get_node ( base_path ) ;
return path_to ;
# else
return NULL ;
# endif
}
StringName VisualScriptFunctionCall : : _get_base_type ( ) const {
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_SELF & & get_visual_script ( ) . is_valid ( ) )
2016-08-03 00:11:05 +02:00
return get_visual_script ( ) - > get_instance_base_type ( ) ;
2017-03-05 16:44:50 +01:00
else if ( call_mode = = CALL_MODE_NODE_PATH & & get_visual_script ( ) . is_valid ( ) ) {
2016-08-03 00:11:05 +02:00
Node * path = _get_base_node ( ) ;
if ( path )
2017-01-03 03:03:46 +01:00
return path - > get_class ( ) ;
2016-08-03 00:11:05 +02:00
}
return base_type ;
}
2017-03-05 16:44:50 +01:00
int VisualScriptFunctionCall : : get_input_value_port_count ( ) const {
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_BASIC_TYPE ) {
2016-08-03 16:28:20 +02:00
2017-03-05 16:44:50 +01:00
Vector < StringName > names = Variant : : get_method_argument_names ( basic_type , function ) ;
return names . size ( ) + ( rpc_call_mode > = RPC_RELIABLE_TO_ID ? 1 : 0 ) + 1 ;
2016-08-03 16:28:20 +02:00
} else {
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
MethodBind * mb = ClassDB : : get_method ( _get_base_type ( ) , function ) ;
2016-08-25 22:45:20 +02:00
if ( mb ) {
2017-03-05 16:44:50 +01:00
return mb - > get_argument_count ( ) + ( call_mode = = CALL_MODE_INSTANCE ? 1 : 0 ) + ( rpc_call_mode > = RPC_RELIABLE_TO_ID ? 1 : 0 ) - use_default_args ;
2016-08-25 22:45:20 +02:00
}
2016-08-03 16:28:20 +02:00
2017-03-05 16:44:50 +01:00
return method_cache . arguments . size ( ) + ( call_mode = = CALL_MODE_INSTANCE ? 1 : 0 ) + ( rpc_call_mode > = RPC_RELIABLE_TO_ID ? 1 : 0 ) - use_default_args ;
2016-08-03 16:28:20 +02:00
}
2016-08-03 00:11:05 +02:00
}
2017-03-05 16:44:50 +01:00
int VisualScriptFunctionCall : : get_output_value_port_count ( ) const {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_BASIC_TYPE ) {
2016-08-03 16:28:20 +02:00
2017-03-05 16:44:50 +01:00
bool returns = false ;
Variant : : get_method_return_type ( basic_type , function , & returns ) ;
return returns ? 1 : 0 ;
2016-08-03 16:28:20 +02:00
} else {
2016-08-29 01:57:27 +02:00
int ret ;
2017-03-05 16:44:50 +01:00
MethodBind * mb = ClassDB : : get_method ( _get_base_type ( ) , function ) ;
2016-08-25 22:45:20 +02:00
if ( mb ) {
2016-08-29 01:57:27 +02:00
ret = mb - > has_return ( ) ? 1 : 0 ;
} else
ret = 1 ; //it is assumed that script always returns something
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_INSTANCE ) {
2016-08-29 01:57:27 +02:00
ret + + ;
2016-08-25 22:45:20 +02:00
}
2016-08-03 00:11:05 +02:00
2016-08-29 01:57:27 +02:00
return ret ;
2016-08-03 16:28:20 +02:00
}
2016-08-03 00:11:05 +02:00
}
String VisualScriptFunctionCall : : get_output_sequence_port_text ( int p_port ) const {
return String ( ) ;
}
2017-03-05 16:44:50 +01:00
PropertyInfo VisualScriptFunctionCall : : get_input_value_port_info ( int p_idx ) const {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_INSTANCE | | call_mode = = CALL_MODE_BASIC_TYPE ) {
if ( p_idx = = 0 ) {
2016-08-03 00:11:05 +02:00
PropertyInfo pi ;
2017-03-05 16:44:50 +01:00
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 ( ) ) ;
2016-08-03 00:11:05 +02:00
return pi ;
} else {
p_idx - - ;
}
}
2017-03-05 16:44:50 +01:00
if ( rpc_call_mode > = RPC_RELIABLE_TO_ID ) {
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
if ( p_idx = = 0 ) {
return PropertyInfo ( Variant : : INT , " peer_id " ) ;
2016-08-25 22:45:20 +02:00
} else {
p_idx - - ;
}
}
2016-08-03 00:11:05 +02:00
# ifdef DEBUG_METHODS_ENABLED
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_BASIC_TYPE ) {
2016-08-03 16:28:20 +02:00
2017-03-05 16:44:50 +01:00
Vector < StringName > names = Variant : : get_method_argument_names ( basic_type , function ) ;
Vector < Variant : : Type > types = Variant : : get_method_argument_types ( basic_type , function ) ;
return PropertyInfo ( types [ p_idx ] , names [ p_idx ] ) ;
2016-08-03 00:11:05 +02:00
2016-08-03 16:28:20 +02:00
} else {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
MethodBind * mb = ClassDB : : get_method ( _get_base_type ( ) , function ) ;
2016-08-25 22:45:20 +02:00
if ( mb ) {
return mb - > get_argument_info ( p_idx ) ;
}
2017-03-05 16:44:50 +01:00
if ( p_idx > = 0 & & p_idx < method_cache . arguments . size ( ) ) {
2016-08-25 22:45:20 +02:00
return method_cache . arguments [ p_idx ] ;
}
2016-08-03 00:11:05 +02:00
2016-08-25 22:45:20 +02:00
return PropertyInfo ( ) ;
2016-08-03 16:28:20 +02:00
}
2016-08-03 00:11:05 +02:00
# else
return PropertyInfo ( ) ;
# endif
}
2017-03-05 16:44:50 +01:00
PropertyInfo VisualScriptFunctionCall : : get_output_value_port_info ( int p_idx ) const {
2016-08-03 00:11:05 +02:00
# ifdef DEBUG_METHODS_ENABLED
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_BASIC_TYPE ) {
2016-08-03 16:28:20 +02:00
2017-03-05 16:44:50 +01:00
return PropertyInfo ( Variant : : get_method_return_type ( basic_type , function ) , " " ) ;
2016-08-03 16:28:20 +02:00
} else {
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_INSTANCE ) {
if ( p_idx = = 0 ) {
return PropertyInfo ( Variant : : OBJECT , " pass " ) ;
2016-08-29 01:57:27 +02:00
} else {
p_idx - - ;
}
}
PropertyInfo ret ;
2017-01-03 03:03:46 +01:00
/*MethodBind *mb = ClassDB::get_method(_get_base_type(),function);
2016-08-25 22:45:20 +02:00
if ( mb ) {
2016-08-29 01:57:27 +02:00
ret = mb - > get_argument_info ( - 1 ) ;
} else { */
ret = method_cache . return_val ;
//}
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_INSTANCE ) {
ret . name = " return " ;
2016-08-29 01:57:27 +02:00
} else {
2017-03-05 16:44:50 +01:00
ret . name = " " ;
2016-08-25 22:45:20 +02:00
}
2016-08-29 01:57:27 +02:00
return ret ;
2016-08-03 16:28:20 +02:00
}
2016-08-03 00:11:05 +02:00
# else
return PropertyInfo ( ) ;
# endif
}
String VisualScriptFunctionCall : : get_caption ( ) const {
2017-03-05 16:44:50 +01:00
static const char * cname [ 5 ] = {
2016-08-03 16:28:20 +02:00
" CallSelf " ,
" CallNode " ,
" CallInstance " ,
2016-08-29 01:57:27 +02:00
" CallBasic " ,
" CallSingleton "
2016-08-03 16:28:20 +02:00
} ;
2016-08-25 22:45:20 +02:00
String caption = cname [ call_mode ] ;
if ( rpc_call_mode ) {
2017-03-05 16:44:50 +01:00
caption + = " (RPC) " ;
2016-08-25 22:45:20 +02:00
}
return caption ;
2016-08-03 00:11:05 +02:00
}
String VisualScriptFunctionCall : : get_text ( ) const {
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_SELF )
return " " + String ( function ) + " () " ;
if ( call_mode = = CALL_MODE_SINGLETON )
return String ( singleton ) + " : " + String ( function ) + " () " ;
else if ( call_mode = = CALL_MODE_BASIC_TYPE )
return Variant : : get_type_name ( basic_type ) + " . " + String ( function ) + " () " ;
else if ( call_mode = = CALL_MODE_NODE_PATH )
return " [ " + String ( base_path . simplified ( ) ) + " ]. " + String ( function ) + " () " ;
2016-08-03 00:11:05 +02:00
else
2017-03-05 16:44:50 +01:00
return " " + base_type + " . " + String ( function ) + " () " ;
2016-08-03 00:11:05 +02:00
}
2016-08-03 16:28:20 +02:00
void VisualScriptFunctionCall : : set_basic_type ( Variant : : Type p_type ) {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
if ( basic_type = = p_type )
2016-08-03 00:11:05 +02:00
return ;
2017-03-05 16:44:50 +01:00
basic_type = p_type ;
2016-08-25 22:45:20 +02:00
2016-08-03 16:28:20 +02:00
_change_notify ( ) ;
2016-08-04 03:06:39 +02:00
ports_changed_notify ( ) ;
2016-08-03 16:28:20 +02:00
}
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
Variant : : Type VisualScriptFunctionCall : : get_basic_type ( ) const {
2016-08-03 00:11:05 +02:00
2016-08-03 16:28:20 +02:00
return basic_type ;
2016-08-03 00:11:05 +02:00
}
2017-03-05 16:44:50 +01:00
void VisualScriptFunctionCall : : set_base_type ( const StringName & p_type ) {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
if ( base_type = = p_type )
2016-08-03 00:11:05 +02:00
return ;
2017-03-05 16:44:50 +01:00
base_type = p_type ;
2016-08-03 00:11:05 +02:00
_change_notify ( ) ;
2016-08-04 03:06:39 +02:00
ports_changed_notify ( ) ;
2016-08-03 00:11:05 +02:00
}
2017-03-05 16:44:50 +01:00
StringName VisualScriptFunctionCall : : get_base_type ( ) const {
2016-08-03 00:11:05 +02:00
return base_type ;
}
2017-03-05 16:44:50 +01:00
void VisualScriptFunctionCall : : set_base_script ( const String & p_path ) {
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
if ( base_script = = p_path )
2016-08-25 22:45:20 +02:00
return ;
2017-03-05 16:44:50 +01:00
base_script = p_path ;
2016-08-25 22:45:20 +02:00
_change_notify ( ) ;
ports_changed_notify ( ) ;
}
String VisualScriptFunctionCall : : get_base_script ( ) const {
return base_script ;
}
2017-08-12 18:52:50 +02:00
void VisualScriptFunctionCall : : set_singleton ( const StringName & p_type ) {
2016-08-29 01:57:27 +02:00
2017-08-12 18:52:50 +02:00
if ( singleton = = p_type )
2016-08-29 01:57:27 +02:00
return ;
2017-08-12 18:52:50 +02:00
singleton = p_type ;
2017-07-19 22:00:46 +02:00
Object * obj = ProjectSettings : : get_singleton ( ) - > get_singleton_object ( singleton ) ;
2016-08-29 01:57:27 +02:00
if ( obj ) {
2017-03-05 16:44:50 +01:00
base_type = obj - > get_class ( ) ;
2016-08-29 01:57:27 +02:00
}
_change_notify ( ) ;
ports_changed_notify ( ) ;
}
StringName VisualScriptFunctionCall : : get_singleton ( ) const {
return singleton ;
}
2016-08-25 22:45:20 +02:00
void VisualScriptFunctionCall : : _update_method_cache ( ) {
StringName type ;
Ref < Script > script ;
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_NODE_PATH ) {
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
Node * node = _get_base_node ( ) ;
2016-08-25 22:45:20 +02:00
if ( node ) {
2017-03-05 16:44:50 +01:00
type = node - > get_class ( ) ;
base_type = type ; //cache, too
2016-08-25 22:45:20 +02:00
script = node - > get_script ( ) ;
}
2017-03-05 16:44:50 +01:00
} else if ( call_mode = = CALL_MODE_SELF ) {
2016-08-25 22:45:20 +02:00
if ( get_visual_script ( ) . is_valid ( ) ) {
2017-03-05 16:44:50 +01:00
type = get_visual_script ( ) - > get_instance_base_type ( ) ;
base_type = type ; //cache, too
script = get_visual_script ( ) ;
2016-08-25 22:45:20 +02:00
}
2016-08-29 01:57:27 +02:00
2017-03-05 16:44:50 +01:00
} else if ( call_mode = = CALL_MODE_SINGLETON ) {
2016-08-29 01:57:27 +02:00
2017-07-19 22:00:46 +02:00
Object * obj = ProjectSettings : : get_singleton ( ) - > get_singleton_object ( singleton ) ;
2016-08-29 01:57:27 +02:00
if ( obj ) {
2017-03-05 16:44:50 +01:00
type = obj - > get_class ( ) ;
script = obj - > get_script ( ) ;
2016-08-29 01:57:27 +02:00
}
2017-03-05 16:44:50 +01:00
} else if ( call_mode = = CALL_MODE_INSTANCE ) {
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
type = base_type ;
if ( base_script ! = String ( ) ) {
2016-08-25 22:45:20 +02:00
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 ) ) {
2017-03-05 16:44:50 +01:00
script = Ref < Resource > ( ResourceCache : : get ( base_script ) ) ;
2016-08-25 22:45:20 +02:00
} else {
return ;
}
}
}
2017-01-14 12:26:56 +01:00
//print_line("BASE: "+String(type)+" FUNC: "+String(function));
2017-03-05 16:44:50 +01:00
MethodBind * mb = ClassDB : : get_method ( type , function ) ;
2016-08-25 22:45:20 +02:00
if ( mb ) {
2017-03-05 16:44:50 +01:00
use_default_args = mb - > get_default_argument_count ( ) ;
2016-08-25 22:45:20 +02:00
method_cache = MethodInfo ( ) ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < mb - > get_argument_count ( ) ; i + + ) {
2016-08-25 22:45:20 +02:00
# ifdef DEBUG_METHODS_ENABLED
method_cache . arguments . push_back ( mb - > get_argument_info ( i ) ) ;
# else
method_cache . arguments . push_back ( PropertyInfo ( ) ) ;
# endif
}
2016-08-31 04:44:14 +02:00
if ( mb - > is_const ( ) ) {
2017-03-05 16:44:50 +01:00
method_cache . flags | = METHOD_FLAG_CONST ;
2016-08-31 04:44:14 +02:00
}
2016-08-25 22:45:20 +02:00
# ifdef DEBUG_METHODS_ENABLED
method_cache . return_val = mb - > get_argument_info ( - 1 ) ;
# endif
2016-09-08 00:39:02 +02:00
if ( mb - > is_vararg ( ) ) {
//for vararg just give it 10 arguments (should be enough for most use cases)
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 10 ; i + + ) {
method_cache . arguments . push_back ( PropertyInfo ( Variant : : NIL , " arg " + itos ( i ) ) ) ;
2016-09-08 00:39:02 +02:00
use_default_args + + ;
}
}
2016-08-25 22:45:20 +02:00
} else if ( script . is_valid ( ) & & script - > has_method ( function ) ) {
method_cache = script - > get_method_info ( function ) ;
2017-03-05 16:44:50 +01:00
use_default_args = method_cache . default_arguments . size ( ) ;
2016-08-25 22:45:20 +02:00
}
}
2017-03-05 16:44:50 +01:00
void VisualScriptFunctionCall : : set_function ( const StringName & p_type ) {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
if ( function = = p_type )
2016-08-03 00:11:05 +02:00
return ;
2017-03-05 16:44:50 +01:00
function = p_type ;
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_BASIC_TYPE ) {
use_default_args = Variant : : get_method_default_arguments ( basic_type , function ) . size ( ) ;
2016-08-25 22:45:20 +02:00
} else {
//update all caches
_update_method_cache ( ) ;
}
2016-08-03 00:11:05 +02:00
_change_notify ( ) ;
2016-08-04 03:06:39 +02:00
ports_changed_notify ( ) ;
2016-08-03 00:11:05 +02:00
}
StringName VisualScriptFunctionCall : : get_function ( ) const {
return function ;
}
2017-03-05 16:44:50 +01:00
void VisualScriptFunctionCall : : set_base_path ( const NodePath & p_type ) {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
if ( base_path = = p_type )
2016-08-03 00:11:05 +02:00
return ;
2017-03-05 16:44:50 +01:00
base_path = p_type ;
2016-08-03 00:11:05 +02:00
_change_notify ( ) ;
2016-08-04 03:06:39 +02:00
ports_changed_notify ( ) ;
2016-08-03 00:11:05 +02:00
}
NodePath VisualScriptFunctionCall : : get_base_path ( ) const {
return base_path ;
}
void VisualScriptFunctionCall : : set_call_mode ( CallMode p_mode ) {
2017-03-05 16:44:50 +01:00
if ( call_mode = = p_mode )
2016-08-03 00:11:05 +02:00
return ;
2017-03-05 16:44:50 +01:00
call_mode = p_mode ;
2016-08-03 00:11:05 +02:00
_change_notify ( ) ;
2016-08-04 03:06:39 +02:00
ports_changed_notify ( ) ;
2016-08-03 00:11:05 +02:00
}
VisualScriptFunctionCall : : CallMode VisualScriptFunctionCall : : get_call_mode ( ) const {
return call_mode ;
}
void VisualScriptFunctionCall : : set_use_default_args ( int p_amount ) {
2017-03-05 16:44:50 +01:00
if ( use_default_args = = p_amount )
2016-08-03 00:11:05 +02:00
return ;
2017-03-05 16:44:50 +01:00
use_default_args = p_amount ;
2016-08-04 03:06:39 +02:00
ports_changed_notify ( ) ;
2016-08-03 00:11:05 +02:00
}
2016-08-25 22:45:20 +02:00
void VisualScriptFunctionCall : : set_rpc_call_mode ( VisualScriptFunctionCall : : RPCCallMode p_mode ) {
2017-03-05 16:44:50 +01:00
if ( rpc_call_mode = = p_mode )
2016-08-25 22:45:20 +02:00
return ;
2017-03-05 16:44:50 +01:00
rpc_call_mode = p_mode ;
2016-08-25 22:45:20 +02:00
ports_changed_notify ( ) ;
_change_notify ( ) ;
}
2017-03-05 16:44:50 +01:00
VisualScriptFunctionCall : : RPCCallMode VisualScriptFunctionCall : : get_rpc_call_mode ( ) const {
2016-08-25 22:45:20 +02:00
return rpc_call_mode ;
}
2017-03-05 16:44:50 +01:00
int VisualScriptFunctionCall : : get_use_default_args ( ) const {
2016-08-03 00:11:05 +02:00
return use_default_args ;
}
2016-08-25 22:45:20 +02:00
2016-08-31 22:58:51 +02:00
void VisualScriptFunctionCall : : set_validate ( bool p_amount ) {
2017-03-05 16:44:50 +01:00
validate = p_amount ;
2016-08-31 22:58:51 +02:00
}
bool VisualScriptFunctionCall : : get_validate ( ) const {
return validate ;
}
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
void VisualScriptFunctionCall : : _set_argument_cache ( const Dictionary & p_cache ) {
2016-08-25 22:45:20 +02:00
//so everything works in case all else fails
2017-03-05 16:44:50 +01:00
method_cache = MethodInfo : : from_dict ( p_cache ) ;
2016-08-25 22:45:20 +02:00
}
Dictionary VisualScriptFunctionCall : : _get_argument_cache ( ) const {
return method_cache ;
}
2017-03-05 16:44:50 +01:00
void VisualScriptFunctionCall : : _validate_property ( PropertyInfo & property ) const {
2016-08-03 00:11:05 +02:00
2017-07-01 02:30:17 +02:00
if ( property . name = = " base_type " ) {
2017-03-05 16:44:50 +01:00
if ( call_mode ! = CALL_MODE_INSTANCE ) {
property . usage = PROPERTY_USAGE_NOEDITOR ;
2016-08-03 00:11:05 +02:00
}
}
2017-07-01 02:30:17 +02:00
if ( property . name = = " base_script " ) {
2017-03-05 16:44:50 +01:00
if ( call_mode ! = CALL_MODE_INSTANCE ) {
property . usage = 0 ;
2016-08-25 22:45:20 +02:00
}
}
2017-07-01 02:30:17 +02:00
if ( property . name = = " basic_type " ) {
2017-03-05 16:44:50 +01:00
if ( call_mode ! = CALL_MODE_BASIC_TYPE ) {
property . usage = 0 ;
2016-08-03 16:28:20 +02:00
}
}
2016-08-03 00:11:05 +02:00
2017-07-01 02:30:17 +02:00
if ( property . name = = " singleton " ) {
2017-03-05 16:44:50 +01:00
if ( call_mode ! = CALL_MODE_SINGLETON ) {
property . usage = 0 ;
2016-08-29 01:57:27 +02:00
} else {
2017-07-19 22:00:46 +02:00
List < ProjectSettings : : Singleton > names ;
ProjectSettings : : get_singleton ( ) - > get_singletons ( & names ) ;
2017-03-05 16:44:50 +01:00
property . hint = PROPERTY_HINT_ENUM ;
2016-08-29 01:57:27 +02:00
String sl ;
2017-07-19 22:00:46 +02:00
for ( List < ProjectSettings : : Singleton > : : Element * E = names . front ( ) ; E ; E = E - > next ( ) ) {
2017-03-05 16:44:50 +01:00
if ( sl ! = String ( ) )
sl + = " , " ;
sl + = E - > get ( ) . name ;
2016-08-29 01:57:27 +02:00
}
2017-03-05 16:44:50 +01:00
property . hint_string = sl ;
2016-08-29 01:57:27 +02:00
}
}
2017-07-01 02:30:17 +02:00
if ( property . name = = " node_path " ) {
2017-03-05 16:44:50 +01:00
if ( call_mode ! = CALL_MODE_NODE_PATH ) {
property . usage = 0 ;
2016-08-03 00:11:05 +02:00
} else {
Node * bnode = _get_base_node ( ) ;
if ( bnode ) {
2017-03-05 16:44:50 +01:00
property . hint_string = bnode - > get_path ( ) ; //convert to loong string
2016-08-03 00:11:05 +02:00
} else {
}
}
}
2017-07-01 02:30:17 +02:00
if ( property . name = = " function " ) {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_BASIC_TYPE ) {
2016-08-03 16:28:20 +02:00
2017-03-05 16:44:50 +01:00
property . hint = PROPERTY_HINT_METHOD_OF_VARIANT_TYPE ;
property . hint_string = Variant : : get_type_name ( basic_type ) ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
} else if ( call_mode = = CALL_MODE_SELF & & get_visual_script ( ) . is_valid ( ) ) {
property . hint = PROPERTY_HINT_METHOD_OF_SCRIPT ;
2017-08-07 12:17:31 +02:00
property . hint_string = itos ( get_visual_script ( ) - > get_instance_id ( ) ) ;
2017-03-05 16:44:50 +01:00
} else if ( call_mode = = CALL_MODE_SINGLETON ) {
2016-08-29 01:57:27 +02:00
2017-07-19 22:00:46 +02:00
Object * obj = ProjectSettings : : get_singleton ( ) - > get_singleton_object ( singleton ) ;
2016-08-29 01:57:27 +02:00
if ( obj ) {
2017-03-05 16:44:50 +01:00
property . hint = PROPERTY_HINT_METHOD_OF_INSTANCE ;
2017-08-07 12:17:31 +02:00
property . hint_string = itos ( obj - > get_instance_id ( ) ) ;
2016-08-29 01:57:27 +02:00
} else {
2017-03-05 16:44:50 +01:00
property . hint = PROPERTY_HINT_METHOD_OF_BASE_TYPE ;
property . hint_string = base_type ; //should be cached
2016-08-29 01:57:27 +02:00
}
2017-03-05 16:44:50 +01:00
} else if ( call_mode = = CALL_MODE_INSTANCE ) {
property . hint = PROPERTY_HINT_METHOD_OF_BASE_TYPE ;
property . hint_string = base_type ;
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
if ( base_script ! = String ( ) ) {
2016-08-25 22:45:20 +02:00
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 ) ) {
2017-03-05 16:44:50 +01:00
Ref < Script > script = Ref < Resource > ( ResourceCache : : get ( base_script ) ) ;
2016-08-25 22:45:20 +02:00
if ( script . is_valid ( ) ) {
2017-03-05 16:44:50 +01:00
property . hint = PROPERTY_HINT_METHOD_OF_SCRIPT ;
2017-08-07 12:17:31 +02:00
property . hint_string = itos ( script - > get_instance_id ( ) ) ;
2016-08-25 22:45:20 +02:00
}
}
}
2017-03-05 16:44:50 +01:00
} else if ( call_mode = = CALL_MODE_NODE_PATH ) {
2016-08-24 00:29:07 +02:00
Node * node = _get_base_node ( ) ;
if ( node ) {
2017-03-05 16:44:50 +01:00
property . hint = PROPERTY_HINT_METHOD_OF_INSTANCE ;
2017-08-07 12:17:31 +02:00
property . hint_string = itos ( node - > get_instance_id ( ) ) ;
2016-08-24 00:29:07 +02:00
} else {
2017-03-05 16:44:50 +01:00
property . hint = PROPERTY_HINT_METHOD_OF_BASE_TYPE ;
property . hint_string = get_base_type ( ) ;
2016-08-24 00:29:07 +02:00
}
2016-08-03 00:11:05 +02:00
}
}
2017-07-01 02:30:17 +02:00
if ( property . name = = " use_default_args " ) {
2016-08-03 16:28:20 +02:00
2017-03-05 16:44:50 +01:00
property . hint = PROPERTY_HINT_RANGE ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
int mc = 0 ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_BASIC_TYPE ) {
2016-08-03 16:28:20 +02:00
2017-03-05 16:44:50 +01:00
mc = Variant : : get_method_default_arguments ( basic_type , function ) . size ( ) ;
2016-08-03 16:28:20 +02:00
} else {
2017-03-05 16:44:50 +01:00
MethodBind * mb = ClassDB : : get_method ( _get_base_type ( ) , function ) ;
2016-08-03 16:28:20 +02:00
if ( mb ) {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
mc = mb - > get_default_argument_count ( ) ;
2016-08-03 16:28:20 +02:00
}
2016-08-03 00:11:05 +02:00
}
2017-03-05 16:44:50 +01:00
if ( mc = = 0 ) {
property . usage = 0 ; //do not show
2016-08-03 16:28:20 +02:00
} else {
2017-03-05 16:44:50 +01:00
property . hint_string = " 0, " + itos ( mc ) + " ,1 " ;
2016-08-03 16:28:20 +02:00
}
2016-08-03 00:11:05 +02:00
}
2016-08-25 22:45:20 +02:00
2017-07-01 02:30:17 +02:00
if ( property . name = = " rpc_call_mode " ) {
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_BASIC_TYPE ) {
property . usage = 0 ;
2016-08-25 22:45:20 +02:00
}
}
2016-08-03 00:11:05 +02:00
}
void VisualScriptFunctionCall : : _bind_methods ( ) {
2017-03-05 16:44:50 +01:00
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 ) ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
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 ) ;
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
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 ) ;
2016-08-03 16:28:20 +02:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_singleton " , " singleton " ) , & VisualScriptFunctionCall : : set_singleton ) ;
ClassDB : : bind_method ( D_METHOD ( " get_singleton " ) , & VisualScriptFunctionCall : : get_singleton ) ;
2016-08-29 01:57:27 +02:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_function " , " function " ) , & VisualScriptFunctionCall : : set_function ) ;
ClassDB : : bind_method ( D_METHOD ( " get_function " ) , & VisualScriptFunctionCall : : get_function ) ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
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 ) ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
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 ) ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
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 ) ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
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 ) ;
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
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 ) ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_validate " , " enable " ) , & VisualScriptFunctionCall : : set_validate ) ;
ClassDB : : bind_method ( D_METHOD ( " get_validate " ) , & VisualScriptFunctionCall : : get_validate ) ;
2016-08-31 22:58:51 +02:00
2016-08-03 16:28:20 +02:00
String bt ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < Variant : : VARIANT_MAX ; i + + ) {
if ( i > 0 )
bt + = " , " ;
2016-08-03 16:28:20 +02:00
2017-03-05 16:44:50 +01:00
bt + = Variant : : get_type_name ( Variant : : Type ( i ) ) ;
2016-08-03 16:28:20 +02:00
}
2016-08-25 22:45:20 +02:00
List < String > script_extensions ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < ScriptServer : : get_language_count ( ) ; i + + ) {
2016-08-25 22:45:20 +02:00
ScriptServer : : get_language ( i ) - > get_recognized_extensions ( & script_extensions ) ;
}
String script_ext_hint ;
2017-03-05 16:44:50 +01:00
for ( List < String > : : Element * E = script_extensions . front ( ) ; E ; E = E - > next ( ) ) {
if ( script_ext_hint ! = String ( ) )
script_ext_hint + = " , " ;
script_ext_hint + = " *. " + E - > get ( ) ;
}
2017-07-01 02:30:17 +02:00
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_NOEDITOR ) , " _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.
2017-03-05 16:44:50 +01:00
2017-08-20 17:45:01 +02:00
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 ) ;
2017-09-12 21:09:06 +02:00
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 ) ;
2016-08-03 00:11:05 +02:00
}
2016-08-06 03:46:45 +02:00
class VisualScriptNodeInstanceFunctionCall : public VisualScriptNodeInstance {
public :
VisualScriptFunctionCall : : CallMode call_mode ;
NodePath node_path ;
int input_args ;
2016-08-31 22:58:51 +02:00
bool validate ;
2016-08-06 03:46:45 +02:00
bool returns ;
2016-08-25 22:45:20 +02:00
VisualScriptFunctionCall : : RPCCallMode rpc_mode ;
2016-08-06 03:46:45 +02:00
StringName function ;
2016-08-29 01:57:27 +02:00
StringName singleton ;
2016-08-06 03:46:45 +02:00
VisualScriptFunctionCall * node ;
VisualScriptInstance * instance ;
//virtual int get_working_memory_size() const { 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; }
2017-03-05 16:44:50 +01:00
_FORCE_INLINE_ bool call_rpc ( Object * p_base , const Variant * * p_args , int p_argcount ) {
2016-08-25 22:45:20 +02:00
if ( ! p_base )
return false ;
2017-08-24 22:58:51 +02:00
Node * node = Object : : cast_to < Node > ( p_base ) ;
2016-08-25 22:45:20 +02:00
if ( ! node )
return false ;
2017-03-05 16:44:50 +01:00
int to_id = 0 ;
bool reliable = true ;
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
if ( rpc_mode > = VisualScriptFunctionCall : : RPC_RELIABLE_TO_ID ) {
2016-08-25 22:45:20 +02:00
to_id = * p_args [ 0 ] ;
2017-03-05 16:44:50 +01:00
p_args + = 1 ;
p_argcount - = 1 ;
if ( rpc_mode = = VisualScriptFunctionCall : : RPC_UNRELIABLE_TO_ID ) {
reliable = false ;
2016-08-25 22:45:20 +02:00
}
2017-03-05 16:44:50 +01:00
} else if ( rpc_mode = = VisualScriptFunctionCall : : RPC_UNRELIABLE ) {
reliable = false ;
2016-08-25 22:45:20 +02:00
}
2017-03-05 16:44:50 +01:00
node - > rpcp ( to_id , ! reliable , function , p_args , p_argcount ) ;
2016-08-25 22:45:20 +02:00
return true ;
}
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 ) {
2016-08-06 03:46:45 +02:00
2017-03-05 16:44:50 +01:00
switch ( call_mode ) {
2016-08-06 03:46:45 +02:00
case VisualScriptFunctionCall : : CALL_MODE_SELF : {
2017-03-05 16:44:50 +01:00
Object * object = instance - > get_owner_ptr ( ) ;
2016-08-06 03:46:45 +02:00
2016-08-25 22:45:20 +02:00
if ( rpc_mode ) {
2017-03-05 16:44:50 +01:00
call_rpc ( object , p_inputs , input_args ) ;
2016-08-25 22:45:20 +02:00
} else if ( returns ) {
2017-03-05 16:44:50 +01:00
* p_outputs [ 0 ] = object - > call ( function , p_inputs , input_args , r_error ) ;
2016-08-06 03:46:45 +02:00
} else {
2017-03-05 16:44:50 +01:00
object - > call ( function , p_inputs , input_args , r_error ) ;
2016-08-06 03:46:45 +02:00
}
} break ;
case VisualScriptFunctionCall : : CALL_MODE_NODE_PATH : {
2017-08-24 22:58:51 +02:00
Node * node = Object : : cast_to < Node > ( instance - > get_owner_ptr ( ) ) ;
2016-08-06 03:46:45 +02:00
if ( ! node ) {
2017-03-05 16:44:50 +01:00
r_error . error = Variant : : CallError : : CALL_ERROR_INVALID_METHOD ;
r_error_str = " Base object is not a Node! " ;
2016-08-06 03:46:45 +02:00
return 0 ;
}
2017-03-05 16:44:50 +01:00
Node * another = node - > get_node ( node_path ) ;
2017-08-25 17:14:33 +02:00
if ( ! another ) {
2017-03-05 16:44:50 +01:00
r_error . error = Variant : : CallError : : CALL_ERROR_INVALID_METHOD ;
r_error_str = " Path does not lead Node! " ;
2016-08-06 03:46:45 +02:00
return 0 ;
}
2016-08-25 22:45:20 +02:00
if ( rpc_mode ) {
2017-03-05 16:44:50 +01:00
call_rpc ( node , p_inputs , input_args ) ;
2016-08-25 22:45:20 +02:00
} else if ( returns ) {
2017-03-05 16:44:50 +01:00
* p_outputs [ 0 ] = another - > call ( function , p_inputs , input_args , r_error ) ;
2016-08-06 03:46:45 +02:00
} else {
2017-03-05 16:44:50 +01:00
another - > call ( function , p_inputs , input_args , r_error ) ;
2016-08-06 03:46:45 +02:00
}
} break ;
case VisualScriptFunctionCall : : CALL_MODE_INSTANCE :
case VisualScriptFunctionCall : : CALL_MODE_BASIC_TYPE : {
Variant v = * p_inputs [ 0 ] ;
2016-08-08 00:22:33 +02:00
2016-08-25 22:45:20 +02:00
if ( rpc_mode ) {
Object * obj = v ;
if ( obj ) {
2017-03-05 16:44:50 +01:00
call_rpc ( obj , p_inputs + 1 , input_args - 1 ) ;
2016-08-25 22:45:20 +02:00
}
} else if ( returns ) {
2017-03-05 16:44:50 +01:00
if ( call_mode = = VisualScriptFunctionCall : : CALL_MODE_INSTANCE ) {
* p_outputs [ 1 ] = v . call ( function , p_inputs + 1 , input_args , r_error ) ;
2016-08-29 01:57:27 +02:00
} else {
2017-03-05 16:44:50 +01:00
* p_outputs [ 0 ] = v . call ( function , p_inputs + 1 , input_args , r_error ) ;
2016-08-29 01:57:27 +02:00
}
2016-08-06 03:46:45 +02:00
} else {
2017-03-05 16:44:50 +01:00
v . call ( function , p_inputs + 1 , input_args , r_error ) ;
2016-08-06 03:46:45 +02:00
}
2017-03-05 16:44:50 +01:00
if ( call_mode = = VisualScriptFunctionCall : : CALL_MODE_INSTANCE ) {
* p_outputs [ 0 ] = * p_inputs [ 0 ] ;
2016-08-29 01:57:27 +02:00
}
2016-08-06 03:46:45 +02:00
} break ;
2016-08-29 01:57:27 +02:00
case VisualScriptFunctionCall : : CALL_MODE_SINGLETON : {
2017-07-19 22:00:46 +02:00
Object * object = ProjectSettings : : get_singleton ( ) - > get_singleton_object ( singleton ) ;
2016-08-29 01:57:27 +02:00
if ( ! object ) {
2017-03-05 16:44:50 +01:00
r_error . error = Variant : : CallError : : CALL_ERROR_INVALID_METHOD ;
r_error_str = " Invalid singleton name: ' " + String ( singleton ) + " ' " ;
2016-08-29 01:57:27 +02:00
return 0 ;
}
2016-08-06 03:46:45 +02:00
2016-08-29 01:57:27 +02:00
if ( rpc_mode ) {
2017-03-05 16:44:50 +01:00
call_rpc ( object , p_inputs , input_args ) ;
2016-08-29 01:57:27 +02:00
} else if ( returns ) {
2017-03-05 16:44:50 +01:00
* p_outputs [ 0 ] = object - > call ( function , p_inputs , input_args , r_error ) ;
2016-08-29 01:57:27 +02:00
} else {
2017-03-05 16:44:50 +01:00
object - > call ( function , p_inputs , input_args , r_error ) ;
2016-08-29 01:57:27 +02:00
}
} break ;
2016-08-06 03:46:45 +02:00
}
2016-08-31 22:58:51 +02:00
if ( ! validate ) {
//ignore call errors if validation is disabled
2017-03-05 16:44:50 +01:00
r_error . error = Variant : : CallError : : CALL_OK ;
r_error_str = String ( ) ;
2016-08-31 22:58:51 +02:00
}
2016-08-06 03:46:45 +02:00
return 0 ;
}
} ;
2017-03-05 16:44:50 +01:00
VisualScriptNodeInstance * VisualScriptFunctionCall : : instance ( 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 ;
2016-08-06 03:46:45 +02:00
return instance ;
}
2016-09-03 19:58:23 +02:00
2017-03-05 16:44:50 +01:00
VisualScriptFunctionCall : : TypeGuess VisualScriptFunctionCall : : guess_output_type ( TypeGuess * p_inputs , int p_output ) const {
2016-09-03 19:58:23 +02:00
2017-03-05 16:44:50 +01:00
if ( p_output = = 0 & & call_mode = = CALL_MODE_INSTANCE ) {
2016-09-03 19:58:23 +02:00
return p_inputs [ 0 ] ;
}
2017-03-05 16:44:50 +01:00
return VisualScriptNode : : guess_output_type ( p_inputs , p_output ) ;
2016-09-03 19:58:23 +02:00
}
2016-08-03 00:11:05 +02:00
VisualScriptFunctionCall : : VisualScriptFunctionCall ( ) {
2017-03-05 16:44:50 +01:00
validate = true ;
call_mode = CALL_MODE_SELF ;
basic_type = Variant : : NIL ;
use_default_args = 0 ;
base_type = " Object " ;
rpc_call_mode = RPC_DISABLED ;
2016-08-03 00:11:05 +02:00
}
2017-03-05 16:44:50 +01:00
template < VisualScriptFunctionCall : : CallMode cmode >
static Ref < VisualScriptNode > create_function_call_node ( const String & p_name ) {
2016-08-03 00:11:05 +02:00
Ref < VisualScriptFunctionCall > node ;
node . instance ( ) ;
node - > set_call_mode ( cmode ) ;
return node ;
}
//////////////////////////////////////////
////////////////SET//////////////////////
//////////////////////////////////////////
int VisualScriptPropertySet : : get_output_sequence_port_count ( ) const {
2017-03-05 16:44:50 +01:00
return call_mode ! = CALL_MODE_BASIC_TYPE ? 1 : 0 ;
2016-08-03 00:11:05 +02:00
}
2017-03-05 16:44:50 +01:00
bool VisualScriptPropertySet : : has_input_sequence_port ( ) const {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
return call_mode ! = CALL_MODE_BASIC_TYPE ? true : false ;
2016-08-03 00:11:05 +02:00
}
Node * VisualScriptPropertySet : : _get_base_node ( ) const {
# ifdef TOOLS_ENABLED
Ref < Script > script = get_visual_script ( ) ;
if ( ! script . is_valid ( ) )
return NULL ;
2017-03-05 16:44:50 +01:00
MainLoop * main_loop = OS : : get_singleton ( ) - > get_main_loop ( ) ;
2016-08-03 00:11:05 +02:00
2017-08-24 22:58:51 +02:00
SceneTree * scene_tree = Object : : cast_to < SceneTree > ( main_loop ) ;
2016-08-03 00:11:05 +02:00
if ( ! scene_tree )
return NULL ;
Node * edited_scene = scene_tree - > get_edited_scene_root ( ) ;
if ( ! edited_scene )
return NULL ;
2017-03-05 16:44:50 +01:00
Node * script_node = _find_script_node ( edited_scene , edited_scene , script ) ;
2016-08-03 00:11:05 +02:00
if ( ! script_node )
return NULL ;
if ( ! script_node - > has_node ( base_path ) )
return NULL ;
Node * path_to = script_node - > get_node ( base_path ) ;
return path_to ;
# else
return NULL ;
# endif
}
StringName VisualScriptPropertySet : : _get_base_type ( ) const {
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_SELF & & get_visual_script ( ) . is_valid ( ) )
2016-08-03 00:11:05 +02:00
return get_visual_script ( ) - > get_instance_base_type ( ) ;
2017-03-05 16:44:50 +01:00
else if ( call_mode = = CALL_MODE_NODE_PATH & & get_visual_script ( ) . is_valid ( ) ) {
2016-08-03 00:11:05 +02:00
Node * path = _get_base_node ( ) ;
if ( path )
2017-01-03 03:03:46 +01:00
return path - > get_class ( ) ;
2016-08-03 00:11:05 +02:00
}
return base_type ;
}
2017-03-05 16:44:50 +01:00
int VisualScriptPropertySet : : get_input_value_port_count ( ) const {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
int pc = ( call_mode = = CALL_MODE_BASIC_TYPE | | call_mode = = CALL_MODE_INSTANCE ) ? 2 : 1 ;
2016-08-03 00:11:05 +02:00
2016-08-03 16:28:20 +02:00
return pc ;
2016-08-03 00:11:05 +02:00
}
2017-03-05 16:44:50 +01:00
int VisualScriptPropertySet : : get_output_value_port_count ( ) const {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
return ( call_mode = = CALL_MODE_BASIC_TYPE | | call_mode = = CALL_MODE_INSTANCE ) ? 1 : 0 ;
2016-08-03 00:11:05 +02:00
}
String VisualScriptPropertySet : : get_output_sequence_port_text ( int p_port ) const {
return String ( ) ;
}
2017-07-01 02:30:17 +02:00
void VisualScriptPropertySet : : _adjust_input_index ( PropertyInfo & pinfo ) const {
if ( index ! = StringName ( ) ) {
Variant v ;
Variant : : CallError ce ;
v = Variant : : construct ( pinfo . type , NULL , 0 , ce ) ;
Variant i = v . get ( index ) ;
pinfo . type = i . get_type ( ) ;
}
}
2017-03-05 16:44:50 +01:00
PropertyInfo VisualScriptPropertySet : : get_input_value_port_info ( int p_idx ) const {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_INSTANCE | | call_mode = = CALL_MODE_BASIC_TYPE ) {
if ( p_idx = = 0 ) {
2016-08-03 00:11:05 +02:00
PropertyInfo pi ;
2017-03-05 16:44:50 +01:00
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 ( ) ) ;
2017-07-01 02:30:17 +02:00
_adjust_input_index ( pi ) ;
2016-08-03 00:11:05 +02:00
return pi ;
} else {
p_idx - - ;
}
}
2017-03-05 16:44:50 +01:00
PropertyInfo pinfo = type_cache ;
pinfo . name = " value " ;
2017-07-01 02:30:17 +02:00
_adjust_input_index ( pinfo ) ;
2016-08-25 22:45:20 +02:00
return pinfo ;
2016-08-03 00:11:05 +02:00
}
2017-03-05 16:44:50 +01:00
PropertyInfo VisualScriptPropertySet : : get_output_value_port_info ( int p_idx ) const {
if ( call_mode = = CALL_MODE_BASIC_TYPE ) {
return PropertyInfo ( basic_type , " out " ) ;
} else if ( call_mode = = CALL_MODE_INSTANCE ) {
return PropertyInfo ( Variant : : OBJECT , " pass " ) ;
2016-08-08 00:22:33 +02:00
} else {
return PropertyInfo ( ) ;
}
2016-08-03 00:11:05 +02:00
}
String VisualScriptPropertySet : : get_caption ( ) const {
2017-03-05 16:44:50 +01:00
static const char * cname [ 4 ] = {
2017-07-01 02:30:17 +02:00
" Self " ,
" Node " ,
" Instance " ,
" Basic "
2016-08-03 16:28:20 +02:00
} ;
2017-07-01 02:30:17 +02:00
static const char * opname [ ASSIGN_OP_MAX ] = {
" Set " , " Add " , " Sub " , " Mul " , " Div " , " Mod " , " ShiftLeft " , " ShiftRight " , " BitAnd " , " BitOr " , " BitXor "
} ;
return String ( cname [ call_mode ] ) + opname [ assign_op ] ;
2016-08-03 00:11:05 +02:00
}
String VisualScriptPropertySet : : get_text ( ) const {
2016-08-03 16:28:20 +02:00
String prop ;
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_BASIC_TYPE )
prop = Variant : : get_type_name ( basic_type ) + " . " + property ;
else if ( call_mode = = CALL_MODE_NODE_PATH )
prop = String ( base_path ) + " : " + property ;
else if ( call_mode = = CALL_MODE_SELF )
prop = property ;
else if ( call_mode = = CALL_MODE_INSTANCE )
prop = String ( base_type ) + " : " + property ;
2016-08-03 16:28:20 +02:00
2017-07-01 02:30:17 +02:00
if ( index ! = StringName ( ) ) {
prop + = " . " + String ( index ) ;
}
2016-08-03 16:28:20 +02:00
return prop ;
}
2016-08-04 03:06:39 +02:00
void VisualScriptPropertySet : : _update_base_type ( ) {
//cache it because this information may not be available on load
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_NODE_PATH ) {
2016-08-03 16:28:20 +02:00
2017-03-05 16:44:50 +01:00
Node * node = _get_base_node ( ) ;
2016-08-04 03:06:39 +02:00
if ( node ) {
2017-03-05 16:44:50 +01:00
base_type = node - > get_class ( ) ;
2016-08-04 03:06:39 +02:00
}
2017-03-05 16:44:50 +01:00
} else if ( call_mode = = CALL_MODE_SELF ) {
2016-08-04 03:06:39 +02:00
if ( get_visual_script ( ) . is_valid ( ) ) {
2017-03-05 16:44:50 +01:00
base_type = get_visual_script ( ) - > get_instance_base_type ( ) ;
2016-08-04 03:06:39 +02:00
}
}
}
2016-08-03 16:28:20 +02:00
void VisualScriptPropertySet : : set_basic_type ( Variant : : Type p_type ) {
2017-03-05 16:44:50 +01:00
if ( basic_type = = p_type )
2016-08-03 16:28:20 +02:00
return ;
2017-03-05 16:44:50 +01:00
basic_type = p_type ;
2016-08-03 16:28:20 +02:00
_change_notify ( ) ;
2016-08-04 03:06:39 +02:00
_update_base_type ( ) ;
ports_changed_notify ( ) ;
2016-08-03 16:28:20 +02:00
}
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
Variant : : Type VisualScriptPropertySet : : get_basic_type ( ) const {
2016-08-03 16:28:20 +02:00
return basic_type ;
2016-08-03 00:11:05 +02:00
}
2017-03-05 16:44:50 +01:00
void VisualScriptPropertySet : : set_base_type ( const StringName & p_type ) {
2016-08-03 16:28:20 +02:00
2017-03-05 16:44:50 +01:00
if ( base_type = = p_type )
2016-08-03 00:11:05 +02:00
return ;
2017-03-05 16:44:50 +01:00
base_type = p_type ;
_change_notify ( ) ;
2016-08-04 03:06:39 +02:00
ports_changed_notify ( ) ;
2016-08-03 00:11:05 +02:00
}
2017-03-05 16:44:50 +01:00
StringName VisualScriptPropertySet : : get_base_type ( ) const {
2016-08-03 00:11:05 +02:00
return base_type ;
}
2017-03-05 16:44:50 +01:00
void VisualScriptPropertySet : : set_base_script ( const String & p_path ) {
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
if ( base_script = = p_path )
2016-08-25 22:45:20 +02:00
return ;
2017-03-05 16:44:50 +01:00
base_script = p_path ;
2016-08-25 22:45:20 +02:00
_change_notify ( ) ;
ports_changed_notify ( ) ;
}
String VisualScriptPropertySet : : get_base_script ( ) const {
return base_script ;
}
void VisualScriptPropertySet : : _update_cache ( ) {
2017-08-24 22:58:51 +02:00
if ( ! Object : : cast_to < SceneTree > ( OS : : get_singleton ( ) - > get_main_loop ( ) ) )
2016-08-25 22:45:20 +02:00
return ;
2017-08-19 01:02:56 +02:00
if ( ! Engine : : get_singleton ( ) - > is_editor_hint ( ) ) //only update cache if editor exists, it's pointless otherwise
2016-08-25 22:45:20 +02:00
return ;
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_BASIC_TYPE ) {
2016-08-25 22:45:20 +02:00
//not super efficient..
Variant v ;
2017-05-20 17:38:03 +02:00
Variant : : CallError ce ;
v = Variant : : construct ( basic_type , NULL , 0 , ce ) ;
2016-08-25 22:45:20 +02:00
List < PropertyInfo > pinfo ;
v . get_property_list ( & pinfo ) ;
2017-03-05 16:44:50 +01:00
for ( List < PropertyInfo > : : Element * E = pinfo . front ( ) ; E ; E = E - > next ( ) ) {
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
if ( E - > get ( ) . name = = property ) {
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
type_cache = E - > get ( ) ;
2016-08-25 22:45:20 +02:00
}
}
} else {
StringName type ;
Ref < Script > script ;
2017-03-05 16:44:50 +01:00
Node * node = NULL ;
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_NODE_PATH ) {
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
node = _get_base_node ( ) ;
2016-08-25 22:45:20 +02:00
if ( node ) {
2017-03-05 16:44:50 +01:00
type = node - > get_class ( ) ;
base_type = type ; //cache, too
2016-08-25 22:45:20 +02:00
script = node - > get_script ( ) ;
}
2017-03-05 16:44:50 +01:00
} else if ( call_mode = = CALL_MODE_SELF ) {
2016-08-25 22:45:20 +02:00
if ( get_visual_script ( ) . is_valid ( ) ) {
2017-03-05 16:44:50 +01:00
type = get_visual_script ( ) - > get_instance_base_type ( ) ;
base_type = type ; //cache, too
script = get_visual_script ( ) ;
2016-08-25 22:45:20 +02:00
}
2017-03-05 16:44:50 +01:00
} else if ( call_mode = = CALL_MODE_INSTANCE ) {
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
type = base_type ;
if ( base_script ! = String ( ) ) {
2016-08-25 22:45:20 +02:00
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 ) ) {
2017-03-05 16:44:50 +01:00
script = Ref < Resource > ( ResourceCache : : get ( base_script ) ) ;
2016-08-25 22:45:20 +02:00
} else {
return ;
}
}
}
List < PropertyInfo > pinfo ;
if ( node ) {
node - > get_property_list ( & pinfo ) ;
} else {
2017-03-05 16:44:50 +01:00
ClassDB : : get_property_list ( type , & pinfo ) ;
2016-08-25 22:45:20 +02:00
}
if ( script . is_valid ( ) ) {
script - > get_script_property_list ( & pinfo ) ;
}
2017-03-05 16:44:50 +01:00
for ( List < PropertyInfo > : : Element * E = pinfo . front ( ) ; E ; E = E - > next ( ) ) {
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
if ( E - > get ( ) . name = = property ) {
type_cache = E - > get ( ) ;
2016-08-25 22:45:20 +02:00
return ;
}
}
}
}
2017-03-05 16:44:50 +01:00
void VisualScriptPropertySet : : set_property ( const StringName & p_type ) {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
if ( property = = p_type )
2016-08-03 00:11:05 +02:00
return ;
2017-03-05 16:44:50 +01:00
property = p_type ;
2017-07-01 02:30:17 +02:00
index = StringName ( ) ;
2016-08-25 22:45:20 +02:00
_update_cache ( ) ;
2017-03-05 16:44:50 +01:00
_change_notify ( ) ;
2016-08-04 03:06:39 +02:00
ports_changed_notify ( ) ;
2016-08-03 00:11:05 +02:00
}
StringName VisualScriptPropertySet : : get_property ( ) const {
return property ;
}
2017-03-05 16:44:50 +01:00
void VisualScriptPropertySet : : set_base_path ( const NodePath & p_type ) {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
if ( base_path = = p_type )
2016-08-03 00:11:05 +02:00
return ;
2017-03-05 16:44:50 +01:00
base_path = p_type ;
2016-08-04 03:06:39 +02:00
_update_base_type ( ) ;
2016-08-03 00:11:05 +02:00
_change_notify ( ) ;
2016-08-04 03:06:39 +02:00
ports_changed_notify ( ) ;
2016-08-03 00:11:05 +02:00
}
NodePath VisualScriptPropertySet : : get_base_path ( ) const {
return base_path ;
}
void VisualScriptPropertySet : : set_call_mode ( CallMode p_mode ) {
2017-03-05 16:44:50 +01:00
if ( call_mode = = p_mode )
2016-08-03 00:11:05 +02:00
return ;
2017-03-05 16:44:50 +01:00
call_mode = p_mode ;
2016-08-04 03:06:39 +02:00
_update_base_type ( ) ;
2016-08-03 00:11:05 +02:00
_change_notify ( ) ;
2016-08-04 03:06:39 +02:00
ports_changed_notify ( ) ;
2016-08-03 00:11:05 +02:00
}
VisualScriptPropertySet : : CallMode VisualScriptPropertySet : : get_call_mode ( ) const {
return call_mode ;
}
2016-08-25 22:45:20 +02:00
void VisualScriptPropertySet : : _set_type_cache ( const Dictionary & p_type ) {
2017-03-05 16:44:50 +01:00
type_cache = PropertyInfo : : from_dict ( p_type ) ;
2016-08-25 22:45:20 +02:00
}
Dictionary VisualScriptPropertySet : : _get_type_cache ( ) const {
return type_cache ;
}
2017-07-01 02:30:17 +02:00
void VisualScriptPropertySet : : set_index ( const StringName & p_type ) {
if ( index = = p_type )
return ;
index = p_type ;
_update_cache ( ) ;
_change_notify ( ) ;
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 ( ) ;
_change_notify ( ) ;
ports_changed_notify ( ) ;
}
VisualScriptPropertySet : : AssignOp VisualScriptPropertySet : : get_assign_op ( ) const {
return assign_op ;
}
2017-03-05 16:44:50 +01:00
void VisualScriptPropertySet : : _validate_property ( PropertyInfo & property ) const {
2016-08-03 00:11:05 +02:00
2017-07-01 02:30:17 +02:00
if ( property . name = = " base_type " ) {
2017-03-05 16:44:50 +01:00
if ( call_mode ! = CALL_MODE_INSTANCE ) {
property . usage = PROPERTY_USAGE_NOEDITOR ;
2016-08-03 00:11:05 +02:00
}
}
2017-07-01 02:30:17 +02:00
if ( property . name = = " base_script " ) {
2017-03-05 16:44:50 +01:00
if ( call_mode ! = CALL_MODE_INSTANCE ) {
property . usage = 0 ;
2016-08-25 22:45:20 +02:00
}
}
2016-08-03 00:11:05 +02:00
2017-07-01 02:30:17 +02:00
if ( property . name = = " basic_type " ) {
2017-03-05 16:44:50 +01:00
if ( call_mode ! = CALL_MODE_BASIC_TYPE ) {
property . usage = 0 ;
2016-08-03 16:28:20 +02:00
}
}
2017-07-01 02:30:17 +02:00
if ( property . name = = " node_path " ) {
2017-03-05 16:44:50 +01:00
if ( call_mode ! = CALL_MODE_NODE_PATH ) {
property . usage = 0 ;
2016-08-03 00:11:05 +02:00
} else {
Node * bnode = _get_base_node ( ) ;
if ( bnode ) {
2017-03-05 16:44:50 +01:00
property . hint_string = bnode - > get_path ( ) ; //convert to loong string
2016-08-03 00:11:05 +02:00
} else {
}
}
}
2017-07-01 02:30:17 +02:00
if ( property . name = = " property " ) {
2016-08-03 16:28:20 +02:00
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_BASIC_TYPE ) {
2016-08-03 16:28:20 +02:00
2017-03-05 16:44:50 +01:00
property . hint = PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE ;
property . hint_string = Variant : : get_type_name ( basic_type ) ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
} else if ( call_mode = = CALL_MODE_SELF & & get_visual_script ( ) . is_valid ( ) ) {
property . hint = PROPERTY_HINT_PROPERTY_OF_SCRIPT ;
2017-08-07 12:17:31 +02:00
property . hint_string = itos ( get_visual_script ( ) - > get_instance_id ( ) ) ;
2017-03-05 16:44:50 +01:00
} else if ( call_mode = = CALL_MODE_INSTANCE ) {
property . hint = PROPERTY_HINT_PROPERTY_OF_BASE_TYPE ;
property . hint_string = base_type ;
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
if ( base_script ! = String ( ) ) {
2016-08-25 22:45:20 +02:00
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 ) ) {
2017-03-05 16:44:50 +01:00
Ref < Script > script = Ref < Resource > ( ResourceCache : : get ( base_script ) ) ;
2016-08-25 22:45:20 +02:00
if ( script . is_valid ( ) ) {
2017-03-05 16:44:50 +01:00
property . hint = PROPERTY_HINT_PROPERTY_OF_SCRIPT ;
2017-08-07 12:17:31 +02:00
property . hint_string = itos ( script - > get_instance_id ( ) ) ;
2016-08-25 22:45:20 +02:00
}
}
}
2017-03-05 16:44:50 +01:00
} else if ( call_mode = = CALL_MODE_NODE_PATH ) {
2016-08-24 00:29:07 +02:00
Node * node = _get_base_node ( ) ;
if ( node ) {
2017-03-05 16:44:50 +01:00
property . hint = PROPERTY_HINT_PROPERTY_OF_INSTANCE ;
2017-08-07 12:17:31 +02:00
property . hint_string = itos ( node - > get_instance_id ( ) ) ;
2016-08-03 00:11:05 +02:00
} else {
2017-03-05 16:44:50 +01:00
property . hint = PROPERTY_HINT_PROPERTY_OF_BASE_TYPE ;
property . hint_string = get_base_type ( ) ;
2016-08-03 00:11:05 +02:00
}
}
}
2017-07-01 02:30:17 +02:00
if ( property . name = = " index " ) {
Variant : : CallError ce ;
Variant v = Variant : : construct ( type_cache . type , NULL , 0 , ce ) ;
List < PropertyInfo > plist ;
v . get_property_list ( & plist ) ;
String options = " " ;
for ( List < PropertyInfo > : : Element * E = plist . front ( ) ; E ; E = E - > next ( ) ) {
options + = " , " + E - > get ( ) . name ;
}
property . hint = PROPERTY_HINT_ENUM ;
property . hint_string = options ;
property . type = Variant : : STRING ;
if ( options = = " " )
property . usage = 0 ; //hide if type has no usable index
}
2016-08-03 00:11:05 +02:00
}
void VisualScriptPropertySet : : _bind_methods ( ) {
2017-03-05 16:44:50 +01:00
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 ) ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
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 ) ;
2016-08-03 16:28:20 +02:00
2017-03-05 16:44:50 +01:00
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 ) ;
2016-08-03 16:28:20 +02:00
2017-03-05 16:44:50 +01:00
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 ) ;
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_property " , " property " ) , & VisualScriptPropertySet : : set_property ) ;
ClassDB : : bind_method ( D_METHOD ( " get_property " ) , & VisualScriptPropertySet : : get_property ) ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
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 ) ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
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 ) ;
2016-08-03 00:11:05 +02:00
2017-07-01 02:30:17 +02:00
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 ) ;
2016-08-03 16:28:20 +02:00
String bt ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < Variant : : VARIANT_MAX ; i + + ) {
if ( i > 0 )
bt + = " , " ;
2016-08-03 16:28:20 +02:00
2017-03-05 16:44:50 +01:00
bt + = Variant : : get_type_name ( Variant : : Type ( i ) ) ;
2016-08-03 16:28:20 +02:00
}
2016-08-25 22:45:20 +02:00
List < String > script_extensions ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < ScriptServer : : get_language_count ( ) ; i + + ) {
2016-08-25 22:45:20 +02:00
ScriptServer : : get_language ( i ) - > get_recognized_extensions ( & script_extensions ) ;
}
String script_ext_hint ;
2017-03-05 16:44:50 +01:00
for ( List < String > : : Element * E = script_extensions . front ( ) ; E ; E = E - > next ( ) ) {
if ( script_ext_hint ! = String ( ) )
script_ext_hint + = " , " ;
script_ext_hint + = " *. " + E - > get ( ) ;
2016-08-25 22:45:20 +02:00
}
2016-08-08 00:22:33 +02:00
2017-07-01 02:30:17 +02:00
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_NOEDITOR ) , " _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 " ) ;
2017-08-20 17:45:01 +02:00
BIND_ENUM_CONSTANT ( CALL_MODE_SELF ) ;
BIND_ENUM_CONSTANT ( CALL_MODE_NODE_PATH ) ;
BIND_ENUM_CONSTANT ( CALL_MODE_INSTANCE ) ;
2017-09-12 21:09:06 +02:00
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 ) ;
2016-08-03 00:11:05 +02:00
}
2016-08-06 03:46:45 +02:00
class VisualScriptNodeInstancePropertySet : public VisualScriptNodeInstance {
public :
VisualScriptPropertySet : : CallMode call_mode ;
NodePath node_path ;
StringName property ;
VisualScriptPropertySet * node ;
VisualScriptInstance * instance ;
2017-07-01 02:30:17 +02:00
VisualScriptPropertySet : : AssignOp assign_op ;
StringName index ;
bool needs_get ;
2016-08-06 03:46:45 +02:00
//virtual int get_working_memory_size() const { 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; }
2017-07-01 02:30:17 +02:00
_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 : {
2017-09-17 02:32:05 +02:00
value = Variant : : evaluate ( Variant : : OP_SUBTRACT , value , p_argument ) ;
2017-07-01 02:30:17 +02:00
} 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 ;
}
}
}
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 ) {
2016-08-06 03:46:45 +02:00
2017-03-05 16:44:50 +01:00
switch ( call_mode ) {
2016-08-06 03:46:45 +02:00
case VisualScriptPropertySet : : CALL_MODE_SELF : {
2017-03-05 16:44:50 +01:00
Object * object = instance - > get_owner_ptr ( ) ;
2016-08-06 03:46:45 +02:00
bool valid ;
2017-07-01 02:30:17 +02:00
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 ) ;
}
2016-08-06 03:46:45 +02:00
if ( ! valid ) {
2017-03-05 16:44:50 +01:00
r_error . error = Variant : : CallError : : CALL_ERROR_INVALID_METHOD ;
r_error_str = " Invalid set value ' " + String ( * p_inputs [ 0 ] ) + " ' on property ' " + String ( property ) + " ' of type " + object - > get_class ( ) ;
2016-08-06 03:46:45 +02:00
}
} break ;
case VisualScriptPropertySet : : CALL_MODE_NODE_PATH : {
2017-08-24 22:58:51 +02:00
Node * node = Object : : cast_to < Node > ( instance - > get_owner_ptr ( ) ) ;
2016-08-06 03:46:45 +02:00
if ( ! node ) {
2017-03-05 16:44:50 +01:00
r_error . error = Variant : : CallError : : CALL_ERROR_INVALID_METHOD ;
r_error_str = " Base object is not a Node! " ;
2016-08-06 03:46:45 +02:00
return 0 ;
}
2017-03-05 16:44:50 +01:00
Node * another = node - > get_node ( node_path ) ;
2017-08-25 17:14:33 +02:00
if ( ! another ) {
2017-03-05 16:44:50 +01:00
r_error . error = Variant : : CallError : : CALL_ERROR_INVALID_METHOD ;
r_error_str = " Path does not lead Node! " ;
2016-08-06 03:46:45 +02:00
return 0 ;
}
bool valid ;
2017-07-01 02:30:17 +02:00
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 ) ;
}
2016-08-06 03:46:45 +02:00
if ( ! valid ) {
2017-03-05 16:44:50 +01:00
r_error . error = Variant : : CallError : : CALL_ERROR_INVALID_METHOD ;
r_error_str = " Invalid set value ' " + String ( * p_inputs [ 0 ] ) + " ' on property ' " + String ( property ) + " ' of type " + another - > get_class ( ) ;
2016-08-06 03:46:45 +02:00
}
} break ;
case VisualScriptPropertySet : : CALL_MODE_INSTANCE :
case VisualScriptPropertySet : : CALL_MODE_BASIC_TYPE : {
Variant v = * p_inputs [ 0 ] ;
bool valid ;
2017-07-01 02:30:17 +02:00
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 ) ;
}
2016-08-06 03:46:45 +02:00
if ( ! valid ) {
2017-03-05 16:44:50 +01:00
r_error . error = Variant : : 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 ( ) ) ;
2016-08-06 03:46:45 +02:00
}
2017-03-05 16:44:50 +01:00
* p_outputs [ 0 ] = v ;
2016-08-08 00:22:33 +02:00
2016-08-06 03:46:45 +02:00
} break ;
}
return 0 ;
}
} ;
2017-03-05 16:44:50 +01:00
VisualScriptNodeInstance * VisualScriptPropertySet : : instance ( VisualScriptInstance * p_instance ) {
2016-08-06 03:46:45 +02:00
2017-03-05 16:44:50 +01:00
VisualScriptNodeInstancePropertySet * instance = memnew ( VisualScriptNodeInstancePropertySet ) ;
instance - > node = this ;
instance - > instance = p_instance ;
instance - > property = property ;
instance - > call_mode = call_mode ;
instance - > node_path = base_path ;
2017-07-01 02:30:17 +02:00
instance - > assign_op = assign_op ;
instance - > index = index ;
instance - > needs_get = index ! = StringName ( ) | | assign_op ! = ASSIGN_OP_NONE ;
2016-08-06 03:46:45 +02:00
return instance ;
2016-08-03 00:11:05 +02:00
}
2017-03-05 16:44:50 +01:00
VisualScriptPropertySet : : TypeGuess VisualScriptPropertySet : : guess_output_type ( TypeGuess * p_inputs , int p_output ) const {
2016-09-03 19:58:23 +02:00
2017-03-05 16:44:50 +01:00
if ( p_output = = 0 & & call_mode = = CALL_MODE_INSTANCE ) {
2016-09-03 19:58:23 +02:00
return p_inputs [ 0 ] ;
}
2017-03-05 16:44:50 +01:00
return VisualScriptNode : : guess_output_type ( p_inputs , p_output ) ;
2016-09-03 19:58:23 +02:00
}
2016-08-03 00:11:05 +02:00
VisualScriptPropertySet : : VisualScriptPropertySet ( ) {
2017-07-01 02:30:17 +02:00
assign_op = ASSIGN_OP_NONE ;
2017-03-05 16:44:50 +01:00
call_mode = CALL_MODE_SELF ;
base_type = " Object " ;
basic_type = Variant : : NIL ;
2016-08-03 00:11:05 +02:00
}
2017-03-05 16:44:50 +01:00
template < VisualScriptPropertySet : : CallMode cmode >
static Ref < VisualScriptNode > create_property_set_node ( const String & p_name ) {
2016-08-03 00:11:05 +02:00
Ref < VisualScriptPropertySet > node ;
node . instance ( ) ;
node - > set_call_mode ( cmode ) ;
return node ;
}
//////////////////////////////////////////
2016-08-03 16:28:20 +02:00
////////////////GET//////////////////////
2016-08-03 00:11:05 +02:00
//////////////////////////////////////////
int VisualScriptPropertyGet : : get_output_sequence_port_count ( ) const {
2017-03-05 16:44:50 +01:00
return 0 ; // (call_mode==CALL_MODE_SELF || call_mode==CALL_MODE_NODE_PATH)?0:1;
2016-08-03 00:11:05 +02:00
}
2017-03-05 16:44:50 +01:00
bool VisualScriptPropertyGet : : has_input_sequence_port ( ) const {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
return false ; //(call_mode==CALL_MODE_SELF || call_mode==CALL_MODE_NODE_PATH)?false:true;
2016-08-03 00:11:05 +02:00
}
2016-08-04 03:06:39 +02:00
void VisualScriptPropertyGet : : _update_base_type ( ) {
//cache it because this information may not be available on load
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_NODE_PATH ) {
2016-08-04 03:06:39 +02:00
2017-03-05 16:44:50 +01:00
Node * node = _get_base_node ( ) ;
2016-08-04 03:06:39 +02:00
if ( node ) {
2017-03-05 16:44:50 +01:00
base_type = node - > get_class ( ) ;
2016-08-04 03:06:39 +02:00
}
2017-03-05 16:44:50 +01:00
} else if ( call_mode = = CALL_MODE_SELF ) {
2016-08-03 00:11:05 +02:00
2016-08-04 03:06:39 +02:00
if ( get_visual_script ( ) . is_valid ( ) ) {
2017-03-05 16:44:50 +01:00
base_type = get_visual_script ( ) - > get_instance_base_type ( ) ;
2016-08-04 03:06:39 +02:00
}
}
}
2016-08-03 00:11:05 +02:00
Node * VisualScriptPropertyGet : : _get_base_node ( ) const {
# ifdef TOOLS_ENABLED
Ref < Script > script = get_visual_script ( ) ;
if ( ! script . is_valid ( ) )
return NULL ;
2017-03-05 16:44:50 +01:00
MainLoop * main_loop = OS : : get_singleton ( ) - > get_main_loop ( ) ;
2016-08-03 00:11:05 +02:00
2017-08-24 22:58:51 +02:00
SceneTree * scene_tree = Object : : cast_to < SceneTree > ( main_loop ) ;
2016-08-03 00:11:05 +02:00
if ( ! scene_tree )
return NULL ;
Node * edited_scene = scene_tree - > get_edited_scene_root ( ) ;
if ( ! edited_scene )
return NULL ;
2017-03-05 16:44:50 +01:00
Node * script_node = _find_script_node ( edited_scene , edited_scene , script ) ;
2016-08-03 00:11:05 +02:00
if ( ! script_node )
return NULL ;
if ( ! script_node - > has_node ( base_path ) )
return NULL ;
Node * path_to = script_node - > get_node ( base_path ) ;
return path_to ;
# else
return NULL ;
# endif
}
StringName VisualScriptPropertyGet : : _get_base_type ( ) const {
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_SELF & & get_visual_script ( ) . is_valid ( ) )
2016-08-03 00:11:05 +02:00
return get_visual_script ( ) - > get_instance_base_type ( ) ;
2017-03-05 16:44:50 +01:00
else if ( call_mode = = CALL_MODE_NODE_PATH & & get_visual_script ( ) . is_valid ( ) ) {
2016-08-03 00:11:05 +02:00
Node * path = _get_base_node ( ) ;
if ( path )
2017-01-03 03:03:46 +01:00
return path - > get_class ( ) ;
2016-08-03 00:11:05 +02:00
}
return base_type ;
}
2017-03-05 16:44:50 +01:00
int VisualScriptPropertyGet : : get_input_value_port_count ( ) const {
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
return ( call_mode = = CALL_MODE_BASIC_TYPE | | call_mode = = CALL_MODE_INSTANCE ) ? 1 : 0 ;
2016-08-03 00:11:05 +02:00
}
2017-03-05 16:44:50 +01:00
int VisualScriptPropertyGet : : get_output_value_port_count ( ) const {
2016-08-03 00:11:05 +02:00
return 1 ;
}
String VisualScriptPropertyGet : : get_output_sequence_port_text ( int p_port ) const {
return String ( ) ;
}
2017-03-05 16:44:50 +01:00
PropertyInfo VisualScriptPropertyGet : : get_input_value_port_info ( int p_idx ) const {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_INSTANCE | | call_mode = = CALL_MODE_BASIC_TYPE ) {
if ( p_idx = = 0 ) {
2016-08-03 00:11:05 +02:00
PropertyInfo pi ;
2017-03-05 16:44:50 +01:00
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 ( ) ) ;
2016-08-03 00:11:05 +02:00
return pi ;
} else {
p_idx - - ;
}
}
return PropertyInfo ( ) ;
}
2017-03-05 16:44:50 +01:00
PropertyInfo VisualScriptPropertyGet : : get_output_value_port_info ( int p_idx ) const {
2016-08-03 00:11:05 +02:00
2017-07-01 02:30:17 +02:00
if ( index ! = StringName ( ) ) {
Variant v ;
Variant : : CallError ce ;
v = Variant : : construct ( type_cache , NULL , 0 , ce ) ;
Variant i = v . get ( index ) ;
return PropertyInfo ( i . get_type ( ) , " value. " + String ( index ) ) ;
}
2017-03-05 16:44:50 +01:00
return PropertyInfo ( type_cache , " value " ) ;
2016-08-25 22:45:20 +02:00
}
2016-08-03 00:11:05 +02:00
2016-08-25 22:45:20 +02:00
String VisualScriptPropertyGet : : get_caption ( ) const {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
static const char * cname [ 4 ] = {
2016-08-25 22:45:20 +02:00
" SelfGet " ,
" NodeGet " ,
" InstanceGet " ,
" BasicGet "
} ;
2016-08-03 00:11:05 +02:00
2016-08-25 22:45:20 +02:00
return cname [ call_mode ] ;
}
String VisualScriptPropertyGet : : get_text ( ) const {
2016-08-29 01:57:27 +02:00
String prop ;
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_BASIC_TYPE )
prop = Variant : : get_type_name ( basic_type ) + " . " + property ;
else if ( call_mode = = CALL_MODE_NODE_PATH )
prop = String ( base_path ) + " : " + property ;
else if ( call_mode = = CALL_MODE_SELF )
prop = property ;
else if ( call_mode = = CALL_MODE_INSTANCE )
prop = String ( base_type ) + " : " + property ;
2016-08-25 22:45:20 +02:00
2016-08-29 01:57:27 +02:00
return prop ;
2016-08-25 22:45:20 +02:00
}
2017-03-05 16:44:50 +01:00
void VisualScriptPropertyGet : : set_base_type ( const StringName & p_type ) {
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
if ( base_type = = p_type )
2016-08-25 22:45:20 +02:00
return ;
2017-03-05 16:44:50 +01:00
base_type = p_type ;
2016-08-25 22:45:20 +02:00
_change_notify ( ) ;
ports_changed_notify ( ) ;
}
2017-03-05 16:44:50 +01:00
StringName VisualScriptPropertyGet : : get_base_type ( ) const {
2016-08-25 22:45:20 +02:00
return base_type ;
}
2017-03-05 16:44:50 +01:00
void VisualScriptPropertyGet : : set_base_script ( const String & p_path ) {
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
if ( base_script = = p_path )
2016-08-25 22:45:20 +02:00
return ;
2017-03-05 16:44:50 +01:00
base_script = p_path ;
2016-08-25 22:45:20 +02:00
_change_notify ( ) ;
ports_changed_notify ( ) ;
}
String VisualScriptPropertyGet : : get_base_script ( ) const {
return base_script ;
}
void VisualScriptPropertyGet : : _update_cache ( ) {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_BASIC_TYPE ) {
2016-08-03 16:28:20 +02:00
2016-08-25 22:45:20 +02:00
//not super efficient..
2016-08-03 16:28:20 +02:00
2016-08-08 00:22:33 +02:00
Variant v ;
2017-05-20 17:38:03 +02:00
Variant : : CallError ce ;
v = Variant : : construct ( basic_type , NULL , 0 , ce ) ;
2016-08-25 22:45:20 +02:00
List < PropertyInfo > pinfo ;
2016-08-03 16:28:20 +02:00
v . get_property_list ( & pinfo ) ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
for ( List < PropertyInfo > : : Element * E = pinfo . front ( ) ; E ; E = E - > next ( ) ) {
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
if ( E - > get ( ) . name = = property ) {
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
type_cache = E - > get ( ) . type ;
2016-08-25 22:45:20 +02:00
return ;
}
2016-08-03 00:11:05 +02:00
}
2016-08-25 22:45:20 +02:00
2016-08-03 00:11:05 +02:00
} else {
2016-08-25 22:45:20 +02:00
StringName type ;
Ref < Script > script ;
2017-03-05 16:44:50 +01:00
Node * node = NULL ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_NODE_PATH ) {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
node = _get_base_node ( ) ;
2016-08-25 22:45:20 +02:00
if ( node ) {
2017-03-05 16:44:50 +01:00
type = node - > get_class ( ) ;
base_type = type ; //cache, too
2016-08-25 22:45:20 +02:00
script = node - > get_script ( ) ;
}
2017-03-05 16:44:50 +01:00
} else if ( call_mode = = CALL_MODE_SELF ) {
2016-08-03 00:11:05 +02:00
2016-08-25 22:45:20 +02:00
if ( get_visual_script ( ) . is_valid ( ) ) {
2017-03-05 16:44:50 +01:00
type = get_visual_script ( ) - > get_instance_base_type ( ) ;
base_type = type ; //cache, too
script = get_visual_script ( ) ;
2016-08-25 22:45:20 +02:00
}
2017-03-05 16:44:50 +01:00
} else if ( call_mode = = CALL_MODE_INSTANCE ) {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
type = base_type ;
if ( base_script ! = String ( ) ) {
2016-08-03 00:11:05 +02:00
2016-08-25 22:45:20 +02:00
if ( ! ResourceCache : : has ( base_script ) & & ScriptServer : : edit_request_func ) {
2016-08-03 00:11:05 +02:00
2016-08-25 22:45:20 +02:00
ScriptServer : : edit_request_func ( base_script ) ; //make sure it's loaded
}
2016-08-03 00:11:05 +02:00
2016-08-25 22:45:20 +02:00
if ( ResourceCache : : has ( base_script ) ) {
2016-08-03 16:28:20 +02:00
2017-03-05 16:44:50 +01:00
script = Ref < Resource > ( ResourceCache : : get ( base_script ) ) ;
2016-08-25 22:45:20 +02:00
} else {
return ;
}
}
}
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
bool valid = false ;
2016-08-03 16:28:20 +02:00
2016-08-25 22:45:20 +02:00
Variant : : Type type_ret ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
type_ret = ClassDB : : get_property_type ( base_type , property , & valid ) ;
2016-08-03 00:11:05 +02:00
2016-08-25 22:45:20 +02:00
if ( valid ) {
2017-03-05 16:44:50 +01:00
type_cache = type_ret ;
2016-08-25 22:45:20 +02:00
return ; //all dandy
}
2016-08-03 00:11:05 +02:00
2016-08-25 22:45:20 +02:00
if ( node ) {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
Variant prop = node - > get ( property , & valid ) ;
2016-08-25 22:45:20 +02:00
if ( valid ) {
2017-03-05 16:44:50 +01:00
type_cache = prop . get_type ( ) ;
2016-08-25 22:45:20 +02:00
return ; //all dandy again
}
}
2016-08-03 00:11:05 +02:00
2016-08-25 22:45:20 +02:00
if ( script . is_valid ( ) ) {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
type_ret = script - > get_static_property_type ( property , & valid ) ;
2016-08-25 22:45:20 +02:00
if ( valid ) {
2017-03-05 16:44:50 +01:00
type_cache = type_ret ;
2016-08-25 22:45:20 +02:00
return ; //all dandy
}
}
}
2016-08-03 00:11:05 +02:00
}
2017-03-05 16:44:50 +01:00
void VisualScriptPropertyGet : : set_property ( const StringName & p_type ) {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
if ( property = = p_type )
2016-08-03 00:11:05 +02:00
return ;
2017-03-05 16:44:50 +01:00
property = p_type ;
2016-08-25 22:45:20 +02:00
_update_cache ( ) ;
2016-08-03 00:11:05 +02:00
_change_notify ( ) ;
2016-08-04 03:06:39 +02:00
ports_changed_notify ( ) ;
2016-08-03 00:11:05 +02:00
}
StringName VisualScriptPropertyGet : : get_property ( ) const {
return property ;
}
2017-03-05 16:44:50 +01:00
void VisualScriptPropertyGet : : set_base_path ( const NodePath & p_type ) {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
if ( base_path = = p_type )
2016-08-03 00:11:05 +02:00
return ;
2017-03-05 16:44:50 +01:00
base_path = p_type ;
2016-08-03 00:11:05 +02:00
_change_notify ( ) ;
2016-08-04 03:06:39 +02:00
_update_base_type ( ) ;
ports_changed_notify ( ) ;
2016-08-03 00:11:05 +02:00
}
NodePath VisualScriptPropertyGet : : get_base_path ( ) const {
return base_path ;
}
void VisualScriptPropertyGet : : set_call_mode ( CallMode p_mode ) {
2017-03-05 16:44:50 +01:00
if ( call_mode = = p_mode )
2016-08-03 00:11:05 +02:00
return ;
2017-03-05 16:44:50 +01:00
call_mode = p_mode ;
2016-08-03 00:11:05 +02:00
_change_notify ( ) ;
2016-08-04 03:06:39 +02:00
_update_base_type ( ) ;
ports_changed_notify ( ) ;
2016-08-03 00:11:05 +02:00
}
VisualScriptPropertyGet : : CallMode VisualScriptPropertyGet : : get_call_mode ( ) const {
return call_mode ;
}
2016-08-03 16:28:20 +02:00
void VisualScriptPropertyGet : : set_basic_type ( Variant : : Type p_type ) {
2017-03-05 16:44:50 +01:00
if ( basic_type = = p_type )
2016-08-03 16:28:20 +02:00
return ;
2017-03-05 16:44:50 +01:00
basic_type = p_type ;
2016-08-03 16:28:20 +02:00
_change_notify ( ) ;
2016-08-04 03:06:39 +02:00
ports_changed_notify ( ) ;
2016-08-03 16:28:20 +02:00
}
2017-03-05 16:44:50 +01:00
Variant : : Type VisualScriptPropertyGet : : get_basic_type ( ) const {
2016-08-03 16:28:20 +02:00
return basic_type ;
}
2016-08-25 22:45:20 +02:00
void VisualScriptPropertyGet : : _set_type_cache ( Variant : : Type p_type ) {
2017-03-05 16:44:50 +01:00
type_cache = p_type ;
2016-08-25 22:45:20 +02:00
}
Variant : : Type VisualScriptPropertyGet : : _get_type_cache ( ) const {
return type_cache ;
}
2017-07-01 02:30:17 +02:00
void VisualScriptPropertyGet : : set_index ( const StringName & p_type ) {
if ( index = = p_type )
return ;
index = p_type ;
_update_cache ( ) ;
_change_notify ( ) ;
ports_changed_notify ( ) ;
}
StringName VisualScriptPropertyGet : : get_index ( ) const {
return index ;
}
2017-03-05 16:44:50 +01:00
void VisualScriptPropertyGet : : _validate_property ( PropertyInfo & property ) const {
2016-08-25 22:45:20 +02:00
2017-07-01 02:30:17 +02:00
if ( property . name = = " base_type " ) {
2017-03-05 16:44:50 +01:00
if ( call_mode ! = CALL_MODE_INSTANCE ) {
property . usage = PROPERTY_USAGE_NOEDITOR ;
2016-08-03 00:11:05 +02:00
}
}
2017-07-01 02:30:17 +02:00
if ( property . name = = " base_script " ) {
2017-03-05 16:44:50 +01:00
if ( call_mode ! = CALL_MODE_INSTANCE ) {
property . usage = 0 ;
2016-08-25 22:45:20 +02:00
}
}
2016-08-03 00:11:05 +02:00
2017-07-01 02:30:17 +02:00
if ( property . name = = " basic_type " ) {
2017-03-05 16:44:50 +01:00
if ( call_mode ! = CALL_MODE_BASIC_TYPE ) {
property . usage = 0 ;
2016-08-03 16:28:20 +02:00
}
}
2017-07-01 02:30:17 +02:00
if ( property . name = = " node_path " ) {
2017-03-05 16:44:50 +01:00
if ( call_mode ! = CALL_MODE_NODE_PATH ) {
property . usage = 0 ;
2016-08-03 00:11:05 +02:00
} else {
Node * bnode = _get_base_node ( ) ;
if ( bnode ) {
2017-03-05 16:44:50 +01:00
property . hint_string = bnode - > get_path ( ) ; //convert to loong string
2016-08-03 00:11:05 +02:00
} else {
}
}
}
2017-07-01 02:30:17 +02:00
if ( property . name = = " property " ) {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
if ( call_mode = = CALL_MODE_BASIC_TYPE ) {
2016-08-03 16:28:20 +02:00
2017-03-05 16:44:50 +01:00
property . hint = PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE ;
property . hint_string = Variant : : get_type_name ( basic_type ) ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
} else if ( call_mode = = CALL_MODE_SELF & & get_visual_script ( ) . is_valid ( ) ) {
property . hint = PROPERTY_HINT_PROPERTY_OF_SCRIPT ;
2017-08-07 12:17:31 +02:00
property . hint_string = itos ( get_visual_script ( ) - > get_instance_id ( ) ) ;
2017-03-05 16:44:50 +01:00
} else if ( call_mode = = CALL_MODE_INSTANCE ) {
property . hint = PROPERTY_HINT_PROPERTY_OF_BASE_TYPE ;
property . hint_string = base_type ;
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
if ( base_script ! = String ( ) ) {
2016-08-25 22:45:20 +02:00
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 ) ) {
2017-03-05 16:44:50 +01:00
Ref < Script > script = Ref < Resource > ( ResourceCache : : get ( base_script ) ) ;
2016-08-25 22:45:20 +02:00
if ( script . is_valid ( ) ) {
2017-03-05 16:44:50 +01:00
property . hint = PROPERTY_HINT_PROPERTY_OF_SCRIPT ;
2017-08-07 12:17:31 +02:00
property . hint_string = itos ( script - > get_instance_id ( ) ) ;
2016-08-25 22:45:20 +02:00
}
}
}
2017-03-05 16:44:50 +01:00
} else if ( call_mode = = CALL_MODE_NODE_PATH ) {
2016-08-24 00:29:07 +02:00
Node * node = _get_base_node ( ) ;
if ( node ) {
2017-03-05 16:44:50 +01:00
property . hint = PROPERTY_HINT_PROPERTY_OF_INSTANCE ;
2017-08-07 12:17:31 +02:00
property . hint_string = itos ( node - > get_instance_id ( ) ) ;
2016-08-03 00:11:05 +02:00
} else {
2017-03-05 16:44:50 +01:00
property . hint = PROPERTY_HINT_PROPERTY_OF_BASE_TYPE ;
property . hint_string = get_base_type ( ) ;
2016-08-03 00:11:05 +02:00
}
2016-08-03 16:28:20 +02:00
}
2016-08-03 00:11:05 +02:00
}
2017-07-01 02:30:17 +02:00
if ( property . name = = " index " ) {
Variant : : CallError ce ;
Variant v = Variant : : construct ( type_cache , NULL , 0 , ce ) ;
List < PropertyInfo > plist ;
v . get_property_list ( & plist ) ;
String options = " " ;
for ( List < PropertyInfo > : : Element * E = plist . front ( ) ; E ; E = E - > next ( ) ) {
options + = " , " + E - > get ( ) . name ;
}
property . hint = PROPERTY_HINT_ENUM ;
property . hint_string = options ;
property . type = Variant : : STRING ;
if ( options = = " " )
property . usage = 0 ; //hide if type has no usable index
}
2016-08-03 00:11:05 +02:00
}
void VisualScriptPropertyGet : : _bind_methods ( ) {
2017-03-05 16:44:50 +01:00
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 ) ;
2016-08-03 16:28:20 +02:00
2017-03-05 16:44:50 +01:00
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 ) ;
2016-08-03 16:28:20 +02:00
2017-03-05 16:44:50 +01:00
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 ) ;
2016-08-25 22:45:20 +02:00
2017-03-05 16:44:50 +01:00
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 ) ;
2016-08-08 00:22:33 +02:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_property " , " property " ) , & VisualScriptPropertyGet : : set_property ) ;
ClassDB : : bind_method ( D_METHOD ( " get_property " ) , & VisualScriptPropertyGet : : get_property ) ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
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 ) ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
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 ) ;
2016-08-03 00:11:05 +02:00
2017-07-01 02:30:17 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_index " , " index " ) , & VisualScriptPropertyGet : : set_index ) ;
ClassDB : : bind_method ( D_METHOD ( " get_index " ) , & VisualScriptPropertyGet : : get_index ) ;
2016-08-03 16:28:20 +02:00
String bt ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < Variant : : VARIANT_MAX ; i + + ) {
if ( i > 0 )
bt + = " , " ;
2016-08-03 16:28:20 +02:00
2017-03-05 16:44:50 +01:00
bt + = Variant : : get_type_name ( Variant : : Type ( i ) ) ;
2016-08-03 16:28:20 +02:00
}
2016-08-03 00:11:05 +02:00
2016-08-25 22:45:20 +02:00
List < String > script_extensions ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < ScriptServer : : get_language_count ( ) ; i + + ) {
2016-08-25 22:45:20 +02:00
ScriptServer : : get_language ( i ) - > get_recognized_extensions ( & script_extensions ) ;
}
String script_ext_hint ;
2017-03-05 16:44:50 +01:00
for ( List < String > : : Element * E = script_extensions . front ( ) ; E ; E = E - > next ( ) ) {
if ( script_ext_hint ! = String ( ) )
script_ext_hint + = " , " ;
script_ext_hint + = " . " + E - > get ( ) ;
2016-08-25 22:45:20 +02:00
}
2016-08-03 00:11:05 +02:00
2017-07-01 02:30:17 +02:00
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_NOEDITOR ) , " _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 " ) ;
2016-08-03 00:11:05 +02:00
2017-08-20 17:45:01 +02:00
BIND_ENUM_CONSTANT ( CALL_MODE_SELF ) ;
BIND_ENUM_CONSTANT ( CALL_MODE_NODE_PATH ) ;
BIND_ENUM_CONSTANT ( CALL_MODE_INSTANCE ) ;
2016-08-03 00:11:05 +02:00
}
2016-08-06 03:46:45 +02:00
class VisualScriptNodeInstancePropertyGet : public VisualScriptNodeInstance {
public :
VisualScriptPropertyGet : : CallMode call_mode ;
NodePath node_path ;
StringName property ;
2017-07-01 02:30:17 +02:00
StringName index ;
2016-08-06 03:46:45 +02:00
VisualScriptPropertyGet * node ;
VisualScriptInstance * instance ;
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 ) {
2016-08-06 03:46:45 +02:00
2017-03-05 16:44:50 +01:00
switch ( call_mode ) {
2016-08-06 03:46:45 +02:00
case VisualScriptPropertyGet : : CALL_MODE_SELF : {
2017-03-05 16:44:50 +01:00
Object * object = instance - > get_owner_ptr ( ) ;
2016-08-06 03:46:45 +02:00
bool valid ;
2017-03-05 16:44:50 +01:00
* p_outputs [ 0 ] = object - > get ( property , & valid ) ;
2016-08-06 03:46:45 +02:00
2017-07-01 02:30:17 +02:00
if ( index ! = StringName ( ) ) {
* p_outputs [ 0 ] = p_outputs [ 0 ] - > get_named ( index ) ;
}
2016-08-06 03:46:45 +02:00
if ( ! valid ) {
2017-03-05 16:44:50 +01:00
r_error . error = Variant : : CallError : : CALL_ERROR_INVALID_METHOD ;
r_error_str = RTR ( " Invalid index property name. " ) ;
2016-08-31 04:44:14 +02:00
return 0 ;
2016-08-06 03:46:45 +02:00
}
} break ;
case VisualScriptPropertyGet : : CALL_MODE_NODE_PATH : {
2017-08-24 22:58:51 +02:00
Node * node = Object : : cast_to < Node > ( instance - > get_owner_ptr ( ) ) ;
2016-08-06 03:46:45 +02:00
if ( ! node ) {
2017-03-05 16:44:50 +01:00
r_error . error = Variant : : CallError : : CALL_ERROR_INVALID_METHOD ;
r_error_str = RTR ( " Base object is not a Node! " ) ;
2016-08-31 04:44:14 +02:00
return 0 ;
2016-08-06 03:46:45 +02:00
}
2017-03-05 16:44:50 +01:00
Node * another = node - > get_node ( node_path ) ;
2017-08-25 17:14:33 +02:00
if ( ! another ) {
2017-03-05 16:44:50 +01:00
r_error . error = Variant : : CallError : : CALL_ERROR_INVALID_METHOD ;
r_error_str = RTR ( " Path does not lead Node! " ) ;
2016-08-31 04:44:14 +02:00
return 0 ;
2016-08-06 03:46:45 +02:00
}
bool valid ;
2017-03-05 16:44:50 +01:00
* p_outputs [ 0 ] = another - > get ( property , & valid ) ;
2016-08-06 03:46:45 +02:00
2017-07-01 02:30:17 +02:00
if ( index ! = StringName ( ) ) {
* p_outputs [ 0 ] = p_outputs [ 0 ] - > get_named ( index ) ;
}
2016-08-06 03:46:45 +02:00
if ( ! valid ) {
2017-03-05 16:44:50 +01:00
r_error . error = Variant : : CallError : : CALL_ERROR_INVALID_METHOD ;
r_error_str = vformat ( RTR ( " Invalid index property name '%s' in node %s. " ) , String ( property ) , another - > get_name ( ) ) ;
2016-08-31 04:44:14 +02:00
return 0 ;
2016-08-06 03:46:45 +02:00
}
} break ;
2016-08-31 04:44:14 +02:00
default : {
2016-08-06 03:46:45 +02:00
2016-08-31 04:44:14 +02:00
bool valid ;
Variant v = * p_inputs [ 0 ] ;
2016-08-06 03:46:45 +02:00
2017-03-05 16:44:50 +01:00
* p_outputs [ 0 ] = v . get ( property , & valid ) ;
2017-07-01 02:30:17 +02:00
if ( index ! = StringName ( ) ) {
* p_outputs [ 0 ] = p_outputs [ 0 ] - > get_named ( index ) ;
}
2016-08-06 03:46:45 +02:00
2016-08-31 04:44:14 +02:00
if ( ! valid ) {
2017-03-05 16:44:50 +01:00
r_error . error = Variant : : CallError : : CALL_ERROR_INVALID_METHOD ;
r_error_str = RTR ( " Invalid index property name. " ) ;
2016-08-31 04:44:14 +02:00
}
} ;
2016-08-06 03:46:45 +02:00
}
return 0 ;
}
} ;
2017-03-05 16:44:50 +01:00
VisualScriptNodeInstance * VisualScriptPropertyGet : : instance ( VisualScriptInstance * p_instance ) {
2016-08-06 03:46:45 +02:00
2017-03-05 16:44:50 +01:00
VisualScriptNodeInstancePropertyGet * instance = memnew ( VisualScriptNodeInstancePropertyGet ) ;
instance - > node = this ;
instance - > instance = p_instance ;
instance - > property = property ;
instance - > call_mode = call_mode ;
instance - > node_path = base_path ;
2017-07-01 02:30:17 +02:00
instance - > index = index ;
2016-08-06 03:46:45 +02:00
return instance ;
2016-08-03 00:11:05 +02:00
}
VisualScriptPropertyGet : : VisualScriptPropertyGet ( ) {
2017-03-05 16:44:50 +01:00
call_mode = CALL_MODE_SELF ;
base_type = " Object " ;
basic_type = Variant : : NIL ;
type_cache = Variant : : NIL ;
2016-08-03 00:11:05 +02:00
}
2017-03-05 16:44:50 +01:00
template < VisualScriptPropertyGet : : CallMode cmode >
static Ref < VisualScriptNode > create_property_get_node ( const String & p_name ) {
2016-08-03 00:11:05 +02:00
Ref < VisualScriptPropertyGet > node ;
node . instance ( ) ;
node - > set_call_mode ( cmode ) ;
return node ;
}
//////////////////////////////////////////
2016-08-06 03:46:45 +02:00
////////////////EMIT//////////////////////
2016-08-03 00:11:05 +02:00
//////////////////////////////////////////
int VisualScriptEmitSignal : : get_output_sequence_port_count ( ) const {
return 1 ;
}
2017-03-05 16:44:50 +01:00
bool VisualScriptEmitSignal : : has_input_sequence_port ( ) const {
2016-08-03 00:11:05 +02:00
return true ;
}
2017-03-05 16:44:50 +01:00
int VisualScriptEmitSignal : : get_input_value_port_count ( ) const {
2016-08-03 00:11:05 +02:00
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 ;
}
2017-03-05 16:44:50 +01:00
int VisualScriptEmitSignal : : get_output_value_port_count ( ) const {
2016-08-03 00:11:05 +02:00
return 0 ;
}
String VisualScriptEmitSignal : : get_output_sequence_port_text ( int p_port ) const {
return String ( ) ;
}
2017-03-05 16:44:50 +01:00
PropertyInfo VisualScriptEmitSignal : : get_input_value_port_info ( int p_idx ) const {
2016-08-03 00:11:05 +02:00
Ref < VisualScript > vs = get_visual_script ( ) ;
if ( vs . is_valid ( ) ) {
if ( ! vs - > has_custom_signal ( name ) )
return PropertyInfo ( ) ;
2017-03-05 16:44:50 +01:00
return PropertyInfo ( vs - > custom_signal_get_argument_type ( name , p_idx ) , vs - > custom_signal_get_argument_name ( name , p_idx ) ) ;
2016-08-03 00:11:05 +02:00
}
return PropertyInfo ( ) ;
}
2017-03-05 16:44:50 +01:00
PropertyInfo VisualScriptEmitSignal : : get_output_value_port_info ( int p_idx ) const {
2016-08-03 00:11:05 +02:00
return PropertyInfo ( ) ;
}
String VisualScriptEmitSignal : : get_caption ( ) const {
return " EmitSignal " ;
}
String VisualScriptEmitSignal : : get_text ( ) const {
2017-03-05 16:44:50 +01:00
return " emit " + String ( name ) ;
2016-08-03 00:11:05 +02:00
}
2017-03-05 16:44:50 +01:00
void VisualScriptEmitSignal : : set_signal ( const StringName & p_type ) {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
if ( name = = p_type )
2016-08-03 00:11:05 +02:00
return ;
2017-03-05 16:44:50 +01:00
name = p_type ;
2016-08-03 00:11:05 +02:00
_change_notify ( ) ;
2016-08-04 03:06:39 +02:00
ports_changed_notify ( ) ;
2016-08-03 00:11:05 +02:00
}
StringName VisualScriptEmitSignal : : get_signal ( ) const {
return name ;
}
2017-03-05 16:44:50 +01:00
void VisualScriptEmitSignal : : _validate_property ( PropertyInfo & property ) const {
2016-08-03 00:11:05 +02:00
2017-07-01 02:30:17 +02:00
if ( property . name = = " signal " ) {
2017-03-05 16:44:50 +01:00
property . hint = PROPERTY_HINT_ENUM ;
2016-08-03 00:11:05 +02:00
List < StringName > sigs ;
Ref < VisualScript > vs = get_visual_script ( ) ;
if ( vs . is_valid ( ) ) {
vs - > get_custom_signal_list ( & sigs ) ;
}
String ml ;
2017-03-05 16:44:50 +01:00
for ( List < StringName > : : Element * E = sigs . front ( ) ; E ; E = E - > next ( ) ) {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
if ( ml ! = String ( ) )
ml + = " , " ;
ml + = E - > get ( ) ;
2016-08-03 00:11:05 +02:00
}
2017-03-05 16:44:50 +01:00
property . hint_string = ml ;
2016-08-03 00:11:05 +02:00
}
}
void VisualScriptEmitSignal : : _bind_methods ( ) {
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_signal " , " name " ) , & VisualScriptEmitSignal : : set_signal ) ;
ClassDB : : bind_method ( D_METHOD ( " get_signal " ) , & VisualScriptEmitSignal : : get_signal ) ;
2016-08-03 00:11:05 +02:00
2017-07-01 02:30:17 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : STRING , " signal " ) , " set_signal " , " get_signal " ) ;
2016-08-03 00:11:05 +02:00
}
2016-08-06 03:46:45 +02:00
class VisualScriptNodeInstanceEmitSignal : public VisualScriptNodeInstance {
public :
VisualScriptEmitSignal * node ;
VisualScriptInstance * instance ;
int argcount ;
StringName name ;
//virtual int get_working_memory_size() const { 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; }
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 ) {
2016-08-06 03:46:45 +02:00
Object * obj = instance - > get_owner_ptr ( ) ;
2017-03-05 16:44:50 +01:00
obj - > emit_signal ( name , p_inputs , argcount ) ;
2016-08-06 03:46:45 +02:00
return 0 ;
}
} ;
2017-03-05 16:44:50 +01:00
VisualScriptNodeInstance * VisualScriptEmitSignal : : instance ( VisualScriptInstance * p_instance ) {
2016-08-06 03:46:45 +02:00
2017-03-05 16:44:50 +01:00
VisualScriptNodeInstanceEmitSignal * instance = memnew ( VisualScriptNodeInstanceEmitSignal ) ;
instance - > node = this ;
instance - > instance = p_instance ;
instance - > name = name ;
instance - > argcount = get_input_value_port_count ( ) ;
2016-08-06 03:46:45 +02:00
return instance ;
2016-08-03 00:11:05 +02:00
}
VisualScriptEmitSignal : : VisualScriptEmitSignal ( ) {
}
2017-03-05 16:44:50 +01:00
static Ref < VisualScriptNode > create_basic_type_call_node ( const String & p_name ) {
2016-08-06 03:46:45 +02:00
Vector < String > path = p_name . split ( " / " ) ;
2017-03-05 16:44:50 +01:00
ERR_FAIL_COND_V ( path . size ( ) < 4 , Ref < VisualScriptNode > ( ) ) ;
2016-08-06 03:46:45 +02:00
String base_type = path [ 2 ] ;
String method = path [ 3 ] ;
Ref < VisualScriptFunctionCall > node ;
node . instance ( ) ;
2017-03-05 16:44:50 +01:00
Variant : : Type type = Variant : : VARIANT_MAX ;
2016-08-06 03:46:45 +02:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < Variant : : VARIANT_MAX ; i + + ) {
2016-08-06 03:46:45 +02:00
2017-03-05 16:44:50 +01:00
if ( Variant : : get_type_name ( Variant : : Type ( i ) ) = = base_type ) {
type = Variant : : Type ( i ) ;
2016-08-06 03:46:45 +02:00
break ;
}
}
2017-03-05 16:44:50 +01:00
ERR_FAIL_COND_V ( type = = Variant : : VARIANT_MAX , Ref < VisualScriptNode > ( ) ) ;
2016-08-06 03:46:45 +02:00
node - > set_call_mode ( VisualScriptFunctionCall : : CALL_MODE_BASIC_TYPE ) ;
node - > set_basic_type ( type ) ;
node - > set_function ( method ) ;
return node ;
}
2016-08-03 00:11:05 +02:00
void register_visual_script_func_nodes ( ) {
2017-03-05 16:44:50 +01:00
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 > ) ;
2016-08-03 00:11:05 +02:00
2016-08-24 00:29:07 +02:00
//VisualScriptLanguage::singleton->add_register_func("functions/call_script/call_self",create_script_call_node<VisualScriptScriptCall::CALL_MODE_SELF>);
2017-01-14 12:26:56 +01:00
//VisualScriptLanguage::singleton->add_register_func("functions/call_script/call_node",create_script_call_node<VisualScriptScriptCall::CALL_MODE_NODE_PATH>);
2017-03-05 16:44:50 +01:00
VisualScriptLanguage : : singleton - > add_register_func ( " functions/emit_signal " , create_node_generic < VisualScriptEmitSignal > ) ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < Variant : : VARIANT_MAX ; i + + ) {
2016-08-06 03:46:45 +02:00
Variant : : Type t = Variant : : Type ( i ) ;
String type_name = Variant : : get_type_name ( t ) ;
Variant : : CallError ce ;
2017-03-05 16:44:50 +01:00
Variant vt = Variant : : construct ( t , NULL , 0 , ce ) ;
2016-08-06 03:46:45 +02:00
List < MethodInfo > ml ;
vt . get_method_list ( & ml ) ;
2017-03-05 16:44:50 +01:00
for ( List < MethodInfo > : : Element * E = ml . front ( ) ; E ; E = E - > next ( ) ) {
VisualScriptLanguage : : singleton - > add_register_func ( " functions/by_type/ " + type_name + " / " + E - > get ( ) . name , create_basic_type_call_node ) ;
2016-08-06 03:46:45 +02:00
}
}
2016-08-03 00:11:05 +02:00
}