|
@@ -355,6 +355,441 @@ int VisualScriptFunction::get_stack_size() const {
|
|
|
return stack_size;
|
|
|
}
|
|
|
|
|
|
+//////////////////////////////////////////
|
|
|
+/////////////////LISTS////////////////////
|
|
|
+//////////////////////////////////////////
|
|
|
+
|
|
|
+int VisualScriptLists::get_output_sequence_port_count() const {
|
|
|
+ if (sequenced)
|
|
|
+ return 1;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+bool VisualScriptLists::has_input_sequence_port() const {
|
|
|
+ return sequenced;
|
|
|
+}
|
|
|
+
|
|
|
+String VisualScriptLists::get_output_sequence_port_text(int p_port) const {
|
|
|
+ return "";
|
|
|
+}
|
|
|
+
|
|
|
+int VisualScriptLists::get_input_value_port_count() const {
|
|
|
+ return inputports.size();
|
|
|
+}
|
|
|
+int VisualScriptLists::get_output_value_port_count() const {
|
|
|
+ return outputports.size();
|
|
|
+}
|
|
|
+
|
|
|
+PropertyInfo VisualScriptLists::get_input_value_port_info(int p_idx) const {
|
|
|
+ ERR_FAIL_INDEX_V(p_idx, inputports.size(), PropertyInfo());
|
|
|
+
|
|
|
+ PropertyInfo pi;
|
|
|
+ pi.name = inputports[p_idx].name;
|
|
|
+ pi.type = inputports[p_idx].type;
|
|
|
+ return pi;
|
|
|
+}
|
|
|
+PropertyInfo VisualScriptLists::get_output_value_port_info(int p_idx) const {
|
|
|
+ ERR_FAIL_INDEX_V(p_idx, outputports.size(), PropertyInfo());
|
|
|
+
|
|
|
+ PropertyInfo pi;
|
|
|
+ pi.name = outputports[p_idx].name;
|
|
|
+ pi.type = outputports[p_idx].type;
|
|
|
+ return pi;
|
|
|
+}
|
|
|
+
|
|
|
+bool VisualScriptLists::is_input_port_editable() const {
|
|
|
+ return ((flags & INPUT_EDITABLE) == INPUT_EDITABLE);
|
|
|
+}
|
|
|
+bool VisualScriptLists::is_input_port_name_editable() const {
|
|
|
+ return ((flags & INPUT_NAME_EDITABLE) == INPUT_NAME_EDITABLE);
|
|
|
+}
|
|
|
+bool VisualScriptLists::is_input_port_type_editable() const {
|
|
|
+ return ((flags & INPUT_TYPE_EDITABLE) == INPUT_TYPE_EDITABLE);
|
|
|
+}
|
|
|
+
|
|
|
+bool VisualScriptLists::is_output_port_editable() const {
|
|
|
+ return ((flags & OUTPUT_EDITABLE) == OUTPUT_EDITABLE);
|
|
|
+}
|
|
|
+bool VisualScriptLists::is_output_port_name_editable() const {
|
|
|
+ return ((flags & INPUT_NAME_EDITABLE) == INPUT_NAME_EDITABLE);
|
|
|
+}
|
|
|
+bool VisualScriptLists::is_output_port_type_editable() const {
|
|
|
+ return ((flags & INPUT_TYPE_EDITABLE) == INPUT_TYPE_EDITABLE);
|
|
|
+}
|
|
|
+
|
|
|
+// for the inspector
|
|
|
+bool VisualScriptLists::_set(const StringName &p_name, const Variant &p_value) {
|
|
|
+
|
|
|
+ if (p_name == "input_count" && is_input_port_editable()) {
|
|
|
+
|
|
|
+ int new_argc = p_value;
|
|
|
+ int argc = inputports.size();
|
|
|
+ if (argc == new_argc)
|
|
|
+ return true;
|
|
|
+
|
|
|
+ inputports.resize(new_argc);
|
|
|
+
|
|
|
+ for (int i = argc; i < new_argc; i++) {
|
|
|
+ inputports.write[i].name = "arg" + itos(i + 1);
|
|
|
+ inputports.write[i].type = Variant::NIL;
|
|
|
+ }
|
|
|
+ ports_changed_notify();
|
|
|
+ _change_notify();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (String(p_name).begins_with("input_") && is_input_port_editable()) {
|
|
|
+ int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int() - 1;
|
|
|
+ ERR_FAIL_INDEX_V(idx, inputports.size(), false);
|
|
|
+ String what = String(p_name).get_slice("/", 1);
|
|
|
+ if (what == "type") {
|
|
|
+
|
|
|
+ Variant::Type new_type = Variant::Type(int(p_value));
|
|
|
+ inputports.write[idx].type = new_type;
|
|
|
+ ports_changed_notify();
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (what == "name") {
|
|
|
+
|
|
|
+ inputports.write[idx].name = p_value;
|
|
|
+ ports_changed_notify();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (p_name == "output_count" && is_output_port_editable()) {
|
|
|
+
|
|
|
+ int new_argc = p_value;
|
|
|
+ int argc = outputports.size();
|
|
|
+ if (argc == new_argc)
|
|
|
+ return true;
|
|
|
+
|
|
|
+ outputports.resize(new_argc);
|
|
|
+
|
|
|
+ for (int i = argc; i < new_argc; i++) {
|
|
|
+ outputports.write[i].name = "arg" + itos(i + 1);
|
|
|
+ outputports.write[i].type = Variant::NIL;
|
|
|
+ }
|
|
|
+ ports_changed_notify();
|
|
|
+ _change_notify();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (String(p_name).begins_with("output_") && is_output_port_editable()) {
|
|
|
+ int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int() - 1;
|
|
|
+ ERR_FAIL_INDEX_V(idx, outputports.size(), false);
|
|
|
+ String what = String(p_name).get_slice("/", 1);
|
|
|
+ if (what == "type") {
|
|
|
+
|
|
|
+ Variant::Type new_type = Variant::Type(int(p_value));
|
|
|
+ outputports.write[idx].type = new_type;
|
|
|
+ ports_changed_notify();
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (what == "name") {
|
|
|
+
|
|
|
+ outputports.write[idx].name = p_value;
|
|
|
+ ports_changed_notify();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (p_name == "sequenced/sequenced") {
|
|
|
+ sequenced = p_value;
|
|
|
+ ports_changed_notify();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
+bool VisualScriptLists::_get(const StringName &p_name, Variant &r_ret) const {
|
|
|
+
|
|
|
+ if (p_name == "input_count" && is_input_port_editable()) {
|
|
|
+ r_ret = inputports.size();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (String(p_name).begins_with("input_") && is_input_port_editable()) {
|
|
|
+ int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int() - 1;
|
|
|
+ ERR_FAIL_INDEX_V(idx, inputports.size(), false);
|
|
|
+ String what = String(p_name).get_slice("/", 1);
|
|
|
+ if (what == "type") {
|
|
|
+ r_ret = inputports[idx].type;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (what == "name") {
|
|
|
+ r_ret = inputports[idx].name;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (p_name == "output_count" && is_output_port_editable()) {
|
|
|
+ r_ret = outputports.size();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (String(p_name).begins_with("output_") && is_output_port_editable()) {
|
|
|
+ int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int() - 1;
|
|
|
+ ERR_FAIL_INDEX_V(idx, outputports.size(), false);
|
|
|
+ String what = String(p_name).get_slice("/", 1);
|
|
|
+ if (what == "type") {
|
|
|
+ r_ret = outputports[idx].type;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (what == "name") {
|
|
|
+ r_ret = outputports[idx].name;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (p_name == "sequenced/sequenced") {
|
|
|
+ r_ret = sequenced;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
+void VisualScriptLists::_get_property_list(List<PropertyInfo> *p_list) const {
|
|
|
+
|
|
|
+ if (is_input_port_editable()) {
|
|
|
+ p_list->push_back(PropertyInfo(Variant::INT, "input_count", PROPERTY_HINT_RANGE, "0,256"));
|
|
|
+ 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 < inputports.size(); i++) {
|
|
|
+ p_list->push_back(PropertyInfo(Variant::INT, "input_" + itos(i + 1) + "/type", PROPERTY_HINT_ENUM, argt));
|
|
|
+ p_list->push_back(PropertyInfo(Variant::STRING, "input_" + itos(i + 1) + "/name"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (is_output_port_editable()) {
|
|
|
+ p_list->push_back(PropertyInfo(Variant::INT, "output_count", PROPERTY_HINT_RANGE, "0,256"));
|
|
|
+ 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 < outputports.size(); i++) {
|
|
|
+ p_list->push_back(PropertyInfo(Variant::INT, "output_" + itos(i + 1) + "/type", PROPERTY_HINT_ENUM, argt));
|
|
|
+ p_list->push_back(PropertyInfo(Variant::STRING, "output_" + itos(i + 1) + "/name"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ p_list->push_back(PropertyInfo(Variant::BOOL, "sequenced/sequenced"));
|
|
|
+}
|
|
|
+
|
|
|
+// input data port interaction
|
|
|
+void VisualScriptLists::add_input_data_port(Variant::Type p_type, const String &p_name, int p_index) {
|
|
|
+
|
|
|
+ if (!is_input_port_editable())
|
|
|
+ return;
|
|
|
+
|
|
|
+ Port inp;
|
|
|
+ inp.name = p_name;
|
|
|
+ inp.type = p_type;
|
|
|
+ if (p_index >= 0)
|
|
|
+ inputports.insert(p_index, inp);
|
|
|
+ else
|
|
|
+ inputports.push_back(inp);
|
|
|
+
|
|
|
+ ports_changed_notify();
|
|
|
+ _change_notify();
|
|
|
+}
|
|
|
+void VisualScriptLists::set_input_data_port_type(int p_idx, Variant::Type p_type) {
|
|
|
+
|
|
|
+ if (!is_input_port_type_editable())
|
|
|
+ return;
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_idx, inputports.size());
|
|
|
+
|
|
|
+ inputports.write[p_idx].type = p_type;
|
|
|
+ ports_changed_notify();
|
|
|
+ _change_notify();
|
|
|
+}
|
|
|
+void VisualScriptLists::set_input_data_port_name(int p_idx, const String &p_name) {
|
|
|
+
|
|
|
+ if (!is_input_port_name_editable())
|
|
|
+ return;
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_idx, inputports.size());
|
|
|
+
|
|
|
+ inputports.write[p_idx].name = p_name;
|
|
|
+ ports_changed_notify();
|
|
|
+ _change_notify();
|
|
|
+}
|
|
|
+void VisualScriptLists::remove_input_data_port(int p_argidx) {
|
|
|
+
|
|
|
+ if (!is_input_port_editable())
|
|
|
+ return;
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_argidx, inputports.size());
|
|
|
+
|
|
|
+ inputports.remove(p_argidx);
|
|
|
+
|
|
|
+ ports_changed_notify();
|
|
|
+ _change_notify();
|
|
|
+}
|
|
|
+
|
|
|
+// output data port interaction
|
|
|
+void VisualScriptLists::add_output_data_port(Variant::Type p_type, const String &p_name, int p_index) {
|
|
|
+
|
|
|
+ if (!is_output_port_editable())
|
|
|
+ return;
|
|
|
+
|
|
|
+ Port out;
|
|
|
+ out.name = p_name;
|
|
|
+ out.type = p_type;
|
|
|
+ if (p_index >= 0)
|
|
|
+ outputports.insert(p_index, out);
|
|
|
+ else
|
|
|
+ outputports.push_back(out);
|
|
|
+
|
|
|
+ ports_changed_notify();
|
|
|
+ _change_notify();
|
|
|
+}
|
|
|
+void VisualScriptLists::set_output_data_port_type(int p_idx, Variant::Type p_type) {
|
|
|
+
|
|
|
+ if (!is_output_port_type_editable())
|
|
|
+ return;
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_idx, outputports.size());
|
|
|
+
|
|
|
+ outputports.write[p_idx].type = p_type;
|
|
|
+ ports_changed_notify();
|
|
|
+ _change_notify();
|
|
|
+}
|
|
|
+void VisualScriptLists::set_output_data_port_name(int p_idx, const String &p_name) {
|
|
|
+
|
|
|
+ if (!is_output_port_name_editable())
|
|
|
+ return;
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_idx, outputports.size());
|
|
|
+
|
|
|
+ outputports.write[p_idx].name = p_name;
|
|
|
+ ports_changed_notify();
|
|
|
+ _change_notify();
|
|
|
+}
|
|
|
+void VisualScriptLists::remove_output_data_port(int p_argidx) {
|
|
|
+
|
|
|
+ if (!is_output_port_editable())
|
|
|
+ return;
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_argidx, outputports.size());
|
|
|
+
|
|
|
+ outputports.remove(p_argidx);
|
|
|
+
|
|
|
+ ports_changed_notify();
|
|
|
+ _change_notify();
|
|
|
+}
|
|
|
+
|
|
|
+// sequences
|
|
|
+void VisualScriptLists::set_sequenced(bool p_enable) {
|
|
|
+ if (sequenced == p_enable)
|
|
|
+ return;
|
|
|
+ sequenced = p_enable;
|
|
|
+ ports_changed_notify();
|
|
|
+}
|
|
|
+bool VisualScriptLists::is_sequenced() const {
|
|
|
+ return sequenced;
|
|
|
+}
|
|
|
+
|
|
|
+VisualScriptLists::VisualScriptLists() {
|
|
|
+ // initialize
|
|
|
+ sequenced = false;
|
|
|
+ flags = 0;
|
|
|
+}
|
|
|
+
|
|
|
+void VisualScriptLists::_bind_methods() {
|
|
|
+ ClassDB::bind_method(D_METHOD("add_input_data_port"), &VisualScriptLists::add_input_data_port);
|
|
|
+ ClassDB::bind_method(D_METHOD("set_input_data_port_name"), &VisualScriptLists::set_input_data_port_name);
|
|
|
+ ClassDB::bind_method(D_METHOD("set_input_data_port_type"), &VisualScriptLists::set_input_data_port_type);
|
|
|
+ ClassDB::bind_method(D_METHOD("remove_input_data_port"), &VisualScriptLists::remove_input_data_port);
|
|
|
+
|
|
|
+ ClassDB::bind_method(D_METHOD("add_output_data_port"), &VisualScriptLists::add_output_data_port);
|
|
|
+ ClassDB::bind_method(D_METHOD("set_output_data_port_name"), &VisualScriptLists::set_output_data_port_name);
|
|
|
+ ClassDB::bind_method(D_METHOD("set_output_data_port_type"), &VisualScriptLists::set_output_data_port_type);
|
|
|
+ ClassDB::bind_method(D_METHOD("remove_output_data_port"), &VisualScriptLists::remove_output_data_port);
|
|
|
+}
|
|
|
+
|
|
|
+//////////////////////////////////////////
|
|
|
+//////////////COMPOSEARRAY////////////////
|
|
|
+//////////////////////////////////////////
|
|
|
+
|
|
|
+int VisualScriptComposeArray::get_output_sequence_port_count() const {
|
|
|
+ if (sequenced)
|
|
|
+ return 1;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+bool VisualScriptComposeArray::has_input_sequence_port() const {
|
|
|
+ return sequenced;
|
|
|
+}
|
|
|
+
|
|
|
+String VisualScriptComposeArray::get_output_sequence_port_text(int p_port) const {
|
|
|
+ return "";
|
|
|
+}
|
|
|
+
|
|
|
+int VisualScriptComposeArray::get_input_value_port_count() const {
|
|
|
+ return inputports.size();
|
|
|
+}
|
|
|
+int VisualScriptComposeArray::get_output_value_port_count() const {
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+PropertyInfo VisualScriptComposeArray::get_input_value_port_info(int p_idx) const {
|
|
|
+ ERR_FAIL_INDEX_V(p_idx, inputports.size(), PropertyInfo());
|
|
|
+
|
|
|
+ PropertyInfo pi;
|
|
|
+ pi.name = inputports[p_idx].name;
|
|
|
+ pi.type = inputports[p_idx].type;
|
|
|
+ return pi;
|
|
|
+}
|
|
|
+PropertyInfo VisualScriptComposeArray::get_output_value_port_info(int p_idx) const {
|
|
|
+ PropertyInfo pi;
|
|
|
+ pi.name = "out";
|
|
|
+ pi.type = Variant::ARRAY;
|
|
|
+ return pi;
|
|
|
+}
|
|
|
+
|
|
|
+String VisualScriptComposeArray::get_caption() const {
|
|
|
+ return "Compose Array";
|
|
|
+}
|
|
|
+String VisualScriptComposeArray::get_text() const {
|
|
|
+ return "";
|
|
|
+}
|
|
|
+
|
|
|
+class VisualScriptComposeArrayNode : public VisualScriptNodeInstance {
|
|
|
+public:
|
|
|
+ int input_count = 0;
|
|
|
+ virtual int get_working_memory_size() const { return 0; }
|
|
|
+
|
|
|
+ virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Variant::CallError &r_error, String &r_error_str) {
|
|
|
+
|
|
|
+ if (input_count > 0) {
|
|
|
+ Array arr;
|
|
|
+ for (int i = 0; i < input_count; i++)
|
|
|
+ arr.push_back((*p_inputs[i]));
|
|
|
+ Variant va = Variant(arr);
|
|
|
+
|
|
|
+ *p_outputs[0] = va;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+VisualScriptNodeInstance *VisualScriptComposeArray::instance(VisualScriptInstance *p_instance) {
|
|
|
+
|
|
|
+ VisualScriptComposeArrayNode *instance = memnew(VisualScriptComposeArrayNode);
|
|
|
+ instance->input_count = inputports.size();
|
|
|
+ return instance;
|
|
|
+}
|
|
|
+
|
|
|
+VisualScriptComposeArray::VisualScriptComposeArray() {
|
|
|
+ // initialize stuff here
|
|
|
+ sequenced = false;
|
|
|
+ flags = INPUT_EDITABLE;
|
|
|
+}
|
|
|
+
|
|
|
//////////////////////////////////////////
|
|
|
////////////////OPERATOR//////////////////
|
|
|
//////////////////////////////////////////
|
|
@@ -3698,6 +4133,7 @@ void register_visual_script_nodes() {
|
|
|
VisualScriptLanguage::singleton->add_register_func("operators/logic/select", create_node_generic<VisualScriptSelect>);
|
|
|
|
|
|
VisualScriptLanguage::singleton->add_register_func("functions/deconstruct", create_node_generic<VisualScriptDeconstruct>);
|
|
|
+ VisualScriptLanguage::singleton->add_register_func("functions/compose_array", create_node_generic<VisualScriptComposeArray>);
|
|
|
|
|
|
for (int i = 1; i < Variant::VARIANT_MAX; i++) {
|
|
|
|