summaryrefslogtreecommitdiff
path: root/modules/visual_script
diff options
context:
space:
mode:
Diffstat (limited to 'modules/visual_script')
-rw-r--r--modules/visual_script/register_types.cpp20
-rw-r--r--modules/visual_script/visual_script.cpp321
-rw-r--r--modules/visual_script/visual_script.h44
-rw-r--r--modules/visual_script/visual_script_builtin_funcs.cpp15
-rw-r--r--modules/visual_script/visual_script_editor.cpp610
-rw-r--r--modules/visual_script/visual_script_editor.h27
-rw-r--r--modules/visual_script/visual_script_flow_control.cpp209
-rw-r--r--modules/visual_script/visual_script_flow_control.h50
-rw-r--r--modules/visual_script/visual_script_func_nodes.cpp1733
-rw-r--r--modules/visual_script/visual_script_func_nodes.h134
-rw-r--r--modules/visual_script/visual_script_nodes.cpp1312
-rw-r--r--modules/visual_script/visual_script_nodes.h316
-rw-r--r--modules/visual_script/visual_script_yield_nodes.cpp17
-rw-r--r--modules/visual_script/visual_script_yield_nodes.h1
14 files changed, 3555 insertions, 1254 deletions
diff --git a/modules/visual_script/register_types.cpp b/modules/visual_script/register_types.cpp
index 1360e546f3..f1c95a7400 100644
--- a/modules/visual_script/register_types.cpp
+++ b/modules/visual_script/register_types.cpp
@@ -43,6 +43,10 @@ VisualScriptLanguage *visual_script_language=NULL;
void register_visual_script_types() {
+ visual_script_language=memnew( VisualScriptLanguage );
+ //script_language_gd->init();
+ ScriptServer::register_language(visual_script_language);
+
ObjectTypeDB::register_type<VisualScript>();
ObjectTypeDB::register_virtual_type<VisualScriptNode>();
ObjectTypeDB::register_virtual_type<VisualScriptFunctionState>();
@@ -62,11 +66,20 @@ void register_visual_script_types() {
ObjectTypeDB::register_type<VisualScriptSelf>();
ObjectTypeDB::register_type<VisualScriptCustomNode>();
ObjectTypeDB::register_type<VisualScriptSubCall>();
+ ObjectTypeDB::register_type<VisualScriptComment>();
+ ObjectTypeDB::register_type<VisualScriptConstructor>();
+ ObjectTypeDB::register_type<VisualScriptLocalVar>();
+ ObjectTypeDB::register_type<VisualScriptLocalVarSet>();
+ ObjectTypeDB::register_type<VisualScriptInputAction>();
+ ObjectTypeDB::register_type<VisualScriptDeconstruct>();
+ ObjectTypeDB::register_type<VisualScriptPreload>();
+ ObjectTypeDB::register_type<VisualScriptTypeCast>();
+
ObjectTypeDB::register_type<VisualScriptFunctionCall>();
ObjectTypeDB::register_type<VisualScriptPropertySet>();
ObjectTypeDB::register_type<VisualScriptPropertyGet>();
- ObjectTypeDB::register_type<VisualScriptScriptCall>();
+// ObjectTypeDB::register_type<VisualScriptScriptCall>();
ObjectTypeDB::register_type<VisualScriptEmitSignal>();
ObjectTypeDB::register_type<VisualScriptReturn>();
@@ -82,9 +95,6 @@ void register_visual_script_types() {
ObjectTypeDB::register_type<VisualScriptBuiltinFunc>();
- visual_script_language=memnew( VisualScriptLanguage );
- //script_language_gd->init();
- ScriptServer::register_language(visual_script_language);
register_visual_script_nodes();
register_visual_script_func_nodes();
@@ -102,6 +112,8 @@ void register_visual_script_types() {
void unregister_visual_script_types() {
+ unregister_visual_script_nodes();
+
ScriptServer::unregister_language(visual_script_language);
if (visual_script_language)
diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp
index 469ceaac20..af92a006c8 100644
--- a/modules/visual_script/visual_script.cpp
+++ b/modules/visual_script/visual_script.cpp
@@ -1,7 +1,7 @@
#include "visual_script.h"
#include "visual_script_nodes.h"
#include "scene/main/node.h"
-
+#include "os/os.h"
#include "globals.h"
#define SCRIPT_VARIABLES_PREFIX "script_variables/"
@@ -31,11 +31,13 @@ void VisualScriptNode::_notification(int p_what) {
void VisualScriptNode::ports_changed_notify(){
+
default_input_values.resize( MAX(default_input_values.size(),get_input_value_port_count()) ); //let it grow as big as possible, we don't want to lose values on resize
+
emit_signal("ports_changed");
}
-void VisualScriptNode::set_default_input_value(int p_port,const Variant& p_value) {
+void VisualScriptNode::set_default_input_value(int p_port,const Variant& p_value) {
ERR_FAIL_INDEX(p_port,default_input_values.size());
@@ -54,35 +56,40 @@ void VisualScriptNode::_set_default_input_values(Array p_values) {
default_input_values=p_values;
}
-Array VisualScriptNode::_get_default_input_values() const {
- //validate on save, since on load there is little info about this
+void VisualScriptNode::validate_input_default_values() {
+
- Array saved_values;
+
+ default_input_values.resize(get_input_value_port_count());
//actually validate on save
for(int i=0;i<get_input_value_port_count();i++) {
Variant::Type expected = get_input_value_port_info(i).type;
- if (i>=default_input_values.size()) {
+ if (expected==Variant::NIL || expected==default_input_values[i].get_type()) {
+ continue;
+ } else {
+ //not the same, reconvert
Variant::CallError ce;
- saved_values.push_back(Variant::construct(expected,NULL,0,ce,false));
- } else {
-
- if (expected==Variant::NIL || expected==default_input_values[i].get_type()) {
- saved_values.push_back(default_input_values[i]);
- } else {
- //not the same, reconvert
- Variant::CallError ce;
- Variant existing = default_input_values[i];
- const Variant *existingp=&existing;
- saved_values.push_back( Variant::construct(expected,&existingp,1,ce,false) );
+ Variant existing = default_input_values[i];
+ const Variant *existingp=&existing;
+ default_input_values[i] = Variant::construct(expected,&existingp,1,ce,false);
+ if (ce.error!=Variant::CallError::CALL_OK) {
+ //could not convert? force..
+ default_input_values[i] = Variant::construct(expected,NULL,0,ce,false);
}
}
}
- return saved_values;
+}
+
+Array VisualScriptNode::_get_default_input_values() const {
+
+ //validate on save, since on load there is little info about this
+
+ return default_input_values;
}
@@ -99,6 +106,19 @@ void VisualScriptNode::_bind_methods() {
ADD_SIGNAL(MethodInfo("ports_changed"));
}
+VisualScriptNode::TypeGuess VisualScriptNode::guess_output_type(TypeGuess* p_inputs,int p_output) const {
+
+ PropertyInfo pinfo = get_output_value_port_info(p_output);
+
+ TypeGuess tg;
+
+ tg.type=pinfo.type;
+ if (pinfo.hint==PROPERTY_HINT_RESOURCE_TYPE) {
+ tg.obj_type=pinfo.hint_string;
+ }
+
+ return tg;
+}
Ref<VisualScript> VisualScriptNode::get_visual_script() const {
@@ -126,15 +146,15 @@ VisualScriptNodeInstance::VisualScriptNodeInstance() {
VisualScriptNodeInstance::~VisualScriptNodeInstance() {
if (sequence_outputs) {
- memdelete(sequence_outputs);
+ memdelete_arr(sequence_outputs);
}
if (input_ports) {
- memdelete(input_ports);
+ memdelete_arr(input_ports);
}
if (output_ports) {
- memdelete(output_ports);
+ memdelete_arr(output_ports);
}
}
@@ -224,6 +244,7 @@ int VisualScript::get_function_node_id(const StringName& p_name) const {
void VisualScript::_node_ports_changed(int p_id) {
+
StringName function;
for (Map<StringName,Function>::Element *E=functions.front();E;E=E->next()) {
@@ -239,6 +260,10 @@ void VisualScript::_node_ports_changed(int p_id) {
Function &func = functions[function];
Ref<VisualScriptNode> vsn = func.nodes[p_id].node;
+ if (OS::get_singleton()->get_main_loop() && OS::get_singleton()->get_main_loop()->cast_to<SceneTree>() && OS::get_singleton()->get_main_loop()->cast_to<SceneTree>()->is_editor_hint()) {
+ vsn->validate_input_default_values(); //force validate default values when editing on editor
+ }
+
//must revalidate all the functions
{
@@ -552,7 +577,7 @@ void VisualScript::get_data_connection_list(const StringName& p_func,List<DataCo
}
}
-void VisualScript::add_variable(const StringName& p_name,const Variant& p_default_value) {
+void VisualScript::add_variable(const StringName& p_name,const Variant& p_default_value,bool p_export) {
ERR_FAIL_COND( instances.size() );
ERR_FAIL_COND(!String(p_name).is_valid_identifier());
@@ -563,6 +588,7 @@ void VisualScript::add_variable(const StringName& p_name,const Variant& p_defaul
v.info.type=p_default_value.get_type();
v.info.name=p_name;
v.info.hint=PROPERTY_HINT_NONE;
+ v._export=p_export;
variables[p_name]=v;
script_variable_remap[SCRIPT_VARIABLES_PREFIX+String(p_name)]=p_name;
@@ -626,6 +652,21 @@ PropertyInfo VisualScript::get_variable_info(const StringName& p_name) const{
return variables[p_name].info;
}
+void VisualScript::set_variable_export(const StringName& p_name,bool p_export) {
+
+ ERR_FAIL_COND(!variables.has(p_name));
+
+ variables[p_name]._export=p_export;
+}
+
+bool VisualScript::get_variable_export(const StringName& p_name) const {
+
+ ERR_FAIL_COND_V(!variables.has(p_name),false);
+ return variables[p_name]._export;
+
+}
+
+
void VisualScript::_set_variable_info(const StringName& p_name,const Dictionary& p_info) {
PropertyInfo pinfo;
@@ -656,7 +697,7 @@ Dictionary VisualScript::_get_variable_info(const StringName& p_name) const{
return d;
}
-void VisualScript::get_variable_list(List<StringName> *r_variables){
+void VisualScript::get_variable_list(List<StringName> *r_variables) const{
for (Map<StringName,Variable>::Element *E=variables.front();E;E=E->next()) {
@@ -836,6 +877,10 @@ StringName VisualScript::get_instance_base_type() const {
return base_type;
}
+Ref<Script> VisualScript::get_base_script() const {
+ return Ref<Script>(); // no inheritance in visual script
+}
+
#ifdef TOOLS_ENABLED
void VisualScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder) {
@@ -1045,6 +1090,18 @@ MethodInfo VisualScript::get_method_info(const StringName& p_method) const{
return mi;
}
+void VisualScript::get_script_property_list(List<PropertyInfo> *p_list) const {
+
+ List<StringName> vars;
+ get_variable_list(&vars);
+
+ for (List<StringName>::Element *E=vars.front();E;E=E->next()) {
+ if (!variables[E->get()]._export)
+ continue;
+ p_list->push_back(variables[E->get()].info);
+ }
+}
+
void VisualScript::_set_data(const Dictionary& p_data) {
@@ -1061,6 +1118,7 @@ void VisualScript::_set_data(const Dictionary& p_data) {
add_variable(name);
_set_variable_info(name,v);
set_variable_default_value(name,v["default_value"]);
+ set_variable_export(name,v.has("export") && bool(v["export"]));
}
@@ -1131,6 +1189,7 @@ Dictionary VisualScript::_get_data() const{
Dictionary var = _get_variable_info(E->key());
var["name"]=E->key(); //make sure it's the right one
var["default_value"]=E->get().default_value;
+ var["export"]=E->get()._export;
vars.push_back(var);
}
d["variables"]=vars;
@@ -1241,13 +1300,15 @@ void VisualScript::_bind_methods() {
ObjectTypeDB::bind_method(_MD("data_disconnect","func","from_node","from_port","to_node","to_port"),&VisualScript::data_disconnect);
ObjectTypeDB::bind_method(_MD("has_data_connection","func","from_node","from_port","to_node","to_port"),&VisualScript::has_data_connection);
- ObjectTypeDB::bind_method(_MD("add_variable","name","default_value"),&VisualScript::add_variable,DEFVAL(Variant()));
+ ObjectTypeDB::bind_method(_MD("add_variable","name","default_value","export"),&VisualScript::add_variable,DEFVAL(Variant()),DEFVAL(false));
ObjectTypeDB::bind_method(_MD("has_variable","name"),&VisualScript::has_variable);
ObjectTypeDB::bind_method(_MD("remove_variable","name"),&VisualScript::remove_variable);
ObjectTypeDB::bind_method(_MD("set_variable_default_value","name","value"),&VisualScript::set_variable_default_value);
ObjectTypeDB::bind_method(_MD("get_variable_default_value","name"),&VisualScript::get_variable_default_value);
ObjectTypeDB::bind_method(_MD("set_variable_info","name","value"),&VisualScript::_set_variable_info);
ObjectTypeDB::bind_method(_MD("get_variable_info","name"),&VisualScript::_get_variable_info);
+ ObjectTypeDB::bind_method(_MD("set_variable_export","name","enable"),&VisualScript::set_variable_export);
+ ObjectTypeDB::bind_method(_MD("get_variable_export","name"),&VisualScript::get_variable_export);
ObjectTypeDB::bind_method(_MD("rename_variable","name","new_name"),&VisualScript::rename_variable);
ObjectTypeDB::bind_method(_MD("add_custom_signal","name"),&VisualScript::add_custom_signal);
@@ -1324,6 +1385,8 @@ void VisualScriptInstance::get_property_list(List<PropertyInfo> *p_properties) c
for (const Map<StringName,VisualScript::Variable>::Element *E=script->variables.front();E;E=E->next()) {
+ if (!E->get()._export)
+ continue;
PropertyInfo p = E->get().info;
p.name=SCRIPT_VARIABLES_PREFIX+String(E->key());
p_properties->push_back(p);
@@ -1389,7 +1452,59 @@ bool VisualScriptInstance::has_method(const StringName& p_method) const{
//#define VSDEBUG(m_text) print_line(m_text)
#define VSDEBUG(m_text)
-Variant VisualScriptInstance::_call_internal(const StringName& p_method, void* p_stack, int p_stack_size, VisualScriptNodeInstance* p_node, int p_flow_stack_pos, bool p_resuming_yield, Variant::CallError &r_error) {
+void VisualScriptInstance::_dependency_step(VisualScriptNodeInstance* node,int p_pass,int *pass_stack,const Variant **input_args,Variant **output_args,Variant *variant_stack,Variant::CallError& r_error,String& error_str,VisualScriptNodeInstance** r_error_node) {
+
+ ERR_FAIL_COND(node->pass_idx==-1);
+
+ if (pass_stack[node->pass_idx]==p_pass)
+ return;
+
+ pass_stack[node->pass_idx]=p_pass;
+
+ if (!node->dependencies.empty()) {
+
+ int dc = node->dependencies.size();
+ VisualScriptNodeInstance **deps=node->dependencies.ptr();
+
+ for(int i=0;i<dc;i++) {
+
+ _dependency_step(deps[i],p_pass,pass_stack,input_args,output_args,variant_stack,r_error,error_str,r_error_node);
+ if (r_error.error!=Variant::CallError::CALL_OK)
+ return;
+
+ }
+ }
+
+
+ for(int i=0;i<node->input_port_count;i++) {
+
+ int index = node->input_ports[i] & VisualScriptNodeInstance::INPUT_MASK;
+
+
+ if (node->input_ports[i] & VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT) {
+ //is a default value (unassigned input port)
+ input_args[i]=&default_values[index];
+ } else {
+ //regular temporary in stack
+ input_args[i]=&variant_stack[index];
+
+ }
+ }
+ for(int i=0 ; i<node->output_port_count ; i++) {
+ output_args[i] = &variant_stack[ node->output_ports[i] ];
+ }
+
+ Variant *working_mem=node->working_mem_idx>=0 ? &variant_stack[node->working_mem_idx] : (Variant*)NULL;
+
+ node->step(input_args,output_args,VisualScriptNodeInstance::START_MODE_BEGIN_SEQUENCE,working_mem,r_error,error_str);
+ //ignore return
+ if (r_error.error!=Variant::CallError::CALL_OK) {
+ *r_error_node=node;
+ }
+
+}
+
+Variant VisualScriptInstance::_call_internal(const StringName& p_method, void* p_stack, int p_stack_size, VisualScriptNodeInstance* p_node, int p_flow_stack_pos, int p_pass, bool p_resuming_yield, Variant::CallError &r_error) {
Map<StringName,Function>::Element *F = functions.find(p_method);
ERR_FAIL_COND_V(!F,Variant());
@@ -1402,6 +1517,7 @@ Variant VisualScriptInstance::_call_internal(const StringName& p_method, void* p
Variant **output_args=(Variant**)(input_args + max_input_args);
int flow_max = f->flow_stack_size;
int* flow_stack = flow_max? (int*)(output_args + max_output_args) : (int*)NULL;
+ int *pass_stack = flow_stack + flow_max;
String error_str;
@@ -1421,6 +1537,7 @@ Variant VisualScriptInstance::_call_internal(const StringName& p_method, void* p
while(true) {
+ p_pass++; //increment pass
current_node_id=node->get_id();
VSDEBUG("==========AT NODE: "+itos(current_node_id)+" base: "+node->get_base_node()->get_type());
@@ -1439,38 +1556,46 @@ Variant VisualScriptInstance::_call_internal(const StringName& p_method, void* p
input_args[i]=&variant_stack[i];
}
} else {
- //setup input pointers normally
- VSDEBUG("INPUT PORTS: "+itos(node->input_port_count));
- for(int i=0 ; i<node->input_port_count ; i++) {
+ //run dependencies first
- int index = node->input_ports[i] & VisualScriptNodeInstance::INPUT_MASK;
+ if (!node->dependencies.empty()) {
- if (node->input_ports[i] & VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT) {
- //is a default value (unassigned input port)
- input_args[i]=&default_values[index];
- VSDEBUG("\tPORT "+itos(i)+" DEFAULT VAL");
- } else if (node->input_ports[i] & VisualScriptNodeInstance::INPUT_UNSEQUENCED_READ_BIT) {
- //from a node that requires read
- Function::UnsequencedGet *ug = &f->unsequenced_gets[index];
+ int dc = node->dependencies.size();
+ VisualScriptNodeInstance **deps=node->dependencies.ptr();
- bool ok = ug->from->get_output_port_unsequenced(i,&variant_stack[ug->to_stack],working_mem,error_str);
- if (!ok) {
- r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
- current_node_id=ug->from->get_id();
+ for(int i=0;i<dc;i++) {
+
+ _dependency_step(deps[i],p_pass,pass_stack,input_args,output_args,variant_stack,r_error,error_str,&node);
+ if (r_error.error!=Variant::CallError::CALL_OK) {
error=true;
- working_mem=NULL;
+ current_node_id=node->id;
break;
}
+ }
+ }
- VSDEBUG("\tPORT "+itos(i)+" UNSEQ READ TO STACK: " + itos(ug->to_stack));
- input_args[i]=&variant_stack[ug->to_stack];
- } else {
- //regular temporary in stack
- input_args[i]=&variant_stack[index];
- VSDEBUG("PORT "+itos(i)+" AT STACK "+itos(index));
+ if (!error) {
+
+ //setup input pointers normally
+ VSDEBUG("INPUT PORTS: "+itos(node->input_port_count));
+ for(int i=0 ; i<node->input_port_count ; i++) {
+
+
+ int index = node->input_ports[i] & VisualScriptNodeInstance::INPUT_MASK;
+
+ if (node->input_ports[i] & VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT) {
+ //is a default value (unassigned input port)
+ input_args[i]=&default_values[index];
+ VSDEBUG("\tPORT "+itos(i)+" DEFAULT VAL");
+ } else {
+ //regular temporary in stack
+ input_args[i]=&variant_stack[index];
+ VSDEBUG("PORT "+itos(i)+" AT STACK "+itos(index));
+
+ }
}
}
}
@@ -1492,13 +1617,13 @@ Variant VisualScriptInstance::_call_internal(const StringName& p_method, void* p
{
if (p_resuming_yield)
start_mode=VisualScriptNodeInstance::START_MODE_RESUME_YIELD;
- else if (flow_stack && !(flow_stack[flow_stack_pos] & VisualScriptNodeInstance::FLOW_STACK_PUSHED_BIT)) //if there is a push bit, it means we are continuing a sequence
+ else if (!flow_stack || !(flow_stack[flow_stack_pos] & VisualScriptNodeInstance::FLOW_STACK_PUSHED_BIT)) //if there is a push bit, it means we are continuing a sequence
start_mode=VisualScriptNodeInstance::START_MODE_BEGIN_SEQUENCE;
else
start_mode=VisualScriptNodeInstance::START_MODE_CONTINUE_SEQUENCE;
}
- VSDEBUG("STEP - STARTSEQ: "+itos(start_sequence));
+ VSDEBUG("STEP - STARTSEQ: "+itos(start_mode));
int ret = node->step(input_args,output_args,start_mode,working_mem,r_error,error_str);
@@ -1537,6 +1662,7 @@ Variant VisualScriptInstance::_call_internal(const StringName& p_method, void* p
state->node=node;
state->flow_stack_pos=flow_stack_pos;
state->stack.resize(p_stack_size);
+ state->pass=p_pass;
copymem(state->stack.ptr(),p_stack,p_stack_size);
//step 2, run away, return directly
r_error.error=Variant::CallError::CALL_OK;
@@ -1707,6 +1833,7 @@ Variant VisualScriptInstance::_call_internal(const StringName& p_method, void* p
node = instances[ flow_stack[i] & VisualScriptNodeInstance::FLOW_STACK_MASK ];
flow_stack_pos=i;
found=true;
+ break;
}
}
@@ -1735,6 +1862,22 @@ Variant VisualScriptInstance::_call_internal(const StringName& p_method, void* p
String err_func = p_method;
int err_line=current_node_id; //not a line but it works as one
+ if (node && (r_error.error!=Variant::CallError::CALL_ERROR_INVALID_METHOD || error_str==String())) {
+
+ if (r_error.error==Variant::CallError::CALL_ERROR_INVALID_ARGUMENT) {
+ int errorarg=r_error.argument;
+ error_str="Cannot convert argument "+itos(errorarg+1)+" to "+Variant::get_type_name(r_error.expected)+".";
+ } else if (r_error.error==Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) {
+ error_str="Expected "+itos(r_error.argument)+" arguments.";
+ } else if (r_error.error==Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) {
+ error_str="Expected "+itos(r_error.argument)+" arguments.";
+ } else if (r_error.error==Variant::CallError::CALL_ERROR_INVALID_METHOD) {
+ error_str="Invalid Call.";
+ } else if (r_error.error==Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL) {
+ error_str="Instance is null";
+ }
+ }
+
//if (!GDScriptLanguage::get_singleton()->debug_break(err_text,false)) {
// debugger break did not happen
@@ -1787,6 +1930,7 @@ Variant VisualScriptInstance::call(const StringName& p_method, const Variant** p
total_stack_size+=f->node_count*sizeof(bool);
total_stack_size+=(max_input_args+max_output_args)*sizeof(Variant*); //arguments
total_stack_size+=f->flow_stack_size*sizeof(int); //flow
+ total_stack_size+=f->pass_stack_size*sizeof(int);
VSDEBUG("STACK SIZE: "+itos(total_stack_size));
VSDEBUG("STACK VARIANTS: : "+itos(f->max_stack));
@@ -1794,6 +1938,7 @@ Variant VisualScriptInstance::call(const StringName& p_method, const Variant** p
VSDEBUG("MAX INPUT: "+itos(max_input_args));
VSDEBUG("MAX OUTPUT: "+itos(max_output_args));
VSDEBUG("FLOW STACK SIZE: "+itos(f->flow_stack_size));
+ VSDEBUG("PASS STACK SIZE: "+itos(f->pass_stack_size));
void *stack = alloca(total_stack_size);
@@ -1803,11 +1948,13 @@ Variant VisualScriptInstance::call(const StringName& p_method, const Variant** p
Variant **output_args=(Variant**)(input_args + max_input_args);
int flow_max = f->flow_stack_size;
int* flow_stack = flow_max? (int*)(output_args + max_output_args) : (int*)NULL;
+ int *pass_stack = flow_stack + flow_max;
for(int i=0;i<f->node_count;i++) {
sequence_bits[i]=false; //all starts as false
}
+ zeromem(pass_stack,f->pass_stack_size*sizeof(int));
Map<int,VisualScriptNodeInstance*>::Element *E = instances.find(f->node);
if (!E) {
@@ -1850,7 +1997,7 @@ Variant VisualScriptInstance::call(const StringName& p_method, const Variant** p
variant_stack[i]=*p_args[i];
}
- return _call_internal(p_method,stack,total_stack_size,node,0,false,r_error);
+ return _call_internal(p_method,stack,total_stack_size,node,0,0,false,r_error);
}
@@ -1873,8 +2020,23 @@ Ref<Script> VisualScriptInstance::get_script() const{
ScriptInstance::RPCMode VisualScriptInstance::get_rpc_mode(const StringName& p_method) const {
+ const Map<StringName,VisualScript::Function>::Element *E = script->functions.find(p_method);
+ if (!E) {
+ return RPC_MODE_DISABLED;
+ }
+
+ if (E->get().function_id>=0 && E->get().nodes.has(E->get().function_id)) {
+
+ Ref<VisualScriptFunction> vsf = E->get().nodes[E->get().function_id].node;
+ if (vsf.is_valid()) {
+
+ return vsf->get_rpc_mode();
+ }
+ }
+
return RPC_MODE_DISABLED;
}
+
ScriptInstance::RPCMode VisualScriptInstance::get_rset_mode(const StringName& p_variable) const {
return RPC_MODE_DISABLED;
@@ -1907,6 +2069,7 @@ void VisualScriptInstance::create(const Ref<VisualScript>& p_script,Object *p_ow
for(const Map<StringName,VisualScript::Variable>::Element *E=script->variables.front();E;E=E->next()) {
variables[E->key()]=E->get().default_value;
+ //no hacer que todo exporte, solo las que queres!
}
@@ -1916,7 +2079,9 @@ void VisualScriptInstance::create(const Ref<VisualScript>& p_script,Object *p_ow
function.node=E->get().function_id;
function.max_stack=0;
function.flow_stack_size=0;
+ function.pass_stack_size=0;
function.node_count=0;
+ Map<StringName,int> local_var_indices;
if (function.node<0) {
VisualScriptLanguage::singleton->debug_break_parse(get_script()->get_path(),0,"No start node in function: "+String(E->key()));
@@ -1958,12 +2123,14 @@ void VisualScriptInstance::create(const Ref<VisualScript>& p_script,Object *p_ow
instance->output_port_count = node->get_output_value_port_count();
instance->sequence_output_count = node->get_output_sequence_port_count();
instance->sequence_index=function.node_count++;
+ instance->pass_idx=-1;
if (instance->input_port_count) {
instance->input_ports = memnew_arr(int,instance->input_port_count);
for(int i=0;i<instance->input_port_count;i++) {
+
instance->input_ports[i]=-1; //if not assigned, will become default value
- }
+ }
}
if (instance->output_port_count) {
@@ -1980,7 +2147,25 @@ void VisualScriptInstance::create(const Ref<VisualScript>& p_script,Object *p_ow
}
}
- if (instance->get_working_memory_size()) {
+ if (node->cast_to<VisualScriptLocalVar>() || node->cast_to<VisualScriptLocalVarSet>()) {
+ //working memory is shared only for this node, for the same variables
+ Ref<VisualScriptLocalVar> vslv = node;
+
+ StringName var_name;
+
+ if (node->cast_to<VisualScriptLocalVar>())
+ var_name = String(node->cast_to<VisualScriptLocalVar>()->get_var_name()).strip_edges();
+ else
+ var_name = String(node->cast_to<VisualScriptLocalVarSet>()->get_var_name()).strip_edges();
+
+ if (!local_var_indices.has(var_name)) {
+ local_var_indices[var_name]=function.max_stack;
+ function.max_stack++;
+ }
+
+ instance->working_mem_idx=local_var_indices[var_name];
+
+ } else if (instance->get_working_memory_size()) {
instance->working_mem_idx = function.max_stack;
function.max_stack+=instance->get_working_memory_size();
} else {
@@ -2016,24 +2201,17 @@ void VisualScriptInstance::create(const Ref<VisualScript>& p_script,Object *p_ow
}
- if (from->is_output_port_unsequenced(dc.from_node)) {
-
- //prepare an unsequenced read (must actually get the value from the output)
- int stack_pos = function.max_stack++;
-
- Function::UnsequencedGet uget;
- uget.from=from;
- uget.from_port=dc.from_port;
- uget.to_stack=stack_pos;
-
- to->input_ports[dc.to_port] = function.unsequenced_gets.size() | VisualScriptNodeInstance::INPUT_UNSEQUENCED_READ_BIT;
- function.unsequenced_gets.push_back(uget);
-
- } else {
-
- to->input_ports[dc.to_port] = from->output_ports[dc.from_port]; //read from wherever the stack is
+ if (from->get_sequence_output_count()==0 && to->dependencies.find(from)==-1) {
+ //if the node we are reading from has no output sequence, we must call step() before reading from it.
+ if (from->pass_idx==-1) {
+ from->pass_idx=function.pass_stack_size;
+ function.pass_stack_size++;
+ }
+ to->dependencies.push_back(from);
}
+ to->input_ports[dc.to_port] = from->output_ports[dc.from_port]; //read from wherever the stack is
+
}
//third pass, do sequence connections
@@ -2168,7 +2346,7 @@ Variant VisualScriptFunctionState::_signal_callback(const Variant** p_args, int
*working_mem=args; //arguments go to working mem.
- Variant ret = instance->_call_internal(function,stack.ptr(),stack.size(),node,flow_stack_pos,true,r_error);
+ Variant ret = instance->_call_internal(function,stack.ptr(),stack.size(),node,flow_stack_pos,pass,true,r_error);
function=StringName(); //invalidate
return ret;
}
@@ -2210,7 +2388,7 @@ Variant VisualScriptFunctionState::resume(Array p_args) {
*working_mem=p_args; //arguments go to working mem.
- Variant ret= instance->_call_internal(function,stack.ptr(),stack.size(),node,flow_stack_pos,true,r_error);
+ Variant ret= instance->_call_internal(function,stack.ptr(),stack.size(),node,flow_stack_pos,pass,true,r_error);
function=StringName(); //invalidate
return ret;
}
@@ -2436,8 +2614,6 @@ void VisualScriptLanguage::debug_get_stack_level_locals(int p_level,List<String>
if (in_from&VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT) {
p_values->push_back(_call_stack[l].instance->default_values[in_value]);
- } else if (in_from&VisualScriptNodeInstance::INPUT_UNSEQUENCED_READ_BIT) {
- p_values->push_back( _call_stack[l].stack[ func->unsequenced_gets[ in_value ].to_stack ] );
} else {
p_values->push_back( _call_stack[l].stack[ in_value] );
}
@@ -2588,7 +2764,6 @@ void VisualScriptLanguage::get_registered_node_names(List<String> *r_names) {
VisualScriptLanguage::VisualScriptLanguage() {
notification="_notification";
- _get_output_port_unsequenced="_get_output_port_unsequenced";
_step="_step";
_subcall="_subcall";
singleton=this;
diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h
index 398df95664..8f541a367b 100644
--- a/modules/visual_script/visual_script.h
+++ b/modules/visual_script/visual_script.h
@@ -20,6 +20,8 @@ friend class VisualScript;
void _set_default_input_values(Array p_values);
Array _get_default_input_values() const;
+
+ void validate_input_default_values();
protected:
virtual bool _use_builtin_script() const { return false; }
@@ -56,6 +58,18 @@ public:
virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance)=0;
+ struct TypeGuess {
+
+ Variant::Type type;
+ InputEvent::Type ev_type;
+ StringName obj_type;
+ String script_type;
+
+ TypeGuess() { type=Variant::NIL; ev_type=InputEvent::NONE; }
+ };
+
+ virtual TypeGuess guess_output_type(TypeGuess* p_inputs, int p_output) const;
+
VisualScriptNode();
};
@@ -69,7 +83,6 @@ friend class VisualScriptLanguage; //for debugger
INPUT_SHIFT=1<<24,
INPUT_MASK=INPUT_SHIFT-1,
INPUT_DEFAULT_VALUE_BIT=INPUT_SHIFT, // from unassigned input port, using default value (edited by user)
- INPUT_UNSEQUENCED_READ_BIT=INPUT_SHIFT<<1, //from unsequenced read (requires calling a function, used for constants, variales, etc).
};
@@ -77,11 +90,13 @@ friend class VisualScriptLanguage; //for debugger
int sequence_index;
VisualScriptNodeInstance **sequence_outputs;
int sequence_output_count;
+ Vector<VisualScriptNodeInstance*> dependencies;
int *input_ports;
int input_port_count;
int *output_ports;
int output_port_count;
int working_mem_idx;
+ int pass_idx;
VisualScriptNode *base;
@@ -115,10 +130,6 @@ public:
virtual int get_working_memory_size() const { return 0; }
- //unsequenced ports are those that can return a value even if no sequence happened through them, used for constants, variables, etc.
- virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
- virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
-
virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str)=0; //do a step, return which sequence port to go out
Ref<VisualScriptNode> get_base_node() { return Ref<VisualScriptNode>( base ); }
@@ -207,6 +218,7 @@ friend class VisualScriptInstance;
struct Variable {
PropertyInfo info;
Variant default_value;
+ bool _export;
};
@@ -268,14 +280,16 @@ public:
void get_data_connection_list(const StringName& p_func,List<DataConnection> *r_connection) const;
bool is_input_value_port_connected(const StringName& p_name,int p_node,int p_port) const;
- void add_variable(const StringName& p_name,const Variant& p_default_value=Variant());
+ void add_variable(const StringName& p_name,const Variant& p_default_value=Variant(),bool p_export=false);
bool has_variable(const StringName& p_name) const;
void remove_variable(const StringName& p_name);
void set_variable_default_value(const StringName& p_name,const Variant& p_value);
Variant get_variable_default_value(const StringName& p_name) const;
void set_variable_info(const StringName& p_name,const PropertyInfo& p_info);
PropertyInfo get_variable_info(const StringName& p_name) const;
- void get_variable_list(List<StringName> *r_variables);
+ void set_variable_export(const StringName& p_name,bool p_export);
+ bool get_variable_export(const StringName& p_name) const;
+ void get_variable_list(List<StringName> *r_variables) const;
void rename_variable(const StringName& p_name,const StringName& p_new_name);
@@ -300,6 +314,7 @@ public:
virtual bool can_instance() const;
+ virtual Ref<Script> get_base_script() const;
virtual StringName get_instance_base_type() const;
virtual ScriptInstance* instance_create(Object *p_this);
virtual bool instance_has(const Object *p_this) const;
@@ -325,6 +340,7 @@ public:
virtual bool has_method(const StringName& p_method) const;
virtual MethodInfo get_method_info(const StringName& p_method) const;
+ virtual void get_script_property_list(List<PropertyInfo> *p_list) const;
VisualScript();
@@ -345,18 +361,10 @@ class VisualScriptInstance : public ScriptInstance {
int trash_pos;
int return_pos;
int flow_stack_size;
+ int pass_stack_size;
int node_count;
int argument_count;
bool valid;
-
- struct UnsequencedGet {
- VisualScriptNodeInstance* from;
- int from_port;
- int to_stack;
- };
-
- Vector<UnsequencedGet> unsequenced_gets;
-
};
Map<StringName,Function> functions;
@@ -366,7 +374,8 @@ class VisualScriptInstance : public ScriptInstance {
StringName source;
- Variant _call_internal(const StringName& p_method, void* p_stack,int p_stack_size, VisualScriptNodeInstance* p_node, int p_flow_stack_pos, bool p_resuming_yield,Variant::CallError &r_error);
+ void _dependency_step(VisualScriptNodeInstance* node, int p_pass, int *pass_stack, const Variant **input_args, Variant **output_args, Variant *variant_stack, Variant::CallError& r_error, String& error_str, VisualScriptNodeInstance **r_error_node);
+ Variant _call_internal(const StringName& p_method, void* p_stack,int p_stack_size, VisualScriptNodeInstance* p_node, int p_flow_stack_pos, int p_pass, bool p_resuming_yield,Variant::CallError &r_error);
//Map<StringName,Function> functions;
@@ -435,6 +444,7 @@ friend class VisualScriptInstance;
int variant_stack_size;
VisualScriptNodeInstance *node;
int flow_stack_pos;
+ int pass;
Variant _signal_callback(const Variant** p_args, int p_argcount, Variant::CallError& r_error);
protected:
diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp
index e813d9ea84..1d0bca0b30 100644
--- a/modules/visual_script/visual_script_builtin_funcs.cpp
+++ b/modules/visual_script/visual_script_builtin_funcs.cpp
@@ -69,12 +69,23 @@ const char* VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX
int VisualScriptBuiltinFunc::get_output_sequence_port_count() const {
- return 1;
+ return has_input_sequence_port() ? 1 : 0;
}
bool VisualScriptBuiltinFunc::has_input_sequence_port() const{
- return true;
+ switch(func) {
+
+ case MATH_RANDOMIZE:
+ case TEXT_PRINT:
+ case TEXT_PRINTERR:
+ case TEXT_PRINTRAW:
+ return true;
+ default:
+ return false;
+
+ }
+
}
int VisualScriptBuiltinFunc::get_input_value_port_count() const{
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index 412865fbfe..1d4d8f6d4b 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -4,6 +4,7 @@
#include "visual_script_flow_control.h"
#include "visual_script_func_nodes.h"
#include "os/input.h"
+#include "tools/editor/editor_resource_preview.h"
#include "os/keyboard.h"
#ifdef TOOLS_ENABLED
@@ -241,6 +242,11 @@ protected:
return true;
}
+ if (String(p_name)=="export") {
+ script->set_variable_export(var,p_value);
+ return true;
+ }
+
return false;
}
@@ -270,6 +276,11 @@ protected:
return true;
}
+ if (String(p_name)=="export") {
+ r_ret=script->get_variable_export(var);
+ return true;
+ }
+
return false;
}
void _get_property_list( List<PropertyInfo> *p_list) const {
@@ -285,6 +296,7 @@ protected:
p_list->push_back(PropertyInfo(script->get_variable_info(var).type,"value",script->get_variable_info(var).hint,script->get_variable_info(var).hint_string,PROPERTY_USAGE_DEFAULT));
p_list->push_back(PropertyInfo(Variant::INT,"hint",PROPERTY_HINT_ENUM,"None,Range,ExpRange,Enum,ExpEasing,Length,SpriteFrame,KeyAccel,BitFlags,AllFlags,File,Dir,GlobalFile,GlobalDir,ResourceType,MultilineText"));
p_list->push_back(PropertyInfo(Variant::STRING,"hint_string"));
+ p_list->push_back(PropertyInfo(Variant::BOOL,"export"));
}
@@ -301,9 +313,45 @@ public:
};
static Color _color_from_type(Variant::Type p_type) {
-
Color color;
- color.set_hsv(p_type/float(Variant::VARIANT_MAX),0.7,0.7);
+ switch(p_type) {
+ case Variant::NIL: color = Color::html("69ecbd"); break;
+
+ case Variant::BOOL: color = Color::html("8da6f0"); break;
+ case Variant::INT: color = Color::html("7dc6ef"); break;
+ case Variant::REAL: color = Color::html("61daf4"); break;
+ case Variant::STRING: color = Color::html("6ba7ec"); break;
+
+ case Variant::VECTOR2: color = Color::html("bd91f1"); break;
+ case Variant::RECT2: color = Color::html("f191a5"); break;
+ case Variant::VECTOR3: color = Color::html("d67dee"); break;
+ case Variant::MATRIX32: color = Color::html("c4ec69"); break;
+ case Variant::PLANE: color = Color::html("f77070"); break;
+ case Variant::QUAT: color = Color::html("ec69a3"); break;
+ case Variant::_AABB: color = Color::html("ee7991"); break;
+ case Variant::MATRIX3: color = Color::html("e3ec69"); break;
+ case Variant::TRANSFORM: color = Color::html("ecd669"); break;
+
+ case Variant::COLOR: color = Color::html("9dff70"); break;
+ case Variant::IMAGE: color = Color::html("93f1b9"); break;
+ case Variant::NODE_PATH: color = Color::html("6993ec"); break;
+ case Variant::_RID: color = Color::html("69ec9a"); break;
+ case Variant::OBJECT: color = Color::html("79f3e8"); break;
+ case Variant::INPUT_EVENT: color = Color::html("adf18f"); break;
+ case Variant::DICTIONARY: color = Color::html("77edb1"); break;
+
+ case Variant::ARRAY: color = Color::html("e0e0e0"); break;
+ case Variant::RAW_ARRAY: color = Color::html("aaf4c8"); break;
+ case Variant::INT_ARRAY: color = Color::html("afdcf5"); break;
+ case Variant::REAL_ARRAY: color = Color::html("97e7f8"); break;
+ case Variant::STRING_ARRAY: color = Color::html("9dc4f2"); break;
+ case Variant::VECTOR2_ARRAY: color = Color::html("d1b3f5"); break;
+ case Variant::VECTOR3_ARRAY: color = Color::html("df9bf2"); break;
+ case Variant::COLOR_ARRAY: color = Color::html("e9ff97"); break;
+
+ default:
+ color.set_hsv(p_type/float(Variant::VARIANT_MAX),0.7,0.7);
+ }
return color;
}
@@ -347,6 +395,8 @@ void VisualScriptEditor::_update_graph_connections() {
void VisualScriptEditor::_update_graph(int p_only_id) {
+ if (updating_graph)
+ return;
updating_graph=true;
@@ -387,7 +437,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
Control::get_icon("MiniVector2","EditorIcons"),
Control::get_icon("MiniRect2","EditorIcons"),
Control::get_icon("MiniVector3","EditorIcons"),
- Control::get_icon("MiniMatrix2","EditorIcons"),
+ Control::get_icon("MiniMatrix32","EditorIcons"),
Control::get_icon("MiniPlane","EditorIcons"),
Control::get_icon("MiniQuat","EditorIcons"),
Control::get_icon("MiniAabb","EditorIcons"),
@@ -438,6 +488,8 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
gnode->set_modulate(EditorSettings::get_singleton()->get("visual_script_editor/color_"+node->get_category()));
}
+
+
gnode->set_meta("__vnode",node);
gnode->set_name(itos(E->get()));
gnode->connect("dragged",this,"_node_moved",varray(E->get()));
@@ -449,10 +501,21 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
gnode->set_show_close_button(true);
}
+
Label *text = memnew( Label );
text->set_text(node->get_text());
gnode->add_child(text);
+ if (node->cast_to<VisualScriptComment>()) {
+ Ref<VisualScriptComment> vsc=node;
+ gnode->set_comment(true);
+ gnode->set_resizeable(true);
+ gnode->set_custom_minimum_size(vsc->get_size()*EDSCALE);
+ gnode->connect("resize_request",this,"_comment_node_resized",varray(E->get()));
+
+ }
+
+
int slot_idx=0;
bool single_seq_output = node->get_output_sequence_port_count()==1 && node->get_output_sequence_port_text(0)==String();
@@ -478,6 +541,8 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
Variant::Type left_type=Variant::NIL;
String left_name;
+
+
if (i<node->get_input_value_port_count()) {
PropertyInfo pi = node->get_input_value_port_info(i);
left_ok=true;
@@ -514,6 +579,8 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
hbc->add_child(memnew(Label(left_name)));
if (left_type!=Variant::NIL && !script->is_input_value_port_connected(edited_func,E->get(),i)) {
+
+ PropertyInfo pi = node->get_input_value_port_info(i);
Button *button = memnew( Button );
Variant value = node->get_default_input_value(i);
if (value.get_type()!=left_type) {
@@ -524,7 +591,24 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
value = Variant::construct(left_type,&existingp,1,ce,false);
}
- button->set_text(value);
+ if (left_type==Variant::COLOR) {
+ button->set_custom_minimum_size(Size2(30,0)*EDSCALE);
+ button->connect("draw",this,"_draw_color_over_button",varray(button,value));
+ } else if (left_type==Variant::OBJECT && Ref<Resource>(value).is_valid()) {
+
+ Ref<Resource> res = value;
+ Array arr;
+ arr.push_back(button->get_instance_ID());
+ arr.push_back(String(value));
+ EditorResourcePreview::get_singleton()->queue_edited_resource_preview(res,this,"_button_resource_previewed",arr);
+
+ } else if (pi.type==Variant::INT && pi.hint==PROPERTY_HINT_ENUM){
+
+ button->set_text(pi.hint_string.get_slice(",",value));
+ } else {
+
+ button->set_text(value);
+ }
button->connect("pressed",this,"_default_value_edited",varray(button,E->get(),i));
hbc->add_child(button);
}
@@ -561,6 +645,10 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
}
graph->add_child(gnode);
+
+ if (gnode->is_comment()) {
+ graph->move_child(gnode,0);
+ }
}
_update_graph_connections();
@@ -608,12 +696,48 @@ void VisualScriptEditor::_update_members() {
variables->add_button(0,Control::get_icon("Add","EditorIcons"));
variables->set_custom_bg_color(0,Control::get_color("prop_section","Editor"));
+ Ref<Texture> type_icons[Variant::VARIANT_MAX]={
+ Control::get_icon("MiniVariant","EditorIcons"),
+ Control::get_icon("MiniBoolean","EditorIcons"),
+ Control::get_icon("MiniInteger","EditorIcons"),
+ Control::get_icon("MiniFloat","EditorIcons"),
+ Control::get_icon("MiniString","EditorIcons"),
+ Control::get_icon("MiniVector2","EditorIcons"),
+ Control::get_icon("MiniRect2","EditorIcons"),
+ Control::get_icon("MiniVector3","EditorIcons"),
+ Control::get_icon("MiniMatrix32","EditorIcons"),
+ Control::get_icon("MiniPlane","EditorIcons"),
+ Control::get_icon("MiniQuat","EditorIcons"),
+ Control::get_icon("MiniAabb","EditorIcons"),
+ Control::get_icon("MiniMatrix3","EditorIcons"),
+ Control::get_icon("MiniTransform","EditorIcons"),
+ Control::get_icon("MiniColor","EditorIcons"),
+ Control::get_icon("MiniImage","EditorIcons"),
+ Control::get_icon("MiniPath","EditorIcons"),
+ Control::get_icon("MiniRid","EditorIcons"),
+ Control::get_icon("MiniObject","EditorIcons"),
+ Control::get_icon("MiniInput","EditorIcons"),
+ Control::get_icon("MiniDictionary","EditorIcons"),
+ Control::get_icon("MiniArray","EditorIcons"),
+ Control::get_icon("MiniRawArray","EditorIcons"),
+ Control::get_icon("MiniIntArray","EditorIcons"),
+ Control::get_icon("MiniFloatArray","EditorIcons"),
+ Control::get_icon("MiniStringArray","EditorIcons"),
+ Control::get_icon("MiniVector2Array","EditorIcons"),
+ Control::get_icon("MiniVector3Array","EditorIcons"),
+ Control::get_icon("MiniColorArray","EditorIcons")
+ };
List<StringName> var_names;
script->get_variable_list(&var_names);
for (List<StringName>::Element *E=var_names.front();E;E=E->next()) {
TreeItem *ti = members->create_item(variables);
+
ti->set_text(0,E->get());
+ Variant var = script->get_variable_default_value(E->get());
+ ti->set_suffix(0,"="+String(var));
+ ti->set_icon(0,type_icons[script->get_variable_info(E->get()).type]);
+
ti->set_selectable(0,true);
ti->set_editable(0,true);
ti->add_button(0,Control::get_icon("Edit","EditorIcons"),0);
@@ -1385,6 +1509,8 @@ bool VisualScriptEditor::can_drop_data_fw(const Point2& p_point,const Variant& p
String(d["type"])=="visual_script_variable_drag" ||
String(d["type"])=="visual_script_signal_drag" ||
String(d["type"])=="obj_property" ||
+ String(d["type"])=="resource" ||
+ String(d["type"])=="files" ||
String(d["type"])=="nodes"
) ) {
@@ -1392,18 +1518,27 @@ bool VisualScriptEditor::can_drop_data_fw(const Point2& p_point,const Variant& p
if (String(d["type"])=="obj_property") {
#ifdef OSX_ENABLED
- const_cast<VisualScriptEditor*>(this)->_show_hint("Hold Meta to drop a Setter, Shift+Meta to drop a Setter and copy the value.");
+ const_cast<VisualScriptEditor*>(this)->_show_hint(TTR("Hold Meta to drop a Getter. Hold Shift to drop a generic signature."));
#else
- const_cast<VisualScriptEditor*>(this)->_show_hint("Hold Ctrl to drop a Setter, Shift+Ctrl to drop a Setter and copy the value.");
+ const_cast<VisualScriptEditor*>(this)->_show_hint(TTR("Hold Ctrl to drop a Getter. Hold Shift to drop a generic signature."));
+#endif
+ }
+
+ if (String(d["type"])=="nodes") {
+
+#ifdef OSX_ENABLED
+ const_cast<VisualScriptEditor*>(this)->_show_hint(TTR("Hold Meta to drop a simple reference to the node."));
+#else
+ const_cast<VisualScriptEditor*>(this)->_show_hint(TTR("Hold Ctrl to drop a simple reference to the node."));
#endif
}
if (String(d["type"])=="visual_script_variable_drag") {
#ifdef OSX_ENABLED
- const_cast<VisualScriptEditor*>(this)->_show_hint("Hold Meta to drop a Variable Setter.");
+ const_cast<VisualScriptEditor*>(this)->_show_hint(TTR("Hold Meta to drop a Variable Setter."));
#else
- const_cast<VisualScriptEditor*>(this)->_show_hint("Hold Ctrl to drop a Variable Setter.");
+ const_cast<VisualScriptEditor*>(this)->_show_hint(TTR("Hold Ctrl to drop a Variable Setter."));
#endif
}
@@ -1442,6 +1577,8 @@ static Node* _find_script_node(Node* p_edited_scene,Node* p_current_node,const R
#endif
+
+
void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from){
if (p_from==graph) {
@@ -1531,15 +1668,17 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat
ofs/=EDSCALE;
- Ref<VisualScriptScriptCall> vnode;
+ Ref<VisualScriptFunctionCall> vnode;
vnode.instance();
- vnode->set_call_mode(VisualScriptScriptCall::CALL_MODE_SELF);
- vnode->set_function(d["function"]);
+ vnode->set_call_mode(VisualScriptFunctionCall::CALL_MODE_SELF);
int new_id = script->get_available_id();
undo_redo->create_action(TTR("Add Node"));
undo_redo->add_do_method(script.ptr(),"add_node",edited_func,new_id,vnode,ofs);
+ undo_redo->add_do_method(vnode.ptr(),"set_base_type",script->get_instance_base_type());
+ undo_redo->add_do_method(vnode.ptr(),"set_function",d["function"]);
+
undo_redo->add_undo_method(script.ptr(),"remove_node",edited_func,new_id);
undo_redo->add_do_method(this,"_update_graph");
undo_redo->add_undo_method(this,"_update_graph");
@@ -1550,6 +1689,7 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat
graph->set_selected(node);
_node_selected(node);
}
+
}
@@ -1580,8 +1720,90 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat
if (node) {
graph->set_selected(node);
_node_selected(node);
+ }
+ }
+
+ if (d.has("type") && String(d["type"])=="resource") {
+
+ Vector2 ofs = graph->get_scroll_ofs() + p_point;
+ if (graph->is_using_snap()) {
+ int snap = graph->get_snap();
+ ofs = ofs.snapped(Vector2(snap,snap));
+ }
+
+ ofs/=EDSCALE;
+
+ Ref<VisualScriptPreload> prnode;
+ prnode.instance();
+ prnode->set_preload(d["resource"]);
+
+ int new_id = script->get_available_id();
+
+ undo_redo->create_action(TTR("Add Preload Node"));
+ undo_redo->add_do_method(script.ptr(),"add_node",edited_func,new_id,prnode,ofs);
+ undo_redo->add_undo_method(script.ptr(),"remove_node",edited_func,new_id);
+ undo_redo->add_do_method(this,"_update_graph");
+ undo_redo->add_undo_method(this,"_update_graph");
+ undo_redo->commit_action();
+
+ Node* node = graph->get_node(itos(new_id));
+ if (node) {
+ graph->set_selected(node);
+ _node_selected(node);
}
}
+
+ if (d.has("type") && String(d["type"])=="files") {
+
+ Vector2 ofs = graph->get_scroll_ofs() + p_point;
+ if (graph->is_using_snap()) {
+ int snap = graph->get_snap();
+ ofs = ofs.snapped(Vector2(snap,snap));
+ }
+
+ ofs/=EDSCALE;
+
+ Array files = d["files"];
+
+ List<int> new_ids;
+ int new_id = script->get_available_id();
+
+ if (files.size()) {
+ undo_redo->create_action(TTR("Add Preload Node"));
+
+ for(int i=0;i<files.size();i++) {
+
+ Ref<Resource> res = ResourceLoader::load(files[i]);
+ if (!res.is_valid())
+ continue;
+
+ Ref<VisualScriptPreload> prnode;
+ prnode.instance();
+ prnode->set_preload(res);
+
+ undo_redo->add_do_method(script.ptr(),"add_node",edited_func,new_id,prnode,ofs);
+ undo_redo->add_undo_method(script.ptr(),"remove_node",edited_func,new_id);
+ new_ids.push_back(new_id);
+ new_id++;
+ ofs+=Vector2(20,20)*EDSCALE;
+ }
+
+
+ undo_redo->add_do_method(this,"_update_graph");
+ undo_redo->add_undo_method(this,"_update_graph");
+ undo_redo->commit_action();
+ }
+
+ for(List<int>::Element *E=new_ids.front();E;E=E->next()) {
+
+ Node* node = graph->get_node(itos(E->get()));
+ if (node) {
+ graph->set_selected(node);
+ _node_selected(node);
+ }
+ }
+ }
+
if (d.has("type") && String(d["type"])=="nodes") {
Node* sn = _find_script_node(get_tree()->get_edited_scene_root(),get_tree()->get_edited_scene_root(),script);
@@ -1592,6 +1814,14 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat
return;
}
+
+#ifdef OSX_ENABLED
+ bool use_node = Input::get_singleton()->is_key_pressed(KEY_META);
+#else
+ bool use_node = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+#endif
+
+
Array nodes = d["nodes"];
Vector2 ofs = graph->get_scroll_ofs() + p_point;
@@ -1605,6 +1835,10 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat
undo_redo->create_action(TTR("Add Node(s) From Tree"));
int base_id = script->get_available_id();
+ if (nodes.size()>1) {
+ use_node=true;
+ }
+
for(int i=0;i<nodes.size();i++) {
NodePath np = nodes[i];
@@ -1613,10 +1847,30 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat
continue;
}
- Ref<VisualScriptSceneNode> scene_node;
- scene_node.instance();
- scene_node->set_node_path(sn->get_path_to(node));
- undo_redo->add_do_method(script.ptr(),"add_node",edited_func,base_id,scene_node,ofs);
+ Ref<VisualScriptNode> n;
+
+ if (use_node) {
+ Ref<VisualScriptSceneNode> scene_node;
+ scene_node.instance();
+ scene_node->set_node_path(sn->get_path_to(node));
+ n=scene_node;
+
+
+ } else {
+ Ref<VisualScriptFunctionCall> call;
+ call.instance();
+ call->set_call_mode(VisualScriptFunctionCall::CALL_MODE_NODE_PATH);
+ call->set_base_path(sn->get_path_to(node));;
+ call->set_base_type(node->get_type());
+ n=call;
+
+ method_select->select_method_from_instance(node);
+ selecting_method_id=base_id;
+
+ }
+
+
+ undo_redo->add_do_method(script.ptr(),"add_node",edited_func,base_id,n,ofs);
undo_redo->add_undo_method(script.ptr(),"remove_node",edited_func,base_id);
base_id++;
@@ -1634,9 +1888,9 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat
Node* sn = _find_script_node(get_tree()->get_edited_scene_root(),get_tree()->get_edited_scene_root(),script);
- if (!sn) {
- //EditorNode::get_singleton()->show_warning("Can't drop properties because script '"+get_name()+"' is not used in this scene.");
- //return;
+ if (!sn && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ EditorNode::get_singleton()->show_warning("Can't drop properties because script '"+get_name()+"' is not used in this scene.\nDrop holding 'Shift' to just copy the signature.");
+ return;
}
Object *obj=d["object"];
@@ -1654,36 +1908,33 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat
ofs/=EDSCALE;
#ifdef OSX_ENABLED
- bool use_set = Input::get_singleton()->is_key_pressed(KEY_META);
+ bool use_get = Input::get_singleton()->is_key_pressed(KEY_META);
#else
- bool use_set = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+ bool use_get = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
#endif
- bool use_value = Input::get_singleton()->is_key_pressed(KEY_SHIFT);
-
- if (!node) {
+ if (!node || Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
- if (use_set)
- undo_redo->create_action(TTR("Add Setter Property"));
- else
+ if (use_get)
undo_redo->create_action(TTR("Add Getter Property"));
+ else
+ undo_redo->create_action(TTR("Add Setter Property"));
int base_id = script->get_available_id();
Ref<VisualScriptNode> vnode;
- if (use_set) {
+ if (!use_get) {
Ref<VisualScriptPropertySet> pset;
pset.instance();
pset->set_call_mode(VisualScriptPropertySet::CALL_MODE_INSTANCE);
pset->set_base_type(obj->get_type());
- pset->set_property(d["property"]);
- if (use_value) {
+ /*if (use_value) {
pset->set_use_builtin_value(true);
pset->set_builtin_value(d["value"]);
- }
+ }*/
vnode=pset;
} else {
@@ -1691,12 +1942,17 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat
pget.instance();
pget->set_call_mode(VisualScriptPropertyGet::CALL_MODE_INSTANCE);
pget->set_base_type(obj->get_type());
- pget->set_property(d["property"]);
+
vnode=pget;
}
undo_redo->add_do_method(script.ptr(),"add_node",edited_func,base_id,vnode,ofs);
+ undo_redo->add_do_method(vnode.ptr(),"set_property",d["property"]);
+ if (!use_get) {
+ undo_redo->add_do_method(vnode.ptr(),"set_default_input_value",0,d["value"]);
+ }
+
undo_redo->add_undo_method(script.ptr(),"remove_node",edited_func,base_id);
undo_redo->add_do_method(this,"_update_graph");
@@ -1707,25 +1963,24 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat
- if (use_set)
- undo_redo->create_action(TTR("Add Setter Property"));
- else
+ if (use_get)
undo_redo->create_action(TTR("Add Getter Property"));
+ else
+ undo_redo->create_action(TTR("Add Setter Property"));
int base_id = script->get_available_id();
Ref<VisualScriptNode> vnode;
- if (use_set) {
+ if (!use_get) {
Ref<VisualScriptPropertySet> pset;
pset.instance();
- pset->set_call_mode(VisualScriptPropertySet::CALL_MODE_NODE_PATH);
- pset->set_base_path(sn->get_path_to(sn));
- pset->set_property(d["property"]);
- if (use_value) {
- pset->set_use_builtin_value(true);
- pset->set_builtin_value(d["value"]);
+ if (sn==node) {
+ pset->set_call_mode(VisualScriptPropertySet::CALL_MODE_SELF);
+ } else {
+ pset->set_call_mode(VisualScriptPropertySet::CALL_MODE_NODE_PATH);
+ pset->set_base_path(sn->get_path_to(node));
}
vnode=pset;
@@ -1733,13 +1988,20 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat
Ref<VisualScriptPropertyGet> pget;
pget.instance();
- pget->set_call_mode(VisualScriptPropertyGet::CALL_MODE_NODE_PATH);
- pget->set_base_path(sn->get_path_to(sn));
- pget->set_property(d["property"]);
+ if (sn==node) {
+ pget->set_call_mode(VisualScriptPropertyGet::CALL_MODE_SELF);
+ } else {
+ pget->set_call_mode(VisualScriptPropertyGet::CALL_MODE_NODE_PATH);
+ pget->set_base_path(sn->get_path_to(node));
+ }
vnode=pget;
}
undo_redo->add_do_method(script.ptr(),"add_node",edited_func,base_id,vnode,ofs);
+ undo_redo->add_do_method(vnode.ptr(),"set_property",d["property"]);
+ if (!use_get) {
+ undo_redo->add_do_method(vnode.ptr(),"set_default_input_value",0,d["value"]);
+ }
undo_redo->add_undo_method(script.ptr(),"remove_node",edited_func,base_id);
undo_redo->add_do_method(this,"_update_graph");
@@ -1757,6 +2019,50 @@ void VisualScriptEditor::drop_data_fw(const Point2& p_point,const Variant& p_dat
}
+void VisualScriptEditor::_selected_method(const String& p_method) {
+
+ Ref<VisualScriptFunctionCall> vsfc = script->get_node(edited_func,selecting_method_id);
+ if (!vsfc.is_valid())
+ return;
+ vsfc->set_function(p_method);
+
+}
+
+void VisualScriptEditor::_draw_color_over_button(Object* obj,Color p_color) {
+
+ Button *button = obj->cast_to<Button>();
+ if (!button)
+ return;
+
+ Ref<StyleBox> normal = get_stylebox("normal","Button" );
+ button->draw_rect(Rect2(normal->get_offset(),button->get_size()-normal->get_minimum_size()),p_color);
+
+}
+
+void VisualScriptEditor::_button_resource_previewed(const String& p_path,const Ref<Texture>& p_preview,Variant p_ud) {
+
+
+ Array ud=p_ud;
+ ERR_FAIL_COND(ud.size()!=2);
+
+ ObjectID id = ud[0];
+ Object *obj = ObjectDB::get_instance(id);
+
+ if (!obj)
+ return;
+
+ Button *b = obj->cast_to<Button>();
+ ERR_FAIL_COND(!b);
+
+ if (p_preview.is_null()) {
+ b->set_text(ud[1]);
+ } else {
+
+ b->set_icon(p_preview);
+ }
+
+}
+
/////////////////////////
@@ -2251,6 +2557,11 @@ void VisualScriptEditor::_graph_disconnected(const String& p_from,int p_from_slo
}
+void VisualScriptEditor::_graph_connect_to_empty(const String& p_from,int p_from_slot,const Vector2& p_release_pos) {
+
+
+}
+
void VisualScriptEditor::_default_value_changed() {
@@ -2286,8 +2597,12 @@ void VisualScriptEditor::_default_value_edited(Node * p_button,int p_id,int p_in
default_value_edit->set_pos(p_button->cast_to<Control>()->get_global_pos()+Vector2(0,p_button->cast_to<Control>()->get_size().y));
default_value_edit->set_size(Size2(1,1));
- if (default_value_edit->edit(NULL,pinfo.name,pinfo.type,existing,pinfo.hint,pinfo.hint_string))
- default_value_edit->popup();
+ if (default_value_edit->edit(NULL,pinfo.name,pinfo.type,existing,pinfo.hint,pinfo.hint_string)) {
+ if (pinfo.hint==PROPERTY_HINT_MULTILINE_TEXT)
+ default_value_edit->popup_centered_ratio();
+ else
+ default_value_edit->popup();
+ }
editing_id = p_id;
editing_input=p_input_port;
@@ -2332,6 +2647,39 @@ void VisualScriptEditor::_graph_ofs_changed(const Vector2& p_ofs) {
updating_graph=false;
}
+void VisualScriptEditor::_comment_node_resized(const Vector2& p_new_size,int p_node) {
+
+ if (updating_graph)
+ return;
+
+ Ref<VisualScriptComment> vsc = script->get_node(edited_func,p_node);
+ if (vsc.is_null())
+ return;
+
+ Node *node = graph->get_node(itos(p_node));
+ if (!node)
+ return;
+ GraphNode *gn = node->cast_to<GraphNode>();
+ if (!gn)
+ return;
+
+ updating_graph=true;
+
+ graph->set_block_minimum_size_adjust(true); //faster resize
+
+ undo_redo->create_action("Resize Comment",UndoRedo::MERGE_ENDS);
+ undo_redo->add_do_method(vsc.ptr(),"set_size",p_new_size/EDSCALE);
+ undo_redo->add_undo_method(vsc.ptr(),"set_size",vsc->get_size());
+ undo_redo->commit_action();
+
+ gn->set_custom_minimum_size(p_new_size); //for this time since graph update is blocked
+ gn->set_size(Size2(1,1));
+ graph->set_block_minimum_size_adjust(false);
+ updating_graph=false;
+
+
+}
+
void VisualScriptEditor::_menu_option(int p_what) {
switch(p_what) {
@@ -2367,7 +2715,150 @@ void VisualScriptEditor::_menu_option(int p_what) {
//popup disappearing grabs focus to owner, so use call deferred
node_filter->call_deferred("grab_focus");
node_filter->call_deferred("select_all");
+ } break;
+ case EDIT_COPY_NODES:
+ case EDIT_CUT_NODES: {
+
+ if (!script->has_function(edited_func))
+ break;
+
+ clipboard.nodes.clear();
+ clipboard.data_connections.clear();
+ clipboard.sequence_connections.clear();
+
+ for(int i=0;i<graph->get_child_count();i++) {
+ GraphNode *gn = graph->get_child(i)->cast_to<GraphNode>();
+ if (gn) {
+ if (gn->is_selected()) {
+
+ int id = String(gn->get_name()).to_int();
+ Ref<VisualScriptNode> node = script->get_node(edited_func,id);
+ if (node->cast_to<VisualScriptFunction>()) {
+ EditorNode::get_singleton()->show_warning("Can't copy the function node.");
+ return;
+ }
+ if (node.is_valid()) {
+ clipboard.nodes[id]=node->duplicate();
+ clipboard.nodes_positions[id]=script->get_node_pos(edited_func,id);
+ }
+
+ }
+ }
+ }
+
+ if (clipboard.nodes.empty())
+ break;
+
+ List<VisualScript::SequenceConnection> sequence_connections;
+
+ script->get_sequence_connection_list(edited_func,&sequence_connections);
+
+ for (List<VisualScript::SequenceConnection>::Element *E=sequence_connections.front();E;E=E->next()) {
+
+ if (clipboard.nodes.has(E->get().from_node) && clipboard.nodes.has(E->get().to_node)) {
+
+ clipboard.sequence_connections.insert(E->get());
+ }
+ }
+
+ List<VisualScript::DataConnection> data_connections;
+
+ script->get_data_connection_list(edited_func,&data_connections);
+
+ for (List<VisualScript::DataConnection>::Element *E=data_connections.front();E;E=E->next()) {
+
+ if (clipboard.nodes.has(E->get().from_node) && clipboard.nodes.has(E->get().to_node)) {
+
+ clipboard.data_connections.insert(E->get());
+ }
+ }
+
+ if (p_what==EDIT_CUT_NODES) {
+ _on_nodes_delete(); // oh yeah, also delete on cut
+ }
+
+
} break;
+ case EDIT_PASTE_NODES: {
+ if (!script->has_function(edited_func))
+ break;
+
+ if (clipboard.nodes.empty()) {
+ EditorNode::get_singleton()->show_warning("Clipboard is empty!");
+ break;
+ }
+
+ Map<int,int> remap;
+
+ undo_redo->create_action("Paste VisualScript Nodes");
+ int idc=script->get_available_id()+1;
+
+ Set<int> to_select;
+
+ Set<Vector2> existing_positions;
+
+ {
+ List<int> nodes;
+ script->get_node_list(edited_func,&nodes);
+ for (List<int>::Element *E=nodes.front();E;E=E->next()) {
+ Vector2 pos = script->get_node_pos(edited_func,E->get()).snapped(Vector2(2,2));
+ existing_positions.insert(pos);
+ }
+ }
+
+ for (Map<int,Ref<VisualScriptNode> >::Element *E=clipboard.nodes.front();E;E=E->next()) {
+
+
+ Ref<VisualScriptNode> node = E->get()->duplicate();
+
+ int new_id = idc++;
+ to_select.insert(new_id);
+
+ remap[E->key()]=new_id;
+
+ Vector2 paste_pos = clipboard.nodes_positions[E->key()];
+
+ while(existing_positions.has(paste_pos.snapped(Vector2(2,2)))) {
+ paste_pos+=Vector2(20,20)*EDSCALE;
+ }
+
+
+ undo_redo->add_do_method(script.ptr(),"add_node",edited_func,new_id,node,paste_pos);
+ undo_redo->add_undo_method(script.ptr(),"remove_node",edited_func,new_id);
+
+ }
+
+ for (Set<VisualScript::SequenceConnection>::Element *E=clipboard.sequence_connections.front();E;E=E->next()) {
+
+
+ undo_redo->add_do_method(script.ptr(),"sequence_connect",edited_func,remap[E->get().from_node],E->get().from_output,remap[E->get().to_node]);
+ undo_redo->add_undo_method(script.ptr(),"sequence_disconnect",edited_func,remap[E->get().from_node],E->get().from_output,remap[E->get().to_node]);
+
+ }
+
+ for (Set<VisualScript::DataConnection>::Element *E=clipboard.data_connections.front();E;E=E->next()) {
+
+
+ undo_redo->add_do_method(script.ptr(),"data_connect",edited_func,remap[E->get().from_node],E->get().from_port,remap[E->get().to_node],E->get().to_port);
+ undo_redo->add_undo_method(script.ptr(),"data_disconnect",edited_func,remap[E->get().from_node],E->get().from_port,remap[E->get().to_node],E->get().to_port);
+
+ }
+
+ undo_redo->add_do_method(this,"_update_graph");
+ undo_redo->add_undo_method(this,"_update_graph");
+
+ undo_redo->commit_action();
+
+ for(int i=0;i<graph->get_child_count();i++) {
+ GraphNode *gn = graph->get_child(i)->cast_to<GraphNode>();
+ if (gn) {
+ int id = gn->get_name().operator String().to_int();
+ gn->set_selected(to_select.has(id));
+
+ }
+ }
+ } break;
+
}
}
@@ -2395,6 +2886,9 @@ void VisualScriptEditor::_bind_methods() {
ObjectTypeDB::bind_method("_menu_option",&VisualScriptEditor::_menu_option);
ObjectTypeDB::bind_method("_graph_ofs_changed",&VisualScriptEditor::_graph_ofs_changed);
ObjectTypeDB::bind_method("_center_on_node",&VisualScriptEditor::_center_on_node);
+ ObjectTypeDB::bind_method("_comment_node_resized",&VisualScriptEditor::_comment_node_resized);
+ ObjectTypeDB::bind_method("_button_resource_previewed",&VisualScriptEditor::_button_resource_previewed);
+
@@ -2410,9 +2904,16 @@ void VisualScriptEditor::_bind_methods() {
ObjectTypeDB::bind_method("_graph_connected",&VisualScriptEditor::_graph_connected);
ObjectTypeDB::bind_method("_graph_disconnected",&VisualScriptEditor::_graph_disconnected);
+ ObjectTypeDB::bind_method("_graph_connect_to_empty",&VisualScriptEditor::_graph_connect_to_empty);
+
ObjectTypeDB::bind_method("_update_graph_connections",&VisualScriptEditor::_update_graph_connections);
ObjectTypeDB::bind_method("_node_filter_changed",&VisualScriptEditor::_node_filter_changed);
+ ObjectTypeDB::bind_method("_selected_method",&VisualScriptEditor::_selected_method);
+ ObjectTypeDB::bind_method("_draw_color_over_button",&VisualScriptEditor::_draw_color_over_button);
+
+
+
}
@@ -2427,6 +2928,11 @@ VisualScriptEditor::VisualScriptEditor() {
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/delete_selected"), EDIT_DELETE_NODES);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/toggle_breakpoint"), EDIT_TOGGLE_BREAKPOINT);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/find_node_type"), EDIT_FIND_NODE_TYPE);
+ edit_menu->get_popup()->add_separator();
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/copy_nodes"), EDIT_COPY_NODES);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/cut_nodes"), EDIT_CUT_NODES);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/paste_nodes"), EDIT_PASTE_NODES);
+
edit_menu->get_popup()->connect("item_pressed",this,"_menu_option");
main_hsplit = memnew( HSplitContainer );
@@ -2441,7 +2947,7 @@ VisualScriptEditor::VisualScriptEditor() {
left_vb->set_v_size_flags(SIZE_EXPAND_FILL);
left_vb->set_custom_minimum_size(Size2(180,1)*EDSCALE);
- base_type_select = memnew( Button );
+ base_type_select = memnew( Button );
left_vb->add_margin_child(TTR("Base Type:"),base_type_select);
base_type_select->connect("pressed",this,"_change_base_type");
@@ -2532,6 +3038,7 @@ VisualScriptEditor::VisualScriptEditor() {
graph->connect("connection_request",this,"_graph_connected");
graph->connect("disconnection_request",this,"_graph_disconnected");
+ graph->connect("connection_to_empty",this,"_graph_connect_to_empty");
edit_signal_dialog = memnew( AcceptDialog );
edit_signal_dialog->get_ok()->set_text(TTR("Close"));
@@ -2577,7 +3084,11 @@ VisualScriptEditor::VisualScriptEditor() {
add_child(default_value_edit);
default_value_edit->connect("variant_changed",this,"_default_value_changed");
+ method_select = memnew( PropertySelector );
+ add_child(method_select);
+ method_select->connect("selected",this,"_selected_method");
error_line=-1;
+
}
VisualScriptEditor::~VisualScriptEditor() {
@@ -2608,7 +3119,10 @@ static void register_editor_callback() {
ED_SHORTCUT("visual_script_editor/delete_selected", TTR("Delete Selected"));
ED_SHORTCUT("visual_script_editor/toggle_breakpoint", TTR("Toggle Breakpoint"), KEY_F9);
- ED_SHORTCUT("visual_script_editor/find_node_type", TTR("Find Node Tyoe"), KEY_MASK_CMD+KEY_F);
+ ED_SHORTCUT("visual_script_editor/find_node_type", TTR("Find Node Type"), KEY_MASK_CMD+KEY_F);
+ ED_SHORTCUT("visual_script_editor/copy_nodes", TTR("Copy Nodes"), KEY_MASK_CMD+KEY_C);
+ ED_SHORTCUT("visual_script_editor/cut_nodes", TTR("Cut Nodes"), KEY_MASK_CMD+KEY_X);
+ ED_SHORTCUT("visual_script_editor/paste_nodes", TTR("Paste Nodes"), KEY_MASK_CMD+KEY_V);
}
diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h
index 252519913d..735eaae446 100644
--- a/modules/visual_script/visual_script_editor.h
+++ b/modules/visual_script/visual_script_editor.h
@@ -6,7 +6,7 @@
#include "tools/editor/property_editor.h"
#include "scene/gui/graph_edit.h"
#include "tools/editor/create_dialog.h"
-
+#include "tools/editor/property_selector.h"
class VisualScriptEditorSignalEdit;
class VisualScriptEditorVariableEdit;
@@ -27,6 +27,9 @@ class VisualScriptEditor : public ScriptEditorBase {
EDIT_DELETE_NODES,
EDIT_TOGGLE_BREAKPOINT,
EDIT_FIND_NODE_TYPE,
+ EDIT_COPY_NODES,
+ EDIT_CUT_NODES,
+ EDIT_PASTE_NODES,
};
MenuButton *edit_menu;
@@ -48,6 +51,7 @@ class VisualScriptEditor : public ScriptEditorBase {
AcceptDialog *edit_signal_dialog;
PropertyEditor *edit_signal_edit;
+ PropertySelector *method_select;
VisualScriptEditorVariableEdit *variable_editor;
@@ -98,6 +102,15 @@ class VisualScriptEditor : public ScriptEditorBase {
String _validate_name(const String& p_name) const;
+ struct Clipboard {
+
+ Map<int,Ref<VisualScriptNode> > nodes;
+ Map<int,Vector2 > nodes_positions;
+
+ Set<VisualScript::SequenceConnection> sequence_connections;
+ Set<VisualScript::DataConnection> data_connections;
+ } clipboard;
+
int error_line;
@@ -119,6 +132,8 @@ class VisualScriptEditor : public ScriptEditorBase {
void _remove_node(int p_id);
void _graph_connected(const String& p_from,int p_from_slot,const String& p_to,int p_to_slot);
void _graph_disconnected(const String& p_from,int p_from_slot,const String& p_to,int p_to_slot);
+ void _graph_connect_to_empty(const String& p_from,int p_from_slot,const Vector2& p_release_pos);
+
void _node_ports_changed(const String& p_func,int p_id);
void _available_node_doubleclicked();
@@ -147,6 +162,15 @@ class VisualScriptEditor : public ScriptEditorBase {
void _menu_option(int p_what);
void _graph_ofs_changed(const Vector2& p_ofs);
+ void _comment_node_resized(const Vector2& p_new_size,int p_node);
+
+ int selecting_method_id;
+ void _selected_method(const String& p_method);
+
+ void _draw_color_over_button(Object* obj,Color p_color);
+ void _button_resource_previewed(const String& p_path,const Ref<Texture>& p_preview,Variant p_ud);
+
+
protected:
void _notification(int p_what);
@@ -175,6 +199,7 @@ public:
virtual void set_debugger_active(bool p_active);
virtual void set_tooltip_request_func(String p_method,Object* p_obj);
virtual Control *get_edit_menu();
+ virtual bool can_lose_focus_on_node_selection() { return false; }
static void register_editor();
diff --git a/modules/visual_script/visual_script_flow_control.cpp b/modules/visual_script/visual_script_flow_control.cpp
index cb0ff4086c..700d5d57ff 100644
--- a/modules/visual_script/visual_script_flow_control.cpp
+++ b/modules/visual_script/visual_script_flow_control.cpp
@@ -2,6 +2,7 @@
#include "os/keyboard.h"
#include "globals.h"
+
//////////////////////////////////////////
////////////////RETURN////////////////////
//////////////////////////////////////////
@@ -85,7 +86,7 @@ void VisualScriptReturn::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_enable_return_value","enable"),&VisualScriptReturn::set_enable_return_value);
ObjectTypeDB::bind_method(_MD("is_return_value_enabled"),&VisualScriptReturn::is_return_value_enabled);
- String argt="Variant";
+ String argt="Any";
for(int i=1;i<Variant::VARIANT_MAX;i++) {
argt+=","+Variant::get_type_name(Variant::Type(i));
}
@@ -152,7 +153,7 @@ static Ref<VisualScriptNode> create_return_node(const String& p_name) {
int VisualScriptCondition::get_output_sequence_port_count() const {
- return 2;
+ return 3;
}
bool VisualScriptCondition::has_input_sequence_port() const{
@@ -173,8 +174,10 @@ String VisualScriptCondition::get_output_sequence_port_text(int p_port) const {
if (p_port==0)
return "true";
- else
+ else if (p_port==1)
return "false";
+ else
+ return "done";
}
PropertyInfo VisualScriptCondition::get_input_value_port_info(int p_idx) const{
@@ -217,10 +220,12 @@ public:
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) {
- if (p_inputs[0]->operator bool())
- return 0;
+ if (p_start_mode==START_MODE_CONTINUE_SEQUENCE)
+ return 2;
+ else if (p_inputs[0]->operator bool())
+ return 0 | STEP_FLAG_PUSH_STACK_BIT;
else
- return 1;
+ return 1 | STEP_FLAG_PUSH_STACK_BIT;
}
@@ -1660,6 +1665,197 @@ VisualScriptInputFilter::VisualScriptInputFilter() {
}
+//////////////////////////////////////////
+////////////////TYPE CAST///////////
+//////////////////////////////////////////
+
+
+int VisualScriptTypeCast::get_output_sequence_port_count() const {
+
+ return 2;
+}
+
+bool VisualScriptTypeCast::has_input_sequence_port() const{
+
+ return true;
+}
+
+int VisualScriptTypeCast::get_input_value_port_count() const{
+
+
+ return 1;
+}
+int VisualScriptTypeCast::get_output_value_port_count() const{
+
+ return 1;
+}
+
+String VisualScriptTypeCast::get_output_sequence_port_text(int p_port) const {
+
+ return p_port==0 ? "yes" : "no";
+}
+
+PropertyInfo VisualScriptTypeCast::get_input_value_port_info(int p_idx) const{
+
+ return PropertyInfo(Variant::OBJECT,"instance");
+}
+
+PropertyInfo VisualScriptTypeCast::get_output_value_port_info(int p_idx) const{
+
+ return PropertyInfo(Variant::OBJECT,"");
+}
+
+
+String VisualScriptTypeCast::get_caption() const {
+
+ return "TypeCast";
+}
+
+String VisualScriptTypeCast::get_text() const {
+
+ if (script!=String())
+ return "Is "+script.get_file()+"?";
+ else
+ return "Is "+base_type+"?";
+}
+
+void VisualScriptTypeCast::set_base_type(const StringName& p_type) {
+
+ if (base_type==p_type)
+ return;
+
+ base_type=p_type;
+ _change_notify();
+ ports_changed_notify();
+}
+
+StringName VisualScriptTypeCast::get_base_type() const{
+
+ return base_type;
+}
+
+void VisualScriptTypeCast::set_base_script(const String& p_path){
+
+ if (script==p_path)
+ return;
+
+ script=p_path;
+ _change_notify();
+ ports_changed_notify();
+
+}
+String VisualScriptTypeCast::get_base_script() const{
+
+ return script;
+}
+
+
+class VisualScriptNodeInstanceTypeCast : public VisualScriptNodeInstance {
+public:
+
+ VisualScriptInstance* instance;
+ StringName base_type;
+ String script;
+
+ //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 false; }
+
+ 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) {
+
+ Object *obj = *p_inputs[0];
+
+ *p_outputs[0]=Variant();
+
+ if (!obj) {
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error_str="Instance is null";
+ return 0;
+ }
+
+ if (script!=String()) {
+
+ Ref<Script> obj_script = obj->get_script();
+ if (!obj_script.is_valid()) {
+ return 1; //well, definitely not the script because object we got has no script.
+ }
+
+ if (!ResourceCache::has(script)) {
+ //if the script is not in use by anyone, we can safely assume whathever we got is not casting to it.
+ return 1;
+ }
+ Ref<Script> cast_script = Ref<Resource>(ResourceCache::get(script));
+ if (!cast_script.is_valid()) {
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error_str="Script path is not a script: "+script;
+ return 1;
+ }
+
+ while(obj_script.is_valid()) {
+
+ if (cast_script==obj_script) {
+ *p_outputs[0]=*p_inputs[0]; //copy
+ return 0; // it is the script, yey
+ }
+
+ obj_script=obj_script->get_base_script();
+ }
+
+ return 1; //not found sorry
+ }
+
+ if (ObjectTypeDB::is_type(obj->get_type_name(),base_type)) {
+ *p_outputs[0]=*p_inputs[0]; //copy
+ return 0;
+ } else
+ return 1;
+
+ }
+
+
+};
+
+VisualScriptNodeInstance* VisualScriptTypeCast::instance(VisualScriptInstance* p_instance) {
+
+ VisualScriptNodeInstanceTypeCast * instance = memnew(VisualScriptNodeInstanceTypeCast );
+ instance->instance=p_instance;
+ instance->base_type=base_type;
+ instance->script=script;
+ return instance;
+}
+
+
+
+void VisualScriptTypeCast::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("set_base_type","type"),&VisualScriptTypeCast::set_base_type);
+ ObjectTypeDB::bind_method(_MD("get_base_type"),&VisualScriptTypeCast::get_base_type);
+
+ ObjectTypeDB::bind_method(_MD("set_base_script","path"),&VisualScriptTypeCast::set_base_script);
+ ObjectTypeDB::bind_method(_MD("get_base_script"),&VisualScriptTypeCast::get_base_script);
+
+
+ List<String> script_extensions;
+ for(int i=0;i>ScriptServer::get_language_count();i++) {
+ ScriptServer::get_language(i)->get_recognized_extensions(&script_extensions);
+ }
+
+ String script_ext_hint;
+ for (List<String>::Element *E=script_extensions.front();E;E=E->next()) {
+ if (script_ext_hint!=String())
+ script_ext_hint+=",";
+ script_ext_hint+="*."+E->get();
+ }
+
+ ADD_PROPERTY(PropertyInfo(Variant::STRING,"function/base_type",PROPERTY_HINT_TYPE_STRING,"Object"),_SCS("set_base_type"),_SCS("get_base_type"));
+ ADD_PROPERTY(PropertyInfo(Variant::STRING,"property/base_script",PROPERTY_HINT_FILE,script_ext_hint),_SCS("set_base_script"),_SCS("get_base_script"));
+
+}
+
+VisualScriptTypeCast::VisualScriptTypeCast() {
+
+ base_type="Object";
+}
void register_visual_script_flow_control_nodes() {
@@ -1672,6 +1868,7 @@ void register_visual_script_flow_control_nodes() {
VisualScriptLanguage::singleton->add_register_func("flow_control/sequence",create_node_generic<VisualScriptSequence>);
VisualScriptLanguage::singleton->add_register_func("flow_control/input_select",create_node_generic<VisualScriptInputSelector>);
VisualScriptLanguage::singleton->add_register_func("flow_control/input_filter",create_node_generic<VisualScriptInputFilter>);
+ VisualScriptLanguage::singleton->add_register_func("flow_control/type_cast",create_node_generic<VisualScriptTypeCast>);
diff --git a/modules/visual_script/visual_script_flow_control.h b/modules/visual_script/visual_script_flow_control.h
index ed0e328629..42fab2e44d 100644
--- a/modules/visual_script/visual_script_flow_control.h
+++ b/modules/visual_script/visual_script_flow_control.h
@@ -273,6 +273,56 @@ public:
VisualScriptInputFilter();
};
+
+
+
+
+class VisualScriptTypeCast : public VisualScriptNode {
+
+ OBJ_TYPE(VisualScriptTypeCast,VisualScriptNode)
+
+
+ StringName base_type;
+ String script;
+
+protected:
+
+ static void _bind_methods();
+public:
+
+ virtual int get_output_sequence_port_count() const;
+ virtual bool has_input_sequence_port() const;
+
+
+ virtual String get_output_sequence_port_text(int p_port) const;
+
+
+ virtual int get_input_value_port_count() const;
+ virtual int get_output_value_port_count() const;
+
+
+ virtual PropertyInfo get_input_value_port_info(int p_idx) const;
+ virtual PropertyInfo get_output_value_port_info(int p_idx) const;
+
+ virtual String get_caption() const;
+ virtual String get_text() const;
+ virtual String get_category() const { return "flow_control"; }
+
+ void set_base_type(const StringName& p_type);
+ StringName get_base_type() const;
+
+ void set_base_script(const String& p_path);
+ String get_base_script() const;
+
+ virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
+
+
+ VisualScriptTypeCast();
+};
+
+
+
+
void register_visual_script_flow_control_nodes();
diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp
index 14bc0bc828..a81f323729 100644
--- a/modules/visual_script/visual_script_func_nodes.cpp
+++ b/modules/visual_script/visual_script_func_nodes.cpp
@@ -3,6 +3,8 @@
#include "os/os.h"
#include "scene/main/node.h"
#include "visual_script_nodes.h"
+#include "io/resource_loader.h"
+#include "globals.h"
//////////////////////////////////////////
////////////////CALL//////////////////////
@@ -10,12 +12,18 @@
int VisualScriptFunctionCall::get_output_sequence_port_count() const {
- return 1;
+ if (method_cache.flags&METHOD_FLAG_CONST)
+ return 0;
+ else
+ return 1;
}
bool VisualScriptFunctionCall::has_input_sequence_port() const{
- return true;
+ if (method_cache.flags&METHOD_FLAG_CONST)
+ return false;
+ else
+ return true;
}
#ifdef TOOLS_ENABLED
@@ -91,20 +99,23 @@ StringName VisualScriptFunctionCall::_get_base_type() const {
return base_type;
}
+
int VisualScriptFunctionCall::get_input_value_port_count() const{
if (call_mode==CALL_MODE_BASIC_TYPE) {
Vector<StringName> names = Variant::get_method_argument_names(basic_type,function);
- return names.size()+1;
+ return names.size() + (rpc_call_mode>=RPC_RELIABLE_TO_ID?1:0) + 1;
} else {
+
MethodBind *mb = ObjectTypeDB::get_method(_get_base_type(),function);
- if (!mb)
- return 0;
+ if (mb) {
+ return mb->get_argument_count() + (call_mode==CALL_MODE_INSTANCE?1:0) + (rpc_call_mode>=RPC_RELIABLE_TO_ID?1:0) - use_default_args;
+ }
- return mb->get_argument_count() + (call_mode==CALL_MODE_INSTANCE?1:0) - use_default_args;
+ return method_cache.arguments.size() + (call_mode==CALL_MODE_INSTANCE?1:0) + (rpc_call_mode>=RPC_RELIABLE_TO_ID?1:0) - use_default_args;
}
}
@@ -117,11 +128,18 @@ int VisualScriptFunctionCall::get_output_value_port_count() const{
return returns?1:0;
} else {
+ int ret;
MethodBind *mb = ObjectTypeDB::get_method(_get_base_type(),function);
- if (!mb)
- return 0;
+ if (mb) {
+ ret = mb->has_return() ? 1 : 0;
+ } else
+ ret = 1; //it is assumed that script always returns something
- return mb->has_return() ? 1 : 0;
+ if (call_mode==CALL_MODE_INSTANCE) {
+ ret++;
+ }
+
+ return ret;
}
}
@@ -143,6 +161,16 @@ PropertyInfo VisualScriptFunctionCall::get_input_value_port_info(int p_idx) cons
}
}
+ if (rpc_call_mode>=RPC_RELIABLE_TO_ID) {
+
+ if (p_idx==0) {
+ return PropertyInfo(Variant::INT,"peer_id");
+ } else {
+ p_idx--;
+ }
+
+ }
+
#ifdef DEBUG_METHODS_ENABLED
if (call_mode==CALL_MODE_BASIC_TYPE) {
@@ -155,10 +183,15 @@ PropertyInfo VisualScriptFunctionCall::get_input_value_port_info(int p_idx) cons
} else {
MethodBind *mb = ObjectTypeDB::get_method(_get_base_type(),function);
- if (!mb)
- return PropertyInfo();
+ if (mb) {
+ return mb->get_argument_info(p_idx);
+ }
- return mb->get_argument_info(p_idx);
+ if (p_idx>=0 && p_idx < method_cache.arguments.size()) {
+ return method_cache.arguments[p_idx];
+ }
+
+ return PropertyInfo();
}
#else
return PropertyInfo();
@@ -177,13 +210,34 @@ PropertyInfo VisualScriptFunctionCall::get_output_value_port_info(int p_idx) con
return PropertyInfo(Variant::get_method_return_type(basic_type,function),"");
} else {
- MethodBind *mb = ObjectTypeDB::get_method(_get_base_type(),function);
- if (!mb)
- return PropertyInfo();
+ if (call_mode==CALL_MODE_INSTANCE) {
+ if (p_idx==0) {
+ return PropertyInfo(Variant::OBJECT,"pass");
+ } else {
+ p_idx--;
+ }
+ }
+
+ PropertyInfo ret;
+
+ /*MethodBind *mb = ObjectTypeDB::get_method(_get_base_type(),function);
+ if (mb) {
+
+ ret = mb->get_argument_info(-1);
+ } else {*/
+
+ ret = method_cache.return_val;
+
+ //}
+
+ if (call_mode==CALL_MODE_INSTANCE) {
+ ret.name="return";
+ } else {
+ ret.name="";
+ }
+ return ret;
+
- PropertyInfo pi = mb->get_argument_info(-1);
- pi.name="";
- return pi;
}
#else
return PropertyInfo();
@@ -193,59 +247,38 @@ PropertyInfo VisualScriptFunctionCall::get_output_value_port_info(int p_idx) con
String VisualScriptFunctionCall::get_caption() const {
- static const char*cname[4]= {
+ static const char*cname[5]= {
"CallSelf",
"CallNode",
"CallInstance",
- "CallBasic"
+ "CallBasic",
+ "CallSingleton"
};
- return cname[call_mode];
+ String caption = cname[call_mode];
+
+ if (rpc_call_mode) {
+ caption+=" (RPC)";
+ }
+
+ return caption;
}
String VisualScriptFunctionCall::get_text() const {
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)+"()";
else
return " "+base_type+"."+String(function)+"()";
}
-void VisualScriptFunctionCall::_update_defargs() {
-
- //save base type if accessible
-
- if (call_mode==CALL_MODE_NODE_PATH) {
-
- Node* node=_get_base_node();
- if (node) {
- base_type=node->get_type();
- }
- } else if (call_mode==CALL_MODE_SELF) {
-
- if (get_visual_script().is_valid()) {
- base_type=get_visual_script()->get_instance_base_type();
- }
- }
-
-
- if (call_mode==CALL_MODE_BASIC_TYPE) {
- use_default_args = Variant::get_method_default_arguments(basic_type,function).size();
- } else {
- if (!get_visual_script().is_valid())
- return; //do not change if not valid yet
-
- MethodBind *mb = ObjectTypeDB::get_method(_get_base_type(),function);
- if (!mb)
- return;
-
- use_default_args=mb->get_default_argument_count();
- }
-
-}
void VisualScriptFunctionCall::set_basic_type(Variant::Type p_type) {
@@ -253,7 +286,7 @@ void VisualScriptFunctionCall::set_basic_type(Variant::Type p_type) {
return;
basic_type=p_type;
- _update_defargs();
+
_change_notify();
ports_changed_notify();
}
@@ -269,7 +302,6 @@ void VisualScriptFunctionCall::set_base_type(const StringName& p_type) {
return;
base_type=p_type;
- _update_defargs();
_change_notify();
ports_changed_notify();
}
@@ -279,13 +311,136 @@ StringName VisualScriptFunctionCall::get_base_type() const{
return base_type;
}
+void VisualScriptFunctionCall::set_base_script(const String& p_path) {
+
+ if (base_script==p_path)
+ return;
+
+ base_script=p_path;
+ _change_notify();
+ ports_changed_notify();
+}
+
+String VisualScriptFunctionCall::get_base_script() const {
+
+ return base_script;
+}
+
+void VisualScriptFunctionCall::set_singleton(const StringName& p_path) {
+
+ if (singleton==p_path)
+ return;
+
+ singleton=p_path;
+ Object *obj = Globals::get_singleton()->get_singleton_object(singleton);
+ if (obj) {
+ base_type=obj->get_type();
+ }
+
+ _change_notify();
+ ports_changed_notify();
+}
+
+StringName VisualScriptFunctionCall::get_singleton() const {
+
+ return singleton;
+}
+
+
+
+void VisualScriptFunctionCall::_update_method_cache() {
+ StringName type;
+ Ref<Script> script;
+
+ if (call_mode==CALL_MODE_NODE_PATH) {
+
+ Node* node=_get_base_node();
+ if (node) {
+ type=node->get_type();
+ base_type=type; //cache, too
+ script = node->get_script();
+ }
+ } else if (call_mode==CALL_MODE_SELF) {
+
+ if (get_visual_script().is_valid()) {
+ type=get_visual_script()->get_instance_base_type();
+ base_type=type; //cache, too
+ script=get_visual_script();
+ }
+
+ } else if (call_mode==CALL_MODE_SINGLETON) {
+
+ Object *obj = Globals::get_singleton()->get_singleton_object(singleton);
+ if (obj) {
+ type=obj->get_type();
+ script=obj->get_script();
+ }
+
+ } else if (call_mode==CALL_MODE_INSTANCE) {
+
+ type=base_type;
+ if (base_script!=String()) {
+
+ if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) {
+
+ ScriptServer::edit_request_func(base_script); //make sure it's loaded
+ }
+
+ if (ResourceCache::has(base_script)) {
+
+ script = Ref<Resource>( ResourceCache::get(base_script) );
+ } else {
+ return;
+ }
+ }
+ }
+
+
+// print_line("BASE: "+String(type)+" FUNC: "+String(function));
+ MethodBind *mb = ObjectTypeDB::get_method(type,function);
+ if (mb) {
+ use_default_args=mb->get_default_argument_count();
+ method_cache = MethodInfo();
+ for(int i=0;i<mb->get_argument_count();i++) {
+#ifdef DEBUG_METHODS_ENABLED
+ method_cache.arguments.push_back(mb->get_argument_info(i));
+#else
+ method_cache.arguments.push_back(PropertyInfo());
+#endif
+ }
+
+ if (mb->is_const()) {
+ method_cache.flags|=METHOD_FLAG_CONST;
+ }
+
+#ifdef DEBUG_METHODS_ENABLED
+
+ method_cache.return_val = mb->get_argument_info(-1);
+#endif
+ } else if (script.is_valid() && script->has_method(function)) {
+
+ method_cache = script->get_method_info(function);
+ use_default_args=method_cache.default_arguments.size();
+ }
+}
+
void VisualScriptFunctionCall::set_function(const StringName& p_type){
if (function==p_type)
return;
function=p_type;
- _update_defargs();
+
+ if (call_mode==CALL_MODE_BASIC_TYPE) {
+ use_default_args = Variant::get_method_default_arguments(basic_type,function).size();
+ } else {
+ //update all caches
+
+ _update_method_cache();
+
+ }
+
+
_change_notify();
ports_changed_notify();
}
@@ -301,7 +456,6 @@ void VisualScriptFunctionCall::set_base_path(const NodePath& p_type) {
return;
base_path=p_type;
- _update_defargs();
_change_notify();
ports_changed_notify();
}
@@ -318,7 +472,6 @@ void VisualScriptFunctionCall::set_call_mode(CallMode p_mode) {
return;
call_mode=p_mode;
- _update_defargs();
_change_notify();
ports_changed_notify();
@@ -339,10 +492,40 @@ void VisualScriptFunctionCall::set_use_default_args(int p_amount) {
}
+void VisualScriptFunctionCall::set_rpc_call_mode(VisualScriptFunctionCall::RPCCallMode p_mode) {
+
+ if (rpc_call_mode==p_mode)
+ return;
+ rpc_call_mode=p_mode;
+ ports_changed_notify();
+ _change_notify();
+}
+
+VisualScriptFunctionCall::RPCCallMode VisualScriptFunctionCall::get_rpc_call_mode() const{
+
+ return rpc_call_mode;
+}
+
+
int VisualScriptFunctionCall::get_use_default_args() const{
return use_default_args;
}
+
+
+
+
+void VisualScriptFunctionCall::_set_argument_cache(const Dictionary& p_cache) {
+ //so everything works in case all else fails
+ method_cache=MethodInfo::from_dict(p_cache);
+
+}
+
+Dictionary VisualScriptFunctionCall::_get_argument_cache() const {
+
+ return method_cache;
+}
+
void VisualScriptFunctionCall::_validate_property(PropertyInfo& property) const {
if (property.name=="function/base_type") {
@@ -351,12 +534,36 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo& property) const
}
}
+ if (property.name=="function/base_script") {
+ if (call_mode!=CALL_MODE_INSTANCE) {
+ property.usage=0;
+ }
+ }
+
if (property.name=="function/basic_type") {
if (call_mode!=CALL_MODE_BASIC_TYPE) {
property.usage=0;
}
}
+ if (property.name=="function/singleton") {
+ if (call_mode!=CALL_MODE_SINGLETON) {
+ property.usage=0;
+ } else {
+ List<Globals::Singleton> names;
+ Globals::get_singleton()->get_singletons(&names);
+ property.hint=PROPERTY_HINT_ENUM;
+ String sl;
+ for (List<Globals::Singleton>::Element *E=names.front();E;E=E->next()) {
+ if (sl!=String())
+ sl+=",";
+ sl+=E->get().name;
+ }
+ property.hint_string=sl;
+
+ }
+ }
+
if (property.name=="function/node_path") {
if (call_mode!=CALL_MODE_NODE_PATH) {
property.usage=0;
@@ -372,48 +579,59 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo& property) const
}
if (property.name=="function/function") {
- property.hint=PROPERTY_HINT_ENUM;
-
-
- List<MethodInfo> methods;
if (call_mode==CALL_MODE_BASIC_TYPE) {
- if (basic_type==Variant::NIL) {
- property.usage=0;
- return; //nothing for nil
- }
- Variant::CallError ce;
- Variant v = Variant::construct(basic_type,NULL,0,ce);
- v.get_method_list(&methods);
+ property.hint=PROPERTY_HINT_METHOD_OF_VARIANT_TYPE;
+ property.hint_string=Variant::get_type_name(basic_type);
+ } else if (call_mode==CALL_MODE_SELF && get_visual_script().is_valid()) {
+ property.hint=PROPERTY_HINT_METHOD_OF_SCRIPT;
+ property.hint_string=itos(get_visual_script()->get_instance_ID());
+ } else if (call_mode==CALL_MODE_SINGLETON) {
- } else {
+ Object *obj = Globals::get_singleton()->get_singleton_object(singleton);
+ if (obj) {
+ property.hint=PROPERTY_HINT_METHOD_OF_INSTANCE;
+ property.hint_string=itos(obj->get_instance_ID());
+ } else {
- StringName base = _get_base_type();
- ObjectTypeDB::get_method_list(base,&methods);
+ property.hint=PROPERTY_HINT_METHOD_OF_BASE_TYPE;
+ property.hint_string=base_type;//should be cached
+ }
+ } else if (call_mode==CALL_MODE_INSTANCE) {
+ property.hint=PROPERTY_HINT_METHOD_OF_BASE_TYPE;
+ property.hint_string=base_type;
+ if (base_script!=String()) {
+ if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) {
- }
+ ScriptServer::edit_request_func(base_script); //make sure it's loaded
+ }
- List<String> mstring;
- for (List<MethodInfo>::Element *E=methods.front();E;E=E->next()) {
- if (E->get().name.begins_with("_"))
- continue;
- mstring.push_back(E->get().name.get_slice(":",0));
- }
+ if (ResourceCache::has(base_script)) {
- mstring.sort();
+ Ref<Script> script = Ref<Resource>( ResourceCache::get(base_script) );
+ if (script.is_valid()) {
- String ml;
- for (List<String>::Element *E=mstring.front();E;E=E->next()) {
+ property.hint=PROPERTY_HINT_METHOD_OF_SCRIPT;
+ property.hint_string=itos(script->get_instance_ID());
+ }
+ }
+ }
+
+ } else if (call_mode==CALL_MODE_NODE_PATH) {
+ Node *node = _get_base_node();
+ if (node) {
+ property.hint=PROPERTY_HINT_METHOD_OF_INSTANCE;
+ property.hint_string=itos(node->get_instance_ID());
+ } else {
+ property.hint=PROPERTY_HINT_METHOD_OF_BASE_TYPE;
+ property.hint_string=get_base_type();
+ }
- if (ml!=String())
- ml+=",";
- ml+=E->get();
}
- property.hint_string=ml;
}
if (property.name=="function/use_default_args") {
@@ -440,6 +658,13 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo& property) const
property.hint_string="0,"+itos(mc)+",1";
}
}
+
+ if (property.name=="rpc/call_mode") {
+ if (call_mode==CALL_MODE_BASIC_TYPE) {
+ property.usage=0;
+ }
+ }
+
}
@@ -448,9 +673,15 @@ void VisualScriptFunctionCall::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_base_type","base_type"),&VisualScriptFunctionCall::set_base_type);
ObjectTypeDB::bind_method(_MD("get_base_type"),&VisualScriptFunctionCall::get_base_type);
+ ObjectTypeDB::bind_method(_MD("set_base_script","base_script"),&VisualScriptFunctionCall::set_base_script);
+ ObjectTypeDB::bind_method(_MD("get_base_script"),&VisualScriptFunctionCall::get_base_script);
+
ObjectTypeDB::bind_method(_MD("set_basic_type","basic_type"),&VisualScriptFunctionCall::set_basic_type);
ObjectTypeDB::bind_method(_MD("get_basic_type"),&VisualScriptFunctionCall::get_basic_type);
+ ObjectTypeDB::bind_method(_MD("set_singleton","singleton"),&VisualScriptFunctionCall::set_singleton);
+ ObjectTypeDB::bind_method(_MD("get_singleton"),&VisualScriptFunctionCall::get_singleton);
+
ObjectTypeDB::bind_method(_MD("set_function","function"),&VisualScriptFunctionCall::set_function);
ObjectTypeDB::bind_method(_MD("get_function"),&VisualScriptFunctionCall::get_function);
@@ -463,6 +694,11 @@ void VisualScriptFunctionCall::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_use_default_args","amount"),&VisualScriptFunctionCall::set_use_default_args);
ObjectTypeDB::bind_method(_MD("get_use_default_args"),&VisualScriptFunctionCall::get_use_default_args);
+ ObjectTypeDB::bind_method(_MD("_set_argument_cache","argument_cache"),&VisualScriptFunctionCall::_set_argument_cache);
+ ObjectTypeDB::bind_method(_MD("_get_argument_cache"),&VisualScriptFunctionCall::_get_argument_cache);
+
+ ObjectTypeDB::bind_method(_MD("set_rpc_call_mode","mode"),&VisualScriptFunctionCall::set_rpc_call_mode);
+ ObjectTypeDB::bind_method(_MD("get_rpc_call_mode"),&VisualScriptFunctionCall::get_rpc_call_mode);
String bt;
for(int i=0;i<Variant::VARIANT_MAX;i++) {
@@ -472,12 +708,31 @@ void VisualScriptFunctionCall::_bind_methods() {
bt+=Variant::get_type_name(Variant::Type(i));
}
- ADD_PROPERTY(PropertyInfo(Variant::INT,"function/call_mode",PROPERTY_HINT_ENUM,"Self,Node Path,Instance,Basic Type",PROPERTY_USAGE_NOEDITOR),_SCS("set_call_mode"),_SCS("get_call_mode"));
+
+ List<String> script_extensions;
+ for(int i=0;i<ScriptServer::get_language_count();i++) {
+ ScriptServer::get_language(i)->get_recognized_extensions(&script_extensions);
+ }
+
+ String script_ext_hint;
+ for (List<String>::Element *E=script_extensions.front();E;E=E->next()) {
+ if (script_ext_hint!=String())
+ script_ext_hint+=",";
+ script_ext_hint+="*."+E->get();
+ }
+
+
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"function/call_mode",PROPERTY_HINT_ENUM,"Self,Node Path,Instance,Basic Type,Singleton"),_SCS("set_call_mode"),_SCS("get_call_mode"));
ADD_PROPERTY(PropertyInfo(Variant::STRING,"function/base_type",PROPERTY_HINT_TYPE_STRING,"Object"),_SCS("set_base_type"),_SCS("get_base_type"));
+ ADD_PROPERTY(PropertyInfo(Variant::STRING,"function/base_script",PROPERTY_HINT_FILE,script_ext_hint),_SCS("set_base_script"),_SCS("get_base_script"));
+ ADD_PROPERTY(PropertyInfo(Variant::STRING,"function/singleton"),_SCS("set_singleton"),_SCS("get_singleton"));
ADD_PROPERTY(PropertyInfo(Variant::INT,"function/basic_type",PROPERTY_HINT_ENUM,bt),_SCS("set_basic_type"),_SCS("get_basic_type"));
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH,"function/node_path",PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE),_SCS("set_base_path"),_SCS("get_base_path"));
- ADD_PROPERTY(PropertyInfo(Variant::STRING,"function/function"),_SCS("set_function"),_SCS("get_function"));
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY,"function/argument_cache",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_argument_cache"),_SCS("_get_argument_cache"));
+ ADD_PROPERTY(PropertyInfo(Variant::STRING,"function/function"),_SCS("set_function"),_SCS("get_function")); //when set, if loaded properly, will override argument count.
ADD_PROPERTY(PropertyInfo(Variant::INT,"function/use_default_args"),_SCS("set_use_default_args"),_SCS("get_use_default_args"));
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"rpc/call_mode",PROPERTY_HINT_ENUM,"Disabled,Reliable,Unreliable,ReliableToID,UnreliableToID"),_SCS("set_rpc_call_mode"),_SCS("get_rpc_call_mode")); //when set, if loaded properly, will override argument count.
BIND_CONSTANT( CALL_MODE_SELF );
BIND_CONSTANT( CALL_MODE_NODE_PATH);
@@ -493,7 +748,9 @@ public:
NodePath node_path;
int input_args;
bool returns;
+ VisualScriptFunctionCall::RPCCallMode rpc_mode;
StringName function;
+ StringName singleton;
VisualScriptFunctionCall *node;
VisualScriptInstance *instance;
@@ -504,6 +761,35 @@ public:
//virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
+
+ _FORCE_INLINE_ bool call_rpc(Object* p_base,const Variant** p_args,int p_argcount) {
+
+ if (!p_base)
+ return false;
+
+ Node * node = p_base->cast_to<Node>();
+ if (!node)
+ return false;
+
+ int to_id=0;
+ bool reliable=true;
+
+ if (rpc_mode>=VisualScriptFunctionCall::RPC_RELIABLE_TO_ID) {
+ to_id = *p_args[0];
+ p_args+=1;
+ p_argcount-=1;
+ if (rpc_mode==VisualScriptFunctionCall::RPC_UNRELIABLE_TO_ID) {
+ reliable=false;
+ }
+ } else if (rpc_mode==VisualScriptFunctionCall::RPC_UNRELIABLE) {
+ reliable=false;
+ }
+
+ node->rpcp(to_id,!reliable,function,p_args,p_argcount);
+
+ return true;
+ }
+
virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
@@ -513,7 +799,9 @@ public:
Object *object=instance->get_owner_ptr();
- if (returns) {
+ if (rpc_mode) {
+ call_rpc(object,p_inputs,input_args);
+ } else if (returns) {
*p_outputs[0] = object->call(function,p_inputs,input_args,r_error);
} else {
object->call(function,p_inputs,input_args,r_error);
@@ -535,7 +823,9 @@ public:
return 0;
}
- if (returns) {
+ if (rpc_mode) {
+ call_rpc(node,p_inputs,input_args);
+ } else if (returns) {
*p_outputs[0] = another->call(function,p_inputs,input_args,r_error);
} else {
another->call(function,p_inputs,input_args,r_error);
@@ -547,14 +837,43 @@ public:
Variant v = *p_inputs[0];
- if (returns) {
- *p_outputs[0] = v.call(function,p_inputs+1,input_args,r_error);
+ if (rpc_mode) {
+ Object *obj = v;
+ if (obj) {
+ call_rpc(obj,p_inputs+1,input_args-1);
+ }
+ } else if (returns) {
+ if (call_mode==VisualScriptFunctionCall::CALL_MODE_INSTANCE) {
+ *p_outputs[1] = v.call(function,p_inputs+1,input_args,r_error);
+ } else {
+ *p_outputs[0] = v.call(function,p_inputs+1,input_args,r_error);
+ }
} else {
v.call(function,p_inputs+1,input_args,r_error);
}
+ if (call_mode==VisualScriptFunctionCall::CALL_MODE_INSTANCE) {
+ *p_outputs[0]=*p_inputs[0];
+ }
+
} break;
+ case VisualScriptFunctionCall::CALL_MODE_SINGLETON: {
+
+ Object *object=Globals::get_singleton()->get_singleton_object(singleton);
+ if (!object) {
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error_str="Invalid singleton name: '"+String(singleton)+"'";
+ return 0;
+ }
+ if (rpc_mode) {
+ call_rpc(object,p_inputs,input_args);
+ } else if (returns) {
+ *p_outputs[0] = object->call(function,p_inputs,input_args,r_error);
+ } else {
+ object->call(function,p_inputs,input_args,r_error);
+ }
+ } break;
}
return 0;
@@ -568,19 +887,23 @@ VisualScriptNodeInstance* VisualScriptFunctionCall::instance(VisualScriptInstanc
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;
return instance;
}
VisualScriptFunctionCall::VisualScriptFunctionCall() {
- call_mode=CALL_MODE_INSTANCE;
+ call_mode=CALL_MODE_SELF;
basic_type=Variant::NIL;
use_default_args=0;
base_type="Object";
+ rpc_call_mode=RPC_DISABLED;
+
}
@@ -613,12 +936,12 @@ static const char* event_type_names[InputEvent::TYPE_MAX]={
int VisualScriptPropertySet::get_output_sequence_port_count() const {
- return 1;
+ return call_mode!=CALL_MODE_BASIC_TYPE ? 1 : 0;
}
bool VisualScriptPropertySet::has_input_sequence_port() const{
- return true;
+ return call_mode!=CALL_MODE_BASIC_TYPE ? true : false;
}
Node *VisualScriptPropertySet::_get_base_node() const {
@@ -675,16 +998,13 @@ StringName VisualScriptPropertySet::_get_base_type() const {
int VisualScriptPropertySet::get_input_value_port_count() const{
- int pc = (call_mode==CALL_MODE_BASIC_TYPE || call_mode==CALL_MODE_INSTANCE)?1:0;
-
- if (!use_builtin_value)
- pc++;
+ int pc = (call_mode==CALL_MODE_BASIC_TYPE || call_mode==CALL_MODE_INSTANCE)?2:1;
return pc;
}
int VisualScriptPropertySet::get_output_value_port_count() const{
- return call_mode==CALL_MODE_BASIC_TYPE? 1 : 0;
+ return (call_mode==CALL_MODE_BASIC_TYPE || call_mode==CALL_MODE_INSTANCE) ? 1 : 0;
}
String VisualScriptPropertySet::get_output_sequence_port_text(int p_port) const {
@@ -705,60 +1025,16 @@ PropertyInfo VisualScriptPropertySet::get_input_value_port_info(int p_idx) const
}
}
-#ifdef DEBUG_METHODS_ENABLED
-
- //not very efficient but..
-
-
- List<PropertyInfo> pinfo;
-
- if (call_mode==CALL_MODE_BASIC_TYPE) {
-
-
- Variant v;
- if (basic_type==Variant::INPUT_EVENT) {
- InputEvent ev;
- ev.type=event_type;
- v=ev;
- } else {
- Variant::CallError ce;
- v = Variant::construct(basic_type,NULL,0,ce);
- }
- v.get_property_list(&pinfo);
-
- } else if (call_mode==CALL_MODE_NODE_PATH) {
-
- Node *n = _get_base_node();
- if (n) {
- n->get_property_list(&pinfo);
- } else {
- ObjectTypeDB::get_property_list(_get_base_type(),&pinfo);
- }
- } else {
- ObjectTypeDB::get_property_list(_get_base_type(),&pinfo);
- }
-
-
- for (List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) {
-
- if (E->get().name==property) {
-
- PropertyInfo info=E->get();
- info.name="value";
- return info;
- }
- }
-
-
-#endif
-
- return PropertyInfo(Variant::NIL,"value");
-
+ PropertyInfo pinfo=type_cache;
+ pinfo.name="value";
+ return pinfo;
}
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");
} else {
return PropertyInfo();
}
@@ -784,18 +1060,12 @@ String VisualScriptPropertySet::get_text() const {
if (call_mode==CALL_MODE_BASIC_TYPE)
prop=Variant::get_type_name(basic_type)+"."+property;
- else
+ else if (call_mode==CALL_MODE_NODE_PATH)
+ prop=String(base_path)+":"+property;
+ else if (call_mode==CALL_MODE_SELF)
prop=property;
-
- if (use_builtin_value) {
- String bit = builtin_value.get_construct_string();
- if (bit.length()>40) {
- bit=bit.substr(0,40);
- bit+="...";
- }
-
- prop+="\n "+bit;
- }
+ else if (call_mode==CALL_MODE_INSTANCE)
+ prop=String(base_type)+":"+property;
return prop;
@@ -839,6 +1109,9 @@ void VisualScriptPropertySet::set_event_type(InputEvent::Type p_type) {
if (event_type==p_type)
return;
event_type=p_type;
+ if (call_mode==CALL_MODE_BASIC_TYPE) {
+ _update_cache();
+ }
_change_notify();
_update_base_type();
ports_changed_notify();
@@ -865,12 +1138,133 @@ StringName VisualScriptPropertySet::get_base_type() const{
return base_type;
}
+
+void VisualScriptPropertySet::set_base_script(const String& p_path) {
+
+ if (base_script==p_path)
+ return;
+
+ base_script=p_path;
+ _change_notify();
+ ports_changed_notify();
+}
+
+String VisualScriptPropertySet::get_base_script() const {
+
+ return base_script;
+}
+
+
+void VisualScriptPropertySet::_update_cache() {
+
+
+ if (!OS::get_singleton()->get_main_loop())
+ return;
+ if (!OS::get_singleton()->get_main_loop()->cast_to<SceneTree>())
+ return;
+
+ if (!OS::get_singleton()->get_main_loop()->cast_to<SceneTree>()->is_editor_hint()) //only update cache if editor exists, it's pointless otherwise
+ return;
+
+ if (call_mode==CALL_MODE_BASIC_TYPE) {
+
+ //not super efficient..
+
+ Variant v;
+ if (basic_type==Variant::INPUT_EVENT) {
+ InputEvent ev;
+ ev.type=event_type;
+ v=ev;
+ } else {
+ Variant::CallError ce;
+ v = Variant::construct(basic_type,NULL,0,ce);
+ }
+
+ List<PropertyInfo> pinfo;
+ v.get_property_list(&pinfo);
+
+ for (List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) {
+
+ if (E->get().name==property) {
+
+ type_cache=E->get();
+ }
+ }
+
+ } else {
+
+
+ StringName type;
+ Ref<Script> script;
+ Node *node=NULL;
+
+ if (call_mode==CALL_MODE_NODE_PATH) {
+
+ node=_get_base_node();
+ if (node) {
+ type=node->get_type();
+ base_type=type; //cache, too
+ script = node->get_script();
+ }
+ } else if (call_mode==CALL_MODE_SELF) {
+
+ if (get_visual_script().is_valid()) {
+ type=get_visual_script()->get_instance_base_type();
+ base_type=type; //cache, too
+ script=get_visual_script();
+ }
+ } else if (call_mode==CALL_MODE_INSTANCE) {
+
+ type=base_type;
+ if (base_script!=String()) {
+
+ if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) {
+
+ ScriptServer::edit_request_func(base_script); //make sure it's loaded
+ }
+
+ if (ResourceCache::has(base_script)) {
+
+ script = Ref<Resource>( ResourceCache::get(base_script) );
+ } else {
+ return;
+ }
+ }
+ }
+
+ List<PropertyInfo> pinfo;
+
+
+ if (node) {
+
+ node->get_property_list(&pinfo);
+ } else {
+ ObjectTypeDB::get_property_list(type,&pinfo);
+ }
+
+ if (script.is_valid()) {
+
+ script->get_script_property_list(&pinfo);
+ }
+
+ for (List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) {
+
+ if (E->get().name==property) {
+ type_cache=E->get();
+ return;
+ }
+ }
+
+ }
+}
+
void VisualScriptPropertySet::set_property(const StringName& p_type){
if (property==p_type)
return;
property=p_type;
+ _update_cache();
_change_notify();
ports_changed_notify();
}
@@ -914,34 +1308,17 @@ VisualScriptPropertySet::CallMode VisualScriptPropertySet::get_call_mode() const
}
-void VisualScriptPropertySet::set_use_builtin_value(bool p_use) {
- if (use_builtin_value==p_use)
- return;
-
- use_builtin_value=p_use;
- _change_notify();
- ports_changed_notify();
-
-}
-
-bool VisualScriptPropertySet::is_using_builtin_value() const{
- return use_builtin_value;
+void VisualScriptPropertySet::_set_type_cache(const Dictionary &p_type) {
+ type_cache=PropertyInfo::from_dict(p_type);
}
-void VisualScriptPropertySet::set_builtin_value(const Variant& p_value){
-
- if (builtin_value==p_value)
- return;
-
- builtin_value=p_value;
+Dictionary VisualScriptPropertySet::_get_type_cache() const {
+ return type_cache;
}
-Variant VisualScriptPropertySet::get_builtin_value() const{
- return builtin_value;
-}
void VisualScriptPropertySet::_validate_property(PropertyInfo& property) const {
if (property.name=="property/base_type") {
@@ -950,6 +1327,11 @@ void VisualScriptPropertySet::_validate_property(PropertyInfo& property) const {
}
}
+ if (property.name=="property/base_script") {
+ if (call_mode!=CALL_MODE_INSTANCE) {
+ property.usage=0;
+ }
+ }
if (property.name=="property/basic_type") {
if (call_mode!=CALL_MODE_BASIC_TYPE) {
@@ -978,99 +1360,50 @@ void VisualScriptPropertySet::_validate_property(PropertyInfo& property) const {
}
if (property.name=="property/property") {
- property.hint=PROPERTY_HINT_ENUM;
-
-
- List<PropertyInfo> pinfo;
-
if (call_mode==CALL_MODE_BASIC_TYPE) {
- Variant::CallError ce;
- Variant v;
- if (basic_type==Variant::INPUT_EVENT) {
- InputEvent ev;
- ev.type=event_type;
- v=ev;
- } else {
- v = Variant::construct(basic_type,NULL,0,ce);
- }
- v.get_property_list(&pinfo);
- } else if (call_mode==CALL_MODE_NODE_PATH) {
-
- Node *n = _get_base_node();
- if (n) {
- n->get_property_list(&pinfo);
- } else {
- ObjectTypeDB::get_property_list(_get_base_type(),&pinfo);
- }
- } else {
+ property.hint=PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE;
+ property.hint_string=Variant::get_type_name(basic_type);
+ } else if (call_mode==CALL_MODE_SELF && get_visual_script().is_valid()) {
+ property.hint=PROPERTY_HINT_PROPERTY_OF_SCRIPT;
+ property.hint_string=itos(get_visual_script()->get_instance_ID());
+ } else if (call_mode==CALL_MODE_INSTANCE) {
+ property.hint=PROPERTY_HINT_PROPERTY_OF_BASE_TYPE;
+ property.hint_string=base_type;
- ObjectTypeDB::get_property_list(_get_base_type(),&pinfo);
+ if (base_script!=String()) {
+ if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) {
- }
+ ScriptServer::edit_request_func(base_script); //make sure it's loaded
+ }
- List<String> mstring;
+ if (ResourceCache::has(base_script)) {
- for (List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) {
+ Ref<Script> script = Ref<Resource>( ResourceCache::get(base_script) );
+ if (script.is_valid()) {
- if (E->get().usage&PROPERTY_USAGE_EDITOR) {
- mstring.push_back(E->get().name);
+ property.hint=PROPERTY_HINT_PROPERTY_OF_SCRIPT;
+ property.hint_string=itos(script->get_instance_ID());
+ }
+ }
}
- }
-
- String ml;
- for (List<String>::Element *E=mstring.front();E;E=E->next()) {
-
- if (ml!=String())
- ml+=",";
- ml+=E->get();
- }
-
- if (ml==String()) {
- property.usage=PROPERTY_USAGE_NOEDITOR; //do not show for editing if empty
- } else {
- property.hint_string=ml;
- }
- }
-
- if (property.name=="value/builtin") {
-
- if (!use_builtin_value) {
- property.usage=0;
- } else {
- List<PropertyInfo> pinfo;
-
- if (call_mode==CALL_MODE_BASIC_TYPE) {
- Variant::CallError ce;
- Variant v = Variant::construct(basic_type,NULL,0,ce);
- v.get_property_list(&pinfo);
- } else if (call_mode==CALL_MODE_NODE_PATH) {
-
- Node *n = _get_base_node();
- if (n) {
- n->get_property_list(&pinfo);
- } else {
- ObjectTypeDB::get_property_list(_get_base_type(),&pinfo);
- }
+ } else if (call_mode==CALL_MODE_NODE_PATH) {
+ Node *node = _get_base_node();
+ if (node) {
+ property.hint=PROPERTY_HINT_PROPERTY_OF_INSTANCE;
+ property.hint_string=itos(node->get_instance_ID());
} else {
- ObjectTypeDB::get_property_list(_get_base_type(),&pinfo);
+ property.hint=PROPERTY_HINT_PROPERTY_OF_BASE_TYPE;
+ property.hint_string=get_base_type();
}
- for (List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) {
-
- if (E->get().name==this->property) {
-
- property.hint=E->get().hint;
- property.type=E->get().type;
- property.hint_string=E->get().hint_string;
- }
- }
}
}
+
}
void VisualScriptPropertySet::_bind_methods() {
@@ -1078,10 +1411,15 @@ void VisualScriptPropertySet::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_base_type","base_type"),&VisualScriptPropertySet::set_base_type);
ObjectTypeDB::bind_method(_MD("get_base_type"),&VisualScriptPropertySet::get_base_type);
+ ObjectTypeDB::bind_method(_MD("set_base_script","base_script"),&VisualScriptPropertySet::set_base_script);
+ ObjectTypeDB::bind_method(_MD("get_base_script"),&VisualScriptPropertySet::get_base_script);
ObjectTypeDB::bind_method(_MD("set_basic_type","basic_type"),&VisualScriptPropertySet::set_basic_type);
ObjectTypeDB::bind_method(_MD("get_basic_type"),&VisualScriptPropertySet::get_basic_type);
+ ObjectTypeDB::bind_method(_MD("_set_type_cache","type_cache"),&VisualScriptPropertySet::_set_type_cache);
+ ObjectTypeDB::bind_method(_MD("_get_type_cache"),&VisualScriptPropertySet::_get_type_cache);
+
ObjectTypeDB::bind_method(_MD("set_event_type","event_type"),&VisualScriptPropertySet::set_event_type);
ObjectTypeDB::bind_method(_MD("get_event_type"),&VisualScriptPropertySet::get_event_type);
@@ -1094,11 +1432,7 @@ void VisualScriptPropertySet::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_base_path","base_path"),&VisualScriptPropertySet::set_base_path);
ObjectTypeDB::bind_method(_MD("get_base_path"),&VisualScriptPropertySet::get_base_path);
- ObjectTypeDB::bind_method(_MD("set_builtin_value","value"),&VisualScriptPropertySet::set_builtin_value);
- ObjectTypeDB::bind_method(_MD("get_builtin_value"),&VisualScriptPropertySet::get_builtin_value);
- ObjectTypeDB::bind_method(_MD("set_use_builtin_value","enable"),&VisualScriptPropertySet::set_use_builtin_value);
- ObjectTypeDB::bind_method(_MD("is_using_builtin_value"),&VisualScriptPropertySet::is_using_builtin_value);
String bt;
for(int i=0;i<Variant::VARIANT_MAX;i++) {
@@ -1116,15 +1450,26 @@ void VisualScriptPropertySet::_bind_methods() {
et+=event_type_names[i];
}
+ List<String> script_extensions;
+ for(int i=0;i<ScriptServer::get_language_count();i++) {
+ ScriptServer::get_language(i)->get_recognized_extensions(&script_extensions);
+ }
+
+ String script_ext_hint;
+ for (List<String>::Element *E=script_extensions.front();E;E=E->next()) {
+ if (script_ext_hint!=String())
+ script_ext_hint+=",";
+ script_ext_hint+="*."+E->get();
+ }
- ADD_PROPERTY(PropertyInfo(Variant::INT,"property/set_mode",PROPERTY_HINT_ENUM,"Self,Node Path,Instance,Basic Type",PROPERTY_USAGE_NOEDITOR),_SCS("set_call_mode"),_SCS("get_call_mode"));
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"property/set_mode",PROPERTY_HINT_ENUM,"Self,Node Path,Instance,Basic Type"),_SCS("set_call_mode"),_SCS("get_call_mode"));
ADD_PROPERTY(PropertyInfo(Variant::STRING,"property/base_type",PROPERTY_HINT_TYPE_STRING,"Object"),_SCS("set_base_type"),_SCS("get_base_type"));
+ ADD_PROPERTY(PropertyInfo(Variant::STRING,"property/base_script",PROPERTY_HINT_FILE,script_ext_hint),_SCS("set_base_script"),_SCS("get_base_script"));
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"property/type_cache",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_type_cache"),_SCS("_get_type_cache"));
ADD_PROPERTY(PropertyInfo(Variant::INT,"property/basic_type",PROPERTY_HINT_ENUM,bt),_SCS("set_basic_type"),_SCS("get_basic_type"));
ADD_PROPERTY(PropertyInfo(Variant::INT,"property/event_type",PROPERTY_HINT_ENUM,et),_SCS("set_event_type"),_SCS("get_event_type"));
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH,"property/node_path",PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE),_SCS("set_base_path"),_SCS("get_base_path"));
ADD_PROPERTY(PropertyInfo(Variant::STRING,"property/property"),_SCS("set_property"),_SCS("get_property"));
- ADD_PROPERTY(PropertyInfo(Variant::BOOL,"value/use_builtin"),_SCS("set_use_builtin_value"),_SCS("is_using_builtin_value"));
- ADD_PROPERTY(PropertyInfo(Variant::NIL,"value/builtin"),_SCS("set_builtin_value"),_SCS("get_builtin_value"));
BIND_CONSTANT( CALL_MODE_SELF );
BIND_CONSTANT( CALL_MODE_NODE_PATH);
@@ -1139,8 +1484,6 @@ public:
VisualScriptPropertySet::CallMode call_mode;
NodePath node_path;
StringName property;
- bool use_builtin;
- Variant builtin_val;
VisualScriptPropertySet *node;
VisualScriptInstance *instance;
@@ -1162,15 +1505,11 @@ public:
bool valid;
- if (use_builtin) {
- object->set(property,builtin_val,&valid);
- } else {
- object->set(property,*p_inputs[0],&valid);
- }
+ object->set(property,*p_inputs[0],&valid);
if (!valid) {
r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
- r_error_str="Invalid index property name.";
+ r_error_str="Invalid set value '"+String(*p_inputs[0])+"' on property '"+String(property)+"' of type "+object->get_type();
}
} break;
case VisualScriptPropertySet::CALL_MODE_NODE_PATH: {
@@ -1191,15 +1530,11 @@ public:
bool valid;
- if (use_builtin) {
- another->set(property,builtin_val,&valid);
- } else {
- another->set(property,*p_inputs[0],&valid);
- }
+ another->set(property,*p_inputs[0],&valid);
if (!valid) {
r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
- r_error_str="Invalid index property name.";
+ r_error_str="Invalid set value '"+String(*p_inputs[0])+"' on property '"+String(property)+"' of type "+another->get_type();
}
} break;
@@ -1210,20 +1545,14 @@ public:
bool valid;
- if (use_builtin) {
- v.set(property,builtin_val,&valid);
- } else {
- v.set(property,p_inputs[1],&valid);
- }
+ v.set(property,*p_inputs[1],&valid);
if (!valid) {
- r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
- r_error_str="Invalid index property name.";
+ 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());
}
- if (call_mode==VisualScriptPropertySet::CALL_MODE_BASIC_TYPE) {
- *p_outputs[0]=v;
- }
+ *p_outputs[0]=v;
} break;
@@ -1243,14 +1572,12 @@ VisualScriptNodeInstance* VisualScriptPropertySet::instance(VisualScriptInstance
instance->property=property;
instance->call_mode=call_mode;
instance->node_path=base_path;
- instance->use_builtin=use_builtin_value;
- instance->builtin_val=builtin_value;
return instance;
}
VisualScriptPropertySet::VisualScriptPropertySet() {
- call_mode=CALL_MODE_INSTANCE;
+ call_mode=CALL_MODE_SELF;
base_type="Object";
basic_type=Variant::NIL;
event_type=InputEvent::NONE;
@@ -1273,12 +1600,12 @@ static Ref<VisualScriptNode> create_property_set_node(const String& p_name) {
int VisualScriptPropertyGet::get_output_sequence_port_count() const {
- return (call_mode==CALL_MODE_SELF || call_mode==CALL_MODE_NODE_PATH)?0:1;
+ return 0;// (call_mode==CALL_MODE_SELF || call_mode==CALL_MODE_NODE_PATH)?0:1;
}
bool VisualScriptPropertyGet::has_input_sequence_port() const{
- return (call_mode==CALL_MODE_SELF || call_mode==CALL_MODE_NODE_PATH)?false:true;
+ return false;//(call_mode==CALL_MODE_SELF || call_mode==CALL_MODE_NODE_PATH)?false:true;
}
void VisualScriptPropertyGet::_update_base_type() {
//cache it because this information may not be available on load
@@ -1348,6 +1675,7 @@ StringName VisualScriptPropertyGet::_get_base_type() const {
return base_type;
}
+
int VisualScriptPropertyGet::get_input_value_port_count() const{
return (call_mode==CALL_MODE_BASIC_TYPE || call_mode==CALL_MODE_INSTANCE)?1:0;
@@ -1381,17 +1709,75 @@ PropertyInfo VisualScriptPropertyGet::get_input_value_port_info(int p_idx) const
PropertyInfo VisualScriptPropertyGet::get_output_value_port_info(int p_idx) const{
+ return PropertyInfo(type_cache,"value");
+}
-#ifdef DEBUG_METHODS_ENABLED
+String VisualScriptPropertyGet::get_caption() const {
+
+ static const char*cname[4]= {
+ "SelfGet",
+ "NodeGet",
+ "InstanceGet",
+ "BasicGet"
+ };
+
+ return cname[call_mode];
+}
+
+String VisualScriptPropertyGet::get_text() const {
+
+ String prop;
+
+ 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;
+
+ return prop;
+}
+
+void VisualScriptPropertyGet::set_base_type(const StringName& p_type) {
+
+ if (base_type==p_type)
+ return;
- //not very efficient but..
+ base_type=p_type;
+ _change_notify();
+ ports_changed_notify();
+}
+
+StringName VisualScriptPropertyGet::get_base_type() const{
+
+ return base_type;
+}
+
+void VisualScriptPropertyGet::set_base_script(const String& p_path) {
+
+ if (base_script==p_path)
+ return;
+
+ base_script=p_path;
+ _change_notify();
+ ports_changed_notify();
+}
+
+String VisualScriptPropertyGet::get_base_script() const {
+
+ return base_script;
+}
- List<PropertyInfo> pinfo;
+void VisualScriptPropertyGet::_update_cache() {
+
if (call_mode==CALL_MODE_BASIC_TYPE) {
+ //not super efficient..
Variant v;
if (basic_type==Variant::INPUT_EVENT) {
@@ -1402,71 +1788,91 @@ PropertyInfo VisualScriptPropertyGet::get_output_value_port_info(int p_idx) cons
Variant::CallError ce;
v = Variant::construct(basic_type,NULL,0,ce);
}
+
+ List<PropertyInfo> pinfo;
v.get_property_list(&pinfo);
- } else if (call_mode==CALL_MODE_NODE_PATH) {
- Node *n = _get_base_node();
- if (n) {
- n->get_property_list(&pinfo);
- } else {
- ObjectTypeDB::get_property_list(_get_base_type(),&pinfo);
+ for (List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) {
+
+ if (E->get().name==property) {
+
+ type_cache=E->get().type;
+ return;
+ }
}
+
} else {
- ObjectTypeDB::get_property_list(_get_base_type(),&pinfo);
- }
- for (List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) {
- if (E->get().name==property) {
+ StringName type;
+ Ref<Script> script;
+ Node *node=NULL;
- PropertyInfo info=E->get();
- info.name="";
- return info;
- }
- }
+ if (call_mode==CALL_MODE_NODE_PATH) {
+ node=_get_base_node();
+ if (node) {
+ type=node->get_type();
+ base_type=type; //cache, too
+ script = node->get_script();
+ }
+ } else if (call_mode==CALL_MODE_SELF) {
-#endif
+ if (get_visual_script().is_valid()) {
+ type=get_visual_script()->get_instance_base_type();
+ base_type=type; //cache, too
+ script=get_visual_script();
+ }
+ } else if (call_mode==CALL_MODE_INSTANCE) {
- return PropertyInfo(Variant::NIL,"");
-}
+ type=base_type;
+ if (base_script!=String()) {
+ if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) {
-String VisualScriptPropertyGet::get_caption() const {
+ ScriptServer::edit_request_func(base_script); //make sure it's loaded
+ }
- static const char*cname[4]= {
- "SelfGet",
- "NodeGet",
- "InstanceGet",
- "BasicGet"
- };
+ if (ResourceCache::has(base_script)) {
- return cname[call_mode];
-}
+ script = Ref<Resource>( ResourceCache::get(base_script) );
+ } else {
+ return;
+ }
+ }
+ }
-String VisualScriptPropertyGet::get_text() const {
+ bool valid=false;
- if (call_mode==CALL_MODE_BASIC_TYPE)
- return Variant::get_type_name(basic_type)+"."+property;
- else
- return property;
+ Variant::Type type_ret;
-}
+ type_ret=ObjectTypeDB::get_property_type(base_type,property,&valid);
-void VisualScriptPropertyGet::set_base_type(const StringName& p_type) {
+ if (valid) {
+ type_cache=type_ret;
+ return; //all dandy
+ }
- if (base_type==p_type)
- return;
+ if (node) {
- base_type=p_type;
- _change_notify();
- ports_changed_notify();
-}
+ Variant prop = node->get(property,&valid);
+ if (valid) {
+ type_cache=prop.get_type();
+ return; //all dandy again
+ }
+ }
-StringName VisualScriptPropertyGet::get_base_type() const{
+ if (script.is_valid()) {
- return base_type;
+ type_ret=script->get_static_property_type(property,&valid);
+
+ if (valid) {
+ type_cache=type_ret;
+ return; //all dandy
+ }
+ }
+ }
}
void VisualScriptPropertyGet::set_property(const StringName& p_type){
@@ -1475,6 +1881,9 @@ void VisualScriptPropertyGet::set_property(const StringName& p_type){
return;
property=p_type;
+
+
+ _update_cache();
_change_notify();
ports_changed_notify();
}
@@ -1541,6 +1950,9 @@ void VisualScriptPropertyGet::set_event_type(InputEvent::Type p_type) {
if (event_type==p_type)
return;
event_type=p_type;
+ if(call_mode==CALL_MODE_BASIC_TYPE) {
+ _update_cache();
+ }
_change_notify();
_update_base_type();
ports_changed_notify();
@@ -1551,6 +1963,17 @@ InputEvent::Type VisualScriptPropertyGet::get_event_type() const{
return event_type;
}
+
+void VisualScriptPropertyGet::_set_type_cache(Variant::Type p_type) {
+ type_cache=p_type;
+}
+
+Variant::Type VisualScriptPropertyGet::_get_type_cache() const {
+
+ return type_cache;
+}
+
+
void VisualScriptPropertyGet::_validate_property(PropertyInfo& property) const {
if (property.name=="property/base_type") {
@@ -1559,6 +1982,11 @@ void VisualScriptPropertyGet::_validate_property(PropertyInfo& property) const {
}
}
+ if (property.name=="property/base_script") {
+ if (call_mode!=CALL_MODE_INSTANCE) {
+ property.usage=0;
+ }
+ }
if (property.name=="property/basic_type") {
if (call_mode!=CALL_MODE_BASIC_TYPE) {
@@ -1586,55 +2014,45 @@ void VisualScriptPropertyGet::_validate_property(PropertyInfo& property) const {
}
if (property.name=="property/property") {
- property.hint=PROPERTY_HINT_ENUM;
-
-
- List<PropertyInfo> pinfo;
if (call_mode==CALL_MODE_BASIC_TYPE) {
- Variant::CallError ce;
- Variant v;
- if (basic_type==Variant::INPUT_EVENT) {
- InputEvent ev;
- ev.type=event_type;
- v=ev;
- } else {
- v = Variant::construct(basic_type,NULL,0,ce);
- }
- v.get_property_list(&pinfo);
- } else if (call_mode==CALL_MODE_NODE_PATH) {
+ property.hint=PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE;
+ property.hint_string=Variant::get_type_name(basic_type);
- Node *n = _get_base_node();
- if (n) {
- n->get_property_list(&pinfo);
- } else {
- ObjectTypeDB::get_property_list(_get_base_type(),&pinfo);
- }
- } else {
- ObjectTypeDB::get_property_list(_get_base_type(),&pinfo);
- }
+ } else if (call_mode==CALL_MODE_SELF && get_visual_script().is_valid()) {
+ property.hint=PROPERTY_HINT_PROPERTY_OF_SCRIPT;
+ property.hint_string=itos(get_visual_script()->get_instance_ID());
+ } else if (call_mode==CALL_MODE_INSTANCE) {
+ property.hint=PROPERTY_HINT_PROPERTY_OF_BASE_TYPE;
+ property.hint_string=base_type;
- List<String> mstring;
+ if (base_script!=String()) {
+ if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) {
- for (List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) {
+ ScriptServer::edit_request_func(base_script); //make sure it's loaded
+ }
- if (E->get().usage&PROPERTY_USAGE_EDITOR)
- mstring.push_back(E->get().name);
- }
+ if (ResourceCache::has(base_script)) {
- String ml;
- for (List<String>::Element *E=mstring.front();E;E=E->next()) {
+ Ref<Script> script = Ref<Resource>( ResourceCache::get(base_script) );
+ if (script.is_valid()) {
- if (ml!=String())
- ml+=",";
- ml+=E->get();
- }
+ property.hint=PROPERTY_HINT_PROPERTY_OF_SCRIPT;
+ property.hint_string=itos(script->get_instance_ID());
+ }
+ }
+ }
+ } else if (call_mode==CALL_MODE_NODE_PATH) {
+ Node *node = _get_base_node();
+ if (node) {
+ property.hint=PROPERTY_HINT_PROPERTY_OF_INSTANCE;
+ property.hint_string=itos(node->get_instance_ID());
+ } else {
+ property.hint=PROPERTY_HINT_PROPERTY_OF_BASE_TYPE;
+ property.hint_string=get_base_type();
+ }
- if (ml==String()) {
- property.usage=PROPERTY_USAGE_NOEDITOR; //do not show for editing if empty
- } else {
- property.hint_string=ml;
}
}
@@ -1646,10 +2064,15 @@ void VisualScriptPropertyGet::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_base_type","base_type"),&VisualScriptPropertyGet::set_base_type);
ObjectTypeDB::bind_method(_MD("get_base_type"),&VisualScriptPropertyGet::get_base_type);
+ ObjectTypeDB::bind_method(_MD("set_base_script","base_script"),&VisualScriptPropertyGet::set_base_script);
+ ObjectTypeDB::bind_method(_MD("get_base_script"),&VisualScriptPropertyGet::get_base_script);
ObjectTypeDB::bind_method(_MD("set_basic_type","basic_type"),&VisualScriptPropertyGet::set_basic_type);
ObjectTypeDB::bind_method(_MD("get_basic_type"),&VisualScriptPropertyGet::get_basic_type);
+ ObjectTypeDB::bind_method(_MD("_set_type_cache","type_cache"),&VisualScriptPropertyGet::_set_type_cache);
+ ObjectTypeDB::bind_method(_MD("_get_type_cache"),&VisualScriptPropertyGet::_get_type_cache);
+
ObjectTypeDB::bind_method(_MD("set_event_type","event_type"),&VisualScriptPropertyGet::set_event_type);
ObjectTypeDB::bind_method(_MD("get_event_type"),&VisualScriptPropertyGet::get_event_type);
@@ -1679,9 +2102,22 @@ void VisualScriptPropertyGet::_bind_methods() {
et+=event_type_names[i];
}
+ List<String> script_extensions;
+ for(int i=0;i<ScriptServer::get_language_count();i++) {
+ ScriptServer::get_language(i)->get_recognized_extensions(&script_extensions);
+ }
- ADD_PROPERTY(PropertyInfo(Variant::INT,"property/set_mode",PROPERTY_HINT_ENUM,"Self,Node Path,Instance",PROPERTY_USAGE_NOEDITOR),_SCS("set_call_mode"),_SCS("get_call_mode"));
+ String script_ext_hint;
+ 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();
+ }
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"property/set_mode",PROPERTY_HINT_ENUM,"Self,Node Path,Instance,Basic Type"),_SCS("set_call_mode"),_SCS("get_call_mode"));
ADD_PROPERTY(PropertyInfo(Variant::STRING,"property/base_type",PROPERTY_HINT_TYPE_STRING,"Object"),_SCS("set_base_type"),_SCS("get_base_type"));
+ ADD_PROPERTY(PropertyInfo(Variant::STRING,"property/base_script",PROPERTY_HINT_FILE,script_ext_hint),_SCS("set_base_script"),_SCS("get_base_script"));
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"property/type_cache",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_type_cache"),_SCS("_get_type_cache"));
ADD_PROPERTY(PropertyInfo(Variant::INT,"property/basic_type",PROPERTY_HINT_ENUM,bt),_SCS("set_basic_type"),_SCS("get_basic_type"));
ADD_PROPERTY(PropertyInfo(Variant::INT,"property/event_type",PROPERTY_HINT_ENUM,et),_SCS("set_event_type"),_SCS("get_event_type"));
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH,"property/node_path",PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE),_SCS("set_base_path"),_SCS("get_base_path"));
@@ -1704,12 +2140,10 @@ public:
VisualScriptInstance *instance;
+ 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) {
+
- //virtual int get_working_memory_size() const { return 0; }
- virtual bool is_output_port_unsequenced(int p_idx) const { return (call_mode==VisualScriptPropertyGet::CALL_MODE_SELF || call_mode==VisualScriptPropertyGet::CALL_MODE_NODE_PATH); }
- virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
- //these two modes can be get directly, so they use unsequenced mode
switch(call_mode) {
case VisualScriptPropertyGet::CALL_MODE_SELF: {
@@ -1718,63 +2152,57 @@ public:
bool valid;
- *r_value = object->get(property,&valid);
+ *p_outputs[0] = object->get(property,&valid);
if (!valid) {
- //r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
- r_error=RTR("Invalid index property name.");
- return false;
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error_str=RTR("Invalid index property name.");
+ return 0;
}
} break;
case VisualScriptPropertyGet::CALL_MODE_NODE_PATH: {
Node* node = instance->get_owner_ptr()->cast_to<Node>();
if (!node) {
- //r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
- r_error=RTR("Base object is not a Node!");
- return false;
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error_str=RTR("Base object is not a Node!");
+ return 0;
}
Node* another = node->get_node(node_path);
if (!node) {
- //r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
- r_error=RTR("Path does not lead Node!");
- return false;
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error_str=RTR("Path does not lead Node!");
+ return 0;
}
bool valid;
- *r_value = another->get(property,&valid);
+ *p_outputs[0] = another->get(property,&valid);
if (!valid) {
- //r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
- r_error=vformat(RTR("Invalid index property name '%s' in node %s."),String(property),another->get_name());
- return false;
+ 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());
+ return 0;
}
} break;
- default: {};
- }
- return true;
-
- }
-
- 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) {
+ default: {
+ bool valid;
+ Variant v = *p_inputs[0];
- bool valid;
- Variant v = *p_inputs[0];
-
- *p_outputs[0] = v.get(property,&valid);
+ *p_outputs[0] = v.get(property,&valid);
- if (!valid) {
- r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
- r_error_str=RTR("Invalid index property name.");
+ if (!valid) {
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error_str=RTR("Invalid index property name.");
+ }
+ };
}
-
return 0;
}
@@ -1797,10 +2225,11 @@ VisualScriptNodeInstance* VisualScriptPropertyGet::instance(VisualScriptInstance
VisualScriptPropertyGet::VisualScriptPropertyGet() {
- call_mode=CALL_MODE_INSTANCE;
+ call_mode=CALL_MODE_SELF;
base_type="Object";
basic_type=Variant::NIL;
event_type=InputEvent::NONE;
+ type_cache=Variant::NIL;
}
@@ -1815,463 +2244,6 @@ static Ref<VisualScriptNode> create_property_get_node(const String& p_name) {
//////////////////////////////////////////
-////////////////SCRIPT CALL//////////////////////
-//////////////////////////////////////////
-
-int VisualScriptScriptCall::get_output_sequence_port_count() const {
-
- return 1;
-}
-
-bool VisualScriptScriptCall::has_input_sequence_port() const{
-
- return true;
-}
-
-Node *VisualScriptScriptCall::_get_base_node() const {
-
-#ifdef TOOLS_ENABLED
- Ref<Script> script = get_visual_script();
- if (!script.is_valid())
- return NULL;
-
- MainLoop * main_loop = OS::get_singleton()->get_main_loop();
- if (!main_loop)
- return NULL;
-
- SceneTree *scene_tree = main_loop->cast_to<SceneTree>();
-
- if (!scene_tree)
- return NULL;
-
- Node *edited_scene = scene_tree->get_edited_scene_root();
-
- if (!edited_scene)
- return NULL;
-
- Node* script_node = _find_script_node(edited_scene,edited_scene,script);
-
- 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
-}
-
-
-int VisualScriptScriptCall::get_input_value_port_count() const{
-
-#if 1
- return argument_count;
-#else
- if (call_mode==CALL_MODE_SELF) {
-
- Ref<VisualScript> vs = get_visual_script();
- if (vs.is_valid()) {
-
- if (!vs->has_function(function))
- return 0;
-
- int id = vs->get_function_node_id(function);
- if (id<0)
- return 0;
-
- Ref<VisualScriptFunction> func = vs->get_node(function,id);
-
- return func->get_argument_count();
- }
- } else {
-
- Node*base = _get_base_node();
- if (!base)
- return 0;
- Ref<Script> script = base->get_script();
- if (!script.is_valid())
- return 0;
-
- List<MethodInfo> functions;
- script->get_method_list(&functions);
- for (List<MethodInfo>::Element *E=functions.front();E;E=E->next()) {
- if (E->get().name==function) {
- return E->get().arguments.size();
- }
- }
-
- }
-
-
- return 0;
-#endif
-
-}
-int VisualScriptScriptCall::get_output_value_port_count() const{
- return 1;
-}
-
-String VisualScriptScriptCall::get_output_sequence_port_text(int p_port) const {
-
- return String();
-}
-
-PropertyInfo VisualScriptScriptCall::get_input_value_port_info(int p_idx) const{
-
- if (call_mode==CALL_MODE_SELF) {
-
- Ref<VisualScript> vs = get_visual_script();
- if (vs.is_valid()) {
-
- if (!vs->has_function(function))
- return PropertyInfo();
-
- int id = vs->get_function_node_id(function);
- if (id<0)
- return PropertyInfo();
-
- Ref<VisualScriptFunction> func = vs->get_node(function,id);
-
- if (p_idx>=func->get_argument_count())
- return PropertyInfo();
- return PropertyInfo(func->get_argument_type(p_idx),func->get_argument_name(p_idx));
- }
- } else {
-
- Node*base = _get_base_node();
- if (!base)
- return PropertyInfo();
- Ref<Script> script = base->get_script();
- if (!script.is_valid())
- return PropertyInfo();
-
- List<MethodInfo> functions;
- script->get_script_method_list(&functions);
- for (List<MethodInfo>::Element *E=functions.front();E;E=E->next()) {
- if (E->get().name==function) {
- if (p_idx<0 || p_idx>=E->get().arguments.size())
- return PropertyInfo();
- return E->get().arguments[p_idx];
- }
- }
-
- }
-
- return PropertyInfo();
-
-}
-
-PropertyInfo VisualScriptScriptCall::get_output_value_port_info(int p_idx) const{
-
- return PropertyInfo();
-}
-
-
-String VisualScriptScriptCall::get_caption() const {
-
- return "ScriptCall";
-}
-
-String VisualScriptScriptCall::get_text() const {
-
- return " "+String(function)+"()";
-}
-
-void VisualScriptScriptCall::_update_argument_count() {
-
- //try to remember the amount of arguments in the function, because if loaded from scratch
- //this information will not be available
-
- if (call_mode==CALL_MODE_SELF) {
-
- Ref<VisualScript> vs = get_visual_script();
- if (vs.is_valid()) {
-
- if (!vs->has_function(function))
- return ;
-
- int id = vs->get_function_node_id(function);
- if (id<0)
- return;
-
- Ref<VisualScriptFunction> func = vs->get_node(function,id);
-
- argument_count=func->get_argument_count();
- }
- } else {
-
- Node*base = _get_base_node();
- if (!base)
- return;
-
- Ref<Script> script = base->get_script();
- if (!script.is_valid())
- return ;
-
- List<MethodInfo> functions;
- script->get_method_list(&functions);
- for (List<MethodInfo>::Element *E=functions.front();E;E=E->next()) {
- if (E->get().name==function) {
- argument_count=E->get().arguments.size();
- return;
- }
- }
-
- }
-}
-
-
-void VisualScriptScriptCall::set_function(const StringName& p_type){
-
- if (function==p_type)
- return;
-
- function=p_type;
- _update_argument_count();
- _change_notify();
- ports_changed_notify();
-}
-StringName VisualScriptScriptCall::get_function() const {
-
-
- return function;
-}
-
-void VisualScriptScriptCall::set_base_path(const NodePath& p_type) {
-
- if (base_path==p_type)
- return;
-
- base_path=p_type;
- _update_argument_count();
- _change_notify();
- ports_changed_notify();
-}
-
-NodePath VisualScriptScriptCall::get_base_path() const {
-
- return base_path;
-}
-
-
-void VisualScriptScriptCall::set_call_mode(CallMode p_mode) {
-
- if (call_mode==p_mode)
- return;
-
- call_mode=p_mode;
- _update_argument_count();
- _change_notify();
- ports_changed_notify();
-
-}
-
-void VisualScriptScriptCall::set_argument_count(int p_count) {
-
- argument_count=p_count;
- _change_notify();
- ports_changed_notify();
-
-}
-
-int VisualScriptScriptCall::get_argument_count() const {
-
- return argument_count;
-}
-
-VisualScriptScriptCall::CallMode VisualScriptScriptCall::get_call_mode() const {
-
- return call_mode;
-}
-
-void VisualScriptScriptCall::_validate_property(PropertyInfo& property) const {
-
-
-
- if (property.name=="function/node_path") {
- if (call_mode!=CALL_MODE_NODE_PATH) {
- property.usage=0;
- } else {
-
- Node *bnode = _get_base_node();
- if (bnode) {
- property.hint_string=bnode->get_path(); //convert to loong string
- } else {
-
- }
- }
- }
-
- if (property.name=="function/function") {
- property.hint=PROPERTY_HINT_ENUM;
-
-
- List<MethodInfo> methods;
-
- if (call_mode==CALL_MODE_SELF) {
-
- Ref<VisualScript> vs = get_visual_script();
- if (vs.is_valid()) {
-
- vs->get_script_method_list(&methods);
-
- }
- } else {
-
- Node*base = _get_base_node();
- if (!base)
- return;
- Ref<Script> script = base->get_script();
- if (!script.is_valid())
- return;
-
- script->get_script_method_list(&methods);
-
- }
-
- List<String> mstring;
- for (List<MethodInfo>::Element *E=methods.front();E;E=E->next()) {
- if (E->get().name.begins_with("_"))
- continue;
- mstring.push_back(E->get().name.get_slice(":",0));
- }
-
- mstring.sort();
-
- String ml;
- for (List<String>::Element *E=mstring.front();E;E=E->next()) {
-
- if (ml!=String())
- ml+=",";
- ml+=E->get();
- }
-
- property.hint_string=ml;
- }
-
-}
-
-
-void VisualScriptScriptCall::_bind_methods() {
-
- ObjectTypeDB::bind_method(_MD("set_function","function"),&VisualScriptScriptCall::set_function);
- ObjectTypeDB::bind_method(_MD("get_function"),&VisualScriptScriptCall::get_function);
-
- ObjectTypeDB::bind_method(_MD("set_call_mode","mode"),&VisualScriptScriptCall::set_call_mode);
- ObjectTypeDB::bind_method(_MD("get_call_mode"),&VisualScriptScriptCall::get_call_mode);
-
- ObjectTypeDB::bind_method(_MD("set_base_path","base_path"),&VisualScriptScriptCall::set_base_path);
- ObjectTypeDB::bind_method(_MD("get_base_path"),&VisualScriptScriptCall::get_base_path);
-
- ObjectTypeDB::bind_method(_MD("set_argument_count","argument_count"),&VisualScriptScriptCall::set_argument_count);
- ObjectTypeDB::bind_method(_MD("get_argument_count"),&VisualScriptScriptCall::get_argument_count);
-
- ADD_PROPERTY(PropertyInfo(Variant::INT,"function/call_mode",PROPERTY_HINT_ENUM,"Self,Node Path"),_SCS("set_call_mode"),_SCS("get_call_mode"));
- ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH,"function/node_path",PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE),_SCS("set_base_path"),_SCS("get_base_path"));
- ADD_PROPERTY(PropertyInfo(Variant::STRING,"function/function"),_SCS("set_function"),_SCS("get_function"));
- ADD_PROPERTY(PropertyInfo(Variant::STRING,"function/argument_count"),_SCS("set_argument_count"),_SCS("get_argument_count"));
-
- BIND_CONSTANT( CALL_MODE_SELF );
- BIND_CONSTANT( CALL_MODE_NODE_PATH);
-
-}
-
-class VisualScriptNodeInstanceScriptCall : public VisualScriptNodeInstance {
-public:
-
-
- VisualScriptScriptCall::CallMode call_mode;
- NodePath node_path;
- int input_args;
- bool returns;
- StringName function;
-
- VisualScriptScriptCall *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; }
-
- 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) {
-
-
- switch(call_mode) {
-
- case VisualScriptScriptCall::CALL_MODE_SELF: {
-
- Object *object=instance->get_owner_ptr();
-
- *p_outputs[0] = object->call(function,p_inputs,input_args,r_error);
-
- } break;
- case VisualScriptScriptCall::CALL_MODE_NODE_PATH: {
-
- Node* node = instance->get_owner_ptr()->cast_to<Node>();
- if (!node) {
- r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
- r_error_str="Base object is not a Node!";
- return 0;
- }
-
- Node* another = node->get_node(node_path);
- if (!node) {
- r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
- r_error_str="Path does not lead Node!";
- return 0;
- }
-
-
- *p_outputs[0] = another->call(function,p_inputs,input_args,r_error);
-
- } break;
-
- }
- return 0;
-
- }
-
-
-};
-
-VisualScriptNodeInstance* VisualScriptScriptCall::instance(VisualScriptInstance* p_instance) {
-
- VisualScriptNodeInstanceScriptCall * instance = memnew(VisualScriptNodeInstanceScriptCall );
- instance->node=this;
- instance->instance=p_instance;
- instance->function=function;
- instance->call_mode=call_mode;
- instance->node_path=base_path;
- instance->input_args = argument_count;
- return instance;
-}
-
-VisualScriptScriptCall::VisualScriptScriptCall() {
-
- call_mode=CALL_MODE_SELF;
- argument_count=0;
-
-
-}
-
-template<VisualScriptScriptCall::CallMode cmode>
-static Ref<VisualScriptNode> create_script_call_node(const String& p_name) {
-
- Ref<VisualScriptScriptCall> node;
- node.instance();
- node->set_call_mode(cmode);
- return node;
-}
-
-
-//////////////////////////////////////////
////////////////EMIT//////////////////////
//////////////////////////////////////////
@@ -2475,24 +2447,13 @@ static Ref<VisualScriptNode> create_basic_type_call_node(const String& p_name) {
void register_visual_script_func_nodes() {
- VisualScriptLanguage::singleton->add_register_func("functions/call_method/call_instance",create_function_call_node<VisualScriptFunctionCall::CALL_MODE_INSTANCE>);
- VisualScriptLanguage::singleton->add_register_func("functions/call_method/call_basic_type",create_function_call_node<VisualScriptFunctionCall::CALL_MODE_BASIC_TYPE>);
- VisualScriptLanguage::singleton->add_register_func("functions/call_method/call_self",create_function_call_node<VisualScriptFunctionCall::CALL_MODE_SELF>);
- VisualScriptLanguage::singleton->add_register_func("functions/call_method/call_node",create_function_call_node<VisualScriptFunctionCall::CALL_MODE_NODE_PATH>);
-
- VisualScriptLanguage::singleton->add_register_func("functions/property_set/instace_set",create_property_set_node<VisualScriptPropertySet::CALL_MODE_INSTANCE>);
- VisualScriptLanguage::singleton->add_register_func("functions/property_set/basic_type_set",create_property_set_node<VisualScriptPropertySet::CALL_MODE_BASIC_TYPE>);
- VisualScriptLanguage::singleton->add_register_func("functions/property_set/self_set",create_property_set_node<VisualScriptPropertySet::CALL_MODE_SELF>);
- VisualScriptLanguage::singleton->add_register_func("functions/property_set/node_set",create_property_set_node<VisualScriptPropertySet::CALL_MODE_NODE_PATH>);
-
- VisualScriptLanguage::singleton->add_register_func("functions/property_get/instance_get",create_property_get_node<VisualScriptPropertyGet::CALL_MODE_INSTANCE>);
- VisualScriptLanguage::singleton->add_register_func("functions/property_get/basic_type_get",create_property_get_node<VisualScriptPropertyGet::CALL_MODE_BASIC_TYPE>);
- VisualScriptLanguage::singleton->add_register_func("functions/property_get/self_get",create_property_get_node<VisualScriptPropertyGet::CALL_MODE_SELF>);
- VisualScriptLanguage::singleton->add_register_func("functions/property_get/node_get",create_property_get_node<VisualScriptPropertyGet::CALL_MODE_NODE_PATH>);
+ VisualScriptLanguage::singleton->add_register_func("functions/call",create_node_generic<VisualScriptFunctionCall>);
+ VisualScriptLanguage::singleton->add_register_func("functions/set",create_node_generic<VisualScriptPropertySet>);
+ VisualScriptLanguage::singleton->add_register_func("functions/get",create_node_generic<VisualScriptPropertyGet>);
- VisualScriptLanguage::singleton->add_register_func("functions/call_script/call_self",create_script_call_node<VisualScriptScriptCall::CALL_MODE_SELF>);
- VisualScriptLanguage::singleton->add_register_func("functions/call_script/call_node",create_script_call_node<VisualScriptScriptCall::CALL_MODE_NODE_PATH>);
- VisualScriptLanguage::singleton->add_register_func("functions/call_script/emit_signal",create_node_generic<VisualScriptEmitSignal>);
+ //VisualScriptLanguage::singleton->add_register_func("functions/call_script/call_self",create_script_call_node<VisualScriptScriptCall::CALL_MODE_SELF>);
+// VisualScriptLanguage::singleton->add_register_func("functions/call_script/call_node",create_script_call_node<VisualScriptScriptCall::CALL_MODE_NODE_PATH>);
+ VisualScriptLanguage::singleton->add_register_func("functions/emit_signal",create_node_generic<VisualScriptEmitSignal>);
for(int i=0;i<Variant::VARIANT_MAX;i++) {
diff --git a/modules/visual_script/visual_script_func_nodes.h b/modules/visual_script/visual_script_func_nodes.h
index 2ccc61242a..fa6ab99b9b 100644
--- a/modules/visual_script/visual_script_func_nodes.h
+++ b/modules/visual_script/visual_script_func_nodes.h
@@ -13,20 +13,39 @@ public:
CALL_MODE_NODE_PATH,
CALL_MODE_INSTANCE,
CALL_MODE_BASIC_TYPE,
+ CALL_MODE_SINGLETON,
};
+
+ enum RPCCallMode {
+ RPC_DISABLED,
+ RPC_RELIABLE,
+ RPC_UNRELIABLE,
+ RPC_RELIABLE_TO_ID,
+ RPC_UNRELIABLE_TO_ID
+ };
+
private:
CallMode call_mode;
StringName base_type;
+ String base_script;
Variant::Type basic_type;
NodePath base_path;
StringName function;
int use_default_args;
+ RPCCallMode rpc_call_mode;
+ StringName singleton;
+
Node *_get_base_node() const;
StringName _get_base_type() const;
- void _update_defargs();
+ MethodInfo method_cache;
+ void _update_method_cache();
+
+ void _set_argument_cache(const Dictionary& p_args);
+ Dictionary _get_argument_cache() const;
+
protected:
virtual void _validate_property(PropertyInfo& property) const;
@@ -58,24 +77,35 @@ public:
void set_base_type(const StringName& p_type);
StringName get_base_type() const;
+ void set_base_script(const String& p_path);
+ String get_base_script() const;
+
+ void set_singleton(const StringName& p_type);
+ StringName get_singleton() const;
+
void set_function(const StringName& p_type);
StringName get_function() const;
void set_base_path(const NodePath& p_type);
NodePath get_base_path() const;
+
void set_call_mode(CallMode p_mode);
CallMode get_call_mode() const;
void set_use_default_args(int p_amount);
int get_use_default_args() const;
+ void set_rpc_call_mode(RPCCallMode p_mode);
+ RPCCallMode get_rpc_call_mode() const;
+
virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
VisualScriptFunctionCall();
};
VARIANT_ENUM_CAST(VisualScriptFunctionCall::CallMode );
+VARIANT_ENUM_CAST(VisualScriptFunctionCall::RPCCallMode );
class VisualScriptPropertySet : public VisualScriptNode {
@@ -92,13 +122,14 @@ public:
};
private:
+ PropertyInfo type_cache;
+
CallMode call_mode;
Variant::Type basic_type;
StringName base_type;
+ String base_script;
NodePath base_path;
StringName property;
- bool use_builtin_value;
- Variant builtin_value;
InputEvent::Type event_type;
Node *_get_base_node() const;
@@ -106,6 +137,12 @@ private:
void _update_base_type();
+ void _update_cache();
+
+ void _set_type_cache(const Dictionary& p_type);
+ Dictionary _get_type_cache() const;
+
+
protected:
virtual void _validate_property(PropertyInfo& property) const;
@@ -134,6 +171,9 @@ public:
void set_base_type(const StringName& p_type);
StringName get_base_type() const;
+ void set_base_script(const String& p_path);
+ String get_base_script() const;
+
void set_basic_type(Variant::Type p_type);
Variant::Type get_basic_type() const;
@@ -149,11 +189,6 @@ public:
void set_call_mode(CallMode p_mode);
CallMode get_call_mode() const;
- void set_use_builtin_value(bool p_use);
- bool is_using_builtin_value() const;
-
- void set_builtin_value(const Variant &p_value);
- Variant get_builtin_value() const;
virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
@@ -171,14 +206,17 @@ public:
CALL_MODE_SELF,
CALL_MODE_NODE_PATH,
CALL_MODE_INSTANCE,
- CALL_MODE_BASIC_TYPE
+ CALL_MODE_BASIC_TYPE,
};
private:
+ Variant::Type type_cache;
+
CallMode call_mode;
Variant::Type basic_type;
StringName base_type;
+ String base_script;
NodePath base_path;
StringName property;
InputEvent::Type event_type;
@@ -187,6 +225,10 @@ private:
Node *_get_base_node() const;
StringName _get_base_type() const;
+ void _update_cache();
+
+ void _set_type_cache(Variant::Type p_type);
+ Variant::Type _get_type_cache() const;
protected:
virtual void _validate_property(PropertyInfo& property) const;
@@ -216,6 +258,9 @@ public:
void set_base_type(const StringName& p_type);
StringName get_base_type() const;
+ void set_base_script(const String& p_path);
+ String get_base_script() const;
+
void set_basic_type(Variant::Type p_type);
Variant::Type get_basic_type() const;
@@ -244,74 +289,6 @@ VARIANT_ENUM_CAST(VisualScriptPropertyGet::CallMode );
-class VisualScriptScriptCall : public VisualScriptNode {
-
- OBJ_TYPE(VisualScriptScriptCall,VisualScriptNode)
-public:
- enum CallMode {
- CALL_MODE_SELF,
- CALL_MODE_NODE_PATH,
- };
-private:
-
- CallMode call_mode;
- NodePath base_path;
- StringName function;
- int argument_count;
-
-
- Node *_get_base_node() const;
-
-
- void _update_argument_count();
-protected:
- virtual void _validate_property(PropertyInfo& property) const;
-
- static void _bind_methods();
-
-public:
-
- virtual int get_output_sequence_port_count() const;
- virtual bool has_input_sequence_port() const;
-
-
- virtual String get_output_sequence_port_text(int p_port) const;
-
-
- virtual int get_input_value_port_count() const;
- virtual int get_output_value_port_count() const;
-
-
- virtual PropertyInfo get_input_value_port_info(int p_idx) const;
- virtual PropertyInfo get_output_value_port_info(int p_idx) const;
-
- virtual String get_caption() const;
- virtual String get_text() const;
- virtual String get_category() const { return "functions"; }
-
- void set_function(const StringName& p_type);
- StringName get_function() const;
-
- void set_base_path(const NodePath& p_type);
- NodePath get_base_path() const;
-
- void set_call_mode(CallMode p_mode);
- CallMode get_call_mode() const;
-
- void set_argument_count(int p_count);
- int get_argument_count() const;
-
-
- virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
-
- VisualScriptScriptCall();
-};
-
-VARIANT_ENUM_CAST(VisualScriptScriptCall::CallMode );
-
-
-
-
class VisualScriptEmitSignal : public VisualScriptNode {
OBJ_TYPE(VisualScriptEmitSignal,VisualScriptNode)
@@ -351,6 +328,9 @@ public:
virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
+
+
+
VisualScriptEmitSignal();
};
diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp
index d205a40f76..09ba7e4e2d 100644
--- a/modules/visual_script/visual_script_nodes.cpp
+++ b/modules/visual_script/visual_script_nodes.cpp
@@ -4,6 +4,7 @@
#include "scene/main/scene_main_loop.h"
#include "os/os.h"
#include "scene/main/node.h"
+#include "os/input.h"
//////////////////////////////////////////
////////////////FUNCTION//////////////////
@@ -62,6 +63,12 @@ bool VisualScriptFunction::_set(const StringName& p_name, const Variant& p_valu
stack_size=p_value;
return true;
}
+
+ if (p_name=="rpc/mode") {
+ rpc_mode=ScriptInstance::RPCMode(int(p_value));
+ return true;
+ }
+
return false;
}
@@ -99,13 +106,18 @@ bool VisualScriptFunction::_get(const StringName& p_name,Variant &r_ret) const
return true;
}
+ if (p_name=="rpc/mode") {
+ r_ret=rpc_mode;
+ return true;
+ }
+
return false;
}
void VisualScriptFunction::_get_property_list( List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::INT,"argument_count",PROPERTY_HINT_RANGE,"0,256"));
- String argt="Variant";
+ String argt="Any";
for(int i=1;i<Variant::VARIANT_MAX;i++) {
argt+=","+Variant::get_type_name(Variant::Type(i));
}
@@ -118,6 +130,7 @@ void VisualScriptFunction::_get_property_list( List<PropertyInfo> *p_list) cons
p_list->push_back(PropertyInfo(Variant::INT,"stack/size",PROPERTY_HINT_RANGE,"1,100000"));
}
p_list->push_back(PropertyInfo(Variant::BOOL,"stack/stackless"));
+ p_list->push_back(PropertyInfo(Variant::INT,"rpc/mode",PROPERTY_HINT_ENUM,"Disabled,Remote,Sync,Master,Slave"));
}
@@ -224,6 +237,16 @@ int VisualScriptFunction::get_argument_count() const {
return arguments.size();
}
+
+void VisualScriptFunction::set_rpc_mode(ScriptInstance::RPCMode p_mode) {
+ rpc_mode=p_mode;
+}
+
+ScriptInstance::RPCMode VisualScriptFunction::get_rpc_mode() const {
+ return rpc_mode;
+}
+
+
class VisualScriptNodeInstanceFunction : public VisualScriptNodeInstance {
public:
@@ -231,8 +254,6 @@ public:
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; }
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) {
@@ -272,6 +293,7 @@ VisualScriptFunction::VisualScriptFunction() {
stack_size=256;
stack_less=false;
+ rpc_mode=ScriptInstance::RPC_MODE_DISABLED;
}
@@ -302,12 +324,12 @@ int VisualScriptFunction::get_stack_size() const {
int VisualScriptOperator::get_output_sequence_port_count() const {
- return 1;
+ return 0;
}
bool VisualScriptOperator::has_input_sequence_port() const{
- return true;
+ return false;
}
int VisualScriptOperator::get_input_value_port_count() const{
@@ -362,6 +384,8 @@ PropertyInfo VisualScriptOperator::get_input_value_port_info(int p_idx) const{
PropertyInfo pinfo;
pinfo.name=p_idx==0?"A":"B";
pinfo.type=port_types[op][p_idx];
+ if (pinfo.type==Variant::NIL)
+ pinfo.type=typed;
return pinfo;
}
PropertyInfo VisualScriptOperator::get_output_value_port_info(int p_idx) const{
@@ -400,6 +424,8 @@ PropertyInfo VisualScriptOperator::get_output_value_port_info(int p_idx) const{
PropertyInfo pinfo;
pinfo.name="";
pinfo.type=port_types[op];
+ if (pinfo.type==Variant::NIL)
+ pinfo.type=typed;
return pinfo;
}
@@ -492,19 +518,43 @@ Variant::Operator VisualScriptOperator::get_operator() const{
return op;
}
+void VisualScriptOperator::set_typed(Variant::Type p_op) {
+
+ if (typed==p_op)
+ return;
+
+ typed=p_op;
+ ports_changed_notify();
+}
+
+Variant::Type VisualScriptOperator::get_typed() const {
+
+ return typed;
+}
+
void VisualScriptOperator::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_operator","op"),&VisualScriptOperator::set_operator);
ObjectTypeDB::bind_method(_MD("get_operator"),&VisualScriptOperator::get_operator);
+ ObjectTypeDB::bind_method(_MD("set_typed","type"),&VisualScriptOperator::set_typed);
+ ObjectTypeDB::bind_method(_MD("get_typed"),&VisualScriptOperator::get_typed);
+
String types;
for(int i=0;i<Variant::OP_MAX;i++) {
if (i>0)
types+=",";
types+=op_names[i];
}
- ADD_PROPERTY(PropertyInfo(Variant::INT,"operator_value/type",PROPERTY_HINT_ENUM,types),_SCS("set_operator"),_SCS("get_operator"));
+
+ String argt="Any";
+ for(int i=1;i<Variant::VARIANT_MAX;i++) {
+ argt+=","+Variant::get_type_name(Variant::Type(i));
+ }
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"operator_value/type",PROPERTY_HINT_ENUM,types,PROPERTY_USAGE_NOEDITOR),_SCS("set_operator"),_SCS("get_operator"));
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"typed_value/typed",PROPERTY_HINT_ENUM,argt),_SCS("set_typed"),_SCS("get_typed"));
}
@@ -515,8 +565,6 @@ public:
Variant::Operator op;
//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; }
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) {
@@ -558,6 +606,7 @@ VisualScriptNodeInstance* VisualScriptOperator::instance(VisualScriptInstance* p
VisualScriptOperator::VisualScriptOperator() {
op=Variant::OP_ADD;
+ typed=Variant::NIL;
}
@@ -679,20 +728,14 @@ public:
VisualScriptInstance *instance;
StringName variable;
- //virtual int get_working_memory_size() const { return 0; }
- virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
- virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
-
- if (instance->get_variable(variable,r_value)==false) {
- r_error=RTR("VariableGet not found in script: ")+"'"+String(variable)+"'";
- return false;
- } else {
- return true;
- }
- }
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) {
+ if (instance->get_variable(variable,p_outputs[0])==false) {
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error_str=RTR("VariableGet not found in script: ")+"'"+String(variable)+"'";
+ return false;
+ }
return 0;
}
@@ -714,7 +757,7 @@ VisualScriptVariableGet::VisualScriptVariableGet() {
//////////////////////////////////////////
-////////////////VARIABLE GET//////////////////
+////////////////VARIABLE SET//////////////////
//////////////////////////////////////////
int VisualScriptVariableSet::get_output_sequence_port_count() const {
@@ -822,17 +865,16 @@ public:
StringName variable;
//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 false; }
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) {
if (instance->set_variable(variable,*p_inputs[0])==false) {
- r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD ;
+
+
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str=RTR("VariableSet not found in script: ")+"'"+String(variable)+"'";
}
-
return 0;
}
@@ -971,17 +1013,10 @@ public:
Variant constant;
//virtual int get_working_memory_size() const { return 0; }
- virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
- virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
-
- *r_value=constant;
-
- return true;
-
- }
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) {
+ *p_outputs[0]=constant;
return 0;
}
@@ -1001,6 +1036,118 @@ VisualScriptConstant::VisualScriptConstant() {
}
+//////////////////////////////////////////
+////////////////PRELOAD//////////////////
+//////////////////////////////////////////
+
+int VisualScriptPreload::get_output_sequence_port_count() const {
+
+ return 0;
+}
+
+bool VisualScriptPreload::has_input_sequence_port() const{
+
+ return false;
+}
+
+int VisualScriptPreload::get_input_value_port_count() const{
+
+ return 0;
+}
+int VisualScriptPreload::get_output_value_port_count() const{
+
+ return 1;
+}
+
+String VisualScriptPreload::get_output_sequence_port_text(int p_port) const {
+
+ return String();
+}
+
+PropertyInfo VisualScriptPreload::get_input_value_port_info(int p_idx) const{
+
+ return PropertyInfo();
+}
+
+PropertyInfo VisualScriptPreload::get_output_value_port_info(int p_idx) const{
+
+ return PropertyInfo(Variant::OBJECT,"res");
+}
+
+
+String VisualScriptPreload::get_caption() const {
+
+ return "Preload";
+}
+
+String VisualScriptPreload::get_text() const {
+
+ if (preload.is_valid()) {
+ if (preload->get_path().is_resource_file()) {
+ return preload->get_path();
+ } else if (preload->get_name()!=String()) {
+ return preload->get_name();
+ } else {
+ return preload->get_type();
+ }
+ } else {
+ return "<empty>";
+ }
+}
+
+
+void VisualScriptPreload::set_preload(const Ref<Resource>& p_preload){
+
+ if (preload==p_preload)
+ return;
+
+ preload=p_preload;
+ ports_changed_notify();
+}
+Ref<Resource> VisualScriptPreload::get_preload() const{
+
+ return preload;
+}
+
+
+void VisualScriptPreload::_bind_methods() {
+
+
+ ObjectTypeDB::bind_method(_MD("set_preload","resource"),&VisualScriptPreload::set_preload);
+ ObjectTypeDB::bind_method(_MD("get_preload"),&VisualScriptPreload::get_preload);
+
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT,"resource",PROPERTY_HINT_RESOURCE_TYPE,"Resource"),_SCS("set_preload"),_SCS("get_preload"));
+
+}
+
+class VisualScriptNodeInstancePreload : public VisualScriptNodeInstance {
+public:
+
+ Ref<Resource> preload;
+ //virtual int get_working_memory_size() const { return 0; }
+
+ virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
+
+ *p_outputs[0]=preload;
+ return 0;
+ }
+
+
+};
+
+VisualScriptNodeInstance* VisualScriptPreload::instance(VisualScriptInstance* p_instance) {
+
+ VisualScriptNodeInstancePreload * instance = memnew(VisualScriptNodeInstancePreload );
+ instance->preload=preload;
+ return instance;
+}
+
+VisualScriptPreload::VisualScriptPreload() {
+
+}
+
+
//////////////////////////////////////////
@@ -1009,12 +1156,12 @@ VisualScriptConstant::VisualScriptConstant() {
int VisualScriptIndexGet::get_output_sequence_port_count() const {
- return 1;
+ return 0;
}
bool VisualScriptIndexGet::has_input_sequence_port() const{
- return true;
+ return false;
}
int VisualScriptIndexGet::get_input_value_port_count() const{
@@ -1063,8 +1210,6 @@ public:
//virtual int get_working_memory_size() const { return 0; }
- //virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
- //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return false; }
virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
@@ -1155,8 +1300,6 @@ public:
//virtual int get_working_memory_size() const { return 0; }
- //virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
- //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return false; }
virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
@@ -1252,17 +1395,11 @@ public:
int index;
//virtual int get_working_memory_size() const { return 0; }
- virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
- virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
-
- *r_value = GlobalConstants::get_global_constant_value(index);
- return true;
-
- }
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) {
+ *p_outputs[0] = GlobalConstants::get_global_constant_value(index);
return 0;
}
@@ -1384,17 +1521,10 @@ public:
float value;
//virtual int get_working_memory_size() const { return 0; }
- virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
- virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
-
- *r_value = value;
- return true;
-
- }
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) {
-
+ *p_outputs[0]=value;
return 0;
}
@@ -1501,16 +1631,10 @@ public:
Object* singleton;
//virtual int get_working_memory_size() const { return 0; }
- virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
- virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
-
- *r_value=singleton;
- return true;
- }
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) {
-
+ *p_outputs[0]=singleton;
return 0;
}
@@ -1623,28 +1747,26 @@ public:
NodePath path;
//virtual int get_working_memory_size() const { return 0; }
- virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
- virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
+
+ 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) {
Node* node = instance->get_owner_ptr()->cast_to<Node>();
if (!node) {
- r_error="Base object is not a Node!";
- return false;
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error_str="Base object is not a Node!";
+ return 0;
}
Node* another = node->get_node(path);
if (!node) {
- r_error="Path does not lead Node!";
- return false;
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error_str="Path does not lead Node!";
+ return 0;
}
- *r_value=another;
- return true;
- }
-
- 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) {
+ *p_outputs[0]=another;
return 0;
}
@@ -1789,28 +1911,24 @@ public:
VisualScriptInstance *instance;
//virtual int get_working_memory_size() const { return 0; }
- virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
- virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
+
+ 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) {
Node* node = instance->get_owner_ptr()->cast_to<Node>();
if (!node) {
- r_error="Base object is not a Node!";
- return false;
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error_str="Base object is not a Node!";
+ return 0;
}
SceneTree* tree = node->get_tree();
if (!tree) {
- r_error="Attempt to get SceneTree while node is not in the active tree.";
- return false;
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error_str="Attempt to get SceneTree while node is not in the active tree.";
+ return 0;
}
- *r_value=tree;
- return true;
-
- }
-
- 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) {
-
+ *p_outputs[0]=tree;
return 0;
}
@@ -1907,14 +2025,10 @@ public:
String path;
//virtual int get_working_memory_size() const { return 0; }
- virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
- virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
- *r_value = path;
- return true;
- }
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) {
+ *p_outputs[0] = path;
return 0;
}
@@ -2004,15 +2118,10 @@ public:
VisualScriptInstance* instance;
//virtual int get_working_memory_size() const { return 0; }
- virtual bool is_output_port_unsequenced(int p_idx) const { return true; }
- virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
-
- *r_value = instance->get_owner_ptr();
- return true;
- }
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) {
+ *p_outputs[0] = instance->get_owner_ptr();
return 0;
}
@@ -2138,35 +2247,8 @@ public:
int in_count;
int out_count;
int work_mem_size;
- Vector<bool> out_unsequenced;
virtual int get_working_memory_size() const { return work_mem_size; }
- virtual bool is_output_port_unsequenced(int p_idx) const { return out_unsequenced[p_idx]; }
- virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
-
- if (!node->get_script_instance() || !node->get_script_instance()->has_method(VisualScriptLanguage::singleton->_get_output_port_unsequenced)) {
-#ifdef DEBUG_ENABLED
- r_error=RTR("Custom node has no _get_output_port_unsequenced(idx,wmem), but unsequenced ports were specified.");
- return false;
- }
-#endif
-
- Array work_mem(true);
- work_mem.resize(work_mem_size);
-
- *r_value = node->get_script_instance()->call(VisualScriptLanguage::singleton->_get_output_port_unsequenced,p_idx,work_mem);
-
-
- for(int i=0;i<work_mem_size;i++) {
- if (i<work_mem.size()) {
- p_working_mem[i]=work_mem[i];
- }
- }
-
- return true;
-
- }
-
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) {
if (node->get_script_instance()) {
@@ -2239,10 +2321,6 @@ VisualScriptNodeInstance* VisualScriptCustomNode::instance(VisualScriptInstance*
instance->in_count=get_input_value_port_count();
instance->out_count=get_output_value_port_count();
- for(int i=0;i<instance->out_count;i++) {
- bool unseq = get_script_instance() && get_script_instance()->has_method("_is_output_port_unsequenced") && bool(get_script_instance()->call("_is_output_port_unsequenced",i));
- instance->out_unsequenced.push_back(unseq);
- }
if (get_script_instance() && get_script_instance()->has_method("_get_working_memory_size")) {
instance->work_mem_size = get_script_instance()->call("_get_working_memory_size");
@@ -2275,8 +2353,6 @@ void VisualScriptCustomNode::_bind_methods() {
BIND_VMETHOD( MethodInfo(Variant::STRING,"_get_category") );
BIND_VMETHOD( MethodInfo(Variant::INT,"_get_working_memory_size") );
- BIND_VMETHOD( MethodInfo(Variant::INT,"_is_output_port_unsequenced",PropertyInfo(Variant::INT,"idx")) );
- BIND_VMETHOD( MethodInfo(Variant::INT,"_get_output_port_unsequenced",PropertyInfo(Variant::INT,"idx"),PropertyInfo(Variant::ARRAY,"work_mem")) );
BIND_VMETHOD( MethodInfo(Variant::NIL,"_step:Variant",PropertyInfo(Variant::ARRAY,"inputs"),PropertyInfo(Variant::ARRAY,"outputs"),PropertyInfo(Variant::INT,"start_mode"),PropertyInfo(Variant::ARRAY,"working_mem")) );
BIND_CONSTANT( START_MODE_BEGIN_SEQUENCE );
@@ -2388,8 +2464,6 @@ public:
bool valid;
//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 false; };
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) {
@@ -2432,11 +2506,942 @@ VisualScriptSubCall::VisualScriptSubCall() {
}
+//////////////////////////////////////////
+////////////////Comment///////////
+//////////////////////////////////////////
+
+int VisualScriptComment::get_output_sequence_port_count() const {
+
+ return 0;
+}
+
+bool VisualScriptComment::has_input_sequence_port() const{
+
+ return false;
+}
+
+int VisualScriptComment::get_input_value_port_count() const{
+ return 0;
+}
+int VisualScriptComment::get_output_value_port_count() const{
+
+ return 0;
+}
+
+String VisualScriptComment::get_output_sequence_port_text(int p_port) const {
+
+ return String();
+}
+
+PropertyInfo VisualScriptComment::get_input_value_port_info(int p_idx) const{
+
+ return PropertyInfo();
+}
+
+PropertyInfo VisualScriptComment::get_output_value_port_info(int p_idx) const{
+
+ return PropertyInfo();
+}
+
+
+String VisualScriptComment::get_caption() const {
+
+ return title;
+}
+
+
+String VisualScriptComment::get_text() const {
+
+ return description;
+}
+
+void VisualScriptComment::set_title(const String& p_title) {
+
+
+ if (title==p_title)
+ return;
+ title=p_title;
+ ports_changed_notify();
+}
+
+String VisualScriptComment::get_title() const{
+
+ return title;
+}
+
+void VisualScriptComment::set_description(const String& p_description){
+
+ if (description==p_description)
+ return;
+ description=p_description;
+ ports_changed_notify();
+
+}
+String VisualScriptComment::get_description() const{
+
+ return description;
+}
+
+void VisualScriptComment::set_size(const Size2& p_size){
+
+ if (size==p_size)
+ return;
+ size=p_size;
+ ports_changed_notify();
+
+}
+Size2 VisualScriptComment::get_size() const{
+
+ return size;
+}
+
+
+String VisualScriptComment::get_category() const {
+
+ return "data";
+}
+
+class VisualScriptNodeInstanceComment : public VisualScriptNodeInstance {
+public:
+
+ VisualScriptInstance* instance;
+
+ //virtual int get_working_memory_size() const { return 0; }
+
+ virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
+
+
+ return 0;
+ }
+
+
+};
+
+VisualScriptNodeInstance* VisualScriptComment::instance(VisualScriptInstance* p_instance) {
+
+ VisualScriptNodeInstanceComment * instance = memnew(VisualScriptNodeInstanceComment );
+ instance->instance=p_instance;
+ return instance;
+}
+
+
+
+void VisualScriptComment::_bind_methods() {
+
+
+ ObjectTypeDB::bind_method(_MD("set_title","title"),&VisualScriptComment::set_title);
+ ObjectTypeDB::bind_method(_MD("get_title"),&VisualScriptComment::get_title);
+
+ ObjectTypeDB::bind_method(_MD("set_description","description"),&VisualScriptComment::set_description);
+ ObjectTypeDB::bind_method(_MD("get_description"),&VisualScriptComment::get_description);
+
+ ObjectTypeDB::bind_method(_MD("set_size","size"),&VisualScriptComment::set_size);
+ ObjectTypeDB::bind_method(_MD("get_size"),&VisualScriptComment::get_size);
+
+ ADD_PROPERTY( PropertyInfo(Variant::STRING,"title"),_SCS("set_title"),_SCS("get_title"));
+ ADD_PROPERTY( PropertyInfo(Variant::STRING,"description",PROPERTY_HINT_MULTILINE_TEXT),_SCS("set_description"),_SCS("get_description"));
+ ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"size"),_SCS("set_size"),_SCS("get_size"));
+
+}
+
+VisualScriptComment::VisualScriptComment() {
+
+ title="Comment";
+ size=Size2(150,150);
+}
+
+
+//////////////////////////////////////////
+////////////////Constructor///////////
+//////////////////////////////////////////
+
+int VisualScriptConstructor::get_output_sequence_port_count() const {
+
+ return 0;
+}
+
+bool VisualScriptConstructor::has_input_sequence_port() const{
+
+ return false;
+}
+
+int VisualScriptConstructor::get_input_value_port_count() const{
+ return constructor.arguments.size();
+}
+int VisualScriptConstructor::get_output_value_port_count() const{
+
+ return 1;
+}
+
+String VisualScriptConstructor::get_output_sequence_port_text(int p_port) const {
+
+ return "";
+}
+
+PropertyInfo VisualScriptConstructor::get_input_value_port_info(int p_idx) const{
+
+ return constructor.arguments[p_idx];
+}
+
+PropertyInfo VisualScriptConstructor::get_output_value_port_info(int p_idx) const{
+
+ return PropertyInfo(type,"value");
+}
+
+
+String VisualScriptConstructor::get_caption() const {
+
+ return "Construct";
+}
+
+
+String VisualScriptConstructor::get_text() const {
+
+ return "new "+Variant::get_type_name(type)+"()";
+}
+
+
+String VisualScriptConstructor::get_category() const {
+
+ return "functions";
+}
+
+void VisualScriptConstructor::set_constructor_type(Variant::Type p_type) {
+
+ if (type==p_type)
+ return;
+
+ type=p_type;
+ ports_changed_notify();
+}
+
+Variant::Type VisualScriptConstructor::get_constructor_type() const {
+
+ return type;
+}
+
+void VisualScriptConstructor::set_constructor(const Dictionary& p_info) {
+
+ constructor=MethodInfo::from_dict(p_info);
+}
+
+Dictionary VisualScriptConstructor::get_constructor() const {
+
+ return constructor;
+}
+
+
+class VisualScriptNodeInstanceConstructor : public VisualScriptNodeInstance {
+public:
+
+ VisualScriptInstance* instance;
+ Variant::Type type;
+ int argcount;
+
+ //virtual int get_working_memory_size() const { return 0; }
+
+ virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
+
+ Variant::CallError ce;
+ *p_outputs[0]=Variant::construct(type,p_inputs,argcount,ce);
+ if (ce.error!=Variant::CallError::CALL_OK) {
+ r_error_str="Invalid arguments for constructor";
+ }
+
+ return 0;
+ }
+
+
+};
+
+VisualScriptNodeInstance* VisualScriptConstructor::instance(VisualScriptInstance* p_instance) {
+
+ VisualScriptNodeInstanceConstructor * instance = memnew(VisualScriptNodeInstanceConstructor );
+ instance->instance=p_instance;
+ instance->type=type;
+ instance->argcount=constructor.arguments.size();
+ return instance;
+}
+
+
+
+void VisualScriptConstructor::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("set_constructor_type","type"),&VisualScriptConstructor::set_constructor_type);
+ ObjectTypeDB::bind_method(_MD("get_constructor_type"),&VisualScriptConstructor::get_constructor_type);
+
+ ObjectTypeDB::bind_method(_MD("set_constructor","constructor"),&VisualScriptConstructor::set_constructor);
+ ObjectTypeDB::bind_method(_MD("get_constructor"),&VisualScriptConstructor::get_constructor);
+
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"type",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_constructor_type"),_SCS("get_constructor_type"));
+ ADD_PROPERTY( PropertyInfo(Variant::DICTIONARY,"constructor",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_constructor"),_SCS("get_constructor"));
+
+}
+
+VisualScriptConstructor::VisualScriptConstructor() {
+
+ type=Variant::NIL;
+
+}
+
+static Map<String,Pair<Variant::Type,MethodInfo> > constructor_map;
+
+static Ref<VisualScriptNode> create_constructor_node(const String& p_name) {
+
+ ERR_FAIL_COND_V(!constructor_map.has(p_name),Ref<VisualScriptNode>());
+
+ Ref<VisualScriptConstructor> vsc;
+ vsc.instance();
+ vsc->set_constructor_type(constructor_map[p_name].first);
+ vsc->set_constructor(constructor_map[p_name].second);
+
+ return vsc;
+}
+
+//////////////////////////////////////////
+////////////////LocalVar///////////
+//////////////////////////////////////////
+
+int VisualScriptLocalVar::get_output_sequence_port_count() const {
+
+ return 0;
+}
+
+bool VisualScriptLocalVar::has_input_sequence_port() const{
+
+ return false;
+}
+
+int VisualScriptLocalVar::get_input_value_port_count() const{
+ return 0;
+}
+int VisualScriptLocalVar::get_output_value_port_count() const{
+
+ return 1;
+}
+
+String VisualScriptLocalVar::get_output_sequence_port_text(int p_port) const {
+
+ return "";
+}
+
+PropertyInfo VisualScriptLocalVar::get_input_value_port_info(int p_idx) const{
+
+ return PropertyInfo();
+}
+PropertyInfo VisualScriptLocalVar::get_output_value_port_info(int p_idx) const{
+
+ return PropertyInfo(type,"get");
+}
+
+
+String VisualScriptLocalVar::get_caption() const {
+
+ return "LocalVarGet";
+}
+
+
+String VisualScriptLocalVar::get_text() const {
+
+ return name;
+}
+
+
+String VisualScriptLocalVar::get_category() const {
+
+ return "data";
+}
+
+
+void VisualScriptLocalVar::set_var_name(const StringName& p_name) {
+
+ if (name==p_name)
+ return;
+
+ name=p_name;
+ ports_changed_notify();
+
+}
+
+StringName VisualScriptLocalVar::get_var_name() const {
+
+ return name;
+}
+
+void VisualScriptLocalVar::set_var_type(Variant::Type p_type) {
+
+ type=p_type;
+ ports_changed_notify();
+}
+
+Variant::Type VisualScriptLocalVar::get_var_type() const {
+
+ return type;
+}
+
+
+class VisualScriptNodeInstanceLocalVar : public VisualScriptNodeInstance {
+public:
+
+ VisualScriptInstance* instance;
+ StringName name;
+
+
+ virtual int get_working_memory_size() const { return 1; }
+ 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) {
+
+ *p_outputs[0]=*p_working_mem;
+ return 0;
+ }
+
+
+};
+
+VisualScriptNodeInstance* VisualScriptLocalVar::instance(VisualScriptInstance* p_instance) {
+
+ VisualScriptNodeInstanceLocalVar * instance = memnew(VisualScriptNodeInstanceLocalVar );
+ instance->instance=p_instance;
+ instance->name=name;
+
+ return instance;
+}
+
+
+
+void VisualScriptLocalVar::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("set_var_name","name"),&VisualScriptLocalVar::set_var_name);
+ ObjectTypeDB::bind_method(_MD("get_var_name"),&VisualScriptLocalVar::get_var_name);
+
+ ObjectTypeDB::bind_method(_MD("set_var_type","type"),&VisualScriptLocalVar::set_var_type);
+ ObjectTypeDB::bind_method(_MD("get_var_type"),&VisualScriptLocalVar::get_var_type);
+
+ String argt="Any";
+ for(int i=1;i<Variant::VARIANT_MAX;i++) {
+ argt+=","+Variant::get_type_name(Variant::Type(i));
+ }
+
+ ADD_PROPERTY( PropertyInfo(Variant::STRING,"variable/name"),_SCS("set_var_name"),_SCS("get_var_name"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"variable/type",PROPERTY_HINT_ENUM,argt),_SCS("set_var_type"),_SCS("get_var_type"));
+
+
+}
+
+VisualScriptLocalVar::VisualScriptLocalVar() {
+
+ name="new_local";
+ type=Variant::NIL;
+
+}
+
+//////////////////////////////////////////
+////////////////LocalVar///////////
+//////////////////////////////////////////
+
+int VisualScriptLocalVarSet::get_output_sequence_port_count() const {
+
+ return 1;
+}
+
+bool VisualScriptLocalVarSet::has_input_sequence_port() const{
+
+ return true;
+}
+
+int VisualScriptLocalVarSet::get_input_value_port_count() const{
+ return 1;
+}
+int VisualScriptLocalVarSet::get_output_value_port_count() const{
+
+ return 1;
+}
+
+String VisualScriptLocalVarSet::get_output_sequence_port_text(int p_port) const {
+
+ return "";
+}
+
+PropertyInfo VisualScriptLocalVarSet::get_input_value_port_info(int p_idx) const{
+
+ return PropertyInfo(type,"set");
+}
+PropertyInfo VisualScriptLocalVarSet::get_output_value_port_info(int p_idx) const{
+
+ return PropertyInfo(type,"get");
+}
+
+
+String VisualScriptLocalVarSet::get_caption() const {
+
+ return "LocalVarSet";
+}
+
+
+String VisualScriptLocalVarSet::get_text() const {
+
+ return name;
+}
+
+
+String VisualScriptLocalVarSet::get_category() const {
+
+ return "data";
+}
+
+
+void VisualScriptLocalVarSet::set_var_name(const StringName& p_name) {
+
+ if (name==p_name)
+ return;
+
+ name=p_name;
+ ports_changed_notify();
+
+}
+
+StringName VisualScriptLocalVarSet::get_var_name() const {
+
+ return name;
+}
+
+void VisualScriptLocalVarSet::set_var_type(Variant::Type p_type) {
+
+ type=p_type;
+ ports_changed_notify();
+}
+
+Variant::Type VisualScriptLocalVarSet::get_var_type() const {
+
+ return type;
+}
+
+
+class VisualScriptNodeInstanceLocalVarSet : public VisualScriptNodeInstance {
+public:
+
+ VisualScriptInstance* instance;
+ StringName name;
+
+
+ virtual int get_working_memory_size() const { return 1; }
+ 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) {
+
+ *p_working_mem=*p_inputs[0];
+ *p_outputs[0]=*p_working_mem;
+ return 0;
+ }
+
+
+};
+
+VisualScriptNodeInstance* VisualScriptLocalVarSet::instance(VisualScriptInstance* p_instance) {
+
+ VisualScriptNodeInstanceLocalVarSet * instance = memnew(VisualScriptNodeInstanceLocalVarSet );
+ instance->instance=p_instance;
+ instance->name=name;
+
+ return instance;
+}
+
+
+
+void VisualScriptLocalVarSet::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("set_var_name","name"),&VisualScriptLocalVarSet::set_var_name);
+ ObjectTypeDB::bind_method(_MD("get_var_name"),&VisualScriptLocalVarSet::get_var_name);
+
+ ObjectTypeDB::bind_method(_MD("set_var_type","type"),&VisualScriptLocalVarSet::set_var_type);
+ ObjectTypeDB::bind_method(_MD("get_var_type"),&VisualScriptLocalVarSet::get_var_type);
+
+ String argt="Any";
+ for(int i=1;i<Variant::VARIANT_MAX;i++) {
+ argt+=","+Variant::get_type_name(Variant::Type(i));
+ }
+
+ ADD_PROPERTY( PropertyInfo(Variant::STRING,"variable/name"),_SCS("set_var_name"),_SCS("get_var_name"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"variable/type",PROPERTY_HINT_ENUM,argt),_SCS("set_var_type"),_SCS("get_var_type"));
+
+
+}
+
+VisualScriptLocalVarSet::VisualScriptLocalVarSet() {
+
+ name="new_local";
+ type=Variant::NIL;
+
+}
+
+
+//////////////////////////////////////////
+////////////////LocalVar///////////
+//////////////////////////////////////////
+
+int VisualScriptInputAction::get_output_sequence_port_count() const {
+
+ return 0;
+}
+
+bool VisualScriptInputAction::has_input_sequence_port() const{
+
+ return false;
+}
+
+int VisualScriptInputAction::get_input_value_port_count() const{
+ return 0;
+}
+int VisualScriptInputAction::get_output_value_port_count() const{
+
+ return 1;
+}
+
+String VisualScriptInputAction::get_output_sequence_port_text(int p_port) const {
+
+ return "";
+}
+
+PropertyInfo VisualScriptInputAction::get_input_value_port_info(int p_idx) const{
+
+ return PropertyInfo();
+}
+PropertyInfo VisualScriptInputAction::get_output_value_port_info(int p_idx) const{
+
+ return PropertyInfo(Variant::BOOL,"pressed");
+}
+
+
+String VisualScriptInputAction::get_caption() const {
+
+ return "Action";
+}
+
+
+String VisualScriptInputAction::get_text() const {
+
+ return name;
+}
+
+
+String VisualScriptInputAction::get_category() const {
+
+ return "data";
+}
+
+
+void VisualScriptInputAction::set_action_name(const StringName& p_name) {
+
+ if (name==p_name)
+ return;
+
+ name=p_name;
+ ports_changed_notify();
+
+}
+
+StringName VisualScriptInputAction::get_action_name() const {
+
+ return name;
+}
+
+
+class VisualScriptNodeInstanceInputAction : public VisualScriptNodeInstance {
+public:
+
+ VisualScriptInstance* instance;
+ StringName action;
+
+
+ virtual int get_working_memory_size() const { return 1; }
+
+ 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) {
+
+ *p_outputs[0]=Input::get_singleton()->is_action_pressed(action);
+ return 0;
+ }
+
+
+};
+
+VisualScriptNodeInstance* VisualScriptInputAction::instance(VisualScriptInstance* p_instance) {
+
+ VisualScriptNodeInstanceInputAction * instance = memnew(VisualScriptNodeInstanceInputAction );
+ instance->instance=p_instance;
+ instance->action=name;
+
+ return instance;
+}
+
+void VisualScriptInputAction::_validate_property(PropertyInfo& property) const {
+
+
+ if (property.name=="action") {
+
+ property.hint=PROPERTY_HINT_ENUM;
+ String actions;
+
+ List<PropertyInfo> pinfo;
+ Globals::get_singleton()->get_property_list(&pinfo);
+ Vector<String> al;
+
+ for(List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) {
+ const PropertyInfo &pi=E->get();
+
+ if (!pi.name.begins_with("input/"))
+ continue;
+
+ String name = pi.name.substr(pi.name.find("/")+1,pi.name.length());
+
+
+ al.push_back(name);
+ }
+
+ al.sort();;
+
+ for(int i=0;i<al.size();i++) {
+ if (actions!=String())
+ actions+=",";
+ actions+=al[i];
+ }
+
+ property.hint_string=actions;
+ }
+}
+
+
+void VisualScriptInputAction::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("set_action_name","name"),&VisualScriptInputAction::set_action_name);
+ ObjectTypeDB::bind_method(_MD("get_action_name"),&VisualScriptInputAction::get_action_name);
+
+ ADD_PROPERTY( PropertyInfo(Variant::STRING,"action"),_SCS("set_action_name"),_SCS("get_action_name"));
+
+}
+
+VisualScriptInputAction::VisualScriptInputAction() {
+
+ name="";
+
+}
+
+//////////////////////////////////////////
+////////////////Constructor///////////
+//////////////////////////////////////////
+
+int VisualScriptDeconstruct::get_output_sequence_port_count() const {
+
+ return 0;
+}
+
+bool VisualScriptDeconstruct::has_input_sequence_port() const{
+
+ return false;
+}
+
+int VisualScriptDeconstruct::get_input_value_port_count() const{
+ return 1;
+}
+int VisualScriptDeconstruct::get_output_value_port_count() const{
+
+ return elements.size();
+}
+
+String VisualScriptDeconstruct::get_output_sequence_port_text(int p_port) const {
+
+ return "";
+}
+
+PropertyInfo VisualScriptDeconstruct::get_input_value_port_info(int p_idx) const{
+
+ return PropertyInfo(type,"value");
+}
+
+PropertyInfo VisualScriptDeconstruct::get_output_value_port_info(int p_idx) const{
+
+ return PropertyInfo(elements[p_idx].type,elements[p_idx].name);
+}
+
+
+String VisualScriptDeconstruct::get_caption() const {
+
+ return "Deconstruct";
+}
+
+
+String VisualScriptDeconstruct::get_text() const {
+
+ return "from "+Variant::get_type_name(type)+":";
+}
+
+
+String VisualScriptDeconstruct::get_category() const {
+
+ return "functions";
+}
+
+void VisualScriptDeconstruct::_update_elements() {
+
+ elements.clear();;
+ Variant v;
+ if (type==Variant::INPUT_EVENT) {
+ InputEvent ie;
+ ie.type=input_type;
+ v=ie;
+ } else {
+ Variant::CallError ce;
+ v = Variant::construct(type,NULL,0,ce);
+ }
+
+ List<PropertyInfo> pinfo;
+ v.get_property_list(&pinfo);
+
+ for (List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) {
+
+ Element e;
+ e.name=E->get().name;
+ e.type=E->get().type;
+ elements.push_back(e);
+ }
+}
+
+void VisualScriptDeconstruct::set_deconstruct_type(Variant::Type p_type) {
+
+ if (type==p_type)
+ return;
+
+ type=p_type;
+ _update_elements();
+ ports_changed_notify();
+ _change_notify(); //to make input appear/disappear
+}
+
+Variant::Type VisualScriptDeconstruct::get_deconstruct_type() const {
+
+ return type;
+}
+
+void VisualScriptDeconstruct::set_deconstruct_input_type(InputEvent::Type p_input_type) {
+
+ if (input_type==p_input_type)
+ return;
+
+ input_type=p_input_type;
+ _update_elements();
+ ports_changed_notify();
+}
+
+InputEvent::Type VisualScriptDeconstruct::get_deconstruct_input_type() const {
+
+ return input_type;
+}
+
+void VisualScriptDeconstruct::_set_elem_cache(const Array& p_elements) {
+
+ ERR_FAIL_COND(p_elements.size()%2==1);
+ elements.resize(p_elements.size()/2);
+ for(int i=0;i<elements.size();i++) {
+ elements[i].name=p_elements[i*2+0];
+ elements[i].type=Variant::Type(int(p_elements[i*2+1]));
+ }
+}
+
+Array VisualScriptDeconstruct::_get_elem_cache() const {
+
+ Array ret;
+ for(int i=0;i<elements.size();i++) {
+ ret.push_back(elements[i].name);
+ ret.push_back(elements[i].type);
+ }
+ return ret;
+}
+
+class VisualScriptNodeInstanceDeconstruct : public VisualScriptNodeInstance {
+public:
+
+ VisualScriptInstance* instance;
+ Vector<StringName> outputs;
+
+ //virtual int get_working_memory_size() const { return 0; }
+
+ virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
+
+ Variant in=*p_inputs[0];
+
+ for(int i=0;i<outputs.size();i++) {
+ bool valid;
+ *p_outputs[i]=in.get(outputs[i],&valid);
+ if (!valid) {
+ r_error_str="Can't obtain element '"+String(outputs[i])+"' from "+Variant::get_type_name(in.get_type());
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ return 0;
+ }
+
+ }
+
+ return 0;
+ }
+
+
+};
+
+VisualScriptNodeInstance* VisualScriptDeconstruct::instance(VisualScriptInstance* p_instance) {
+
+ VisualScriptNodeInstanceDeconstruct * instance = memnew(VisualScriptNodeInstanceDeconstruct );
+ instance->instance=p_instance;
+ instance->outputs.resize(elements.size());
+ for(int i=0;i<elements.size();i++) {
+ instance->outputs[i]=elements[i].name;
+ }
+
+ return instance;
+}
+
+
+
+void VisualScriptDeconstruct::_validate_property(PropertyInfo& property) const {
+
+ if (property.name=="input_type") {
+ if (type!=Variant::INPUT_EVENT) {
+ property.usage=0;
+ }
+ }
+}
+
+
+void VisualScriptDeconstruct::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("set_deconstruct_type","type"),&VisualScriptDeconstruct::set_deconstruct_type);
+ ObjectTypeDB::bind_method(_MD("get_deconstruct_type"),&VisualScriptDeconstruct::get_deconstruct_type);
+
+ ObjectTypeDB::bind_method(_MD("set_deconstruct_input_type","input_type"),&VisualScriptDeconstruct::set_deconstruct_input_type);
+ ObjectTypeDB::bind_method(_MD("get_deconstruct_input_type"),&VisualScriptDeconstruct::get_deconstruct_input_type);
+
+ ObjectTypeDB::bind_method(_MD("_set_elem_cache","_cache"),&VisualScriptDeconstruct::_set_elem_cache);
+ ObjectTypeDB::bind_method(_MD("_get_elem_cache"),&VisualScriptDeconstruct::_get_elem_cache);
+
+ String argt="Any";
+ for(int i=1;i<Variant::VARIANT_MAX;i++) {
+ argt+=","+Variant::get_type_name(Variant::Type(i));
+ }
+
+ String iet="None,Key,MouseMotion,MouseButton,JoystickMotion,JoystickButton,ScreenTouch,ScreenDrag,Action";
+
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"type",PROPERTY_HINT_ENUM,argt),_SCS("set_deconstruct_type"),_SCS("get_deconstruct_type"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"input_type",PROPERTY_HINT_ENUM,iet),_SCS("set_deconstruct_input_type"),_SCS("get_deconstruct_input_type"));
+ ADD_PROPERTY( PropertyInfo(Variant::ARRAY,"elem_cache",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_elem_cache"),_SCS("_get_elem_cache"));
+
+}
+
+VisualScriptDeconstruct::VisualScriptDeconstruct() {
+
+ type=Variant::NIL;
+ input_type=InputEvent::NONE;
+
+}
+
void register_visual_script_nodes() {
- VisualScriptLanguage::singleton->add_register_func("data/set_variable",create_node_generic<VisualScriptVariableGet>);
- VisualScriptLanguage::singleton->add_register_func("data/get_variable",create_node_generic<VisualScriptVariableSet>);
+ VisualScriptLanguage::singleton->add_register_func("data/set_variable",create_node_generic<VisualScriptVariableSet>);
+ VisualScriptLanguage::singleton->add_register_func("data/get_variable",create_node_generic<VisualScriptVariableGet>);
VisualScriptLanguage::singleton->add_register_func("data/constant",create_node_generic<VisualScriptConstant>);
VisualScriptLanguage::singleton->add_register_func("data/global_constant",create_node_generic<VisualScriptGlobalConstant>);
VisualScriptLanguage::singleton->add_register_func("data/math_constant",create_node_generic<VisualScriptMathConstant>);
@@ -2447,6 +3452,11 @@ void register_visual_script_nodes() {
VisualScriptLanguage::singleton->add_register_func("data/self",create_node_generic<VisualScriptSelf>);
VisualScriptLanguage::singleton->add_register_func("custom/custom_node",create_node_generic<VisualScriptCustomNode>);
VisualScriptLanguage::singleton->add_register_func("custom/sub_call",create_node_generic<VisualScriptSubCall>);
+ VisualScriptLanguage::singleton->add_register_func("data/comment",create_node_generic<VisualScriptComment>);
+ VisualScriptLanguage::singleton->add_register_func("data/get_local_variable",create_node_generic<VisualScriptLocalVar>);
+ VisualScriptLanguage::singleton->add_register_func("data/set_local_variable",create_node_generic<VisualScriptLocalVarSet>);
+ VisualScriptLanguage::singleton->add_register_func("data/preload",create_node_generic<VisualScriptPreload>);
+ VisualScriptLanguage::singleton->add_register_func("data/action",create_node_generic<VisualScriptInputAction>);
VisualScriptLanguage::singleton->add_register_func("index/get_index",create_node_generic<VisualScriptIndexGet>);
@@ -2481,5 +3491,43 @@ void register_visual_script_nodes() {
VisualScriptLanguage::singleton->add_register_func("operators/logic/not",create_op_node<Variant::OP_NOT>);
VisualScriptLanguage::singleton->add_register_func("operators/logic/in",create_op_node<Variant::OP_IN>);
+ VisualScriptLanguage::singleton->add_register_func("functions/deconstruct",create_node_generic<VisualScriptDeconstruct>);
+
+ for(int i=1;i<Variant::VARIANT_MAX;i++) {
+
+ List<MethodInfo> constructors;
+ Variant::get_constructor_list(Variant::Type(i),&constructors);
+
+ for(List<MethodInfo>::Element *E=constructors.front();E;E=E->next()) {
+
+ if (E->get().arguments.size()>0) {
+
+ String name = "functions/constructors/"+Variant::get_type_name(Variant::Type(i))+" ( ";
+ for(int j=0;j<E->get().arguments.size();j++) {
+ if (j>0)
+ name+=", ";
+ if (E->get().arguments.size()==1)
+ name+=Variant::get_type_name(E->get().arguments[j].type);
+ else
+ name+=E->get().arguments[j].name;
+ }
+ name+=") ";
+
+ VisualScriptLanguage::singleton->add_register_func(name,create_constructor_node);
+ Pair<Variant::Type,MethodInfo> pair;
+ pair.first=Variant::Type(i);
+ pair.second=E->get();
+ constructor_map[name]=pair;
+ }
+ }
+ }
}
+
+
+
+void unregister_visual_script_nodes() {
+
+ constructor_map.clear();
+}
+
diff --git a/modules/visual_script/visual_script_nodes.h b/modules/visual_script/visual_script_nodes.h
index 50f61ecfcc..3016aab866 100644
--- a/modules/visual_script/visual_script_nodes.h
+++ b/modules/visual_script/visual_script_nodes.h
@@ -17,6 +17,7 @@ class VisualScriptFunction : public VisualScriptNode {
bool stack_less;
int stack_size;
+ ScriptInstance::RPCMode rpc_mode;
protected:
@@ -60,6 +61,9 @@ public:
void set_stack_size(int p_size);
int get_stack_size() const;
+ void set_rpc_mode(ScriptInstance::RPCMode p_mode);
+ ScriptInstance::RPCMode get_rpc_mode() const;
+
virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
VisualScriptFunction();
@@ -71,6 +75,7 @@ class VisualScriptOperator : public VisualScriptNode {
OBJ_TYPE(VisualScriptOperator,VisualScriptNode)
+ Variant::Type typed;
Variant::Operator op;
protected:
@@ -98,6 +103,9 @@ public:
void set_operator(Variant::Operator p_op);
Variant::Operator get_operator() const;
+ void set_typed(Variant::Type p_op);
+ Variant::Type get_typed() const;
+
virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
VisualScriptOperator();
@@ -225,6 +233,45 @@ public:
};
+
+class VisualScriptPreload : public VisualScriptNode {
+
+ OBJ_TYPE(VisualScriptPreload,VisualScriptNode)
+
+
+ Ref<Resource> preload;
+protected:
+
+ static void _bind_methods();
+
+public:
+
+ virtual int get_output_sequence_port_count() const;
+ virtual bool has_input_sequence_port() const;
+
+
+ virtual String get_output_sequence_port_text(int p_port) const;
+
+
+ virtual int get_input_value_port_count() const;
+ virtual int get_output_value_port_count() const;
+
+
+ virtual PropertyInfo get_input_value_port_info(int p_idx) const;
+ virtual PropertyInfo get_output_value_port_info(int p_idx) const;
+
+ virtual String get_caption() const;
+ virtual String get_text() const;
+ virtual String get_category() const { return "data"; }
+
+ void set_preload(const Ref<Resource>& p_value);
+ Ref<Resource> get_preload() const;
+
+ virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
+
+ VisualScriptPreload();
+};
+
class VisualScriptIndexGet : public VisualScriptNode {
OBJ_TYPE(VisualScriptIndexGet,VisualScriptNode)
@@ -618,7 +665,6 @@ class VisualScriptSubCall: public VisualScriptNode {
protected:
- virtual bool _use_builtin_script() const { return true; }
static void _bind_methods();
public:
@@ -645,7 +691,275 @@ public:
VisualScriptSubCall();
};
+class VisualScriptComment: public VisualScriptNode {
+
+ OBJ_TYPE(VisualScriptComment,VisualScriptNode)
+
+
+ String title;
+ String description;
+ Size2 size;
+protected:
+
+ static void _bind_methods();
+public:
+ virtual int get_output_sequence_port_count() const;
+ virtual bool has_input_sequence_port() const;
+
+
+ virtual String get_output_sequence_port_text(int p_port) const;
+
+
+ virtual int get_input_value_port_count() const;
+ virtual int get_output_value_port_count() const;
+
+
+ virtual PropertyInfo get_input_value_port_info(int p_idx) const;
+ virtual PropertyInfo get_output_value_port_info(int p_idx) const;
+
+ virtual String get_caption() const;
+ virtual String get_text() const;
+ virtual String get_category() const;
+
+ void set_title(const String& p_title);
+ String get_title() const;
+
+ void set_description(const String& p_description);
+ String get_description() const;
+
+ void set_size(const Size2& p_size);
+ Size2 get_size() const;
+
+ virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
+
+ VisualScriptComment();
+};
+
+class VisualScriptConstructor: public VisualScriptNode {
+
+ OBJ_TYPE(VisualScriptConstructor,VisualScriptNode)
+
+
+ Variant::Type type;
+ MethodInfo constructor;
+
+protected:
+
+
+ static void _bind_methods();
+public:
+ virtual int get_output_sequence_port_count() const;
+ virtual bool has_input_sequence_port() const;
+
+
+ virtual String get_output_sequence_port_text(int p_port) const;
+
+
+ virtual int get_input_value_port_count() const;
+ virtual int get_output_value_port_count() const;
+
+
+ virtual PropertyInfo get_input_value_port_info(int p_idx) const;
+ virtual PropertyInfo get_output_value_port_info(int p_idx) const;
+
+ virtual String get_caption() const;
+ virtual String get_text() const;
+ virtual String get_category() const;
+
+ void set_constructor_type(Variant::Type p_type);
+ Variant::Type get_constructor_type() const;
+
+ void set_constructor(const Dictionary& p_info);
+ Dictionary get_constructor() const;
+
+ virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
+
+ VisualScriptConstructor();
+};
+
+
+
+
+class VisualScriptLocalVar: public VisualScriptNode {
+
+ OBJ_TYPE(VisualScriptLocalVar,VisualScriptNode)
+
+ StringName name;
+ Variant::Type type;
+
+protected:
+
+ static void _bind_methods();
+public:
+ virtual int get_output_sequence_port_count() const;
+ virtual bool has_input_sequence_port() const;
+
+
+ virtual String get_output_sequence_port_text(int p_port) const;
+
+
+ virtual int get_input_value_port_count() const;
+ virtual int get_output_value_port_count() const;
+
+
+ virtual PropertyInfo get_input_value_port_info(int p_idx) const;
+ virtual PropertyInfo get_output_value_port_info(int p_idx) const;
+
+ virtual String get_caption() const;
+ virtual String get_text() const;
+ virtual String get_category() const;
+
+ void set_var_name(const StringName& p_name);
+ StringName get_var_name() const;
+
+ void set_var_type(Variant::Type p_type);
+ Variant::Type get_var_type() const;
+
+ virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
+
+ VisualScriptLocalVar();
+};
+
+class VisualScriptLocalVarSet: public VisualScriptNode {
+
+ OBJ_TYPE(VisualScriptLocalVarSet,VisualScriptNode)
+
+ StringName name;
+ Variant::Type type;
+
+protected:
+
+ static void _bind_methods();
+public:
+ virtual int get_output_sequence_port_count() const;
+ virtual bool has_input_sequence_port() const;
+
+
+ virtual String get_output_sequence_port_text(int p_port) const;
+
+
+ virtual int get_input_value_port_count() const;
+ virtual int get_output_value_port_count() const;
+
+
+ virtual PropertyInfo get_input_value_port_info(int p_idx) const;
+ virtual PropertyInfo get_output_value_port_info(int p_idx) const;
+
+ virtual String get_caption() const;
+ virtual String get_text() const;
+ virtual String get_category() const;
+
+ void set_var_name(const StringName& p_name);
+ StringName get_var_name() const;
+
+ void set_var_type(Variant::Type p_type);
+ Variant::Type get_var_type() const;
+
+ virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
+
+ VisualScriptLocalVarSet();
+};
+
+
+
+class VisualScriptInputAction: public VisualScriptNode {
+
+ OBJ_TYPE(VisualScriptInputAction,VisualScriptNode)
+
+ StringName name;
+
+protected:
+
+ virtual void _validate_property(PropertyInfo& property) const;
+
+ static void _bind_methods();
+public:
+ virtual int get_output_sequence_port_count() const;
+ virtual bool has_input_sequence_port() const;
+
+
+ virtual String get_output_sequence_port_text(int p_port) const;
+
+
+ virtual int get_input_value_port_count() const;
+ virtual int get_output_value_port_count() const;
+
+
+ virtual PropertyInfo get_input_value_port_info(int p_idx) const;
+ virtual PropertyInfo get_output_value_port_info(int p_idx) const;
+
+ virtual String get_caption() const;
+ virtual String get_text() const;
+ virtual String get_category() const;
+
+ void set_action_name(const StringName& p_name);
+ StringName get_action_name() const;
+
+ virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
+
+ VisualScriptInputAction();
+};
+
+
+
+class VisualScriptDeconstruct: public VisualScriptNode {
+
+ OBJ_TYPE(VisualScriptDeconstruct,VisualScriptNode)
+
+
+ struct Element {
+ StringName name;
+ Variant::Type type;
+ };
+
+
+ Vector<Element> elements;
+
+ void _update_elements();
+ Variant::Type type;
+ InputEvent::Type input_type;
+
+ void _set_elem_cache(const Array& p_elements);
+ Array _get_elem_cache() const;
+
+ virtual void _validate_property(PropertyInfo& property) const;
+
+protected:
+
+
+ static void _bind_methods();
+public:
+ virtual int get_output_sequence_port_count() const;
+ virtual bool has_input_sequence_port() const;
+
+
+ virtual String get_output_sequence_port_text(int p_port) const;
+
+
+ virtual int get_input_value_port_count() const;
+ virtual int get_output_value_port_count() const;
+
+
+ virtual PropertyInfo get_input_value_port_info(int p_idx) const;
+ virtual PropertyInfo get_output_value_port_info(int p_idx) const;
+
+ virtual String get_caption() const;
+ virtual String get_text() const;
+ virtual String get_category() const;
+
+ void set_deconstruct_type(Variant::Type p_type);
+ Variant::Type get_deconstruct_type() const;
+
+ void set_deconstruct_input_type(InputEvent::Type p_input_type);
+ InputEvent::Type get_deconstruct_input_type() const;
+
+ virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
+
+ VisualScriptDeconstruct();
+};
+
void register_visual_script_nodes();
+void unregister_visual_script_nodes();
#endif // VISUAL_SCRIPT_NODES_H
diff --git a/modules/visual_script/visual_script_yield_nodes.cpp b/modules/visual_script/visual_script_yield_nodes.cpp
index a6f84a97d9..221c46b6fd 100644
--- a/modules/visual_script/visual_script_yield_nodes.cpp
+++ b/modules/visual_script/visual_script_yield_nodes.cpp
@@ -45,12 +45,13 @@ PropertyInfo VisualScriptYield::get_output_value_port_info(int p_idx) const{
String VisualScriptYield::get_caption() const {
- return "Wait";
+ return yield_mode==YIELD_RETURN?"Yield":"Wait";
}
String VisualScriptYield::get_text() const {
switch (yield_mode) {
+ case YIELD_RETURN: return ""; break;
case YIELD_FRAME: return "Next Frame"; break;
case YIELD_FIXED_FRAME: return "Next Fixed Frame"; break;
case YIELD_WAIT: return rtos(wait_time)+" sec(s)"; break;
@@ -88,8 +89,10 @@ public:
Ref<VisualScriptFunctionState> state;
state.instance();
+ int ret = STEP_YIELD_BIT;
switch(mode) {
+ case VisualScriptYield::YIELD_RETURN: ret=STEP_EXIT_FUNCTION_BIT; break; //return the yield
case VisualScriptYield::YIELD_FRAME: state->connect_to_signal(tree,"idle_frame",Array()); break;
case VisualScriptYield::YIELD_FIXED_FRAME: state->connect_to_signal(tree,"fixed_frame",Array()); break;
case VisualScriptYield::YIELD_WAIT: state->connect_to_signal(tree->create_timer(wait_time).ptr(),"timeout",Array()); break;
@@ -98,7 +101,7 @@ public:
*p_working_mem=state;
- return STEP_YIELD_BIT;
+ return ret;
}
}
@@ -487,7 +490,7 @@ void VisualScriptYieldSignal::_bind_methods() {
bt+=Variant::get_type_name(Variant::Type(i));
}
- ADD_PROPERTY(PropertyInfo(Variant::INT,"signal/call_mode",PROPERTY_HINT_ENUM,"Self,Node Path,Instance",PROPERTY_USAGE_NOEDITOR),_SCS("set_call_mode"),_SCS("get_call_mode"));
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"signal/call_mode",PROPERTY_HINT_ENUM,"Self,Node Path,Instance"),_SCS("set_call_mode"),_SCS("get_call_mode"));
ADD_PROPERTY(PropertyInfo(Variant::STRING,"signal/base_type",PROPERTY_HINT_TYPE_STRING,"Object"),_SCS("set_base_type"),_SCS("get_base_type"));
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH,"signal/node_path",PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE),_SCS("set_base_path"),_SCS("get_base_path"));
ADD_PROPERTY(PropertyInfo(Variant::STRING,"signal/signal"),_SCS("set_signal"),_SCS("get_signal"));
@@ -595,7 +598,7 @@ VisualScriptNodeInstance* VisualScriptYieldSignal::instance(VisualScriptInstance
}
VisualScriptYieldSignal::VisualScriptYieldSignal() {
- call_mode=CALL_MODE_INSTANCE;
+ call_mode=CALL_MODE_SELF;
base_type="Object";
}
@@ -615,8 +618,8 @@ void register_visual_script_yield_nodes() {
VisualScriptLanguage::singleton->add_register_func("functions/wait/wait_fixed_frame",create_yield_node<VisualScriptYield::YIELD_FIXED_FRAME>);
VisualScriptLanguage::singleton->add_register_func("functions/wait/wait_time",create_yield_node<VisualScriptYield::YIELD_WAIT>);
- VisualScriptLanguage::singleton->add_register_func("functions/yield/instance_signal",create_yield_signal_node<VisualScriptYieldSignal::CALL_MODE_INSTANCE>);
- VisualScriptLanguage::singleton->add_register_func("functions/yield/self_signal",create_yield_signal_node<VisualScriptYieldSignal::CALL_MODE_SELF>);
- VisualScriptLanguage::singleton->add_register_func("functions/yield/node_signal",create_yield_signal_node<VisualScriptYieldSignal::CALL_MODE_NODE_PATH>);
+
+ VisualScriptLanguage::singleton->add_register_func("functions/yield",create_yield_node<VisualScriptYield::YIELD_RETURN>);
+ VisualScriptLanguage::singleton->add_register_func("functions/yield_signal",create_node_generic<VisualScriptYieldSignal>);
}
diff --git a/modules/visual_script/visual_script_yield_nodes.h b/modules/visual_script/visual_script_yield_nodes.h
index a7e200305d..ae7f8c15c1 100644
--- a/modules/visual_script/visual_script_yield_nodes.h
+++ b/modules/visual_script/visual_script_yield_nodes.h
@@ -9,6 +9,7 @@ class VisualScriptYield : public VisualScriptNode {
public:
enum YieldMode {
+ YIELD_RETURN,
YIELD_FRAME,
YIELD_FIXED_FRAME,
YIELD_WAIT