-Added yield nodes to visual script

-Added input selection nodes to visual script
-Added script create icon for those who miss it, will only appear when it can be used.
This commit is contained in:
Juan Linietsky 2016-08-07 19:22:33 -03:00
parent 6671c6bdc7
commit b77200728e
20 changed files with 2488 additions and 148 deletions

View file

@ -447,13 +447,17 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) {
} break;
case VARIANT_INPUT_EVENT: {
InputEvent ev;
ev.type=f->get_32(); //will only work for null though.
r_v=ev;
} break;
case VARIANT_DICTIONARY: {
uint32_t len=f->get_32();
Dictionary d(len&0x80000000); //last bit means shared
len&=0x7FFFFFFF;
for(uint32_t i=0;i<len;i++) {
uint32_t len=f->get_32();
Dictionary d(len&0x80000000); //last bit means shared
len&=0x7FFFFFFF;
for(uint32_t i=0;i<len;i++) {
Variant key;
Error err = parse_variant(key);
ERR_FAIL_COND_V(err,ERR_FILE_CORRUPT);
@ -466,11 +470,11 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) {
} break;
case VARIANT_ARRAY: {
uint32_t len=f->get_32();
Array a(len&0x80000000); //last bit means shared
len&=0x7FFFFFFF;
uint32_t len=f->get_32();
Array a(len&0x80000000); //last bit means shared
len&=0x7FFFFFFF;
a.resize(len);
for(uint32_t i=0;i<len;i++) {
for(uint32_t i=0;i<len;i++) {
Variant val;
Error err = parse_variant(val);
ERR_FAIL_COND_V(err,ERR_FILE_CORRUPT);
@ -1725,7 +1729,9 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant& p_property,
case Variant::INPUT_EVENT: {
f->store_32(VARIANT_INPUT_EVENT);
WARN_PRINT("Can't save InputEvent (maybe it could..)");
InputEvent event=p_property;
f->store_32(0); //event type none, nothing else suported for now.
} break;
case Variant::DICTIONARY: {

View file

@ -156,6 +156,7 @@ VARIANT_ENUM_CAST( Orientation );
VARIANT_ENUM_CAST( HAlign );
VARIANT_ENUM_CAST( Variant::Type );
VARIANT_ENUM_CAST( Variant::Operator );
VARIANT_ENUM_CAST( InputEvent::Type );
class MethodBind {

View file

@ -549,6 +549,23 @@ bool ObjectTypeDB::has_signal(StringName p_type,StringName p_signal) {
return false;
}
bool ObjectTypeDB::get_signal(StringName p_type,StringName p_signal,MethodInfo *r_signal) {
TypeInfo *type=types.getptr(p_type);
TypeInfo *check=type;
while(check) {
if (check->signal_map.has(p_signal)) {
if (r_signal) {
*r_signal=check->signal_map[p_signal];
}
return true;
}
check=check->inherits_ptr;
}
return false;
}
void ObjectTypeDB::add_property(StringName p_type,const PropertyInfo& p_pinfo, const StringName& p_setter, const StringName& p_getter, int p_index) {

View file

@ -453,6 +453,7 @@ public:
static void add_signal(StringName p_type,const MethodInfo& p_signal);
static bool has_signal(StringName p_type,StringName p_signal);
static bool get_signal(StringName p_type,StringName p_signal,MethodInfo *r_signal);
static void get_signal_list(StringName p_type,List<MethodInfo> *p_signals,bool p_no_inheritance=false);
static void add_property(StringName p_type,const PropertyInfo& p_pinfo, const StringName& p_setter, const StringName& p_getter, int p_index=-1);

View file

@ -429,6 +429,27 @@ static const _KeyCodeReplace _keycode_replace_neo[]={
{0,0}
};
int keycode_get_count() {
const _KeyCodeText *kct =&_keycodes[0];
int count=0;
while(kct->text) {
count++;
kct++;
}
return count;
}
int keycode_get_value_by_index(int p_index) {
_keycodes[p_index].code;
}
const char* keycode_get_name_by_index(int p_index) {
return _keycodes[p_index].text;
}
int latin_keyboard_keycode_convert(int p_keycode) {

View file

@ -328,6 +328,9 @@ enum KeyModifierMask {
String keycode_get_string(uint32_t p_code);
bool keycode_has_unicode(uint32_t p_unicode);
int find_keycode(const String& p_code);
int keycode_get_count();
int keycode_get_value_by_index(int p_index);
const char* keycode_get_name_by_index(int p_index);
int latin_keyboard_keycode_convert(int p_keycode);
#endif

View file

@ -35,6 +35,7 @@
#include "visual_script_func_nodes.h"
#include "visual_script_builtin_funcs.h"
#include "visual_script_flow_control.h"
#include "visual_script_yield_nodes.h"
VisualScriptLanguage *visual_script_language=NULL;
@ -44,6 +45,7 @@ void register_visual_script_types() {
ObjectTypeDB::register_type<VisualScript>();
ObjectTypeDB::register_virtual_type<VisualScriptNode>();
ObjectTypeDB::register_virtual_type<VisualScriptFunctionState>();
ObjectTypeDB::register_type<VisualScriptFunction>();
ObjectTypeDB::register_type<VisualScriptOperator>();
ObjectTypeDB::register_type<VisualScriptVariableSet>();
@ -70,6 +72,11 @@ void register_visual_script_types() {
ObjectTypeDB::register_type<VisualScriptWhile>();
ObjectTypeDB::register_type<VisualScriptIterator>();
ObjectTypeDB::register_type<VisualScriptSequence>();
ObjectTypeDB::register_type<VisualScriptInputFilter>();
ObjectTypeDB::register_type<VisualScriptInputSelector>();
ObjectTypeDB::register_type<VisualScriptYield>();
ObjectTypeDB::register_type<VisualScriptYieldSignal>();
ObjectTypeDB::register_type<VisualScriptBuiltinFunc>();
@ -81,6 +88,7 @@ void register_visual_script_types() {
register_visual_script_func_nodes();
register_visual_script_builtin_func_node();
register_visual_script_flow_control_nodes();
register_visual_script_yield_nodes();
#ifdef TOOLS_ENABLED
VisualScriptEditor::register_editor();

View file

@ -279,7 +279,9 @@ void VisualScript::_node_ports_changed(int p_id) {
}
}
set_edited(true); //something changed, let's set as edited
emit_signal("node_ports_changed",function,p_id);
}
void VisualScript::add_node(const StringName& p_func,int p_id, const Ref<VisualScriptNode>& p_node, const Point2 &p_pos) {
@ -1354,95 +1356,30 @@ bool VisualScriptInstance::has_method(const StringName& p_method) const{
//#define VSDEBUG(m_text) print_line(m_text)
#define VSDEBUG(m_text)
Variant VisualScriptInstance::call(const StringName& p_method,const Variant** p_args,int p_argcount,Variant::CallError &r_error){
r_error.error=Variant::CallError::CALL_OK; //ok by default
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) {
Map<StringName,Function>::Element *F = functions.find(p_method);
if (!F) {
r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
return Variant();
}
VSDEBUG("CALLING: "+String(p_method));
ERR_FAIL_COND_V(!F,Variant());
Function *f=&F->get();
int total_stack_size=0;
total_stack_size+=f->max_stack*sizeof(Variant); //variants
total_stack_size+=f->node_count*sizeof(bool);
total_stack_size+=(max_input_args+max_output_args)*sizeof(Variant*); //arguments
total_stack_size+=f->flow_stack_size*sizeof(int); //flow
VSDEBUG("STACK SIZE: "+itos(total_stack_size));
VSDEBUG("STACK VARIANTS: : "+itos(f->max_stack));
VSDEBUG("SEQBITS: : "+itos(f->node_count));
VSDEBUG("MAX INPUT: "+itos(max_input_args));
VSDEBUG("MAX OUTPUT: "+itos(max_output_args));
VSDEBUG("FLOW STACK SIZE: "+itos(f->flow_stack_size));
void *stack = alloca(total_stack_size);
Variant *variant_stack=(Variant*)stack;
//this call goes separate, so it can e yielded and suspended
Variant *variant_stack=(Variant*)p_stack;
bool *sequence_bits = (bool*)(variant_stack + f->max_stack);
const Variant **input_args=(const Variant**)(sequence_bits+f->node_count);
Variant **output_args=(Variant**)(input_args + max_input_args);
int flow_max = f->flow_stack_size;
int* flow_stack = flow_max? (int*)(output_args + max_output_args) : (int*)NULL;
for(int i=0;i<f->node_count;i++) {
sequence_bits[i]=false; //all starts as false
}
Map<int,VisualScriptNodeInstance*>::Element *E = instances.find(f->node);
if (!E) {
r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
ERR_EXPLAIN("No VisualScriptFunction node in function!");
ERR_FAIL_V(Variant());
}
VisualScriptNodeInstance *node = E->get();
int flow_stack_pos=0;
if (flow_stack) {
flow_stack[0]=node->get_id();
}
VSDEBUG("ARGUMENTS: "+itos(f->argument_count)=" RECEIVED: "+itos(p_argcount));
if (p_argcount<f->argument_count) {
r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument=node->get_input_port_count();
return Variant();
}
if (p_argcount>f->argument_count) {
r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
r_error.argument=node->get_input_port_count();
return Variant();
}
//allocate variant stack
for(int i=0;i<f->max_stack;i++) {
memnew_placement(&variant_stack[i],Variant);
}
//allocate function arguments (must be copied for yield to work properly)
for(int i=0;i<p_argcount;i++) {
variant_stack[i]=*p_args[i];
}
String error_str;
VisualScriptNodeInstance* node=p_node;
bool error=false;
int current_node_id=f->node;
Variant return_value;
Variant *working_mem=NULL;
int flow_stack_pos=p_flow_stack_pos;
#ifdef DEBUG_ENABLED
if (ScriptDebugger::get_singleton()) {
VisualScriptLanguage::singleton->enter_function(this,&p_method,variant_stack,&working_mem,&current_node_id);
@ -1518,12 +1455,19 @@ Variant VisualScriptInstance::call(const StringName& p_method,const Variant** p_
//do step
bool start_sequence = 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
VisualScriptNodeInstance::StartMode start_mode;
{
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
start_mode=VisualScriptNodeInstance::START_MODE_BEGIN_SEQUENCE;
else
start_mode=VisualScriptNodeInstance::START_MODE_CONTINUE_SEQUENCE;
}
VSDEBUG("STEP - STARTSEQ: "+itos(start_sequence));
int ret = node->step(input_args,output_args,start_sequence,working_mem,r_error,error_str);
int ret = node->step(input_args,output_args,start_mode,working_mem,r_error,error_str);
if (r_error.error!=Variant::CallError::CALL_OK) {
//use error from step
@ -1531,6 +1475,52 @@ Variant VisualScriptInstance::call(const StringName& p_method,const Variant** p_
break;
}
if (ret&VisualScriptNodeInstance::STEP_YIELD_BIT) {
//yielded!
if (node->get_working_memory_size()==0) {
r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
error_str=RTR("A node yielded without working memory, please read the docs on how to yield properly!");
error=true;
break;
} else {
Ref<VisualScriptFunctionState> state = *working_mem;
if (!state.is_valid()) {
r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
error_str=RTR("Node yielded, but did not return a function state in the first working memory.");
error=true;
break;
}
//step 1, capture all state
state->instance_id=get_owner_ptr()->get_instance_ID();
state->script_id=get_script()->get_instance_ID();
state->instance=this;
state->function=p_method;
state->working_mem_index=node->working_mem_idx;
state->variant_stack_size=f->max_stack;
state->node=node;
state->flow_stack_pos=flow_stack_pos;
state->stack.resize(p_stack_size);
copymem(state->stack.ptr(),p_stack,p_stack_size);
//step 2, run away, return directly
r_error.error=Variant::CallError::CALL_OK;
#ifdef DEBUG_ENABLED
//will re-enter later, so exiting
if (ScriptDebugger::get_singleton()) {
VisualScriptLanguage::singleton->exit_function();
}
#endif
return state;
}
}
#ifdef DEBUG_ENABLED
if (ScriptDebugger::get_singleton()) {
// line
@ -1586,10 +1576,11 @@ Variant VisualScriptInstance::call(const StringName& p_method,const Variant** p_
}
next = node->sequence_outputs[output];
if (next)
if (next) {
VSDEBUG("GOT NEXT NODE - "+itos(next->get_id()));
else
} else {
VSDEBUG("GOT NEXT NODE - NULL");
}
}
if (flow_stack) {
@ -1742,6 +1733,95 @@ Variant VisualScriptInstance::call(const StringName& p_method,const Variant** p_
return return_value;
}
Variant VisualScriptInstance::call(const StringName& p_method,const Variant** p_args,int p_argcount,Variant::CallError &r_error){
r_error.error=Variant::CallError::CALL_OK; //ok by default
Map<StringName,Function>::Element *F = functions.find(p_method);
if (!F) {
r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
return Variant();
}
VSDEBUG("CALLING: "+String(p_method));
Function *f=&F->get();
int total_stack_size=0;
total_stack_size+=f->max_stack*sizeof(Variant); //variants
total_stack_size+=f->node_count*sizeof(bool);
total_stack_size+=(max_input_args+max_output_args)*sizeof(Variant*); //arguments
total_stack_size+=f->flow_stack_size*sizeof(int); //flow
VSDEBUG("STACK SIZE: "+itos(total_stack_size));
VSDEBUG("STACK VARIANTS: : "+itos(f->max_stack));
VSDEBUG("SEQBITS: : "+itos(f->node_count));
VSDEBUG("MAX INPUT: "+itos(max_input_args));
VSDEBUG("MAX OUTPUT: "+itos(max_output_args));
VSDEBUG("FLOW STACK SIZE: "+itos(f->flow_stack_size));
void *stack = alloca(total_stack_size);
Variant *variant_stack=(Variant*)stack;
bool *sequence_bits = (bool*)(variant_stack + f->max_stack);
const Variant **input_args=(const Variant**)(sequence_bits+f->node_count);
Variant **output_args=(Variant**)(input_args + max_input_args);
int flow_max = f->flow_stack_size;
int* flow_stack = flow_max? (int*)(output_args + max_output_args) : (int*)NULL;
for(int i=0;i<f->node_count;i++) {
sequence_bits[i]=false; //all starts as false
}
Map<int,VisualScriptNodeInstance*>::Element *E = instances.find(f->node);
if (!E) {
r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
ERR_EXPLAIN("No VisualScriptFunction node in function!");
ERR_FAIL_V(Variant());
}
VisualScriptNodeInstance *node = E->get();
if (flow_stack) {
flow_stack[0]=node->get_id();
}
VSDEBUG("ARGUMENTS: "+itos(f->argument_count)=" RECEIVED: "+itos(p_argcount));
if (p_argcount<f->argument_count) {
r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument=node->get_input_port_count();
return Variant();
}
if (p_argcount>f->argument_count) {
r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
r_error.argument=node->get_input_port_count();
return Variant();
}
//allocate variant stack
for(int i=0;i<f->max_stack;i++) {
memnew_placement(&variant_stack[i],Variant);
}
//allocate function arguments (must be copied for yield to work properly)
for(int i=0;i<p_argcount;i++) {
variant_stack[i]=*p_args[i];
}
return _call_internal(p_method,stack,total_stack_size,node,0,false,r_error);
}
void VisualScriptInstance::notification(int p_notification){
//do nothing as this is called using virtual
@ -1977,8 +2057,130 @@ VisualScriptInstance::~VisualScriptInstance() {
/////////////////////////////////////////////
/////////////////////
Variant VisualScriptFunctionState::_signal_callback(const Variant** p_args, int p_argcount, Variant::CallError& r_error) {
ERR_FAIL_COND_V(function==StringName(),Variant());
#ifdef DEBUG_ENABLED
if (instance_id && !ObjectDB::get_instance(instance_id)) {
ERR_EXPLAIN("Resumed after yield, but class instance is gone");
ERR_FAIL_V(Variant());
}
if (script_id && !ObjectDB::get_instance(script_id)) {
ERR_EXPLAIN("Resumed after yield, but script is gone");
ERR_FAIL_V(Variant());
}
#endif
r_error.error=Variant::CallError::CALL_OK;
Array args;
if (p_argcount==0) {
r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument=1;
return Variant();
} else if (p_argcount==1) {
//noooneee, reserved for me, me and only me.
} else {
for(int i=0;i<p_argcount-1;i++) {
args.push_back(*p_args[i]);
}
}
Ref<VisualScriptFunctionState> self = *p_args[p_argcount-1]; //hi, I'm myself, needed this to remain alive.
if (self.is_null()) {
r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=p_argcount-1;
r_error.expected=Variant::OBJECT;
return Variant();
}
r_error.error=Variant::CallError::CALL_OK;
Variant *working_mem = ((Variant*)stack.ptr()) + working_mem_index;
*working_mem=args; //arguments go to working mem.
Variant ret = instance->_call_internal(function,stack.ptr(),stack.size(),node,flow_stack_pos,true,r_error);
function=StringName(); //invalidate
return ret;
}
void VisualScriptFunctionState::connect_to_signal(Object* p_obj, const String& p_signal, Array p_binds) {
Vector<Variant> binds;
for(int i=0;i<p_binds.size();i++) {
binds.push_back(p_binds[i]);
}
binds.push_back(Ref<VisualScriptFunctionState>(this)); //add myself on the back to avoid dying from unreferencing
p_obj->connect(p_signal,this,"_signal_callback",binds);
}
bool VisualScriptFunctionState::is_valid() const {
return function!=StringName();
}
Variant VisualScriptFunctionState::resume(Array p_args) {
ERR_FAIL_COND_V(function==StringName(),Variant());
#ifdef DEBUG_ENABLED
if (instance_id && !ObjectDB::get_instance(instance_id)) {
ERR_EXPLAIN("Resumed after yield, but class instance is gone");
ERR_FAIL_V(Variant());
}
if (script_id && !ObjectDB::get_instance(script_id)) {
ERR_EXPLAIN("Resumed after yield, but script is gone");
ERR_FAIL_V(Variant());
}
#endif
Variant::CallError r_error;
r_error.error=Variant::CallError::CALL_OK;
Variant *working_mem = ((Variant*)stack.ptr()) + working_mem_index;
*working_mem=p_args; //arguments go to working mem.
Variant ret= instance->_call_internal(function,stack.ptr(),stack.size(),node,flow_stack_pos,true,r_error);
function=StringName(); //invalidate
return ret;
}
void VisualScriptFunctionState::_bind_methods() {
ObjectTypeDB::bind_method(_MD("connect_to_signal","obj","signals","args"),&VisualScriptFunctionState::connect_to_signal);
ObjectTypeDB::bind_method(_MD("resume:Array","args"),&VisualScriptFunctionState::resume,DEFVAL(Variant()));
ObjectTypeDB::bind_method(_MD("is_valid"),&VisualScriptFunctionState::is_valid);
ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"_signal_callback",&VisualScriptFunctionState::_signal_callback,MethodInfo("_signal_callback"));
}
VisualScriptFunctionState::VisualScriptFunctionState() {
}
VisualScriptFunctionState::~VisualScriptFunctionState() {
if (function!=StringName()) {
Variant *s = ((Variant*)stack.ptr());
for(int i=0;i<variant_stack_size;i++) {
s[i].~Variant();
}
}
}

View file

@ -85,12 +85,20 @@ friend class VisualScriptLanguage; //for debugger
public:
enum StartMode {
START_MODE_BEGIN_SEQUENCE,
START_MODE_CONTINUE_SEQUENCE,
START_MODE_RESUME_YIELD
};
enum {
STEP_SHIFT=1<<24,
STEP_MASK=STEP_SHIFT-1,
STEP_FLAG_PUSH_STACK_BIT=STEP_SHIFT, //push bit to stack
STEP_FLAG_GO_BACK_BIT=STEP_SHIFT<<1, //go back to previous node
STEP_EXIT_FUNCTION_BIT=STEP_SHIFT<<2, //return from function
STEP_NO_ADVANCE_BIT=STEP_SHIFT<<2, //do not advance past this node
STEP_EXIT_FUNCTION_BIT=STEP_SHIFT<<3, //return from function
STEP_YIELD_BIT=STEP_SHIFT<<4, //yield (will find VisualScriptFunctionState state in first working memory)
FLOW_STACK_PUSHED_BIT=1<<30, //in flow stack, means bit was pushed (must go back here if end of sequence)
FLOW_STACK_MASK=FLOW_STACK_PUSHED_BIT-1
@ -109,7 +117,7 @@ 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; }
virtual int step(const Variant** p_inputs,Variant** p_outputs,bool p_start_sequence,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str)=0; //do a step, return which sequence port to go out
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 ); }
@ -352,7 +360,11 @@ 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);
//Map<StringName,Function> functions;
friend class VisualScriptFunctionState; //for yield
friend class VisualScriptLanguage; //for debugger
public:
virtual bool set(const StringName& p_name, const Variant& p_value);
@ -400,6 +412,33 @@ public:
};
class VisualScriptFunctionState : public Reference {
OBJ_TYPE(VisualScriptFunctionState,Reference);
friend class VisualScriptInstance;
ObjectID instance_id;
ObjectID script_id;
VisualScriptInstance *instance;
StringName function;
Vector<uint8_t> stack;
int working_mem_index;
int variant_stack_size;
VisualScriptNodeInstance *node;
int flow_stack_pos;
Variant _signal_callback(const Variant** p_args, int p_argcount, Variant::CallError& r_error);
protected:
static void _bind_methods();
public:
void connect_to_signal(Object* p_obj,const String& p_signal,Array p_binds);
bool is_valid() const;
Variant resume(Array p_args);
VisualScriptFunctionState();
~VisualScriptFunctionState();
};
typedef Ref<VisualScriptNode> (*VisualScriptNodeRegisterFunc)(const String& p_type);

View file

@ -565,7 +565,7 @@ 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; }
virtual int step(const Variant** p_inputs,Variant** p_outputs,bool p_start_sequence,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
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(func) {
case VisualScriptBuiltinFunc::MATH_SIN: {

File diff suppressed because it is too large Load diff

View file

@ -194,6 +194,85 @@ public:
VisualScriptSequence();
};
class VisualScriptInputSelector : public VisualScriptNode {
OBJ_TYPE(VisualScriptInputSelector,VisualScriptNode)
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"; }
virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
VisualScriptInputSelector();
};
class VisualScriptInputFilter : public VisualScriptNode {
OBJ_TYPE(VisualScriptInputFilter,VisualScriptNode)
Vector<InputEvent> filters;
protected:
bool _set(const StringName& p_name, const Variant& p_value);
bool _get(const StringName& p_name,Variant &r_ret) const;
void _get_property_list( List<PropertyInfo> *p_list) const;
public:
virtual int get_output_sequence_port_count() const;
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"; }
virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
VisualScriptInputFilter();
};
void register_visual_script_flow_control_nodes();

View file

@ -504,7 +504,7 @@ 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; }
virtual int step(const Variant** p_inputs,Variant** p_outputs,bool p_start_sequence,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
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) {
@ -546,7 +546,7 @@ public:
case VisualScriptFunctionCall::CALL_MODE_BASIC_TYPE: {
Variant v = *p_inputs[0];
print_line("inputs: "+String(v));
if (returns) {
*p_outputs[0] = v.call(function,p_inputs+1,input_args,r_error);
} else {
@ -598,6 +598,19 @@ static Ref<VisualScriptNode> create_function_call_node(const String& p_name) {
////////////////SET//////////////////////
//////////////////////////////////////////
static const char* event_type_names[InputEvent::TYPE_MAX]={
"None",
"Key",
"MouseMotion",
"MouseButton",
"JoystickMotion",
"JoystickButton",
"ScreenTouch",
"ScreenDrag",
"Action"
};
int VisualScriptPropertySet::get_output_sequence_port_count() const {
return 1;
@ -671,7 +684,7 @@ int VisualScriptPropertySet::get_input_value_port_count() const{
}
int VisualScriptPropertySet::get_output_value_port_count() const{
return 0;
return call_mode==CALL_MODE_BASIC_TYPE? 1 : 0;
}
String VisualScriptPropertySet::get_output_sequence_port_text(int p_port) const {
@ -702,9 +715,17 @@ PropertyInfo VisualScriptPropertySet::get_input_value_port_info(int p_idx) const
if (call_mode==CALL_MODE_BASIC_TYPE) {
Variant::CallError ce;
Variant v = Variant::construct(basic_type,NULL,0,ce);
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();
@ -736,8 +757,11 @@ PropertyInfo VisualScriptPropertySet::get_input_value_port_info(int p_idx) const
}
PropertyInfo VisualScriptPropertySet::get_output_value_port_info(int p_idx) const{
return PropertyInfo();
if (call_mode==CALL_MODE_BASIC_TYPE) {
return PropertyInfo(basic_type,"out");
} else {
return PropertyInfo();
}
}
@ -810,6 +834,21 @@ Variant::Type VisualScriptPropertySet::get_basic_type() const{
return basic_type;
}
void VisualScriptPropertySet::set_event_type(InputEvent::Type p_type) {
if (event_type==p_type)
return;
event_type=p_type;
_change_notify();
_update_base_type();
ports_changed_notify();
}
InputEvent::Type VisualScriptPropertySet::get_event_type() const{
return event_type;
}
void VisualScriptPropertySet::set_base_type(const StringName& p_type) {
@ -918,6 +957,12 @@ void VisualScriptPropertySet::_validate_property(PropertyInfo& property) const {
}
}
if (property.name=="property/event_type") {
if (call_mode!=CALL_MODE_BASIC_TYPE || basic_type!=Variant::INPUT_EVENT) {
property.usage=0;
}
}
if (property.name=="property/node_path") {
if (call_mode!=CALL_MODE_NODE_PATH) {
property.usage=0;
@ -941,7 +986,14 @@ void VisualScriptPropertySet::_validate_property(PropertyInfo& property) const {
if (call_mode==CALL_MODE_BASIC_TYPE) {
Variant::CallError ce;
Variant v = Variant::construct(basic_type,NULL,0,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) {
@ -1030,6 +1082,8 @@ void VisualScriptPropertySet::_bind_methods() {
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_event_type","event_type"),&VisualScriptPropertySet::set_event_type);
ObjectTypeDB::bind_method(_MD("get_event_type"),&VisualScriptPropertySet::get_event_type);
ObjectTypeDB::bind_method(_MD("set_property","property"),&VisualScriptPropertySet::set_property);
ObjectTypeDB::bind_method(_MD("get_property"),&VisualScriptPropertySet::get_property);
@ -1054,9 +1108,19 @@ void VisualScriptPropertySet::_bind_methods() {
bt+=Variant::get_type_name(Variant::Type(i));
}
String et;
for(int i=0;i<InputEvent::TYPE_MAX;i++) {
if (i>0)
et+=",";
et+=event_type_names[i];
}
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::STRING,"property/base_type",PROPERTY_HINT_TYPE_STRING,"Object"),_SCS("set_base_type"),_SCS("get_base_type"));
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"));
@ -1087,7 +1151,7 @@ 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; }
virtual int step(const Variant** p_inputs,Variant** p_outputs,bool p_start_sequence,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
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) {
@ -1157,6 +1221,10 @@ public:
r_error_str="Invalid index property name.";
}
if (call_mode==VisualScriptPropertySet::CALL_MODE_BASIC_TYPE) {
*p_outputs[0]=v;
}
} break;
}
@ -1185,6 +1253,7 @@ VisualScriptPropertySet::VisualScriptPropertySet() {
call_mode=CALL_MODE_INSTANCE;
base_type="Object";
basic_type=Variant::NIL;
event_type=InputEvent::NONE;
}
@ -1324,8 +1393,15 @@ PropertyInfo VisualScriptPropertyGet::get_output_value_port_info(int p_idx) cons
if (call_mode==CALL_MODE_BASIC_TYPE) {
Variant::CallError ce;
Variant v = Variant::construct(basic_type,NULL,0,ce);
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) {
@ -1460,6 +1536,21 @@ Variant::Type VisualScriptPropertyGet::get_basic_type() const{
}
void VisualScriptPropertyGet::set_event_type(InputEvent::Type p_type) {
if (event_type==p_type)
return;
event_type=p_type;
_change_notify();
_update_base_type();
ports_changed_notify();
}
InputEvent::Type VisualScriptPropertyGet::get_event_type() const{
return event_type;
}
void VisualScriptPropertyGet::_validate_property(PropertyInfo& property) const {
if (property.name=="property/base_type") {
@ -1474,6 +1565,11 @@ void VisualScriptPropertyGet::_validate_property(PropertyInfo& property) const {
property.usage=0;
}
}
if (property.name=="property/event_type") {
if (call_mode!=CALL_MODE_BASIC_TYPE || basic_type!=Variant::INPUT_EVENT) {
property.usage=0;
}
}
if (property.name=="property/node_path") {
if (call_mode!=CALL_MODE_NODE_PATH) {
@ -1497,7 +1593,14 @@ void VisualScriptPropertyGet::_validate_property(PropertyInfo& property) const {
if (call_mode==CALL_MODE_BASIC_TYPE) {
Variant::CallError ce;
Variant v = Variant::construct(basic_type,NULL,0,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) {
@ -1547,6 +1650,9 @@ void VisualScriptPropertyGet::_bind_methods() {
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_event_type","event_type"),&VisualScriptPropertyGet::set_event_type);
ObjectTypeDB::bind_method(_MD("get_event_type"),&VisualScriptPropertyGet::get_event_type);
ObjectTypeDB::bind_method(_MD("set_property","property"),&VisualScriptPropertyGet::set_property);
ObjectTypeDB::bind_method(_MD("get_property"),&VisualScriptPropertyGet::get_property);
@ -1565,10 +1671,19 @@ void VisualScriptPropertyGet::_bind_methods() {
bt+=Variant::get_type_name(Variant::Type(i));
}
String et;
for(int i=0;i<InputEvent::TYPE_MAX;i++) {
if (i>0)
et+=",";
et+=event_type_names[i];
}
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"));
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::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"));
@ -1645,7 +1760,7 @@ public:
}
virtual int step(const Variant** p_inputs,Variant** p_outputs,bool p_start_sequence,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
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) {
bool valid;
@ -1685,6 +1800,7 @@ VisualScriptPropertyGet::VisualScriptPropertyGet() {
call_mode=CALL_MODE_INSTANCE;
base_type="Object";
basic_type=Variant::NIL;
event_type=InputEvent::NONE;
}
@ -2084,7 +2200,7 @@ 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; }
virtual int step(const Variant** p_inputs,Variant** p_outputs,bool p_start_sequence,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
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) {
@ -2297,7 +2413,7 @@ 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; }
virtual int step(const Variant** p_inputs,Variant** p_outputs,bool p_start_sequence,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
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 = instance->get_owner_ptr();
@ -2359,24 +2475,24 @@ 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/instance_call",create_function_call_node<VisualScriptFunctionCall::CALL_MODE_INSTANCE>);
VisualScriptLanguage::singleton->add_register_func("functions/call_method/basic_type_call",create_function_call_node<VisualScriptFunctionCall::CALL_MODE_BASIC_TYPE>);
VisualScriptLanguage::singleton->add_register_func("functions/call_method/self_call",create_function_call_node<VisualScriptFunctionCall::CALL_MODE_SELF>);
VisualScriptLanguage::singleton->add_register_func("functions/call_method/node_call",create_function_call_node<VisualScriptFunctionCall::CALL_MODE_NODE_PATH>);
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/set_property/instace_set",create_property_set_node<VisualScriptPropertySet::CALL_MODE_INSTANCE>);
VisualScriptLanguage::singleton->add_register_func("functions/set_property/basic_type_set",create_property_set_node<VisualScriptPropertySet::CALL_MODE_BASIC_TYPE>);
VisualScriptLanguage::singleton->add_register_func("functions/set_property/self_set",create_property_set_node<VisualScriptPropertySet::CALL_MODE_SELF>);
VisualScriptLanguage::singleton->add_register_func("functions/set_property/node_set",create_property_set_node<VisualScriptPropertySet::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/get_property/instance_get",create_property_get_node<VisualScriptPropertyGet::CALL_MODE_INSTANCE>);
VisualScriptLanguage::singleton->add_register_func("functions/get_property/basic_type_get",create_property_get_node<VisualScriptPropertyGet::CALL_MODE_BASIC_TYPE>);
VisualScriptLanguage::singleton->add_register_func("functions/get_property/self_get",create_property_get_node<VisualScriptPropertyGet::CALL_MODE_SELF>);
VisualScriptLanguage::singleton->add_register_func("functions/get_property/node_get",create_property_get_node<VisualScriptPropertyGet::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/script/script_call",create_script_call_node<VisualScriptScriptCall::CALL_MODE_SELF>);
VisualScriptLanguage::singleton->add_register_func("functions/script/script_call_in_node",create_script_call_node<VisualScriptScriptCall::CALL_MODE_NODE_PATH>);
VisualScriptLanguage::singleton->add_register_func("functions/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/call_script/emit_signal",create_node_generic<VisualScriptEmitSignal>);
for(int i=0;i<Variant::VARIANT_MAX;i++) {
@ -2389,7 +2505,7 @@ void register_visual_script_func_nodes() {
vt.get_method_list(&ml);
for (List<MethodInfo>::Element *E=ml.front();E;E=E->next()) {
VisualScriptLanguage::singleton->add_register_func("functions/basic_types/"+type_name+"/"+E->get().name,create_basic_type_call_node);
VisualScriptLanguage::singleton->add_register_func("functions/by_type/"+type_name+"/"+E->get().name,create_basic_type_call_node);
}
}
}

View file

@ -93,12 +93,13 @@ public:
private:
CallMode call_mode;
Variant::Type basic_type;
Variant::Type basic_type;
StringName base_type;
NodePath base_path;
StringName property;
bool use_builtin_value;
Variant builtin_value;
InputEvent::Type event_type;
Node *_get_base_node() const;
StringName _get_base_type() const;
@ -136,6 +137,9 @@ public:
void set_basic_type(Variant::Type p_type);
Variant::Type get_basic_type() const;
void set_event_type(InputEvent::Type p_type);
InputEvent::Type get_event_type() const;
void set_property(const StringName& p_type);
StringName get_property() const;
@ -177,6 +181,7 @@ private:
StringName base_type;
NodePath base_path;
StringName property;
InputEvent::Type event_type;
void _update_base_type();
Node *_get_base_node() const;
@ -214,6 +219,9 @@ public:
void set_basic_type(Variant::Type p_type);
Variant::Type get_basic_type() const;
void set_event_type(InputEvent::Type p_type);
InputEvent::Type get_event_type() const;
void set_property(const StringName& p_type);
StringName get_property() const;

View file

@ -234,7 +234,7 @@ 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; }
virtual int step(const Variant** p_inputs,Variant** p_outputs,bool p_start_sequence,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
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) {
int ac = node->get_argument_count();
@ -518,7 +518,7 @@ 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; }
virtual int step(const Variant** p_inputs,Variant** p_outputs,bool p_start_sequence,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
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) {
bool valid;
if (unary) {
@ -691,7 +691,7 @@ public:
}
}
virtual int step(const Variant** p_inputs,Variant** p_outputs,bool p_start_sequence,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
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;
}
@ -825,7 +825,7 @@ 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 false; }
virtual int step(const Variant** p_inputs,Variant** p_outputs,bool p_start_sequence,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
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 ;
@ -980,7 +980,7 @@ public:
}
virtual int step(const Variant** p_inputs,Variant** p_outputs,bool p_start_sequence,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
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;
}
@ -1066,7 +1066,7 @@ public:
//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,bool p_start_sequence,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
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) {
bool valid;
*p_outputs[0] = p_inputs[0]->get(*p_inputs[1],&valid);
@ -1158,7 +1158,7 @@ public:
//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,bool p_start_sequence,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
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) {
bool valid;
*p_outputs[0]=*p_inputs[0];
@ -1260,7 +1260,7 @@ public:
}
virtual int step(const Variant** p_inputs,Variant** p_outputs,bool p_start_sequence,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
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;
@ -1392,7 +1392,7 @@ public:
}
virtual int step(const Variant** p_inputs,Variant** p_outputs,bool p_start_sequence,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
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;
@ -1508,7 +1508,7 @@ public:
return true;
}
virtual int step(const Variant** p_inputs,Variant** p_outputs,bool p_start_sequence,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
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;
@ -1644,7 +1644,7 @@ public:
return true;
}
virtual int step(const Variant** p_inputs,Variant** p_outputs,bool p_start_sequence,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
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;
}
@ -1809,7 +1809,7 @@ public:
}
virtual int step(const Variant** p_inputs,Variant** p_outputs,bool p_start_sequence,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
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;
@ -1913,7 +1913,7 @@ public:
return true;
}
virtual int step(const Variant** p_inputs,Variant** p_outputs,bool p_start_sequence,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
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;
}
@ -1946,7 +1946,7 @@ VisualScriptResourcePath::VisualScriptResourcePath() {
//////////////////////////////////////////
////////////////RESPATH///////////
////////////////SELF///////////
//////////////////////////////////////////
int VisualScriptSelf::get_output_sequence_port_count() const {
@ -2011,7 +2011,7 @@ public:
return true;
}
virtual int step(const Variant** p_inputs,Variant** p_outputs,bool p_start_sequence,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
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;
}

View file

@ -552,8 +552,6 @@ public:
virtual String get_text() const;
virtual String get_category() const { return "data"; }
void set_resource_path(const String &p_path);
String get_resource_path();
virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
@ -561,6 +559,7 @@ public:
};
void register_visual_script_nodes();
#endif // VISUAL_SCRIPT_NODES_H

View file

@ -0,0 +1,622 @@
#include "visual_script_yield_nodes.h"
#include "scene/main/scene_main_loop.h"
#include "os/os.h"
#include "scene/main/node.h"
#include "visual_script_nodes.h"
//////////////////////////////////////////
////////////////YIELD///////////
//////////////////////////////////////////
int VisualScriptYield::get_output_sequence_port_count() const {
return 1;
}
bool VisualScriptYield::has_input_sequence_port() const{
return true;
}
int VisualScriptYield::get_input_value_port_count() const{
return 0;
}
int VisualScriptYield::get_output_value_port_count() const{
return 0;
}
String VisualScriptYield::get_output_sequence_port_text(int p_port) const {
return String();
}
PropertyInfo VisualScriptYield::get_input_value_port_info(int p_idx) const{
return PropertyInfo();
}
PropertyInfo VisualScriptYield::get_output_value_port_info(int p_idx) const{
return PropertyInfo();
}
String VisualScriptYield::get_caption() const {
return "Wait";
}
String VisualScriptYield::get_text() const {
switch (yield_mode) {
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;
}
return String();
}
class VisualScriptNodeInstanceYield : public VisualScriptNodeInstance {
public:
VisualScriptYield::YieldMode mode;
float wait_time;
virtual int get_working_memory_size() const { return 1; } //yield needs at least 1
//virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return false; }
virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
if (p_start_mode==START_MODE_RESUME_YIELD) {
return 0; //resuming yield
} else {
//yield
SceneTree *tree = OS::get_singleton()->get_main_loop()->cast_to<SceneTree>();
if (!tree) {
r_error_str="Main Loop is not SceneTree";
r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
return 0;
}
Ref<VisualScriptFunctionState> state;
state.instance();
switch(mode) {
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;
}
*p_working_mem=state;
return STEP_YIELD_BIT;
}
}
};
VisualScriptNodeInstance* VisualScriptYield::instance(VisualScriptInstance* p_instance) {
VisualScriptNodeInstanceYield * instance = memnew(VisualScriptNodeInstanceYield );
//instance->instance=p_instance;
instance->mode=yield_mode;
instance->wait_time=wait_time;
return instance;
}
void VisualScriptYield::set_yield_mode(YieldMode p_mode) {
if (yield_mode==p_mode)
return;
yield_mode=p_mode;
ports_changed_notify();
_change_notify();
}
VisualScriptYield::YieldMode VisualScriptYield::get_yield_mode(){
return yield_mode;
}
void VisualScriptYield::set_wait_time(float p_time) {
if (wait_time==p_time)
return;
wait_time=p_time;
ports_changed_notify();
}
float VisualScriptYield::get_wait_time(){
return wait_time;
}
void VisualScriptYield::_validate_property(PropertyInfo& property) const {
if (property.name=="wait_time") {
if (yield_mode!=YIELD_WAIT) {
property.usage=0;
}
}
}
void VisualScriptYield::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_yield_mode","mode"),&VisualScriptYield::set_yield_mode);
ObjectTypeDB::bind_method(_MD("get_yield_mode"),&VisualScriptYield::get_yield_mode);
ObjectTypeDB::bind_method(_MD("set_wait_time","sec"),&VisualScriptYield::set_wait_time);
ObjectTypeDB::bind_method(_MD("get_wait_time"),&VisualScriptYield::get_wait_time);
ADD_PROPERTY(PropertyInfo(Variant::INT,"mode",PROPERTY_HINT_ENUM,"Frame,FixedFrame,Time",PROPERTY_USAGE_NOEDITOR),_SCS("set_yield_mode"),_SCS("get_yield_mode"));
ADD_PROPERTY(PropertyInfo(Variant::REAL,"wait_time"),_SCS("set_wait_time"),_SCS("get_wait_time"));
BIND_CONSTANT( YIELD_FRAME );
BIND_CONSTANT( YIELD_FIXED_FRAME );
BIND_CONSTANT( YIELD_WAIT );
}
VisualScriptYield::VisualScriptYield() {
yield_mode=YIELD_FRAME;
wait_time=1;
}
template<VisualScriptYield::YieldMode MODE>
static Ref<VisualScriptNode> create_yield_node(const String& p_name) {
Ref<VisualScriptYield> node;
node.instance();
node->set_yield_mode(MODE);
return node;
}
///////////////////////////////////////////////////
////////////////YIELD SIGNAL//////////////////////
//////////////////////////////////////////////////
int VisualScriptYieldSignal::get_output_sequence_port_count() const {
return 1;
}
bool VisualScriptYieldSignal::has_input_sequence_port() const{
return true;
}
#ifdef TOOLS_ENABLED
static Node* _find_script_node(Node* p_edited_scene,Node* p_current_node,const Ref<Script> &script) {
if (p_edited_scene!=p_current_node && p_current_node->get_owner()!=p_edited_scene)
return NULL;
Ref<Script> scr = p_current_node->get_script();
if (scr.is_valid() && scr==script)
return p_current_node;
for(int i=0;i<p_current_node->get_child_count();i++) {
Node *n = _find_script_node(p_edited_scene,p_current_node->get_child(i),script);
if (n)
return n;
}
return NULL;
}
#endif
Node *VisualScriptYieldSignal::_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
}
StringName VisualScriptYieldSignal::_get_base_type() const {
if (call_mode==CALL_MODE_SELF && get_visual_script().is_valid())
return get_visual_script()->get_instance_base_type();
else if (call_mode==CALL_MODE_NODE_PATH && get_visual_script().is_valid()) {
Node *path = _get_base_node();
if (path)
return path->get_type();
}
return base_type;
}
int VisualScriptYieldSignal::get_input_value_port_count() const{
if (call_mode==CALL_MODE_INSTANCE)
return 1;
else
return 0;
}
int VisualScriptYieldSignal::get_output_value_port_count() const{
MethodInfo sr;
if (!ObjectTypeDB::get_signal(_get_base_type(),signal,&sr))
return 0;
return sr.arguments.size();
}
String VisualScriptYieldSignal::get_output_sequence_port_text(int p_port) const {
return String();
}
PropertyInfo VisualScriptYieldSignal::get_input_value_port_info(int p_idx) const{
if (call_mode==CALL_MODE_INSTANCE)
return PropertyInfo(Variant::OBJECT,"instance");
else
return PropertyInfo();
}
PropertyInfo VisualScriptYieldSignal::get_output_value_port_info(int p_idx) const{
MethodInfo sr;
if (!ObjectTypeDB::get_signal(_get_base_type(),signal,&sr))
return PropertyInfo(); //no signal
ERR_FAIL_INDEX_V(p_idx,sr.arguments.size(),PropertyInfo());
return sr.arguments[p_idx];
}
String VisualScriptYieldSignal::get_caption() const {
static const char*cname[3]= {
"WaitSignal",
"WaitNodeSignal",
"WaitInstanceSigna;",
};
return cname[call_mode];
}
String VisualScriptYieldSignal::get_text() const {
if (call_mode==CALL_MODE_SELF)
return " "+String(signal)+"()";
else
return " "+_get_base_type()+"."+String(signal)+"()";
}
void VisualScriptYieldSignal::set_base_type(const StringName& p_type) {
if (base_type==p_type)
return;
base_type=p_type;
_change_notify();
ports_changed_notify();
}
StringName VisualScriptYieldSignal::get_base_type() const{
return base_type;
}
void VisualScriptYieldSignal::set_signal(const StringName& p_type){
if (signal==p_type)
return;
signal=p_type;
_change_notify();
ports_changed_notify();
}
StringName VisualScriptYieldSignal::get_signal() const {
return signal;
}
void VisualScriptYieldSignal::set_base_path(const NodePath& p_type) {
if (base_path==p_type)
return;
base_path=p_type;
_change_notify();
ports_changed_notify();
}
NodePath VisualScriptYieldSignal::get_base_path() const {
return base_path;
}
void VisualScriptYieldSignal::set_call_mode(CallMode p_mode) {
if (call_mode==p_mode)
return;
call_mode=p_mode;
_change_notify();
ports_changed_notify();
}
VisualScriptYieldSignal::CallMode VisualScriptYieldSignal::get_call_mode() const {
return call_mode;
}
void VisualScriptYieldSignal::_validate_property(PropertyInfo& property) const {
if (property.name=="signal/base_type") {
if (call_mode!=CALL_MODE_INSTANCE) {
property.usage=PROPERTY_USAGE_NOEDITOR;
}
}
if (property.name=="signal/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=="signal/signal") {
property.hint=PROPERTY_HINT_ENUM;
List<MethodInfo> methods;
ObjectTypeDB::get_signal_list(_get_base_type(),&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 VisualScriptYieldSignal::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_base_type","base_type"),&VisualScriptYieldSignal::set_base_type);
ObjectTypeDB::bind_method(_MD("get_base_type"),&VisualScriptYieldSignal::get_base_type);
ObjectTypeDB::bind_method(_MD("set_signal","signal"),&VisualScriptYieldSignal::set_signal);
ObjectTypeDB::bind_method(_MD("get_signal"),&VisualScriptYieldSignal::get_signal);
ObjectTypeDB::bind_method(_MD("set_call_mode","mode"),&VisualScriptYieldSignal::set_call_mode);
ObjectTypeDB::bind_method(_MD("get_call_mode"),&VisualScriptYieldSignal::get_call_mode);
ObjectTypeDB::bind_method(_MD("set_base_path","base_path"),&VisualScriptYieldSignal::set_base_path);
ObjectTypeDB::bind_method(_MD("get_base_path"),&VisualScriptYieldSignal::get_base_path);
String bt;
for(int i=0;i<Variant::VARIANT_MAX;i++) {
if (i>0)
bt+=",";
bt+=Variant::get_type_name(Variant::Type(i));
}
ADD_PROPERTY(PropertyInfo(Variant::INT,"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::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"));
BIND_CONSTANT( CALL_MODE_SELF );
BIND_CONSTANT( CALL_MODE_NODE_PATH);
BIND_CONSTANT( CALL_MODE_INSTANCE);
}
class VisualScriptNodeInstanceYieldSignal : public VisualScriptNodeInstance {
public:
VisualScriptYieldSignal::CallMode call_mode;
NodePath node_path;
int output_args;
StringName signal;
VisualScriptYieldSignal *node;
VisualScriptInstance *instance;
virtual int get_working_memory_size() const { return 1; }
//virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
if (p_start_mode==START_MODE_RESUME_YIELD) {
return 0; //resuming yield
} else {
//yield
Object * object;
switch(call_mode) {
case VisualScriptYieldSignal::CALL_MODE_SELF: {
object=instance->get_owner_ptr();
} break;
case VisualScriptYieldSignal::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;
}
object=another;
} break;
case VisualScriptYieldSignal::CALL_MODE_INSTANCE: {
object = *p_inputs[0];
if (!object) {
r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str="Supplied instance input is null.";
return 0;
}
} break;
}
Ref<VisualScriptFunctionState> state;
state.instance();
state->connect_to_signal(object,signal,Array());
*p_working_mem=state;
return STEP_YIELD_BIT;
}
}
};
VisualScriptNodeInstance* VisualScriptYieldSignal::instance(VisualScriptInstance* p_instance) {
VisualScriptNodeInstanceYieldSignal * instance = memnew(VisualScriptNodeInstanceYieldSignal );
instance->node=this;
instance->instance=p_instance;
instance->signal=signal;
instance->call_mode=call_mode;
instance->node_path=base_path;
instance->output_args = get_output_value_port_count();
return instance;
}
VisualScriptYieldSignal::VisualScriptYieldSignal() {
call_mode=CALL_MODE_INSTANCE;
base_type="Object";
}
template<VisualScriptYieldSignal::CallMode cmode>
static Ref<VisualScriptNode> create_yield_signal_node(const String& p_name) {
Ref<VisualScriptYieldSignal> node;
node.instance();
node->set_call_mode(cmode);
return node;
}
void register_visual_script_yield_nodes() {
VisualScriptLanguage::singleton->add_register_func("functions/wait/wait_frame",create_yield_node<VisualScriptYield::YIELD_FRAME>);
VisualScriptLanguage::singleton->add_register_func("functions/wait/wait_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>);
}

View file

@ -0,0 +1,127 @@
#ifndef VISUAL_SCRIPT_YIELD_NODES_H
#define VISUAL_SCRIPT_YIELD_NODES_H
#include "visual_script.h"
class VisualScriptYield : public VisualScriptNode {
OBJ_TYPE(VisualScriptYield,VisualScriptNode)
public:
enum YieldMode {
YIELD_FRAME,
YIELD_FIXED_FRAME,
YIELD_WAIT
};
private:
YieldMode yield_mode;
float wait_time;
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_yield_mode(YieldMode p_mode);
YieldMode get_yield_mode();
void set_wait_time(float p_time);
float get_wait_time();
virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
VisualScriptYield();
};
VARIANT_ENUM_CAST( VisualScriptYield::YieldMode )
class VisualScriptYieldSignal : public VisualScriptNode {
OBJ_TYPE(VisualScriptYieldSignal,VisualScriptNode)
public:
enum CallMode {
CALL_MODE_SELF,
CALL_MODE_NODE_PATH,
CALL_MODE_INSTANCE,
};
private:
CallMode call_mode;
StringName base_type;
NodePath base_path;
StringName signal;
Node *_get_base_node() const;
StringName _get_base_type() const;
protected:
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_base_type(const StringName& p_type);
StringName get_base_type() const;
void set_signal(const StringName& p_type);
StringName get_signal() const;
void set_base_path(const NodePath& p_type);
NodePath get_base_path() const;
void set_call_mode(CallMode p_mode);
CallMode get_call_mode() const;
virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
VisualScriptYieldSignal();
};
VARIANT_ENUM_CAST(VisualScriptYieldSignal::CallMode );
void register_visual_script_yield_nodes();
#endif // VISUAL_SCRIPT_YIELD_NODES_H

View file

@ -683,6 +683,8 @@ void SceneTreeDock::_notification(int p_what) {
}
button_add->set_icon(get_icon("Add","EditorIcons"));
button_instance->set_icon(get_icon("Instance","EditorIcons"));
button_create_script->set_icon(get_icon("Script","EditorIcons"));
filter_icon->set_texture(get_icon("Zoom","EditorIcons"));
@ -1302,11 +1304,18 @@ void SceneTreeDock::_delete_confirm() {
void SceneTreeDock::_selection_changed() {
if (EditorNode::get_singleton()->get_editor_selection()->get_selection().size()>1) {
int selection_size = EditorNode::get_singleton()->get_editor_selection()->get_selection().size();
if (selection_size>1) {
//automatically turn on multi-edit
_tool_selected(TOOL_MULTI_EDIT);
}
if (selection_size==1 && EditorNode::get_singleton()->get_editor_selection()->get_selection().front()->key()->get_script().is_null()) {
button_create_script->show();
} else {
button_create_script->hide();
}
//tool_buttons[TOOL_MULTI_EDIT]->set_disabled(EditorNode::get_singleton()->get_editor_selection()->get_selection().size()<2);
}
@ -1899,6 +1908,12 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelec
filter->connect("text_changed",this,"_filter_changed");
tb = memnew( ToolButton );
tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_SCRIPT, false));
tb->set_tooltip(TTR("Create a new script for the selected node."));
tb->set_shortcut(ED_GET_SHORTCUT("scene_tree/add_script"));
filter_hbc->add_child(tb);
button_create_script=tb;
scene_tree = memnew( SceneTreeEditor(false,true,true ));

View file

@ -78,6 +78,7 @@ class SceneTreeDock : public VBoxContainer {
ToolButton *button_add;
ToolButton *button_instance;
ToolButton *button_create_script;
SceneTreeEditor *scene_tree;