From 885b74a845b4bf880fce3fcc55152d6ea97f385c Mon Sep 17 00:00:00 2001 From: Rodolphe Suescun Date: Sat, 19 Oct 2019 01:30:25 +0200 Subject: [PATCH] Detect loops when connecting nodes and make sure Material cannot be deleted --- addons/material_maker/engine/gen_base.gd | 10 ++++++++++ addons/material_maker/engine/gen_graph.gd | 13 +++++++++++-- addons/material_maker/engine/gen_material.gd | 3 +++ addons/material_maker/engine/loader.gd | 4 ++-- addons/material_maker/main_window.tscn | 10 +++++----- addons/material_maker/nodes/generic.gd | 4 +++- 6 files changed, 34 insertions(+), 10 deletions(-) diff --git a/addons/material_maker/engine/gen_base.gd b/addons/material_maker/engine/gen_base.gd index 328e3fc..c295ce2 100644 --- a/addons/material_maker/engine/gen_base.gd +++ b/addons/material_maker/engine/gen_base.gd @@ -37,6 +37,9 @@ var parameters = {} func _ready(): init_parameters() +func can_be_deleted() -> bool: + return true + func init_parameters(): for p in get_parameter_defs(): if !parameters.has(p.name): @@ -86,6 +89,13 @@ func get_source(input_index : int): func get_targets(output_index : int): return get_parent().get_port_targets(name, output_index) +# get the list of outputs that depend on the input whose index is passed as parameter +func follow_input(input_index : int) -> Array: + var rv = [] + for i in range(get_output_defs().size()): + rv.push_back(OutputPort.new(self, i)) + return rv + func get_input_shader(input_index : int): var source = get_source(input_index) if source != null: diff --git a/addons/material_maker/engine/gen_graph.gd b/addons/material_maker/engine/gen_graph.gd index 6862c8b..0fe89e8 100644 --- a/addons/material_maker/engine/gen_graph.gd +++ b/addons/material_maker/engine/gen_graph.gd @@ -49,7 +49,7 @@ func get_port_source(gen_name: String, input_index: int) -> OutputPort: return OutputPort.new(src_gen, c.from_port) return null -func get_port_targets(gen_name: String, output_index: int) -> InputPort: +func get_port_targets(gen_name: String, output_index: int) -> Array: var rv = [] for c in connections: if c.from == gen_name and c.from_port == output_index: @@ -83,6 +83,15 @@ func replace_generator(old : MMGenBase, new : MMGenBase): add_child(new) func connect_children(from, from_port : int, to, to_port : int): + # check the new connection does not create a loop + var spreadlist = [ InputPort.new(to, to_port) ] + while !spreadlist.empty(): + var input : InputPort = spreadlist.pop_front() + for o in input.generator.follow_input(input.input_index): + if o.generator == from and o.output_index == from_port: + return false + for t in o.generator.get_parent().get_port_targets(o.generator.name, o.output_index): + spreadlist.push_back(t) # disconnect target while true: var remove = -1 @@ -198,6 +207,6 @@ func create_subgraph(gens): connections = my_new_connections new_graph.connections = new_graph_connections for g in generators: - if g is MMGenRemote: + if g.get_script() == load("res://addons/material_maker/engine/gen_remote.gd"): g.name = "gen_parameters" break diff --git a/addons/material_maker/engine/gen_material.gd b/addons/material_maker/engine/gen_material.gd index dd8476d..8d22aa0 100644 --- a/addons/material_maker/engine/gen_material.gd +++ b/addons/material_maker/engine/gen_material.gd @@ -21,6 +21,9 @@ func _ready(): generated_textures[t.texture] = null material = SpatialMaterial.new() +func can_be_deleted() -> bool: + return false + func get_type(): return "material" diff --git a/addons/material_maker/engine/loader.gd b/addons/material_maker/engine/loader.gd index e78be03..983ebfa 100644 --- a/addons/material_maker/engine/loader.gd +++ b/addons/material_maker/engine/loader.gd @@ -31,8 +31,8 @@ static func add_to_gen_graph(gen_graph, generators, connections): if gennames.has(c.from) and gennames.has(c.to): c.from = gennames[c.from] c.to = gennames[c.to] - gen_graph.connections.append(c) - rv.connections.append(c) + if gen_graph.connect_children(gen_graph.get_node(c.from), c.from_port, gen_graph.get_node(c.to), c.to_port): + rv.connections.append(c) return rv static func create_gen(data) -> MMGenBase: diff --git a/addons/material_maker/main_window.tscn b/addons/material_maker/main_window.tscn index ba08605..84d6414 100644 --- a/addons/material_maker/main_window.tscn +++ b/addons/material_maker/main_window.tscn @@ -41,35 +41,35 @@ margin_bottom = 20.0 margin_right = 35.0 margin_bottom = 20.0 text = "File" -items = [ "New material", null, 0, false, false, 0, 0, null, "", false, "Load material", null, 0, false, false, 1, 134217807, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "Save material", null, 0, false, false, 4, 134217811, null, "", false, "Save material as...", null, 0, false, false, 5, 167772243, null, "", false, "Save all materials...", null, 0, false, false, 6, 0, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "Export material", null, 0, false, false, 8, 134217797, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "Close material", null, 0, false, false, 10, 0, null, "", false, "Quit", null, 0, false, false, 11, 134217809, null, "", false ] +items = [ "New material", null, 0, false, false, 0, 0, null, "", false, "Load material", null, 0, false, false, 1, 268435535, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "Save material", null, 0, false, false, 4, 268435539, null, "", false, "Save material as...", null, 0, false, false, 5, 301989971, null, "", false, "Save all materials...", null, 0, false, false, 6, 0, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "Export material", null, 0, false, false, 8, 268435525, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "Close material", null, 0, false, false, 10, 0, null, "", false, "Quit", null, 0, false, false, 11, 268435537, null, "", false ] [node name="Edit" type="MenuButton" parent="VBoxContainer/Menu"] margin_left = 39.0 margin_right = 75.0 margin_bottom = 20.0 text = "Edit" -items = [ "Cut", null, 0, false, false, 12, 134217816, null, "", false, "Copy", null, 0, false, false, 13, 134217795, null, "", false, "Paste", null, 0, false, false, 14, 134217814, null, "", false ] +items = [ "Cut", null, 0, false, false, 12, 268435544, null, "", false, "Copy", null, 0, false, false, 13, 268435523, null, "", false, "Paste", null, 0, false, false, 14, 268435542, null, "", false ] [node name="View" type="MenuButton" parent="VBoxContainer/Menu"] margin_left = 79.0 margin_right = 121.0 margin_bottom = 20.0 text = "View" -items = [ "Cut", null, 0, false, false, 12, 134217816, null, "", false, "Copy", null, 0, false, false, 13, 134217795, null, "", false, "Paste", null, 0, false, false, 14, 134217814, null, "", false ] +items = [ "Center view", null, 0, false, false, 15, 67, null, "", false, "Reset zoom", null, 0, false, false, 16, 268435504, null, "", false ] [node name="Tools" type="MenuButton" parent="VBoxContainer/Menu"] margin_left = 125.0 margin_right = 171.0 margin_bottom = 20.0 text = "Tools" -items = [ "Create", null, 0, false, false, -1, 0, null, "PopupMenu", false, "Create group", null, 0, false, false, 16, 134217799, null, "", false, "Make selected nodes editable", null, 0, false, false, 17, 134217798, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "Add selected node to user library", null, 0, false, false, 19, 0, null, "", false, "Save user library", null, 0, false, false, 20, 0, null, "", false ] +items = [ "Create", null, 0, false, false, -1, 0, null, "PopupMenu", false, "Create group", null, 0, false, false, 18, 268435527, null, "", false, "Make selected nodes editable", null, 0, false, false, 19, 268435526, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "Add selected node to user library", null, 0, false, false, 21, 0, null, "", false, "Save user library", null, 0, false, false, 22, 0, null, "", false ] [node name="Help" type="MenuButton" parent="VBoxContainer/Menu"] margin_left = 175.0 margin_right = 217.0 margin_bottom = 20.0 text = "Help" -items = [ "User manual", null, 0, false, false, 21, 0, null, "", false, "Report a bug", null, 0, false, false, 22, 0, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "About", null, 0, false, false, 24, 0, null, "", false ] +items = [ "User manual", null, 0, false, false, 23, 0, null, "", false, "Report a bug", null, 0, false, false, 24, 0, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "About", null, 0, false, false, 26, 0, null, "", false ] [node name="HBoxContainer" type="HSplitContainer" parent="VBoxContainer"] margin_top = 24.0 diff --git a/addons/material_maker/nodes/generic.gd b/addons/material_maker/nodes/generic.gd index 4d17227..01321c1 100644 --- a/addons/material_maker/nodes/generic.gd +++ b/addons/material_maker/nodes/generic.gd @@ -2,7 +2,7 @@ tool extends GraphNode class_name MMGraphNodeGeneric -var generator = null setget set_generator +var generator : MMGenBase = null setget set_generator var controls = {} var ignore_parameter_change = "" @@ -152,6 +152,8 @@ func update_node(): remove_child(c) c.free() rect_size = Vector2(0, 0) + # Show or hide the close button + show_close = generator.can_be_deleted() # Rebuild node title = generator.get_type_name() # Inputs