Pārlūkot izejas kodu

[shgraph] More intergration, added delete

Clément Espeute 1 gadu atpakaļ
vecāks
revīzija
a5ad351862

+ 56 - 0
hide/view/GraphEditor.hx

@@ -134,6 +134,10 @@ class GraphEditor extends hide.comp.Component {
 
 		editorMatrix = editorDisplay.group(editorDisplay.element);
 
+		var keys = new hide.ui.Keys(element);
+		keys.register("delete", deleteSelection);
+
+
 		// rectangle Selection
 		var rawheaps = heapsScene.get(0);
 		rawheaps.addEventListener("pointerdown", function(e) {
@@ -244,6 +248,58 @@ class GraphEditor extends hide.comp.Component {
 		}
 	}
 
+	function deleteSelection() {
+		cleanupCreateEdge();
+
+		if (boxesSelected.iterator().hasNext()) {
+			var selection = boxesSelected.copy();
+			var deletedNodes : Array<IGraphNode> = [];
+			var deletedEdges : Array<GraphInterface.Edge> = [];
+			var exec = function(isUndo : Bool) {
+				if (!isUndo) {
+					for (id => _ in selection) {
+						var box = boxes.get(id);
+						for (inputId => input in box.inputs) {
+							var packInput = packIO(id, inputId);
+							var packOutput = outputsToInputs.getLeft(packInput);
+							if (packOutput != null) {
+								var edge = edgeFromPack(packOutput, packInput);
+								deletedEdges.push(edge);
+								removeEdge(edge);
+							}
+						}
+						for (outputId => _ in box.outputs) {
+							var packOutput = packIO(id, outputId);
+							for (packInput in outputsToInputs.iterRights(packOutput)) {
+								var edge = edgeFromPack(packOutput, packInput);
+								deletedEdges.push(edge);
+								removeEdge(edge);
+							}
+						}
+					}
+
+					for (id => _ in selection) {
+						var box = boxes.get(id);
+						deletedNodes.push(box.node);
+						removeBox(box);
+					}
+				}
+				else {
+					for (node in deletedNodes) {
+						node.getPos(Box.tmpPoint);
+						addBox(Box.tmpPoint, node);
+					}
+					for (edge in deletedEdges) {
+						createEdge(edge);
+					}
+				}
+			}
+
+			addUndo(exec);
+			commitUndo();			
+		}
+	}
+
 	function openAddMenu(x : Int = 0, y : Int = 0) {
 
 		var boundsWidth = Std.parseInt(element.css("width"));

+ 15 - 2
hide/view/shadereditor/ShaderEditor.hx

@@ -268,14 +268,15 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
 	}
 
 	public function addNode(node: IGraphNode) : Void {
+		currentGraph.addNode(cast node);
 	}
 
 	public function removeNode(id: Int) : Void {
-
+		currentGraph.removeNode(id);
 	}
 
 	public function canAddEdge(edge: Edge) : Bool {
-		return true;
+		return currentGraph.canAddEdge({outputNodeId: edge.nodeFromId, outputId: edge.outputFromId, inputNodeId: edge.nodeToId, inputId: edge.inputToId});
 	}
 
 	public function addEdge(edge: Edge) : Void {
@@ -285,9 +286,21 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
 
 	}
 
+	public override function save() {
+		var content = shaderGraph.saveToText();
+		currentSign = ide.makeSignature(content);
+		sys.io.File.saveContent(getPath(), content);
+		super.save();
+	}
+
 	public function getUndo() : hide.ui.UndoHistory {
 		return undo;
 	}
+
+	override function getDefaultContent() {
+		var p = (new hrt.shgraph.ShaderGraph(null, null)).serialize();
+		return haxe.io.Bytes.ofString(ide.toJSON(p));
+	}
 	
 	static var _ = FileTree.registerExtension(ShaderEditor,["shgraph"],{ icon : "scribd", createNew: "Shader Graph" });
 }

+ 47 - 6
hrt/shgraph/ShaderGraph.hx

@@ -136,12 +136,12 @@ typedef ShaderNodeDef = {
 };
 
 typedef Edge = {
-	?outputNodeId : Int,
-	nameOutput : String, // Fallback if name has changed
-	?outputId : Int,
-	?inputNodeId : Int,
-	nameInput : String, // Fallback if name has changed
-	?inputId : Int,
+	outputNodeId : Int,
+	?nameOutput : String, // Fallback if name has changed
+	outputId : Int,
+	inputNodeId : Int,
+	?nameInput : String, // Fallback if name has changed
+	inputId : Int,
 };
 
 typedef Connection = {
@@ -673,6 +673,47 @@ class Graph {
 		}
 	}
 
+	public function canAddEdge(edge : Edge) {
+		var node = this.nodes.get(edge.inputNodeId);
+		var output = this.nodes.get(edge.outputNodeId);
+
+		var inputs = node.getInputs();
+		var outputs = output.getOutputs();
+
+		var inputType = inputs[edge.inputId].type;
+		var outputType = outputs[edge.outputId].type;
+
+		if (!areTypesCompatible(inputType, outputType)) {
+			return false;
+		}
+
+		function hasCycle(node: ShaderNode, ?visited: Map<ShaderNode, Bool>) : Bool {
+			var visited = visited?.copy() ?? [];
+			if (visited.get(node) != null) {
+				return true;
+			}
+			visited.set(node, true);
+			for (id => conn in node.connections) {
+				if (conn != null) {
+					if (hasCycle(conn.from, visited))
+						return true;
+				}
+			}
+			return false;
+		}
+
+		var prev = node.connections[edge.inputId];
+		node.connections[edge.inputId] = {from: output, outputId: edge.outputId};
+
+		var res = hasCycle(node);
+		node.connections[edge.inputId] = prev;
+		
+		if (res)
+			return false;
+
+		return true;
+	}
+
 	public function addEdge(edge : Edge) {
 		var node = this.nodes.get(edge.inputNodeId);
 		var output = this.nodes.get(edge.outputNodeId);