diff options
Diffstat (limited to 'modules/visual_script/visual_script_nodes.cpp')
-rw-r--r-- | modules/visual_script/visual_script_nodes.cpp | 1138 |
1 files changed, 1086 insertions, 52 deletions
diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index 1e898675d3..d205a40f76 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -53,7 +53,15 @@ bool VisualScriptFunction::_set(const StringName& p_name, const Variant& p_valu } + if (p_name=="stack/stackless") { + set_stack_less(p_value); + return true; + } + if (p_name=="stack/size") { + stack_size=p_value; + return true; + } return false; } @@ -81,6 +89,16 @@ bool VisualScriptFunction::_get(const StringName& p_name,Variant &r_ret) const } + if (p_name=="stack/stackless") { + r_ret=stack_less; + return true; + } + + if (p_name=="stack/size") { + r_ret=stack_size; + return true; + } + return false; } void VisualScriptFunction::_get_property_list( List<PropertyInfo> *p_list) const { @@ -96,6 +114,11 @@ void VisualScriptFunction::_get_property_list( List<PropertyInfo> *p_list) cons p_list->push_back(PropertyInfo(Variant::INT,"argument/"+itos(i+1)+"/type",PROPERTY_HINT_ENUM,argt)); p_list->push_back(PropertyInfo(Variant::STRING,"argument/"+itos(i+1)+"/name")); } + if (!stack_less) { + p_list->push_back(PropertyInfo(Variant::INT,"stack/size",PROPERTY_HINT_RANGE,"1,100000")); + } + p_list->push_back(PropertyInfo(Variant::BOOL,"stack/stackless")); + } @@ -201,15 +224,75 @@ int VisualScriptFunction::get_argument_count() const { return arguments.size(); } +class VisualScriptNodeInstanceFunction : public VisualScriptNodeInstance { +public: -VisualScriptNodeInstance* VisualScriptFunction::instance(VScriptInstance* p_instance) { + VisualScriptFunction *node; + VisualScriptInstance *instance; - return NULL; + //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) { + + int ac = node->get_argument_count(); + + for(int i=0;i<ac;i++) { +#ifdef DEBUG_ENABLED + Variant::Type expected = node->get_argument_type(i); + if (expected!=Variant::NIL) { + if (!Variant::can_convert_strict(p_inputs[i]->get_type(),expected)) { + r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.expected=expected; + r_error.argument=i; + return 0; + } + } +#endif + + *p_outputs[i]=*p_inputs[i]; + } + + return 0; + } + + +}; + +VisualScriptNodeInstance* VisualScriptFunction::instance(VisualScriptInstance* p_instance) { + + VisualScriptNodeInstanceFunction * instance = memnew(VisualScriptNodeInstanceFunction ); + instance->node=this; + instance->instance=p_instance; + return instance; } VisualScriptFunction::VisualScriptFunction() { + stack_size=256; + stack_less=false; +} + + +void VisualScriptFunction::set_stack_less(bool p_enable) { + stack_less=p_enable; + _change_notify(); +} + +bool VisualScriptFunction::is_stack_less() const { + return stack_less; +} + +void VisualScriptFunction::set_stack_size(int p_size) { + + ERR_FAIL_COND(p_size <1 || p_size>100000); + stack_size=p_size; +} + +int VisualScriptFunction::get_stack_size() const { + return stack_size; } @@ -425,9 +508,51 @@ void VisualScriptOperator::_bind_methods() { } -VisualScriptNodeInstance* VisualScriptOperator::instance(VScriptInstance* p_instance) { +class VisualScriptNodeInstanceOperator : public VisualScriptNodeInstance { +public: - return NULL; + bool unary; + 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) { + + bool valid; + if (unary) { + + Variant::evaluate(op,*p_inputs[0],Variant(),*p_outputs[0],valid); + } else { + Variant::evaluate(op,*p_inputs[0],*p_inputs[1],*p_outputs[0],valid); + } + + if (!valid) { + + r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; + if (p_outputs[0]->get_type()==Variant::STRING) { + r_error_str=*p_outputs[0]; + } else { + if (unary) + r_error_str=String(op_names[op])+RTR(": Invalid argument of type: ")+Variant::get_type_name(p_inputs[0]->get_type()); + else + r_error_str=String(op_names[op])+RTR(": Invalid arguments: ")+"A: "+Variant::get_type_name(p_inputs[0]->get_type())+" B: "+Variant::get_type_name(p_inputs[1]->get_type()); + } + } + + return 0; + } + + +}; + +VisualScriptNodeInstance* VisualScriptOperator::instance(VisualScriptInstance* p_instance) { + + VisualScriptNodeInstanceOperator * instance = memnew(VisualScriptNodeInstanceOperator ); + instance->unary=get_input_value_port_count()==1; + instance->op=op; + return instance; } VisualScriptOperator::VisualScriptOperator() { @@ -447,37 +572,42 @@ static Ref<VisualScriptNode> create_op_node(const String& p_name) { } ////////////////////////////////////////// -////////////////VARIABLE////////////////// +////////////////VARIABLE GET////////////////// ////////////////////////////////////////// -int VisualScriptVariable::get_output_sequence_port_count() const { +int VisualScriptVariableGet::get_output_sequence_port_count() const { - return 1; + return 0; } -bool VisualScriptVariable::has_input_sequence_port() const{ +bool VisualScriptVariableGet::has_input_sequence_port() const{ - return true; + return false; } -int VisualScriptVariable::get_input_value_port_count() const{ +int VisualScriptVariableGet::get_input_value_port_count() const{ - return 1; + return 0; } -int VisualScriptVariable::get_output_value_port_count() const{ +int VisualScriptVariableGet::get_output_value_port_count() const{ return 1; } -String VisualScriptVariable::get_output_sequence_port_text(int p_port) const { +String VisualScriptVariableGet::get_output_sequence_port_text(int p_port) const { return String(); } -PropertyInfo VisualScriptVariable::get_input_value_port_info(int p_idx) const{ +PropertyInfo VisualScriptVariableGet::get_input_value_port_info(int p_idx) const{ + + return PropertyInfo(); +} + +PropertyInfo VisualScriptVariableGet::get_output_value_port_info(int p_idx) const{ PropertyInfo pinfo; - pinfo.name="set"; + pinfo.name="value"; if (get_visual_script().is_valid() && get_visual_script()->has_variable(variable)) { PropertyInfo vinfo = get_visual_script()->get_variable_info(variable); pinfo.type=vinfo.type; @@ -487,10 +617,134 @@ PropertyInfo VisualScriptVariable::get_input_value_port_info(int p_idx) const{ return pinfo; } -PropertyInfo VisualScriptVariable::get_output_value_port_info(int p_idx) const{ + +String VisualScriptVariableGet::get_caption() const { + + return "Variable"; +} + +String VisualScriptVariableGet::get_text() const { + + return variable; +} + +void VisualScriptVariableGet::set_variable(StringName p_variable) { + + if (variable==p_variable) + return; + variable=p_variable; + ports_changed_notify(); + +} + +StringName VisualScriptVariableGet::get_variable() const{ + + return variable; +} + +void VisualScriptVariableGet::_validate_property(PropertyInfo& property) const { + + if (property.name=="variable/name" && get_visual_script().is_valid()) { + Ref<VisualScript> vs = get_visual_script(); + List<StringName> vars; + vs->get_variable_list(&vars); + + String vhint; + for (List<StringName>::Element *E=vars.front();E;E=E->next()) { + if (vhint!=String()) + vhint+=","; + + vhint+=E->get().operator String(); + } + + property.hint=PROPERTY_HINT_ENUM; + property.hint_string=vhint; + } +} + +void VisualScriptVariableGet::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_variable","name"),&VisualScriptVariableGet::set_variable); + ObjectTypeDB::bind_method(_MD("get_variable"),&VisualScriptVariableGet::get_variable); + + + ADD_PROPERTY(PropertyInfo(Variant::STRING,"variable/name"),_SCS("set_variable"),_SCS("get_variable")); + +} + +class VisualScriptNodeInstanceVariableGet : public VisualScriptNodeInstance { +public: + + VisualScriptVariableGet *node; + 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) { + + return 0; + } + + +}; + +VisualScriptNodeInstance* VisualScriptVariableGet::instance(VisualScriptInstance* p_instance) { + + VisualScriptNodeInstanceVariableGet * instance = memnew(VisualScriptNodeInstanceVariableGet ); + instance->node=this; + instance->instance=p_instance; + instance->variable=variable; + return instance; +} +VisualScriptVariableGet::VisualScriptVariableGet() { + + +} + + +////////////////////////////////////////// +////////////////VARIABLE GET////////////////// +////////////////////////////////////////// + +int VisualScriptVariableSet::get_output_sequence_port_count() const { + + return 1; +} + +bool VisualScriptVariableSet::has_input_sequence_port() const{ + + return true; +} + +int VisualScriptVariableSet::get_input_value_port_count() const{ + + return 1; +} +int VisualScriptVariableSet::get_output_value_port_count() const{ + + return 0; +} + +String VisualScriptVariableSet::get_output_sequence_port_text(int p_port) const { + + return String(); +} + +PropertyInfo VisualScriptVariableSet::get_input_value_port_info(int p_idx) const{ PropertyInfo pinfo; - pinfo.name="get"; + pinfo.name="set"; if (get_visual_script().is_valid() && get_visual_script()->has_variable(variable)) { PropertyInfo vinfo = get_visual_script()->get_variable_info(variable); pinfo.type=vinfo.type; @@ -500,18 +754,23 @@ PropertyInfo VisualScriptVariable::get_output_value_port_info(int p_idx) const{ return pinfo; } +PropertyInfo VisualScriptVariableSet::get_output_value_port_info(int p_idx) const{ -String VisualScriptVariable::get_caption() const { + return PropertyInfo(); +} - return "Variable"; + +String VisualScriptVariableSet::get_caption() const { + + return "VariableSet"; } -String VisualScriptVariable::get_text() const { +String VisualScriptVariableSet::get_text() const { return variable; } -void VisualScriptVariable::set_variable(StringName p_variable) { +void VisualScriptVariableSet::set_variable(StringName p_variable) { if (variable==p_variable) return; @@ -520,12 +779,12 @@ void VisualScriptVariable::set_variable(StringName p_variable) { } -StringName VisualScriptVariable::get_variable() const{ +StringName VisualScriptVariableSet::get_variable() const{ return variable; } -void VisualScriptVariable::_validate_property(PropertyInfo& property) const { +void VisualScriptVariableSet::_validate_property(PropertyInfo& property) const { if (property.name=="variable/name" && get_visual_script().is_valid()) { Ref<VisualScript> vs = get_visual_script(); @@ -545,22 +804,50 @@ void VisualScriptVariable::_validate_property(PropertyInfo& property) const { } } -void VisualScriptVariable::_bind_methods() { +void VisualScriptVariableSet::_bind_methods() { - ObjectTypeDB::bind_method(_MD("set_variable","name"),&VisualScriptVariable::set_variable); - ObjectTypeDB::bind_method(_MD("get_variable"),&VisualScriptVariable::get_variable); + ObjectTypeDB::bind_method(_MD("set_variable","name"),&VisualScriptVariableSet::set_variable); + ObjectTypeDB::bind_method(_MD("get_variable"),&VisualScriptVariableSet::get_variable); ADD_PROPERTY(PropertyInfo(Variant::STRING,"variable/name"),_SCS("set_variable"),_SCS("get_variable")); } -VisualScriptNodeInstance* VisualScriptVariable::instance(VScriptInstance* p_instance) { +class VisualScriptNodeInstanceVariableSet : public VisualScriptNodeInstance { +public: - return NULL; -} + VisualScriptVariableSet *node; + VisualScriptInstance *instance; + 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_str=RTR("VariableSet not found in script: ")+"'"+String(variable)+"'"; + } -VisualScriptVariable::VisualScriptVariable() { + + return 0; + } + + +}; + +VisualScriptNodeInstance* VisualScriptVariableSet::instance(VisualScriptInstance* p_instance) { + + VisualScriptNodeInstanceVariableSet * instance = memnew(VisualScriptNodeInstanceVariableSet ); + instance->node=this; + instance->instance=p_instance; + instance->variable=variable; + return instance; +} +VisualScriptVariableSet::VisualScriptVariableSet() { } @@ -679,9 +966,33 @@ void VisualScriptConstant::_bind_methods() { } -VisualScriptNodeInstance* VisualScriptConstant::instance(VScriptInstance* p_instance) { +class VisualScriptNodeInstanceConstant : public VisualScriptNodeInstance { +public: - return NULL; + 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) { + + return 0; + } + + +}; + +VisualScriptNodeInstance* VisualScriptConstant::instance(VisualScriptInstance* p_instance) { + + VisualScriptNodeInstanceConstant * instance = memnew(VisualScriptNodeInstanceConstant ); + instance->constant=value; + return instance; } VisualScriptConstant::VisualScriptConstant() { @@ -747,11 +1058,34 @@ String VisualScriptIndexGet::get_text() const { } -VisualScriptNodeInstance* VisualScriptIndexGet::instance(VScriptInstance* p_instance) { +class VisualScriptNodeInstanceIndexGet : public VisualScriptNodeInstance { +public: - return NULL; -} + //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) { + + bool valid; + *p_outputs[0] = p_inputs[0]->get(*p_inputs[1],&valid); + + if (!valid) { + r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; + r_error_str="Invalid get: "+p_inputs[0]->get_construct_string(); + } + return 0; + } + + +}; + +VisualScriptNodeInstance* VisualScriptIndexGet::instance(VisualScriptInstance* p_instance) { + + VisualScriptNodeInstanceIndexGet * instance = memnew(VisualScriptNodeInstanceIndexGet ); + return instance; +} VisualScriptIndexGet::VisualScriptIndexGet() { @@ -816,11 +1150,35 @@ String VisualScriptIndexSet::get_text() const { } -VisualScriptNodeInstance* VisualScriptIndexSet::instance(VScriptInstance* p_instance) { +class VisualScriptNodeInstanceIndexSet : public VisualScriptNodeInstance { +public: - return NULL; -} + //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) { + + bool valid; + *p_outputs[0]=*p_inputs[0]; + p_outputs[0]->set(*p_inputs[1],*p_inputs[2],&valid); + + if (!valid) { + r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; + r_error_str="Invalid set: "+p_inputs[1]->get_construct_string(); + } + return 0; + } + + +}; + +VisualScriptNodeInstance* VisualScriptIndexSet::instance(VisualScriptInstance* p_instance) { + + VisualScriptNodeInstanceIndexSet * instance = memnew(VisualScriptNodeInstanceIndexSet ); + return instance; +} VisualScriptIndexSet::VisualScriptIndexSet() { @@ -889,10 +1247,33 @@ int VisualScriptGlobalConstant::get_global_constant() { } +class VisualScriptNodeInstanceGlobalConstant : public VisualScriptNodeInstance { +public: -VisualScriptNodeInstance* VisualScriptGlobalConstant::instance(VScriptInstance* p_instance) { + 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 { - return NULL; + *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) { + + + return 0; + } + + +}; + +VisualScriptNodeInstance* VisualScriptGlobalConstant::instance(VisualScriptInstance* p_instance) { + + VisualScriptNodeInstanceGlobalConstant * instance = memnew(VisualScriptNodeInstanceGlobalConstant ); + instance->index=index; + return instance; } void VisualScriptGlobalConstant::_bind_methods() { @@ -931,6 +1312,17 @@ const char* VisualScriptMathConstant::const_name[MATH_CONSTANT_MAX]={ "E", "Sqrt2", }; + +double VisualScriptMathConstant::const_value[MATH_CONSTANT_MAX]={ + 1.0, + Math_PI, + Math_PI*2, + Math_PI*0.5, + 2.71828182845904523536, + Math::sqrt(2.0) +}; + + int VisualScriptMathConstant::get_output_sequence_port_count() const { return 0; @@ -962,7 +1354,7 @@ PropertyInfo VisualScriptMathConstant::get_input_value_port_info(int p_idx) cons PropertyInfo VisualScriptMathConstant::get_output_value_port_info(int p_idx) const{ - return PropertyInfo(Variant::INT,"value"); + return PropertyInfo(Variant::REAL,"value"); } @@ -987,13 +1379,36 @@ VisualScriptMathConstant::MathConstant VisualScriptMathConstant::get_math_consta return constant; } +class VisualScriptNodeInstanceMathConstant : public VisualScriptNodeInstance { +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 { -VisualScriptNodeInstance* VisualScriptMathConstant::instance(VScriptInstance* p_instance) { + *r_value = value; + return true; - return NULL; + } + + 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* VisualScriptMathConstant::instance(VisualScriptInstance* p_instance) { + + VisualScriptNodeInstanceMathConstant * instance = memnew(VisualScriptNodeInstanceMathConstant ); + instance->value=const_value[constant]; + return instance; } + void VisualScriptMathConstant::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_math_constant","which"),&VisualScriptMathConstant::set_math_constant); @@ -1080,11 +1495,35 @@ String VisualScriptEngineSingleton::get_singleton() { -VisualScriptNodeInstance* VisualScriptEngineSingleton::instance(VScriptInstance* p_instance) { +class VisualScriptNodeInstanceEngineSingleton : public VisualScriptNodeInstance { +public: - return NULL; + 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) { + + + return 0; + } + +}; + +VisualScriptNodeInstance* VisualScriptEngineSingleton::instance(VisualScriptInstance* p_instance) { + + VisualScriptNodeInstanceEngineSingleton * instance = memnew(VisualScriptNodeInstanceEngineSingleton ); + instance->singleton=Globals::get_singleton()->get_singleton_object(singleton); + return instance; } + void VisualScriptEngineSingleton::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_singleton","name"),&VisualScriptEngineSingleton::set_singleton); @@ -1176,12 +1615,53 @@ NodePath VisualScriptSceneNode::get_node_path() { } +class VisualScriptNodeInstanceSceneNode : public VisualScriptNodeInstance { +public: -VisualScriptNodeInstance* VisualScriptSceneNode::instance(VScriptInstance* p_instance) { + VisualScriptSceneNode *node; + VisualScriptInstance *instance; + NodePath path; - return NULL; + //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 { + + Node* node = instance->get_owner_ptr()->cast_to<Node>(); + if (!node) { + r_error="Base object is not a Node!"; + return false; + } + + + + Node* another = node->get_node(path); + if (!node) { + r_error="Path does not lead Node!"; + return false; + } + + *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) { + + return 0; + } + + +}; + +VisualScriptNodeInstance* VisualScriptSceneNode::instance(VisualScriptInstance* p_instance) { + + VisualScriptNodeInstanceSceneNode * instance = memnew(VisualScriptNodeInstanceSceneNode ); + instance->node=this; + instance->instance=p_instance; + instance->path=path; + return instance; } + #ifdef TOOLS_ENABLED static Node* _find_script_node(Node* p_edited_scene,Node* p_current_node,const Ref<Script> &script) { @@ -1302,12 +1782,51 @@ String VisualScriptSceneTree::get_text() const { } +class VisualScriptNodeInstanceSceneTree : public VisualScriptNodeInstance { +public: -VisualScriptNodeInstance* VisualScriptSceneTree::instance(VScriptInstance* p_instance) { + VisualScriptSceneTree *node; + VisualScriptInstance *instance; - return NULL; + //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 { + + Node* node = instance->get_owner_ptr()->cast_to<Node>(); + if (!node) { + r_error="Base object is not a Node!"; + return false; + } + + SceneTree* tree = node->get_tree(); + if (!tree) { + r_error="Attempt to get SceneTree while node is not in the active tree."; + return false; + } + + *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) { + + + return 0; + } + + +}; + +VisualScriptNodeInstance* VisualScriptSceneTree::instance(VisualScriptInstance* p_instance) { + + VisualScriptNodeInstanceSceneTree * instance = memnew(VisualScriptNodeInstanceSceneTree ); + instance->node=this; + instance->instance=p_instance; + return instance; } + void VisualScriptSceneTree::_validate_property(PropertyInfo& property) const { } @@ -1382,10 +1901,31 @@ String VisualScriptResourcePath::get_resource_path() { } +class VisualScriptNodeInstanceResourcePath : public VisualScriptNodeInstance { +public: -VisualScriptNodeInstance* VisualScriptResourcePath::instance(VScriptInstance* p_instance) { + String path; - return NULL; + //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) { + + return 0; + } + + +}; + +VisualScriptNodeInstance* VisualScriptResourcePath::instance(VisualScriptInstance* p_instance) { + + VisualScriptNodeInstanceResourcePath * instance = memnew(VisualScriptNodeInstanceResourcePath ); + instance->path=path; + return instance; } @@ -1404,9 +1944,499 @@ VisualScriptResourcePath::VisualScriptResourcePath() { } + +////////////////////////////////////////// +////////////////SELF/////////// +////////////////////////////////////////// + +int VisualScriptSelf::get_output_sequence_port_count() const { + + return 0; +} + +bool VisualScriptSelf::has_input_sequence_port() const{ + + return false; +} + +int VisualScriptSelf::get_input_value_port_count() const{ + + return 0; +} +int VisualScriptSelf::get_output_value_port_count() const{ + + return 1; +} + +String VisualScriptSelf::get_output_sequence_port_text(int p_port) const { + + return String(); +} + +PropertyInfo VisualScriptSelf::get_input_value_port_info(int p_idx) const{ + + return PropertyInfo(); +} + +PropertyInfo VisualScriptSelf::get_output_value_port_info(int p_idx) const{ + + return PropertyInfo(Variant::OBJECT,"instance"); +} + + +String VisualScriptSelf::get_caption() const { + + return "Self"; +} + +String VisualScriptSelf::get_text() const { + + if (get_visual_script().is_valid()) + return get_visual_script()->get_instance_base_type(); + else + return ""; +} + + +class VisualScriptNodeInstanceSelf : public VisualScriptNodeInstance { +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) { + + return 0; + } + + +}; + +VisualScriptNodeInstance* VisualScriptSelf::instance(VisualScriptInstance* p_instance) { + + VisualScriptNodeInstanceSelf * instance = memnew(VisualScriptNodeInstanceSelf ); + instance->instance=p_instance; + return instance; +} + + + +void VisualScriptSelf::_bind_methods() { + +} + +VisualScriptSelf::VisualScriptSelf() { + + +} + +////////////////////////////////////////// +////////////////CUSTOM (SCRIPTED)/////////// +////////////////////////////////////////// + +int VisualScriptCustomNode::get_output_sequence_port_count() const { + + if (get_script_instance() && get_script_instance()->has_method("_get_output_sequence_port_count")) { + return get_script_instance()->call("_get_output_sequence_port_count"); + } + return 0; +} + +bool VisualScriptCustomNode::has_input_sequence_port() const{ + + if (get_script_instance() && get_script_instance()->has_method("_has_input_sequence_port")) { + return get_script_instance()->call("_has_input_sequence_port"); + } + return false; +} + +int VisualScriptCustomNode::get_input_value_port_count() const{ + + if (get_script_instance() && get_script_instance()->has_method("_get_input_value_port_count")) { + return get_script_instance()->call("_get_input_value_port_count"); + } + return 0; +} +int VisualScriptCustomNode::get_output_value_port_count() const{ + + if (get_script_instance() && get_script_instance()->has_method("_get_output_value_port_count")) { + return get_script_instance()->call("_get_output_value_port_count"); + } + return 0; +} + +String VisualScriptCustomNode::get_output_sequence_port_text(int p_port) const { + + if (get_script_instance() && get_script_instance()->has_method("_get_output_sequence_port_text")) { + return get_script_instance()->call("_get_output_sequence_port_text",p_port); + } + + return String(); +} + +PropertyInfo VisualScriptCustomNode::get_input_value_port_info(int p_idx) const{ + + PropertyInfo info; + if (get_script_instance() && get_script_instance()->has_method("_get_input_value_port_type")) { + info.type=Variant::Type(int(get_script_instance()->call("_get_input_value_port_type",p_idx))); + } + if (get_script_instance() && get_script_instance()->has_method("_get_input_value_port_name")) { + info.name=get_script_instance()->call("_get_input_value_port_name",p_idx); + } + return info; +} + +PropertyInfo VisualScriptCustomNode::get_output_value_port_info(int p_idx) const{ + + PropertyInfo info; + if (get_script_instance() && get_script_instance()->has_method("_get_output_value_port_type")) { + info.type=Variant::Type(int(get_script_instance()->call("_get_output_value_port_type",p_idx))); + } + if (get_script_instance() && get_script_instance()->has_method("_get_output_value_port_name")) { + info.name=get_script_instance()->call("_get_output_value_port_name",p_idx); + } + return info; +} + + +String VisualScriptCustomNode::get_caption() const { + + if (get_script_instance() && get_script_instance()->has_method("_get_caption")) { + return get_script_instance()->call("_get_caption"); + } + return "CustomNode"; +} + +String VisualScriptCustomNode::get_text() const { + + if (get_script_instance() && get_script_instance()->has_method("_get_text")) { + return get_script_instance()->call("_get_text"); + } + return ""; +} + +String VisualScriptCustomNode::get_category() const { + + if (get_script_instance() && get_script_instance()->has_method("_get_category")) { + return get_script_instance()->call("_get_category"); + } + return "custom"; +} + +class VisualScriptNodeInstanceCustomNode : public VisualScriptNodeInstance { +public: + + VisualScriptInstance* instance; + VisualScriptCustomNode *node; + 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()) { +#ifdef DEBUG_ENABLED + if (!node->get_script_instance()->has_method(VisualScriptLanguage::singleton->_step)) { + r_error_str=RTR("Custom node has no _step() method, can't process graph."); + r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; + return 0; + } +#endif + Array in_values(true); + Array out_values(true); + Array work_mem(true); + + in_values.resize(in_count); + + for(int i=0;i<in_count;i++) { + in_values[i]=p_inputs[i]; + } + + out_values.resize(in_count); + + work_mem.resize(work_mem_size); + + for(int i=0;i<work_mem_size;i++) { + work_mem[i]=p_working_mem[i]; + } + + int ret_out; + + Variant ret = node->get_script_instance()->call(VisualScriptLanguage::singleton->_step,in_values,out_values,p_start_mode,work_mem); + if (ret.get_type()==Variant::STRING) { + r_error_str=ret; + r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; + return 0; + } else if (ret.is_num()) { + ret_out=ret; + } else { + r_error_str=RTR("Invalid return value from _step(), must be integer (seq out), or string (error)."); + r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; + return 0; + } + + for(int i=0;i<out_count;i++) { + if (i<out_values.size()) { + *p_outputs[i]=out_values[i]; + } + } + + for(int i=0;i<work_mem_size;i++) { + if (i<work_mem.size()) { + p_working_mem[i]=work_mem[i]; + } + } + + return ret_out; + + } + + return 0; + } + + +}; + +VisualScriptNodeInstance* VisualScriptCustomNode::instance(VisualScriptInstance* p_instance) { + + VisualScriptNodeInstanceCustomNode * instance = memnew(VisualScriptNodeInstanceCustomNode ); + instance->instance=p_instance; + 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"); + } else { + instance->work_mem_size=0; + } + + return instance; +} + + + +void VisualScriptCustomNode::_bind_methods() { + + BIND_VMETHOD( MethodInfo(Variant::INT,"_get_output_sequence_port_count") ); + BIND_VMETHOD( MethodInfo(Variant::BOOL,"_has_input_sequence_port") ); + + BIND_VMETHOD( MethodInfo(Variant::STRING,"_get_output_sequence_port_text",PropertyInfo(Variant::INT,"idx")) ); + BIND_VMETHOD( MethodInfo(Variant::INT,"_get_input_value_port_count") ); + BIND_VMETHOD( MethodInfo(Variant::INT,"_get_output_value_port_count") ); + + BIND_VMETHOD( MethodInfo(Variant::INT,"_get_input_value_port_type",PropertyInfo(Variant::INT,"idx")) ); + BIND_VMETHOD( MethodInfo(Variant::STRING,"_get_input_value_port_name",PropertyInfo(Variant::INT,"idx")) ); + + BIND_VMETHOD( MethodInfo(Variant::INT,"_get_output_value_port_type",PropertyInfo(Variant::INT,"idx")) ); + BIND_VMETHOD( MethodInfo(Variant::STRING,"_get_output_value_port_name",PropertyInfo(Variant::INT,"idx")) ); + + BIND_VMETHOD( MethodInfo(Variant::STRING,"_get_caption") ); + BIND_VMETHOD( MethodInfo(Variant::STRING,"_get_text") ); + 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 ); + BIND_CONSTANT( START_MODE_CONTINUE_SEQUENCE ); + BIND_CONSTANT( START_MODE_RESUME_YIELD ); + + BIND_CONSTANT( STEP_PUSH_STACK_BIT ); + BIND_CONSTANT( STEP_GO_BACK_BIT ); + BIND_CONSTANT( STEP_NO_ADVANCE_BIT ); + BIND_CONSTANT( STEP_EXIT_FUNCTION_BIT ); + BIND_CONSTANT( STEP_YIELD_BIT ); + +} + +VisualScriptCustomNode::VisualScriptCustomNode() { + + +} + +////////////////////////////////////////// +////////////////SUBCALL/////////// +////////////////////////////////////////// + +int VisualScriptSubCall::get_output_sequence_port_count() const { + + return 1; +} + +bool VisualScriptSubCall::has_input_sequence_port() const{ + + return true; +} + +int VisualScriptSubCall::get_input_value_port_count() const{ + + Ref<Script> script = get_script(); + + if (script.is_valid() && script->has_method(VisualScriptLanguage::singleton->_subcall)) { + + MethodInfo mi = script->get_method_info(VisualScriptLanguage::singleton->_subcall); + return mi.arguments.size(); + } + + return 0; +} +int VisualScriptSubCall::get_output_value_port_count() const{ + + return 1; +} + +String VisualScriptSubCall::get_output_sequence_port_text(int p_port) const { + + return String(); +} + +PropertyInfo VisualScriptSubCall::get_input_value_port_info(int p_idx) const{ + + Ref<Script> script = get_script(); + if (script.is_valid() && script->has_method(VisualScriptLanguage::singleton->_subcall)) { + + MethodInfo mi = script->get_method_info(VisualScriptLanguage::singleton->_subcall); + return mi.arguments[p_idx]; + } + + return PropertyInfo(); +} + +PropertyInfo VisualScriptSubCall::get_output_value_port_info(int p_idx) const{ + + Ref<Script> script = get_script(); + if (script.is_valid() && script->has_method(VisualScriptLanguage::singleton->_subcall)) { + MethodInfo mi = script->get_method_info(VisualScriptLanguage::singleton->_subcall); + return mi.return_val; + } + return PropertyInfo(); +} + + +String VisualScriptSubCall::get_caption() const { + + return "SubCall"; +} + + +String VisualScriptSubCall::get_text() const { + + Ref<Script> script = get_script(); + if (script.is_valid()) { + if (script->get_name()!=String()) + return script->get_name(); + if (script->get_path().is_resource_file()) + return script->get_path().get_file(); + return script->get_type(); + } + return ""; +} + +String VisualScriptSubCall::get_category() const { + + return "custom"; +} + +class VisualScriptNodeInstanceSubCall : public VisualScriptNodeInstance { +public: + + VisualScriptInstance* instance; + VisualScriptSubCall *subcall; + int input_args; + 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) { + + if (!valid) { + r_error_str="Node requires a script with a _subcall(<args>) method to work."; + r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; + return 0; + } + *p_outputs[0]=subcall->call(VisualScriptLanguage::singleton->_subcall,p_inputs,input_args,r_error_str); + return 0; + } + + +}; + +VisualScriptNodeInstance* VisualScriptSubCall::instance(VisualScriptInstance* p_instance) { + + VisualScriptNodeInstanceSubCall * instance = memnew(VisualScriptNodeInstanceSubCall ); + instance->instance=p_instance; + Ref<Script> script = get_script(); + if (script.is_valid() && script->has_method(VisualScriptLanguage::singleton->_subcall)) { + instance->valid=true; + instance->input_args=get_input_value_port_count(); + } else { + instance->valid=false; + } + return instance; +} + + + +void VisualScriptSubCall::_bind_methods() { + + BIND_VMETHOD( MethodInfo(Variant::NIL,"_subcall",PropertyInfo(Variant::NIL,"arguments:Variant")) ); + +} + +VisualScriptSubCall::VisualScriptSubCall() { + + +} + + void register_visual_script_nodes() { - VisualScriptLanguage::singleton->add_register_func("data/variable",create_node_generic<VisualScriptVariable>); + 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/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>); @@ -1414,6 +2444,9 @@ void register_visual_script_nodes() { VisualScriptLanguage::singleton->add_register_func("data/scene_node",create_node_generic<VisualScriptSceneNode>); VisualScriptLanguage::singleton->add_register_func("data/scene_tree",create_node_generic<VisualScriptSceneTree>); VisualScriptLanguage::singleton->add_register_func("data/resource_path",create_node_generic<VisualScriptResourcePath>); + 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("index/get_index",create_node_generic<VisualScriptIndexGet>); @@ -1448,4 +2481,5 @@ 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>); + } |