From 80d637c1d3818e63798e96bf5b7335195bfea307 Mon Sep 17 00:00:00 2001 From: easynam Date: Fri, 8 Oct 2021 00:47:13 +0100 Subject: [PATCH] Throw together some diff code in gen_graph allows making minimal changes when copying from a source graph, which should reduce the number of buffers that get needlessly recalculated --- addons/material_maker/engine/gen_graph.gd | 140 ++++++++++++++++++ .../panels/graph_edit/graph_edit.gd | 18 +-- 2 files changed, 143 insertions(+), 15 deletions(-) diff --git a/addons/material_maker/engine/gen_graph.gd b/addons/material_maker/engine/gen_graph.gd index 67b93eac..8a7c81a0 100644 --- a/addons/material_maker/engine/gen_graph.gd +++ b/addons/material_maker/engine/gen_graph.gd @@ -433,3 +433,143 @@ func _deserialize(data : Dictionary) -> void: longdesc = data.longdesc var nodes = data.nodes if data.has("nodes") else [] mm_loader.add_to_gen_graph(self, nodes, data.connections if data.has("connections") else []) + + +func apply_diff_from(graph : MMGenGraph) -> void: + shortdesc = graph.shortdesc + longdesc = graph.longdesc + + var child_names = [] + for c in get_children(): + child_names.append([c.name, c.get_type()]) + + child_names.sort_custom(self, "compare_name_and_type") + + var other_child_names = [] + for c in graph.get_children(): + other_child_names.append([c.name, c.get_type()]) + + other_child_names.sort_custom(self, "compare_name_and_type") + + var added = [] + var removed = [] + var maybe_changed = [] + + var idx1 = 0 + var idx2 = 0 + + while idx1 < child_names.size() && idx2 < other_child_names.size(): + if child_names[idx1] == other_child_names[idx2]: + maybe_changed.append(child_names[idx1]) + idx1 += 1 + idx2 += 1 + elif compare_name_and_type(child_names[idx1], other_child_names[idx2]): + remove_generator(get_node(child_names[idx1][0])) + idx1 += 1 + else: + var gen = graph.get_node(other_child_names[idx2][0]).serialize() + add_generator(mm_loader.create_gen(gen)) + idx2 += 1 + + while idx1 < child_names.size(): + remove_generator(get_node(child_names[idx1][0])) + idx1 += 1 + + while idx2 < other_child_names.size(): + var gen = graph.get_node(other_child_names[idx2][0]).serialize() + add_generator(mm_loader.create_gen(gen)) + idx2 += 1 + + for child in maybe_changed: + if child[1] == "graph": + var node = get_node(child[0]) + var other_node = graph.get_node(child[0]) + + node.apply_diff_from(other_node) + continue + + var node = get_node(child[0]) + var other_node = graph.get_node(child[0]) + + node.position = other_node.position + if other_node.seed_locked: + node.seed_locked = true + node.seed_value = other_node.seed_value + + var node_seed = node.seed_value + + var node_serialized = node.serialize() + var other_node_serialized = other_node.serialize() + node_serialized.erase("seed") + other_node_serialized.erase("seed") + + if node_serialized.hash() != other_node_serialized.hash(): + node.deserialize(other_node_serialized) + node.seed_value = node_seed + + diff_connections(graph) + fix_remotes() + +func diff_connections(graph : MMGenGraph): + var cons = [] + connections + cons.sort_custom(self, "compare_connection") + var other_cons = [] + graph.connections + other_cons.sort_custom(self, "compare_connection") + + var new_connections : Array = [] + var added_connections : Array = [] + var removed_connections : Array = [] + + var idx1 = 0 + var idx2 = 0 + + while idx1 < cons.size() && idx2 < other_cons.size(): + if cons[idx1].hash() == other_cons[idx2].hash(): + new_connections.append(cons[idx1]) + idx1 += 1 + idx2 += 1 + elif compare_connection(cons[idx1], other_cons[idx2]): + removed_connections.append(cons[idx1]) + idx1 += 1 + else: + added_connections.append(other_cons[idx2]) + new_connections.append(other_cons[idx2]) + idx2 += 1 + + while idx1 < cons.size(): + removed_connections.append(cons[idx1]) + idx1 += 1 + + while idx2 < other_cons.size(): + added_connections.append(other_cons[idx2]) + new_connections.append(other_cons[idx2]) + idx2 += 1 + + connections = new_connections + emit_signal("connections_changed", removed_connections, added_connections) + +func compare_name_and_type(a, b): + if a[0] < b[0]: + return true + elif a[0] > b[0]: + return false + + return a[1] < b[1] + +func compare_connection(a, b): + if a.from < b.from: + return true + elif a.from > b.from: + return false + + if a.from_port < b.from_port: + return true + elif a.from_port > b.from_port: + return false + + if a.to < b.to: + return true + elif a.to > b.to: + return false + + return a.to_port < b.to_port diff --git a/material_maker/panels/graph_edit/graph_edit.gd b/material_maker/panels/graph_edit/graph_edit.gd index 42d8bde0..0ce50576 100644 --- a/material_maker/panels/graph_edit/graph_edit.gd +++ b/material_maker/panels/graph_edit/graph_edit.gd @@ -728,20 +728,8 @@ func _on_ButtonRegenCopies_pressed(): if copy_from == null: continue - var data = copy_from.generator._serialize({}) - var param_data = copy_from.generator.get_node("gen_parameters")._serialize({}) - - for n in gen.get_children(): - gen.remove_child(n) - n.queue_free() - - data.label = label - gen._deserialize(data) - - var params = gen.get_node("gen_parameters") - params._deserialize(param_data) - gen.fix_remotes() - + gen.apply_diff_from(copy_from.generator) +# var main_window = get_node("/root/MainWindow") main_window.hierarchy.update_from_graph_edit(self) - update() + update_view(generator)