예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        //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);
        }
예제 #5
0
        //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);
        }
예제 #6
0
        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);
            }
        }
예제 #7
0
        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 + "'");
            }
        }
예제 #8
0
        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;
        }
예제 #9
0
        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());
            }
        }
예제 #10
0
        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);
        }
예제 #11
0
        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);
            }
        }
예제 #12
0
        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);
        }
예제 #13
0
        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());
        }
예제 #14
0
        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;
            }
        }