123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859 |
- /**************************************************************************/
- /* visual_script_flow_control.cpp */
- /**************************************************************************/
- /* This file is part of: */
- /* GODOT ENGINE */
- /* https://godotengine.org */
- /**************************************************************************/
- /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
- /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
- /* */
- /* Permission is hereby granted, free of charge, to any person obtaining */
- /* a copy of this software and associated documentation files (the */
- /* "Software"), to deal in the Software without restriction, including */
- /* without limitation the rights to use, copy, modify, merge, publish, */
- /* distribute, sublicense, and/or sell copies of the Software, and to */
- /* permit persons to whom the Software is furnished to do so, subject to */
- /* the following conditions: */
- /* */
- /* The above copyright notice and this permission notice shall be */
- /* included in all copies or substantial portions of the Software. */
- /* */
- /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
- /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
- /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
- /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
- /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
- /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
- /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
- /**************************************************************************/
- #include "visual_script_flow_control.h"
- #include "core/io/resource_loader.h"
- #include "core/os/keyboard.h"
- #include "core/project_settings.h"
- //////////////////////////////////////////
- ////////////////RETURN////////////////////
- //////////////////////////////////////////
- int VisualScriptReturn::get_output_sequence_port_count() const {
- return 0;
- }
- bool VisualScriptReturn::has_input_sequence_port() const {
- return true;
- }
- int VisualScriptReturn::get_input_value_port_count() const {
- return with_value ? 1 : 0;
- }
- int VisualScriptReturn::get_output_value_port_count() const {
- return 0;
- }
- String VisualScriptReturn::get_output_sequence_port_text(int p_port) const {
- return String();
- }
- PropertyInfo VisualScriptReturn::get_input_value_port_info(int p_idx) const {
- PropertyInfo pinfo;
- pinfo.name = "result";
- pinfo.type = type;
- return pinfo;
- }
- PropertyInfo VisualScriptReturn::get_output_value_port_info(int p_idx) const {
- return PropertyInfo();
- }
- String VisualScriptReturn::get_caption() const {
- return RTR("Return");
- }
- String VisualScriptReturn::get_text() const {
- return get_name();
- }
- void VisualScriptReturn::set_return_type(Variant::Type p_type) {
- if (type == p_type) {
- return;
- }
- type = p_type;
- ports_changed_notify();
- }
- Variant::Type VisualScriptReturn::get_return_type() const {
- return type;
- }
- void VisualScriptReturn::set_enable_return_value(bool p_enable) {
- if (with_value == p_enable) {
- return;
- }
- with_value = p_enable;
- ports_changed_notify();
- }
- bool VisualScriptReturn::is_return_value_enabled() const {
- return with_value;
- }
- void VisualScriptReturn::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_return_type", "type"), &VisualScriptReturn::set_return_type);
- ClassDB::bind_method(D_METHOD("get_return_type"), &VisualScriptReturn::get_return_type);
- ClassDB::bind_method(D_METHOD("set_enable_return_value", "enable"), &VisualScriptReturn::set_enable_return_value);
- ClassDB::bind_method(D_METHOD("is_return_value_enabled"), &VisualScriptReturn::is_return_value_enabled);
- String argt = "Any";
- for (int i = 1; i < Variant::VARIANT_MAX; i++) {
- argt += "," + Variant::get_type_name(Variant::Type(i));
- }
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "return_enabled"), "set_enable_return_value", "is_return_value_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "return_type", PROPERTY_HINT_ENUM, argt), "set_return_type", "get_return_type");
- }
- class VisualScriptNodeInstanceReturn : public VisualScriptNodeInstance {
- public:
- VisualScriptReturn *node;
- VisualScriptInstance *instance;
- bool with_value;
- 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 (with_value) {
- *p_working_mem = *p_inputs[0];
- return STEP_EXIT_FUNCTION_BIT;
- } else {
- *p_working_mem = Variant();
- return 0;
- }
- }
- };
- VisualScriptNodeInstance *VisualScriptReturn::instance(VisualScriptInstance *p_instance) {
- VisualScriptNodeInstanceReturn *instance = memnew(VisualScriptNodeInstanceReturn);
- instance->node = this;
- instance->instance = p_instance;
- instance->with_value = with_value;
- return instance;
- }
- VisualScriptReturn::VisualScriptReturn() {
- with_value = false;
- type = Variant::NIL;
- }
- template <bool with_value>
- static Ref<VisualScriptNode> create_return_node(const String &p_name) {
- Ref<VisualScriptReturn> node;
- node.instance();
- node->set_enable_return_value(with_value);
- return node;
- }
- //////////////////////////////////////////
- ////////////////CONDITION/////////////////
- //////////////////////////////////////////
- int VisualScriptCondition::get_output_sequence_port_count() const {
- return 3;
- }
- bool VisualScriptCondition::has_input_sequence_port() const {
- return true;
- }
- int VisualScriptCondition::get_input_value_port_count() const {
- return 1;
- }
- int VisualScriptCondition::get_output_value_port_count() const {
- return 0;
- }
- String VisualScriptCondition::get_output_sequence_port_text(int p_port) const {
- if (p_port == 0) {
- return "true";
- } else if (p_port == 1) {
- return "false";
- } else {
- return "done";
- }
- }
- PropertyInfo VisualScriptCondition::get_input_value_port_info(int p_idx) const {
- PropertyInfo pinfo;
- pinfo.name = "cond";
- pinfo.type = Variant::BOOL;
- return pinfo;
- }
- PropertyInfo VisualScriptCondition::get_output_value_port_info(int p_idx) const {
- return PropertyInfo();
- }
- String VisualScriptCondition::get_caption() const {
- return RTR("Condition");
- }
- String VisualScriptCondition::get_text() const {
- return RTR("if (cond) is:");
- }
- void VisualScriptCondition::_bind_methods() {
- }
- class VisualScriptNodeInstanceCondition : public VisualScriptNodeInstance {
- public:
- VisualScriptCondition *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_CONTINUE_SEQUENCE) {
- return 2;
- } else if (p_inputs[0]->operator bool()) {
- return 0 | STEP_FLAG_PUSH_STACK_BIT;
- } else {
- return 1 | STEP_FLAG_PUSH_STACK_BIT;
- }
- }
- };
- VisualScriptNodeInstance *VisualScriptCondition::instance(VisualScriptInstance *p_instance) {
- VisualScriptNodeInstanceCondition *instance = memnew(VisualScriptNodeInstanceCondition);
- instance->node = this;
- instance->instance = p_instance;
- return instance;
- }
- VisualScriptCondition::VisualScriptCondition() {
- }
- //////////////////////////////////////////
- ////////////////WHILE/////////////////
- //////////////////////////////////////////
- int VisualScriptWhile::get_output_sequence_port_count() const {
- return 2;
- }
- bool VisualScriptWhile::has_input_sequence_port() const {
- return true;
- }
- int VisualScriptWhile::get_input_value_port_count() const {
- return 1;
- }
- int VisualScriptWhile::get_output_value_port_count() const {
- return 0;
- }
- String VisualScriptWhile::get_output_sequence_port_text(int p_port) const {
- if (p_port == 0) {
- return "repeat";
- } else {
- return "exit";
- }
- }
- PropertyInfo VisualScriptWhile::get_input_value_port_info(int p_idx) const {
- PropertyInfo pinfo;
- pinfo.name = "cond";
- pinfo.type = Variant::BOOL;
- return pinfo;
- }
- PropertyInfo VisualScriptWhile::get_output_value_port_info(int p_idx) const {
- return PropertyInfo();
- }
- String VisualScriptWhile::get_caption() const {
- return RTR("While");
- }
- String VisualScriptWhile::get_text() const {
- return RTR("while (cond):");
- }
- void VisualScriptWhile::_bind_methods() {
- }
- class VisualScriptNodeInstanceWhile : public VisualScriptNodeInstance {
- public:
- VisualScriptWhile *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) {
- bool keep_going = p_inputs[0]->operator bool();
- if (keep_going) {
- return 0 | STEP_FLAG_PUSH_STACK_BIT;
- } else {
- return 1;
- }
- }
- };
- VisualScriptNodeInstance *VisualScriptWhile::instance(VisualScriptInstance *p_instance) {
- VisualScriptNodeInstanceWhile *instance = memnew(VisualScriptNodeInstanceWhile);
- instance->node = this;
- instance->instance = p_instance;
- return instance;
- }
- VisualScriptWhile::VisualScriptWhile() {
- }
- //////////////////////////////////////////
- ////////////////ITERATOR/////////////////
- //////////////////////////////////////////
- int VisualScriptIterator::get_output_sequence_port_count() const {
- return 2;
- }
- bool VisualScriptIterator::has_input_sequence_port() const {
- return true;
- }
- int VisualScriptIterator::get_input_value_port_count() const {
- return 1;
- }
- int VisualScriptIterator::get_output_value_port_count() const {
- return 1;
- }
- String VisualScriptIterator::get_output_sequence_port_text(int p_port) const {
- if (p_port == 0) {
- return "each";
- } else {
- return "exit";
- }
- }
- PropertyInfo VisualScriptIterator::get_input_value_port_info(int p_idx) const {
- PropertyInfo pinfo;
- pinfo.name = "input";
- pinfo.type = Variant::NIL;
- return pinfo;
- }
- PropertyInfo VisualScriptIterator::get_output_value_port_info(int p_idx) const {
- PropertyInfo pinfo;
- pinfo.name = "elem";
- pinfo.type = Variant::NIL;
- return pinfo;
- }
- String VisualScriptIterator::get_caption() const {
- return RTR("Iterator");
- }
- String VisualScriptIterator::get_text() const {
- return RTR("for (elem) in (input):");
- }
- void VisualScriptIterator::_bind_methods() {
- }
- class VisualScriptNodeInstanceIterator : public VisualScriptNodeInstance {
- public:
- VisualScriptIterator *node;
- VisualScriptInstance *instance;
- virtual int get_working_memory_size() const { return 2; }
- //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_BEGIN_SEQUENCE) {
- p_working_mem[0] = *p_inputs[0];
- bool valid;
- bool can_iter = p_inputs[0]->iter_init(p_working_mem[1], valid);
- if (!valid) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
- r_error_str = RTR("Input type not iterable:") + " " + Variant::get_type_name(p_inputs[0]->get_type());
- return 0;
- }
- if (!can_iter) {
- return 1; //nothing to iterate
- }
- *p_outputs[0] = p_working_mem[0].iter_get(p_working_mem[1], valid);
- if (!valid) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
- r_error_str = RTR("Iterator became invalid");
- return 0;
- }
- } else { //continue sequence
- bool valid;
- bool can_iter = p_working_mem[0].iter_next(p_working_mem[1], valid);
- if (!valid) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
- r_error_str = RTR("Iterator became invalid:") + " " + Variant::get_type_name(p_inputs[0]->get_type());
- return 0;
- }
- if (!can_iter) {
- return 1; //nothing to iterate
- }
- *p_outputs[0] = p_working_mem[0].iter_get(p_working_mem[1], valid);
- if (!valid) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
- r_error_str = RTR("Iterator became invalid");
- return 0;
- }
- }
- return 0 | STEP_FLAG_PUSH_STACK_BIT; //go around
- }
- };
- VisualScriptNodeInstance *VisualScriptIterator::instance(VisualScriptInstance *p_instance) {
- VisualScriptNodeInstanceIterator *instance = memnew(VisualScriptNodeInstanceIterator);
- instance->node = this;
- instance->instance = p_instance;
- return instance;
- }
- VisualScriptIterator::VisualScriptIterator() {
- }
- //////////////////////////////////////////
- ////////////////SEQUENCE/////////////////
- //////////////////////////////////////////
- int VisualScriptSequence::get_output_sequence_port_count() const {
- return steps;
- }
- bool VisualScriptSequence::has_input_sequence_port() const {
- return true;
- }
- int VisualScriptSequence::get_input_value_port_count() const {
- return 0;
- }
- int VisualScriptSequence::get_output_value_port_count() const {
- return 1;
- }
- String VisualScriptSequence::get_output_sequence_port_text(int p_port) const {
- return itos(p_port + 1);
- }
- PropertyInfo VisualScriptSequence::get_input_value_port_info(int p_idx) const {
- return PropertyInfo();
- }
- PropertyInfo VisualScriptSequence::get_output_value_port_info(int p_idx) const {
- return PropertyInfo(Variant::INT, "current");
- }
- String VisualScriptSequence::get_caption() const {
- return RTR("Sequence");
- }
- String VisualScriptSequence::get_text() const {
- return RTR("in order:");
- }
- void VisualScriptSequence::set_steps(int p_steps) {
- ERR_FAIL_COND(p_steps < 1);
- if (steps == p_steps) {
- return;
- }
- steps = p_steps;
- ports_changed_notify();
- }
- int VisualScriptSequence::get_steps() const {
- return steps;
- }
- void VisualScriptSequence::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_steps", "steps"), &VisualScriptSequence::set_steps);
- ClassDB::bind_method(D_METHOD("get_steps"), &VisualScriptSequence::get_steps);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "steps", PROPERTY_HINT_RANGE, "1,64,1"), "set_steps", "get_steps");
- }
- class VisualScriptNodeInstanceSequence : public VisualScriptNodeInstance {
- public:
- VisualScriptSequence *node;
- VisualScriptInstance *instance;
- int steps;
- 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_BEGIN_SEQUENCE) {
- p_working_mem[0] = 0;
- }
- int step = p_working_mem[0];
- *p_outputs[0] = step;
- if (step + 1 == steps) {
- return step;
- } else {
- p_working_mem[0] = step + 1;
- return step | STEP_FLAG_PUSH_STACK_BIT;
- }
- }
- };
- VisualScriptNodeInstance *VisualScriptSequence::instance(VisualScriptInstance *p_instance) {
- VisualScriptNodeInstanceSequence *instance = memnew(VisualScriptNodeInstanceSequence);
- instance->node = this;
- instance->instance = p_instance;
- instance->steps = steps;
- return instance;
- }
- VisualScriptSequence::VisualScriptSequence() {
- steps = 1;
- }
- //////////////////////////////////////////
- ////////////////EVENT TYPE FILTER///////////
- //////////////////////////////////////////
- int VisualScriptSwitch::get_output_sequence_port_count() const {
- return case_values.size() + 1;
- }
- bool VisualScriptSwitch::has_input_sequence_port() const {
- return true;
- }
- int VisualScriptSwitch::get_input_value_port_count() const {
- return case_values.size() + 1;
- }
- int VisualScriptSwitch::get_output_value_port_count() const {
- return 0;
- }
- String VisualScriptSwitch::get_output_sequence_port_text(int p_port) const {
- if (p_port == case_values.size()) {
- return "done";
- }
- return String();
- }
- PropertyInfo VisualScriptSwitch::get_input_value_port_info(int p_idx) const {
- if (p_idx < case_values.size()) {
- return PropertyInfo(case_values[p_idx].type, " =");
- } else {
- return PropertyInfo(Variant::NIL, "input");
- }
- }
- PropertyInfo VisualScriptSwitch::get_output_value_port_info(int p_idx) const {
- return PropertyInfo();
- }
- String VisualScriptSwitch::get_caption() const {
- return RTR("Switch");
- }
- String VisualScriptSwitch::get_text() const {
- return RTR("'input' is:");
- }
- class VisualScriptNodeInstanceSwitch : public VisualScriptNodeInstance {
- public:
- VisualScriptInstance *instance;
- int case_count;
- //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 (p_start_mode == START_MODE_CONTINUE_SEQUENCE) {
- return case_count; //exit
- }
- for (int i = 0; i < case_count; i++) {
- if (*p_inputs[i] == *p_inputs[case_count]) {
- return i | STEP_FLAG_PUSH_STACK_BIT;
- }
- }
- return case_count;
- }
- };
- VisualScriptNodeInstance *VisualScriptSwitch::instance(VisualScriptInstance *p_instance) {
- VisualScriptNodeInstanceSwitch *instance = memnew(VisualScriptNodeInstanceSwitch);
- instance->instance = p_instance;
- instance->case_count = case_values.size();
- return instance;
- }
- bool VisualScriptSwitch::_set(const StringName &p_name, const Variant &p_value) {
- if (String(p_name) == "case_count") {
- case_values.resize(p_value);
- _change_notify();
- ports_changed_notify();
- return true;
- }
- if (String(p_name).begins_with("case/")) {
- int idx = String(p_name).get_slice("/", 1).to_int();
- ERR_FAIL_INDEX_V(idx, case_values.size(), false);
- case_values.write[idx].type = Variant::Type(int(p_value));
- _change_notify();
- ports_changed_notify();
- return true;
- }
- return false;
- }
- bool VisualScriptSwitch::_get(const StringName &p_name, Variant &r_ret) const {
- if (String(p_name) == "case_count") {
- r_ret = case_values.size();
- return true;
- }
- if (String(p_name).begins_with("case/")) {
- int idx = String(p_name).get_slice("/", 1).to_int();
- ERR_FAIL_INDEX_V(idx, case_values.size(), false);
- r_ret = case_values[idx].type;
- return true;
- }
- return false;
- }
- void VisualScriptSwitch::_get_property_list(List<PropertyInfo> *p_list) const {
- p_list->push_back(PropertyInfo(Variant::INT, "case_count", PROPERTY_HINT_RANGE, "0,128"));
- String argt = "Any";
- for (int i = 1; i < Variant::VARIANT_MAX; i++) {
- argt += "," + Variant::get_type_name(Variant::Type(i));
- }
- for (int i = 0; i < case_values.size(); i++) {
- p_list->push_back(PropertyInfo(Variant::INT, "case/" + itos(i), PROPERTY_HINT_ENUM, argt));
- }
- }
- void VisualScriptSwitch::_bind_methods() {
- }
- VisualScriptSwitch::VisualScriptSwitch() {
- }
- //////////////////////////////////////////
- ////////////////TYPE CAST///////////
- //////////////////////////////////////////
- int VisualScriptTypeCast::get_output_sequence_port_count() const {
- return 2;
- }
- bool VisualScriptTypeCast::has_input_sequence_port() const {
- return true;
- }
- int VisualScriptTypeCast::get_input_value_port_count() const {
- return 1;
- }
- int VisualScriptTypeCast::get_output_value_port_count() const {
- return 1;
- }
- String VisualScriptTypeCast::get_output_sequence_port_text(int p_port) const {
- return p_port == 0 ? "yes" : "no";
- }
- PropertyInfo VisualScriptTypeCast::get_input_value_port_info(int p_idx) const {
- return PropertyInfo(Variant::OBJECT, "instance");
- }
- PropertyInfo VisualScriptTypeCast::get_output_value_port_info(int p_idx) const {
- return PropertyInfo(Variant::OBJECT, "", PROPERTY_HINT_TYPE_STRING, get_base_type());
- }
- String VisualScriptTypeCast::get_caption() const {
- return RTR("Type Cast");
- }
- String VisualScriptTypeCast::get_text() const {
- if (script != String()) {
- return vformat(RTR("Is %s?"), script.get_file());
- } else {
- return vformat(RTR("Is %s?"), base_type);
- }
- }
- void VisualScriptTypeCast::set_base_type(const StringName &p_type) {
- if (base_type == p_type) {
- return;
- }
- base_type = p_type;
- _change_notify();
- ports_changed_notify();
- }
- StringName VisualScriptTypeCast::get_base_type() const {
- return base_type;
- }
- void VisualScriptTypeCast::set_base_script(const String &p_path) {
- if (script == p_path) {
- return;
- }
- script = p_path;
- _change_notify();
- ports_changed_notify();
- }
- String VisualScriptTypeCast::get_base_script() const {
- return script;
- }
- VisualScriptTypeCast::TypeGuess VisualScriptTypeCast::guess_output_type(TypeGuess *p_inputs, int p_output) const {
- TypeGuess tg;
- tg.type = Variant::OBJECT;
- if (script != String()) {
- tg.script = ResourceLoader::load(script);
- }
- //if (!tg.script.is_valid()) {
- // tg.gdclass = base_type;
- //}
- return tg;
- }
- class VisualScriptNodeInstanceTypeCast : public VisualScriptNodeInstance {
- public:
- VisualScriptInstance *instance;
- StringName base_type;
- String script;
- //virtual int get_working_memory_size() const { return 0; }
- //virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
- //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return false; }
- virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
- Object *obj = *p_inputs[0];
- *p_outputs[0] = Variant();
- if (!obj) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
- r_error_str = "Instance is null";
- return 0;
- }
- if (script != String()) {
- Ref<Script> obj_script = obj->get_script();
- if (!obj_script.is_valid()) {
- return 1; //well, definitely not the script because object we got has no script.
- }
- if (!ResourceCache::has(script)) {
- //if the script is not in use by anyone, we can safely assume whatever we got is not casting to it.
- return 1;
- }
- Ref<Script> cast_script = Ref<Resource>(ResourceCache::get(script));
- if (!cast_script.is_valid()) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
- r_error_str = "Script path is not a script: " + script;
- return 1;
- }
- while (obj_script.is_valid()) {
- if (cast_script == obj_script) {
- *p_outputs[0] = *p_inputs[0]; //copy
- return 0; // it is the script, yey
- }
- obj_script = obj_script->get_base_script();
- }
- return 1; //not found sorry
- }
- if (ClassDB::is_parent_class(obj->get_class_name(), base_type)) {
- *p_outputs[0] = *p_inputs[0]; //copy
- return 0;
- } else {
- return 1;
- }
- }
- };
- VisualScriptNodeInstance *VisualScriptTypeCast::instance(VisualScriptInstance *p_instance) {
- VisualScriptNodeInstanceTypeCast *instance = memnew(VisualScriptNodeInstanceTypeCast);
- instance->instance = p_instance;
- instance->base_type = base_type;
- instance->script = script;
- return instance;
- }
- void VisualScriptTypeCast::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_base_type", "type"), &VisualScriptTypeCast::set_base_type);
- ClassDB::bind_method(D_METHOD("get_base_type"), &VisualScriptTypeCast::get_base_type);
- ClassDB::bind_method(D_METHOD("set_base_script", "path"), &VisualScriptTypeCast::set_base_script);
- ClassDB::bind_method(D_METHOD("get_base_script"), &VisualScriptTypeCast::get_base_script);
- List<String> script_extensions;
- for (int i = 0; i > ScriptServer::get_language_count(); i++) {
- ScriptServer::get_language(i)->get_recognized_extensions(&script_extensions);
- }
- String script_ext_hint;
- for (List<String>::Element *E = script_extensions.front(); E; E = E->next()) {
- if (script_ext_hint != String()) {
- script_ext_hint += ",";
- }
- script_ext_hint += "*." + E->get();
- }
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_type", PROPERTY_HINT_TYPE_STRING, "Object"), "set_base_type", "get_base_type");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_script", PROPERTY_HINT_FILE, script_ext_hint), "set_base_script", "get_base_script");
- }
- VisualScriptTypeCast::VisualScriptTypeCast() {
- base_type = "Object";
- }
- void register_visual_script_flow_control_nodes() {
- VisualScriptLanguage::singleton->add_register_func("flow_control/return", create_return_node<false>);
- VisualScriptLanguage::singleton->add_register_func("flow_control/return_with_value", create_return_node<true>);
- VisualScriptLanguage::singleton->add_register_func("flow_control/condition", create_node_generic<VisualScriptCondition>);
- VisualScriptLanguage::singleton->add_register_func("flow_control/while", create_node_generic<VisualScriptWhile>);
- VisualScriptLanguage::singleton->add_register_func("flow_control/iterator", create_node_generic<VisualScriptIterator>);
- VisualScriptLanguage::singleton->add_register_func("flow_control/sequence", create_node_generic<VisualScriptSequence>);
- VisualScriptLanguage::singleton->add_register_func("flow_control/switch", create_node_generic<VisualScriptSwitch>);
- //VisualScriptLanguage::singleton->add_register_func("flow_control/input_filter", create_node_generic<VisualScriptInputFilter>);
- VisualScriptLanguage::singleton->add_register_func("flow_control/type_cast", create_node_generic<VisualScriptTypeCast>);
- }
|