public float Process(PWGraph graph) { float calculTime = 0f; bool realMode = graph.IsRealMode(); currentGraph = graph; hasProcessed = false; if (graph.GetComputeSortedNodes() == null) { graph.UpdateComputeOrder(); } try { foreach (var node in graph.GetComputeSortedNodes()) { //ignore unlinked nodes if (node.computeOrder < 0) { continue; } calculTime += ProcessNode(node, realMode); } } catch (Exception e) { Debug.LogError(e); Debug.Log("Stopping graph processing due to an unexpected error"); return(calculTime); } hasProcessed = true; return(calculTime); }
static void CreateLinkAnchor(PWGraph graph, PWGraphCommand command, string inputCommand) { PWNode fromNode, toNode; GetNodes(graph, command, out fromNode, out toNode, inputCommand); var fromAnchorFields = fromNode.outputAnchorFields; var toAnchorFields = toNode.inputAnchorFields; if (command.fromAnchorIndex < 0 || command.fromAnchorIndex >= fromAnchorFields.Count) { throw new Exception("Anchor " + command.fromAnchorIndex + " out of range in node: " + fromNode); } if (command.toAnchorIndex < 0 || command.toAnchorIndex >= toAnchorFields.Count) { throw new Exception("Anchor " + command.fromAnchorIndex + " out of range in node: " + toNode); } var fromAnchorField = fromAnchorFields[command.fromAnchorIndex]; var toAnchorField = toAnchorFields[command.toAnchorIndex]; PWAnchor fromAnchor, toAnchor; FindAnchors(fromAnchorField, toAnchorField, out fromAnchor, out toAnchor); graph.SafeCreateLink(fromAnchor, toAnchor); }
static void CreateLink(PWGraph graph, PWGraphCommand command, string inputCommand) { //get nodes from the graph: PWNode fromNode, toNode; GetNodes(graph, command, out fromNode, out toNode, inputCommand); //Create the first linkable anchors we found: foreach (var outAnchor in fromNode.outputAnchors) { foreach (var inAnchor in toNode.inputAnchors) { if (PWAnchorUtils.AnchorAreAssignable(outAnchor, inAnchor)) { //if the input anchor is already linked, find another if (inAnchor.linkCount == 1) { continue; } graph.CreateLink(outAnchor, inAnchor); return; } } } Debug.LogError("Can't link " + fromNode + " with " + toNode); }
//Durty Clone cauz unity ScriptableObject does not implement a Clone method >.< public PWGraph Clone() { //Instancing a new graph fmor this one will duplicate the object but not the nodes // so the OnEnable function will bind this new graph to our nodes, to revert // that we need to clone each nodes and assign them to this new graph. PWGraph clonedGraph = Object.Instantiate(this); //clean and add copies of nodes into the cloned graph clonedGraph.nodes.Clear(); foreach (var node in nodes) { clonedGraph.nodes.Add(Object.Instantiate(node)); } //reenable the new graph so the new nodes are taken in account clonedGraph.OnDisable(); clonedGraph.OnEnable(); //reenable all clone graph nodes foreach (var node in clonedGraph.nodes) { node.OnDisable(); node.OnEnable(); } //reenable our graph to rebind our nodes to our graph OnDisable(); OnEnable(); return(clonedGraph); }
//call this methof to create an instance of this class public static PWGraphBuilder FromGraph(PWGraph graph) { PWGraphBuilder builder = new PWGraphBuilder(); builder.graph = graph; return(builder); }
public static void Execute(PWGraph graph, string inputCommand) { PWGraphCommand command = Parse(inputCommand); if (commandTypeFunctions.ContainsKey(command.type)) { commandTypeFunctions[command.type](graph, command, inputCommand); } else { throw new Exception("Command type not handled: " + command.type); } }
static void GetNodes(PWGraph graph, PWGraphCommand command, out PWNode fromNode, out PWNode toNode, string inputCommand) { fromNode = graph.FindNodeByName(command.fromNodeName); toNode = graph.FindNodeByName(command.toNodeName); if (fromNode == null) { throw new Exception("Node " + command.fromNodeName + " not found in graph while parsing: '" + inputCommand + "'"); } if (toNode == null) { throw new Exception("Node " + command.toNodeName + " not found in graph while parsing: '" + inputCommand + "'"); } }
static void CreateNode(PWGraph graph, PWGraphCommand command, string inputCommand) { Vector2 position = command.position; PWNode node = null; //if we receive a CreateNode with input/output graph nodes, we assign them so we don't have multiple inout/output nodes if (command.nodeType == typeof(PWNodeGraphInput) || command.nodeType == typeof(PWNodeBiomeGraphInput)) { node = graph.inputNode; } else if (command.nodeType == typeof(PWNodeGraphOutput) || command.nodeType == typeof(PWNodeBiomeGraphOutput)) { node = graph.outputNode; } else { node = graph.CreateNewNode(command.nodeType, position); } //set the position again for input/output nodes node.rect.position = position; Type nodeType = node.GetType(); if (!String.IsNullOrEmpty(command.attributes)) { foreach (var attr in PWJson.Parse(command.attributes)) { FieldInfo attrField = nodeType.GetField(attr.first, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly); if (attrField != null) { attrField.SetValue(node, attr.second); } else { Debug.LogError("Attribute " + attr.first + " can be found in node " + node); } } } node.name = command.name; }
public void ProcessOnce(PWGraph graph) { if (graph.GetComputeSortedNodes() == null) { graph.UpdateComputeOrder(); } currentGraph = graph; foreach (var node in graph.GetComputeSortedNodes()) { //ignore unlinked nodes if (node.computeOrder < 0) { continue; } node.OnNodeProcessOnce(); ProcessNodeLinks(node, graph.IsRealMode()); } }
public float ProcessNodes(PWGraph graph, List <PWNode> nodes) { float calculTime = 0f; bool realMode = graph.IsRealMode(); currentGraph = graph; //sort nodes by compute order: nodes.Sort((n1, n2) => n1.computeOrder.CompareTo(n2.computeOrder)); foreach (var node in nodes) { if (node.computeOrder < 0) { continue; } calculTime += ProcessNode(node, realMode); } return(calculTime); }
public static void Import(PWGraph graph, string filePath, bool wipeDatas = false) { if (wipeDatas) { while (graph.nodes.Count != 0) { Debug.Log("removing node: " + graph.nodes.First()); graph.RemoveNode(graph.nodes.First()); } } string[] commands = File.ReadAllLines(filePath); foreach (var command in commands) { //ignore empty lines: if (String.IsNullOrEmpty(command.Trim())) { continue; } Execute(graph, command); } }
static void CreateLinkAnchorName(PWGraph graph, PWGraphCommand command, string inputCommand) { PWNode fromNode, toNode; GetNodes(graph, command, out fromNode, out toNode, inputCommand); var fromAnchorField = fromNode.outputAnchorFields.Find(af => af.fieldName == command.fromAnchorFieldName); var toAnchorField = toNode.inputAnchorFields.Find(af => af.fieldName == command.toAnchorFieldName); if (fromAnchorField == null) { throw new Exception("Anchor " + command.fromAnchorFieldName + " not found in node: " + fromNode); } if (toAnchorField == null) { throw new Exception("Anchor " + command.toAnchorFieldName + " not found in node: " + toNode); } PWAnchor fromAnchor, toAnchor; FindAnchors(fromAnchorField, toAnchorField, out fromAnchor, out toAnchor); graph.SafeCreateLink(fromAnchor, toAnchor); }
public static void Export(PWGraph graph, string filePath) { List <string> commands = new List <string>(); List <string> nodeNames = new List <string>(); var nodeToNameMap = new Dictionary <PWNode, string>(); foreach (var node in graph.nodes) { var attrs = new PWGraphCLIAttributes(); //load node attributes FieldInfo[] attrFields = node.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly); foreach (var field in attrFields) { var attributes = field.GetCustomAttributes(false); bool isInput = attributes.Any(a => { return(a.GetType() == typeof(PWInputAttribute)); }); if (isInput) { continue; } //if the field can't be jsonified, we skip it if (PWJson.allowedJsonTypes.FindIndex(j => j.type == field.FieldType) == -1) { continue; } attrs.Add(field.Name, field.GetValue(node)); } string nodeName = node.name; int i = 0; //unique name generation while (nodeNames.Contains(nodeName)) { nodeName = node.name + i++; } nodeNames.Add(nodeName); nodeToNameMap[node] = nodeName; commands.Add(GenerateNewNodeCommand(node.GetType(), nodeName, node.rect.position, attrs)); } foreach (var link in graph.nodeLinkTable.GetLinks()) { if (link.fromNode == null || link.toNode == null) { continue; } var fromName = nodeToNameMap[link.fromNode]; var toName = nodeToNameMap[link.toNode]; var fromAnchorName = link.fromAnchor.fieldName; var toAnchorName = link.toAnchor.fieldName; commands.Add(GenerateLinkAnchorNameCommand(fromName, fromAnchorName, toName, toAnchorName)); } File.WriteAllLines(filePath, commands.ToArray()); }
public void Render(PWGraph graph, Vector2 screenSize) { var e = Event.current; Rect screen = new Rect(-graph.panPosition, screenSize); //check if ordering group is not visible if (!orderGroupRect.Overlaps(screen)) { return; } //Start GUI frame PWGUI.StartFrame(screen); if (orderingGroupStyle == null) { LoadStyles(); } Rect orderGroupWorldRect = PWUtils.DecalRect(orderGroupRect, graph.panPosition); callbackId = 0; int controlSize = 8; int cornerSize = 14; CreateAnchorRectCallabck( //left resize anchor new Rect(orderGroupWorldRect.x, orderGroupWorldRect.y + cornerSize, controlSize, orderGroupWorldRect.height - cornerSize * 2), MouseCursor.ResizeHorizontal, () => orderGroupRect.xMin += e.delta.x ); CreateAnchorRectCallabck( //right resize anchor new Rect(orderGroupWorldRect.x + orderGroupWorldRect.width - controlSize, orderGroupWorldRect.y + cornerSize, controlSize, orderGroupWorldRect.height - cornerSize * 2), MouseCursor.ResizeHorizontal, () => orderGroupRect.xMax += e.delta.x ); CreateAnchorRectCallabck( //top resize anchor new Rect(orderGroupWorldRect.x + cornerSize, orderGroupWorldRect.y, orderGroupWorldRect.width - cornerSize * 2, controlSize), MouseCursor.ResizeVertical, () => orderGroupRect.yMin += e.delta.y ); CreateAnchorRectCallabck( //down resize anchor new Rect(orderGroupWorldRect.x + cornerSize, orderGroupWorldRect.y + orderGroupWorldRect.height - controlSize, orderGroupWorldRect.width - cornerSize * 2, controlSize), MouseCursor.ResizeVertical, () => orderGroupRect.yMax += e.delta.y ); CreateAnchorRectCallabck( //top left anchor new Rect(orderGroupWorldRect.x, orderGroupWorldRect.y, cornerSize, cornerSize), MouseCursor.ResizeUpLeft, () => { orderGroupRect.yMin += e.delta.y; orderGroupRect.xMin += e.delta.x; } ); CreateAnchorRectCallabck( //top right anchor new Rect(orderGroupWorldRect.x + orderGroupWorldRect.width - cornerSize, orderGroupWorldRect.y, cornerSize, cornerSize), MouseCursor.ResizeUpRight, () => { orderGroupRect.yMin += e.delta.y; orderGroupRect.xMax += e.delta.x; } ); CreateAnchorRectCallabck( //down left anchor new Rect(orderGroupWorldRect.x, orderGroupWorldRect.y + orderGroupWorldRect.height - cornerSize, cornerSize, cornerSize), MouseCursor.ResizeUpRight, () => { orderGroupRect.yMax += e.delta.y; orderGroupRect.xMin += e.delta.x; } ); CreateAnchorRectCallabck( //down right anchor new Rect(orderGroupWorldRect.x + orderGroupWorldRect.width - cornerSize, orderGroupWorldRect.y + orderGroupWorldRect.height - cornerSize, cornerSize, cornerSize), MouseCursor.ResizeUpLeft, () => { orderGroupRect.yMax += e.delta.y; orderGroupRect.xMax += e.delta.x; } ); if (e.rawType == EventType.MouseUp) { resizing = false; } //draw renamable name field orderingGroupNameStyle.normal.textColor = color; PWGUI.TextField(orderGroupWorldRect.position + new Vector2(10, -22), ref name, true, orderingGroupNameStyle); //draw move pad Rect movePadRect = new Rect(orderGroupWorldRect.position + new Vector2(10, 10), new Vector2(50, 30)); GUI.DrawTextureWithTexCoords(movePadRect, movepadTexture, new Rect(0, 0, 5, 4)); EditorGUIUtility.AddCursorRect(movePadRect, MouseCursor.MoveArrow); if (e.type == EventType.MouseDown && e.button == 0) { if (movePadRect.Contains(e.mousePosition)) { innerNodes = graph.nodes.Where(n => n.rect.Overlaps(orderGroupRect)).ToList(); moving = true; e.Use(); } } if (e.rawType == EventType.MouseUp) { moving = false; } if (moving && e.type == EventType.MouseDrag) { orderGroupRect.position += e.delta; innerNodes.ForEach(n => n.rect.position += e.delta); } //draw ordering group GUI.color = color; GUI.Label(orderGroupWorldRect, (string)null, orderingGroupStyle); GUI.color = Color.white; //draw color picker Rect colorPickerRect = new Rect(orderGroupWorldRect.x + orderGroupWorldRect.width - 30, orderGroupWorldRect.y + 10, 20, 20); PWGUI.ColorPicker(colorPickerRect, ref color, false); if (orderGroupWorldRect.Contains(e.mousePosition)) { graph.editorEvents.mouseOverOrderingGroup = this; graph.editorEvents.isMouseOverOrderingGroupFrame = true; } }