#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 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; } 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(); if (!tree) { r_error_str="Main Loop is not SceneTree"; r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; return 0; } Ref 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; } *p_working_mem=state; return ret; } } }; 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() { ClassDB::bind_method(D_METHOD("set_yield_mode","mode"),&VisualScriptYield::set_yield_mode); ClassDB::bind_method(D_METHOD("get_yield_mode"),&VisualScriptYield::get_yield_mode); ClassDB::bind_method(D_METHOD("set_wait_time","sec"),&VisualScriptYield::set_wait_time); ClassDB::bind_method(D_METHOD("get_wait_time"),&VisualScriptYield::get_wait_time); ADD_PROPERTY(PropertyInfo(Variant::INT,"mode",PROPERTY_HINT_ENUM,"Frame,FixedFrame,Time",PROPERTY_USAGE_NOEDITOR),"set_yield_mode","get_yield_mode"); ADD_PROPERTY(PropertyInfo(Variant::REAL,"wait_time"),"set_wait_time","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 static Ref create_yield_node(const String& p_name) { Ref 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