1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-05 12:10:55 +00:00

Visualscript editor graph unification & refactoring

Removes the need to have separate graphs per function for the VisualScript Nodes, and refactoring UI and other improvements such as fuzzy search, right click search boxes and in-graph editable nodes
This commit is contained in:
Swarnim Arun
2019-09-14 00:44:12 +05:30
parent edf9055b7f
commit 59738e3fa3
13 changed files with 2705 additions and 725 deletions

View File

@@ -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++) {