Esempio n. 1
0
        public virtual void SetOutputNode(string id)
        {
            if (string.IsNullOrEmpty(id))
            {
                OutputNode = null;
                if (OnOutputSet != null)
                {
                    OnOutputSet.Invoke(null);
                }
                Updated();
                return;
            }

            Node n = null;

            if (NodeLookup.TryGetValue(id, out n))
            {
                OutputNode = n;
                if (OnOutputSet != null)
                {
                    OnOutputSet.Invoke(n);
                }
                Updated();
            }
        }
Esempio n. 2
0
        private void ResolveUnsatisfiedSuccessorActivities(T activityId)
        {
            // Check to make sure the node really exists.
            if (!NodeLookup.TryGetValue(activityId, out Node <T, TActivity> dependencyNode))
            {
                return;
            }

            // Check to see if any existing activities were expecting this activity
            // as a dependency. If so, then then hook their nodes to this activity with an edge.
            if (UnsatisfiedSuccessorsLookup.TryGetValue(activityId, out HashSet <Node <T, TActivity> > unsatisfiedSuccessorNodes))
            {
                // If the dependency node is an End or Isolated node, then convert it.
                if (dependencyNode.NodeType == NodeType.End)
                {
                    dependencyNode.SetNodeType(NodeType.Normal);
                }
                else if (dependencyNode.NodeType == NodeType.Isolated)
                {
                    dependencyNode.SetNodeType(NodeType.Start);
                }

                foreach (Node <T, TActivity> successorNode in unsatisfiedSuccessorNodes)
                {
                    T   edgeId = EdgeIdGenerator();
                    var edge   = new Edge <T, TEvent>(EventGenerator(edgeId));
                    dependencyNode.OutgoingEdges.Add(edgeId);
                    EdgeTailNodeLookup.Add(edgeId, dependencyNode);
                    successorNode.IncomingEdges.Add(edgeId);
                    EdgeHeadNodeLookup.Add(edgeId, successorNode);
                    EdgeLookup.Add(edgeId, edge);
                }
                UnsatisfiedSuccessorsLookup.Remove(activityId);
            }
        }
Esempio n. 3
0
        private void RemoveUnsatisfiedSuccessorActivity(T activityId)
        {
            // Check to make sure the node really exists.
            if (!NodeLookup.TryGetValue(activityId, out Node <T, TActivity> node))
            {
                return;
            }

            if (node.NodeType == NodeType.End ||
                node.NodeType == NodeType.Normal)
            {
                // If the activity was an unsatisfied successor, then remove it from the lookup.
                IList <KeyValuePair <T, HashSet <Node <T, TActivity> > > > kvps =
                    UnsatisfiedSuccessorsLookup.Where(x => x.Value.Select(y => y.Id).Contains(activityId)).ToList();

                foreach (KeyValuePair <T, HashSet <Node <T, TActivity> > > kvp in kvps)
                {
                    HashSet <Node <T, TActivity> > unsatisfiedSuccessorNodes = kvp.Value;
                    unsatisfiedSuccessorNodes.RemoveWhere(x => x.Id.Equals(activityId));
                    if (!unsatisfiedSuccessorNodes.Any())
                    {
                        UnsatisfiedSuccessorsLookup.Remove(kvp);
                    }
                }
            }
        }
Esempio n. 4
0
        private bool ChangeEdgeHeadNodeWithoutCleanup(T edgeId, T newHeadNodeId)
        {
            // Do not attend this unless all dependencies are satisfied.
            if (!AllDependenciesSatisfied)
            {
                return(false);
            }
            // Retrieve the activity edge.
            if (!EdgeLookup.TryGetValue(edgeId, out Edge <T, TEdgeContent> _))
            {
                return(false);
            }
            // Retrieve the new head event node.
            if (!NodeLookup.TryGetValue(newHeadNodeId, out Node <T, TNodeContent> newHeadNode))
            {
                return(false);
            }

            // Remove the connection from the current head node.
            Node <T, TNodeContent> currentHeadNode = EdgeHeadNodeLookup[edgeId];

            currentHeadNode.IncomingEdges.Remove(edgeId);
            EdgeHeadNodeLookup.Remove(edgeId);

            // Attach to the new head node.
            newHeadNode.IncomingEdges.Add(edgeId);
            EdgeHeadNodeLookup.Add(edgeId, newHeadNode);
            return(true);
        }
Esempio n. 5
0
        public virtual void TryAndProcess()
        {
            int c = Nodes.Count;

            for (int i = 0; i < c; i++)
            {
                Node n = Nodes[i];

                if (OutputNodes.Contains(n.Id))
                {
                    continue;
                }
                if (InputNodes.Contains(n.Id))
                {
                    continue;
                }

                n.TryAndProcess();
            }

            c = InputNodes.Count;

            for (int i = 0; i < c; i++)
            {
                Node n;
                if (NodeLookup.TryGetValue(InputNodes[i], out n))
                {
                    InputNode inp = (InputNode)n;
                    inp.TryAndProcess();
                }
            }
        }
Esempio n. 6
0
 public Node <T, TNodeContent> Node(T key)
 {
     if (!NodeLookup.TryGetValue(key, out Node <T, TNodeContent> node))
     {
         return(null);
     }
     return(node);
 }
Esempio n. 7
0
 public virtual void Reset()
 {
     EdgeLookup.Clear();
     NodeLookup.Clear();
     UnsatisfiedSuccessorsLookup.Clear();
     EdgeHeadNodeLookup.Clear();
     EdgeTailNodeLookup.Clear();
 }
Esempio n. 8
0
        /// <summary>
        /// Method exposed as a node in the server to publish a node to IoT Hub that it is connected to
        /// </summary>
        private ServiceResult PublishNodeMethod(ISystemContext context, MethodState method, IList <object> inputArguments, IList <object> outputArguments)
        {
            if (inputArguments[0] == null || inputArguments[1] == null)
            {
                Program.Trace("PublishNodeMethod: Invalid Arguments!");
                return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide all arguments!"));
            }

            string nodeID = inputArguments[0] as string;
            string uri    = inputArguments[1] as string;

            if (string.IsNullOrEmpty(nodeID) || string.IsNullOrEmpty(uri))
            {
                Program.Trace("PublishNodeMethod: Arguments are not valid strings!");
                return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide all arguments as strings!"));
            }

            NodeLookup lookup = new NodeLookup();

            lookup.NodeID = new NodeId(nodeID);
            try
            {
                lookup.EndPointURL = new Uri(uri);
            }
            catch (UriFormatException)
            {
                Program.Trace("PublishNodeMethod: Invalid endpoint URL!");
                return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide a valid OPC UA endpoint URL as second argument!"));
            }

            // create session, if it doesn't exist already and complete asynchonourly (do to thread dependencies in the UA stack)
            if (!Program.m_endpointUrls.Contains(lookup.EndPointURL))
            {
                try
                {
                    Task.Run(() =>
                    {
                        Program.Trace("PublishNodeMethod: Session not found, creating one for " + lookup.EndPointURL);
                        Program.EndpointConnect(lookup.EndPointURL).Wait();
                        Program.Trace("PublishNodeMethod: Session created.");

                        return(DoPublish(lookup));
                    });

                    return(ServiceResult.Create(StatusCodes.GoodCompletesAsynchronously, "Publishing takes a while, please be patient!"));
                }
                catch (Exception ex)
                {
                    Program.Trace("PublishNodeMethod: Exception: " + ex.ToString());
                    return(ServiceResult.Create(ex, StatusCodes.BadUnexpectedError, "Unexpected error publishing node: " + ex.Message));
                }
            }
            else
            {
                // complete synchonoursly
                return(DoPublish(lookup));
            }
        }
Esempio n. 9
0
        protected GraphBuilderBase(
            Graph <T, TEdgeContent, TNodeContent> arrowGraph,
            Func <T> edgeIdGenerator,
            Func <T> nodeIdGenerator,
            Func <T, TEvent> eventGenerator)
            : this(edgeIdGenerator, nodeIdGenerator, eventGenerator)
        {
            if (arrowGraph is null)
            {
                throw new ArgumentNullException(nameof(arrowGraph));
            }
            foreach (Edge <T, TEdgeContent> edge in arrowGraph.Edges)
            {
                EdgeLookup.Add(edge.Id, edge);
            }

            foreach (Node <T, TNodeContent> node in arrowGraph.Nodes)
            {
                // Assimilate incoming edges.
                if (node.NodeType != NodeType.Start && node.NodeType != NodeType.Isolated)
                {
                    foreach (T edgeId in node.IncomingEdges)
                    {
                        EdgeHeadNodeLookup.Add(edgeId, node);
                    }
                }
                // Assimilate Outgoing edges.
                if (node.NodeType != NodeType.End && node.NodeType != NodeType.Isolated)
                {
                    foreach (T edgeId in node.OutgoingEdges)
                    {
                        EdgeTailNodeLookup.Add(edgeId, node);
                    }
                }
                NodeLookup.Add(node.Id, node);
            }

            // Check all edges are used.
            if (!EdgeLookup.Keys.OrderBy(x => x).SequenceEqual(EdgeHeadNodeLookup.Keys.OrderBy(x => x)))
            {
                throw new ArgumentException(Properties.Resources.ListOfEdgeIdsAndEdgesReferencedByHeadNodesDoNotMatch);
            }
            if (!EdgeLookup.Keys.OrderBy(x => x).SequenceEqual(EdgeTailNodeLookup.Keys.OrderBy(x => x)))
            {
                throw new ArgumentException(Properties.Resources.ListOfEdgeIdsAndEdgesReferencedByTailNodesDoNotMatch);
            }

            // Check all nodes are used.
            IEnumerable <T> edgeNodeLookupIds = EdgeHeadNodeLookup.Values.Select(x => x.Id).Union(EdgeTailNodeLookup.Values.Select(x => x.Id));

            if (!NodeLookup.Values.Where(x => x.NodeType != NodeType.Isolated).Select(x => x.Id).OrderBy(x => x).SequenceEqual(edgeNodeLookupIds.OrderBy(x => x)))
            {
                throw new ArgumentException(Properties.Resources.ListOfNodeIdsAndEdgesReferencedByTailNodesDoNotMatch);
            }
        }
Esempio n. 10
0
        /// <summary>
        /// this is used in GraphInstances
        /// To resize proportionate to new size
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        public virtual void ResizeWith(int width, int height)
        {
            this.width  = width;
            this.height = height;

            int c = Nodes.Count;

            for (int i = 0; i < c; i++)
            {
                Node n = Nodes[i];

                if (OutputNodes.Contains(n.Id))
                {
                    continue;
                }
                if (InputNodes.Contains(n.Id))
                {
                    continue;
                }

                if (n is BitmapNode)
                {
                    BitmapNode bn = (BitmapNode)n;
                    bn.TryAndProcess();
                }
                else
                {
                    Point osize;

                    if (OriginSizes.TryGetValue(n.Id, out osize))
                    {
                        float wratio = width / (float)osize.X;
                        float hratio = height / (float)osize.Y;

                        int fwidth  = (int)Math.Min(4096, Math.Max(16, Math.Round(osize.X * wratio)));
                        int fheight = (int)Math.Min(4096, Math.Max(16, Math.Round(osize.Y * hratio)));

                        n.Width  = fwidth;
                        n.Height = fheight;
                    }
                }
            }

            c = InputNodes.Count;

            for (int i = 0; i < c; i++)
            {
                Node n;
                if (NodeLookup.TryGetValue(InputNodes[i], out n))
                {
                    InputNode inp = (InputNode)n;
                    inp.TryAndProcess();
                }
            }
        }
Esempio n. 11
0
        private void Initialize()
        {
            T startEventId = NodeIdGenerator();

            StartNode = new Node <T, TEvent>(NodeType.Start, EventGeneratorWithTimes(startEventId, 0, 0));
            NodeLookup.Add(StartNode.Id, StartNode);
            T endEventId = NodeIdGenerator();

            EndNode = new Node <T, TEvent>(NodeType.End, EventGenerator(endEventId));
            NodeLookup.Add(EndNode.Id, EndNode);
        }
Esempio n. 12
0
        private void ResolveUnsatisfiedSuccessorActivities(T activityId)
        {
            // Check to make sure the edge really exists.
            if (!EdgeLookup.ContainsKey(activityId))
            {
                return;
            }
            // Check to see if any existing activities were expecting this activity
            // as a dependency. If so, then then hook up their tail nodes to this
            // activity's head node with a dummy edge.
            if (UnsatisfiedSuccessorsLookup.TryGetValue(activityId, out HashSet <Node <T, TEvent> > unsatisfiedSuccessorTailNodes))
            {
                // We know that there are unsatisfied dependencies, so create a head node.
                T   headEventId = NodeIdGenerator();
                var headNode    = new Node <T, TEvent>(EventGenerator(headEventId));
                headNode.IncomingEdges.Add(activityId);
                EdgeHeadNodeLookup.Add(activityId, headNode);
                NodeLookup.Add(headNode.Id, headNode);

                foreach (Node <T, TEvent> tailNode in unsatisfiedSuccessorTailNodes)
                {
                    T   dummyEdgeId = EdgeIdGenerator();
                    var dummyEdge   = new Edge <T, TActivity>(DummyActivityGenerator(dummyEdgeId));
                    tailNode.IncomingEdges.Add(dummyEdgeId);
                    EdgeHeadNodeLookup.Add(dummyEdgeId, tailNode);
                    headNode.OutgoingEdges.Add(dummyEdgeId);
                    EdgeTailNodeLookup.Add(dummyEdgeId, headNode);
                    EdgeLookup.Add(dummyEdge.Id, dummyEdge);
                }
                UnsatisfiedSuccessorsLookup.Remove(activityId);
            }
            else
            {
                // No existing activities were expecting this activity as a dependency,
                // so attach it directly to the end node via a dummy.
                T headEventId = NodeIdGenerator();
                Node <T, TEvent> dependencyHeadNode = new Node <T, TEvent>(EventGenerator(headEventId));

                dependencyHeadNode.IncomingEdges.Add(activityId);
                EdgeHeadNodeLookup.Add(activityId, dependencyHeadNode);
                NodeLookup.Add(dependencyHeadNode.Id, dependencyHeadNode);

                T   dummyEdgeId = EdgeIdGenerator();
                var dummyEdge   = new Edge <T, TActivity>(DummyActivityGenerator(dummyEdgeId));

                dependencyHeadNode.OutgoingEdges.Add(dummyEdgeId);
                EdgeTailNodeLookup.Add(dummyEdgeId, dependencyHeadNode);
                EdgeLookup.Add(dummyEdgeId, dummyEdge);

                EndNode.IncomingEdges.Add(dummyEdgeId);
                EdgeHeadNodeLookup.Add(dummyEdgeId, EndNode);
            }
        }
Esempio n. 13
0
        public override void FromJson(string data)
        {
            base.FromJson(data);

            FunctionGraphData d = JsonConvert.DeserializeObject <FunctionGraphData>(data);

            Node n = null;

            NodeLookup.TryGetValue(d.outputNode, out n);

            OutputNode = n;
        }
Esempio n. 14
0
        public void Get_SameStateTwice_NodesAreEqual1NodeInLookup()
        {
            var map   = MapTest.Map06;
            var state = State.Create(map);

            var lookup = new NodeLookup();

            var act0 = lookup.Get(1, map, state);
            var act1 = lookup.Get(1, map, state);

            Assert.AreEqual(act0, act1);
            Assert.AreEqual(1, lookup.Nodes);
        }
Esempio n. 15
0
        protected override PublishedNodesCollection GetPublishedNodesLegacy(string endpointUrl, CancellationToken ct)
        {
            List <OpcNodeOnEndpointModel> nodeList       = GetConfiguredNodesOnEndpoint(endpointUrl, ct);
            PublishedNodesCollection      publishedNodes = new PublishedNodesCollection();

            foreach (var node in nodeList)
            {
                NodeLookup nodeLookup = new NodeLookup();
                nodeLookup.EndPointURL = new Uri(endpointUrl);
                nodeLookup.NodeID      = new NodeId(node.Id);
                publishedNodes.Add(new NodeLookup());
            }
            return(publishedNodes);
        }
Esempio n. 16
0
        public void Get_TwoStates_NodesAreEqual1NodeInLookup()
        {
            var map    = MapTest.Map06;
            var state0 = State.Create(map);
            var state1 = state0.Move(map, MoveDirection.x, state0.PlayerToMove);

            var lookup = new NodeLookup();

            var act0 = lookup.Get(1, map, state0);
            var act1 = lookup.Get(1, map, state1);

            Assert.AreNotEqual(act0, act1);
            Assert.AreEqual(2, lookup.Nodes);
        }
        public override void OnFrameUpdate(ARSession session, ARFrame frame)
        {
            base.OnFrameUpdate(session, frame);
            if (adding)
            {
                return;
            }

            var results = SCNView.HitTest(View.Center, new SCNHitTestOptions {
                SortResults = true, BackFaceCulling = false, SearchMode = SCNHitTestSearchMode.All, FirstFoundOnly = false
            });

            SCNNode newNode = null;

            var match = results.FirstOrDefault(r => NodeLookup.ContainsKey(r.Node));

            if (match != null)
            {
                newNode = match.Node;
            }

            var changed = newNode != SelectedNode;
            var oldNode = SelectedNode;

            SelectedNode = newNode;

            if (changed)
            {
                var panelTransform =
                    SelectedNode != null
                    ? CGAffineTransform.MakeIdentity()
                    : CGAffineTransform.MakeTranslation(0, 1000);

                if (SelectedNode != null)
                {
                    var content = _contentFor[NodeLookup[match.Node].Name];
                    InfoDialog.Label.Text  = content.Description;
                    TitleDialog.Label.Text = content.Name;
                }

                UIView.Animate(.2, 0, UIViewAnimationOptions.CurveEaseOut,
                               () =>
                {
                    InfoDialog.View.Transform  = panelTransform;
                    TitleDialog.View.Transform = panelTransform;
                }, null);
            }
        }
Esempio n. 18
0
        protected bool ChangeEdgeHeadNode(T edgeId, T newHeadNodeId)
        {
            // Do not attend this unless all dependencies are satisfied.
            if (!AllDependenciesSatisfied)
            {
                return(false);
            }

            Node <T, TNodeContent> oldHeadNode = EdgeHeadNodeLookup[edgeId];
            bool changeHeadSuccess             = ChangeEdgeHeadNodeWithoutCleanup(edgeId, newHeadNodeId);

            if (!changeHeadSuccess)
            {
                throw new InvalidOperationException($@"Unable to change head node of edge {edgeId} to node {newHeadNodeId} without cleanup");
            }

            // If the old head node has no other incoming edges, then
            // connect its outgoing edges to the current tail node.
            IList <T> oldHeadNodeIncomingEdgeIds = oldHeadNode.IncomingEdges.ToList();

            if (!oldHeadNodeIncomingEdgeIds.Any())
            {
                Node <T, TNodeContent> tailNode      = EdgeTailNodeLookup[edgeId];
                IList <T> oldHeadNodeOutgoingEdgeIds = oldHeadNode.OutgoingEdges.ToList();
                foreach (T oldHeadNodeOutgoingEdgeId in oldHeadNodeOutgoingEdgeIds)
                {
                    bool changeTailSuccess = ChangeEdgeTailNodeWithoutCleanup(oldHeadNodeOutgoingEdgeId, tailNode.Id);
                    if (!changeTailSuccess)
                    {
                        throw new InvalidOperationException($@"Unable to change tail node of edge {oldHeadNodeOutgoingEdgeId} to node {tailNode.Id} without cleanup");
                    }
                }
            }

            // Final check to see if the head node has no incoming or outgoing edges.
            // If it does not then remove it.
            if (oldHeadNode.NodeType != NodeType.End &&
                oldHeadNode.NodeType != NodeType.Isolated &&
                !oldHeadNode.IncomingEdges.Any() &&
                !oldHeadNode.OutgoingEdges.Any())
            {
                NodeLookup.Remove(oldHeadNode.Id);
            }
            return(true);
        }
Esempio n. 19
0
        public virtual void Remove(Node n)
        {
            if (n is OutputNode)
            {
                OutputNodes.Remove(n.Id);
            }
            else if (n is InputNode)
            {
                InputNodes.Remove(n.Id);
            }

            NodeLookup.Remove(n.Id);
            if (Nodes.Remove(n))
            {
                n.OnUpdate -= N_OnUpdate;
            }
            n.Dispose();
        }
Esempio n. 20
0
        public virtual void FromJson(string data)
        {
            FunctionGraphData d = JsonConvert.DeserializeObject <FunctionGraphData>(data);

            base.FromJson(d);

            Node n = null;

            if (d.outputNode != null)
            {
                NodeLookup.TryGetValue(d.outputNode, out n);
                OutputNode = n;
            }

            //we also want to set vars for argument if we have any
            //so they appear in the dropdown

            foreach (ArgNode arg in args)
            {
                object temp = 0;
                if (arg.InputType == NodeType.Float)
                {
                    temp = 0;
                }
                else if (arg.InputType == NodeType.Bool)
                {
                    temp = false;
                }
                else if (arg.InputType == NodeType.Matrix)
                {
                    temp = Matrix4.Identity;
                }
                else
                {
                    temp = new MVector();
                }

                SetVar(arg.InputName, temp, arg.InputType);
            }
        }
Esempio n. 21
0
        public virtual void SetJsonReadyParameters(Dictionary <string, string> parameters)
        {
            if (parameters != null)
            {
                Parameters = new Dictionary <string, GraphParameterValue>();

                foreach (var k in parameters.Keys)
                {
                    string[] split = k.Split('.');

                    Node n = null;
                    NodeLookup.TryGetValue(split[0], out n);

                    Parameters[k] = GraphParameterValue.FromJson(parameters[k], n);
                    if (Parameters[k].IsFunction())
                    {
                        var f = Parameters[k].Value as FunctionGraph;
                        f.OnGraphUpdated += Graph_OnGraphUpdated;
                    }
                }
            }
        }
Esempio n. 22
0
        public virtual bool Add(Node n)
        {
            if (NodeLookup.ContainsKey(n.Id))
            {
                return(false);
            }

            if (n is OutputNode)
            {
                OutputNodes.Add(n.Id);
            }
            else if (n is InputNode)
            {
                InputNodes.Add(n.Id);
            }

            NodeLookup[n.Id] = n;
            Nodes.Add(n);

            n.OnUpdate += N_OnUpdate;

            return(true);
        }
Esempio n. 23
0
        public override bool AddActivityDependencies(T activityId, HashSet <T> dependencies)
        {
            if (dependencies is null)
            {
                throw new ArgumentNullException(nameof(dependencies));
            }

            if (!NodeLookup.TryGetValue(activityId, out Node <T, TActivity> node))
            {
                return(false);
            }
            if (!dependencies.Any())
            {
                return(true);
            }
            if (dependencies.Contains(activityId))
            {
                return(false);
            }

            // If the node is an Start or Isolated node, then convert it.
            if (node.NodeType == NodeType.Start)
            {
                node.SetNodeType(NodeType.Normal);
            }
            else if (node.NodeType == NodeType.Isolated)
            {
                node.SetNodeType(NodeType.End);
            }

            // Check which of the expected dependencies currently exist.
            IList <T> existingDependencies    = NodeLookup.Keys.Intersect(dependencies).ToList();
            IList <T> nonExistingDependencies = dependencies.Except(existingDependencies).ToList();

            // If any expected dependencies currently exist, generate an edge to connect them.
            foreach (T dependencyId in existingDependencies)
            {
                Node <T, TActivity> dependencyNode = NodeLookup[dependencyId];
                T   edgeId = EdgeIdGenerator();
                var edge   = new Edge <T, TEvent>(EventGenerator(edgeId));
                node.IncomingEdges.Add(edgeId);
                EdgeHeadNodeLookup.Add(edgeId, node);

                // If the dependency node is an End or Isolated node, then convert it.
                if (dependencyNode.NodeType == NodeType.End)
                {
                    dependencyNode.SetNodeType(NodeType.Normal);
                }
                else if (dependencyNode.NodeType == NodeType.Isolated)
                {
                    dependencyNode.SetNodeType(NodeType.Start);
                }

                dependencyNode.OutgoingEdges.Add(edgeId);
                EdgeTailNodeLookup.Add(edgeId, dependencyNode);
                EdgeLookup.Add(edgeId, edge);
            }

            // If any expected dependencies currently do not exist, then record their
            // IDs and add this node as an unsatisfied successor.
            foreach (T dependencyId in nonExistingDependencies)
            {
                if (!UnsatisfiedSuccessorsLookup.TryGetValue(dependencyId, out HashSet <Node <T, TActivity> > successorNodes))
                {
                    successorNodes = new HashSet <Node <T, TActivity> >();
                    UnsatisfiedSuccessorsLookup.Add(dependencyId, successorNodes);
                }
                successorNodes.Add(node);
            }
            return(true);
        }
Esempio n. 24
0
        public override bool AddActivity(TActivity activity, HashSet <T> dependencies)
        {
            if (activity == null)
            {
                throw new ArgumentNullException(nameof(activity));
            }
            if (dependencies is null)
            {
                throw new ArgumentNullException(nameof(dependencies));
            }
            if (EdgeLookup.ContainsKey(activity.Id))
            {
                return(false);
            }
            if (dependencies.Contains(activity.Id))
            {
                return(false);
            }
            // Create a new edge for the activity.
            var edge = new Edge <T, TActivity>(activity);

            EdgeLookup.Add(edge.Id, edge);

            // We expect dependencies at some point.
            if (dependencies.Any())
            {
                // Since we use dummy edges to connect all tail nodes, we can create
                // a new tail node for this edge.
                T   tailEventId = NodeIdGenerator();
                var tailNode    = new Node <T, TEvent>(EventGenerator(tailEventId));
                tailNode.OutgoingEdges.Add(edge.Id);
                EdgeTailNodeLookup.Add(edge.Id, tailNode);
                NodeLookup.Add(tailNode.Id, tailNode);

                // Check which of the expected dependencies currently exist.
                IList <T> existingDependencies    = EdgeLookup.Keys.Intersect(dependencies).ToList();
                IList <T> nonExistingDependencies = dependencies.Except(existingDependencies).ToList();

                // If any expected dependencies currently exist, then hook up their head
                // node to this edge's tail node with dummy edges.
                foreach (T dependencyId in existingDependencies)
                {
                    Node <T, TEvent> dependencyHeadNode = EdgeHeadNodeLookup[dependencyId];
                    T   dummyEdgeId = EdgeIdGenerator();
                    var dummyEdge   = new Edge <T, TActivity>(DummyActivityGenerator(dummyEdgeId));
                    tailNode.IncomingEdges.Add(dummyEdgeId);
                    EdgeHeadNodeLookup.Add(dummyEdgeId, tailNode);

                    // If the head node of the dependency is the End node, then convert it.
                    if (dependencyHeadNode.NodeType == NodeType.End)
                    {
                        dependencyHeadNode.SetNodeType(NodeType.Normal);
                    }

                    dependencyHeadNode.OutgoingEdges.Add(dummyEdgeId);
                    EdgeTailNodeLookup.Add(dummyEdgeId, dependencyHeadNode);
                    EdgeLookup.Add(dummyEdgeId, dummyEdge);
                }

                // If any expected dependencies currently do not exist, then record their
                // IDs and add this edge's tail node as an unsatisfied successor.
                foreach (T dependencyId in nonExistingDependencies)
                {
                    if (!UnsatisfiedSuccessorsLookup.TryGetValue(dependencyId, out HashSet <Node <T, TEvent> > tailNodes))
                    {
                        tailNodes = new HashSet <Node <T, TEvent> >();
                        UnsatisfiedSuccessorsLookup.Add(dependencyId, tailNodes);
                    }
                    tailNodes.Add(tailNode);
                }
            }
            else
            {
                // No dependencies, so attach it directly to the start node.
                StartNode.OutgoingEdges.Add(edge.Id);
                EdgeTailNodeLookup.Add(edge.Id, StartNode);
            }
            ResolveUnsatisfiedSuccessorActivities(edge.Id);
            return(true);
        }
Esempio n. 25
0
        public override bool RemoveActivityDependencies(T activityId, HashSet <T> dependencies)
        {
            if (dependencies is null)
            {
                throw new ArgumentNullException(nameof(dependencies));
            }
            if (!NodeLookup.TryGetValue(activityId, out Node <T, TActivity> node))
            {
                return(false);
            }
            if (!dependencies.Any())
            {
                return(true);
            }

            RemoveUnsatisfiedSuccessorActivityDependencies(activityId, dependencies);

            if (node.NodeType == NodeType.Start ||
                node.NodeType == NodeType.Isolated)
            {
                return(true);
            }

            // If any dependencies currently exist, remove them.
            var       existingDependencyLookup = new HashSet <T>(NodeLookup.Keys.Intersect(dependencies));
            IList <T> incomingEdgeIds          = node.IncomingEdges.ToList();
            int       length = incomingEdgeIds.Count;

            for (int i = 0; i < length; i++)
            {
                T edgeId = incomingEdgeIds[i];
                Node <T, TActivity> tailNode = EdgeTailNodeLookup[edgeId];

                if (!existingDependencyLookup.Contains(tailNode.Id))
                {
                    continue;
                }

                // Remove the edge from the tail node.
                tailNode.OutgoingEdges.Remove(edgeId);
                EdgeTailNodeLookup.Remove(edgeId);

                if (!tailNode.OutgoingEdges.Any())
                {
                    if (tailNode.NodeType == NodeType.Normal)
                    {
                        tailNode.SetNodeType(NodeType.End);
                    }
                    else if (tailNode.NodeType == NodeType.Start)
                    {
                        tailNode.SetNodeType(NodeType.Isolated);
                    }
                }

                // Remove the edge from the head node.
                node.IncomingEdges.Remove(edgeId);
                EdgeHeadNodeLookup.Remove(edgeId);

                // Remove the edge completely.
                EdgeLookup.Remove(edgeId);
            }

            if (!node.IncomingEdges.Any())
            {
                if (node.NodeType == NodeType.Normal)
                {
                    node.SetNodeType(NodeType.Start);
                }
                else if (node.NodeType == NodeType.End)
                {
                    node.SetNodeType(NodeType.Isolated);
                }
            }

            return(true);
        }
Esempio n. 26
0
        /// <summary>
        /// Publishes a single Nodelookup
        /// </summary>
        private ServiceResult DoPublish(NodeLookup lookup)
        {
            try
            {
                // find the right session using our lookup
                Session matchingSession = null;
                foreach (Session session in Program.m_sessions)
                {
                    char[] trimChars = { '/', ' ' };
                    if (session.Endpoint.EndpointUrl.TrimEnd(trimChars).StartsWith(lookup.EndPointURL.ToString().TrimEnd(trimChars), StringComparison.OrdinalIgnoreCase))
                    {
                        lookup.EndPointURL = new Uri(session.Endpoint.EndpointUrl);
                        matchingSession    = session;
                        break;
                    }
                }

                if (matchingSession == null)
                {
                    Program.Trace("PublishNodeMethod: No matching session found for " + lookup.EndPointURL.ToString());
                    return(ServiceResult.Create(StatusCodes.BadSessionIdInvalid, "Session for published node not found!"));
                }
                Program.Trace("PublishNodeMethod: Session found.");


                // check if the node has already been published
                foreach (MonitoredItem item in matchingSession.DefaultSubscription.MonitoredItems)
                {
                    if (item.StartNodeId == lookup.NodeID)
                    {
                        Program.Trace("PublishNodeMethod: Node ID has already been published " + lookup.NodeID.ToString());
                        return(ServiceResult.Create(StatusCodes.BadNodeIdExists, "Node has already been published!"));
                    }
                }

                // subscribe to the node
                Program.CreateMonitoredItem(lookup);
                Program.Trace("PublishNodeMethod: Monitored item created.");

                // update our data
                Program.m_nodesLookups.Add(lookup);
                if (!Program.m_endpointUrls.Contains(lookup.EndPointURL))
                {
                    Program.m_endpointUrls.Add(lookup.EndPointURL);
                }

                //serialize Program.m_nodesLookups to disk
                string publishedNodesFilePath = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "publishednodes.json";
                if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_GW_PNFP")))
                {
                    publishedNodesFilePath = Environment.GetEnvironmentVariable("_GW_PNFP");
                }
                File.WriteAllText(publishedNodesFilePath, JsonConvert.SerializeObject(Program.m_nodesLookups));

                Program.Trace("PublishNodeMethod: Successful publish: " + lookup.ToString());
                return(ServiceResult.Good);
            }
            catch (Exception ex)
            {
                Program.Trace("PublishNodeMethod: Exception: " + ex.ToString());
                return(ServiceResult.Create(ex, StatusCodes.BadUnexpectedError, "Unexpected error publishing node: " + ex.Message));
            }
        }
Esempio n. 27
0
 private GraphNode GetOrCreateNode(NodeType type, string path)
 {
     return(NodeLookup.TryGetValue(path, out GraphNode node) ? node : NodeLookup[path] = new GraphNode(type, GetNextId(), path));
 }
Esempio n. 28
0
        /// <summary>
        /// Method exposed as a node in the server to un-publish a node from IoT Hub that it is connected to
        /// </summary>
        private ServiceResult UnPublishNodeMethod(ISystemContext context, MethodState method, IList <object> inputArguments, IList <object> outputArguments)
        {
            if (inputArguments[0] == null || inputArguments[1] == null)
            {
                Program.Trace("UnPublishNodeMethod: Invalid arguments!");
                return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide all arguments!"));
            }

            string nodeID = inputArguments[0] as string;
            string uri    = inputArguments[1] as string;

            if (string.IsNullOrEmpty(nodeID) || string.IsNullOrEmpty(uri))
            {
                Program.Trace("UnPublishNodeMethod: Arguments are not valid strings!");
                return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide all arguments as strings!"));
            }

            NodeLookup lookup = new NodeLookup();

            lookup.NodeID = new NodeId(nodeID);
            try
            {
                lookup.EndPointURL = new Uri(uri);
            }
            catch (UriFormatException)
            {
                Program.Trace("UnPublishNodeMethod: Invalid endpoint URL!");
                return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide a valid OPC UA endpoint URL as second argument!"));
            }

            // find the right session using our lookup
            Session matchingSession = null;

            foreach (Session session in Program.m_sessions)
            {
                char[] trimChars = { '/', ' ' };
                if (session.Endpoint.EndpointUrl.TrimEnd(trimChars).Equals(lookup.EndPointURL.ToString().TrimEnd(trimChars), StringComparison.OrdinalIgnoreCase))
                {
                    matchingSession = session;
                    break;
                }
            }

            if (matchingSession == null)
            {
                Program.Trace("UnPublishNodeMethod: Session for published node not found: " + lookup.EndPointURL.ToString());
                return(ServiceResult.Create(StatusCodes.BadSessionIdInvalid, "Session for published node not found!"));
            }

            // find the right monitored item to remove
            foreach (MonitoredItem item in matchingSession.DefaultSubscription.MonitoredItems)
            {
                if (item.StartNodeId == lookup.NodeID)
                {
                    matchingSession.DefaultSubscription.RemoveItem(item);
                    Program.Trace("UnPublishNodeMethod: Successful unpublish: " + lookup.NodeID.ToString());

                    // update our data on success only
                    // we keep the session to the server, as there may be other nodes still published on it
                    var itemToRemove = Program.m_nodesLookups.Find(l => l.NodeID == lookup.NodeID && l.EndPointURL == lookup.EndPointURL);
                    Program.m_nodesLookups.Remove(itemToRemove);

                    //serialize Program.m_nodesLookups to disk
                    string publishedNodesFilePath = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "publishednodes.json";
                    if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_GW_PNFP")))
                    {
                        publishedNodesFilePath = Environment.GetEnvironmentVariable("_GW_PNFP");
                    }
                    File.WriteAllText(publishedNodesFilePath, JsonConvert.SerializeObject(Program.m_nodesLookups));

                    return(ServiceResult.Good);
                }
            }

            Program.Trace("UnPublishNodeMethod: Monitored item for node ID not found " + lookup.NodeID.ToString());
            return(ServiceResult.Create(StatusCodes.BadNodeIdInvalid, "Monitored item for node ID not found!"));
        }
Esempio n. 29
0
        private void AddEdge(string sourcePath, string targetPath, string label)
        {
            if (sourcePath.IsNullOrEmpty())
            {
                Debug.LogWarning($"Null source path for {label}.");
                return;
            }

            if (targetPath.IsNullOrEmpty())
            {
                Debug.LogWarning($"Null target path for {label}.");
                return;
            }

            if (!NodeLookup.TryGetValue(sourcePath, out GraphNode source))
            {
                Debug.LogWarning($"Couldn't find node for '{sourcePath}'.");
                return;
            }

            if (!targetPath.Contains('.') && !CurrentKnot.IsNullOrEmpty())
            {
                string testPath = $"{CurrentKnot}.{targetPath}";
                if (NodeLookup.ContainsKey(testPath))
                {
                    targetPath = testPath;
                }
            }

            if (!NodeLookup.TryGetValue(targetPath, out GraphNode target))
            {
                Debug.LogWarning($"Couldn't find node for '{targetPath}'.");
                return;
            }

            source = GetNodeAtDepth(source);
            target = GetNodeAtDepth(target);

            if (source.IsExcluded || target.IsExcluded)
            {
                return;
            }

            if (m_Settings.TunnelNodesHandling == TunnelNodesHandling.Remove && (target.IsTunnel || source.IsTunnel))
            {
                return;
            }

            bool duplicateTunnel = false;

            // Duplicate tunnels if needed.
            if (m_Settings.TunnelNodesHandling == TunnelNodesHandling.Duplicate && target.IsTunnel && source != target)
            {
                string tunnelId = source.Label + "->" + target.Label;

                if (DuplicateTunnelLookup.ContainsKey(tunnelId))
                {
                    // Already created this one.
                    return;
                }

                if (target.IsUsed)
                {
                    target = DuplicateNode(target);
                }
                else
                {
                    target.IsUsed = true;
                }

                DuplicateTunnelLookup[tunnelId] = target;
                duplicateTunnel = true;
            }
            else if (m_Settings.ForceDuplicatePaths.Contains(target.Label))
            {
                string forcedDuplicateId = source.Label + "->" + target.Label;

                if (ForceDuplicateLookup.ContainsKey(forcedDuplicateId))
                {
                    // Already created this one.
                    return;
                }

                if (target.IsUsed)
                {
                    target = DuplicateNode(target);
                }
                else
                {
                    target.IsUsed = true;
                }

                ForceDuplicateLookup[forcedDuplicateId] = target;
            }

            AddEdge(source, target, label);

            if (duplicateTunnel)
            {
                AddEdge(target, source);
            }
        }
Esempio n. 30
0
        public override bool RemoveActivity(T activityId)
        {
            // Retrieve the activity's node.
            if (!NodeLookup.TryGetValue(activityId, out Node <T, TActivity> node))
            {
                return(false);
            }
            if (!node.Content.CanBeRemoved)
            {
                return(false);
            }

            RemoveUnsatisfiedSuccessorActivity(activityId);
            NodeLookup.Remove(node.Id);

            if (node.NodeType == NodeType.Isolated)
            {
                return(true);
            }

            if (node.NodeType == NodeType.End ||
                node.NodeType == NodeType.Normal)
            {
                IList <T> incomingEdgeIds = node.IncomingEdges.ToList();
                int       length          = incomingEdgeIds.Count;
                for (int i = 0; i < length; i++)
                {
                    T edgeId = incomingEdgeIds[i];
                    Node <T, TActivity> tailNode = EdgeTailNodeLookup[edgeId];

                    // Remove the edge from the tail node.
                    tailNode.OutgoingEdges.Remove(edgeId);
                    EdgeTailNodeLookup.Remove(edgeId);

                    if (!tailNode.OutgoingEdges.Any())
                    {
                        if (tailNode.NodeType == NodeType.Normal)
                        {
                            tailNode.SetNodeType(NodeType.End);
                        }
                        else if (tailNode.NodeType == NodeType.Start)
                        {
                            tailNode.SetNodeType(NodeType.Isolated);
                        }
                    }

                    // Remove the edge from the head node.
                    node.IncomingEdges.Remove(edgeId);
                    EdgeHeadNodeLookup.Remove(edgeId);

                    if (!node.IncomingEdges.Any())
                    {
                        if (node.NodeType == NodeType.Normal)
                        {
                            node.SetNodeType(NodeType.Start);
                        }
                        else if (node.NodeType == NodeType.End)
                        {
                            node.SetNodeType(NodeType.Isolated);
                        }
                    }

                    // Remove the edge completely.
                    EdgeLookup.Remove(edgeId);
                }
            }

            if (node.NodeType == NodeType.Start ||
                node.NodeType == NodeType.Normal)
            {
                IList <T> outgoingEdgeIds = node.OutgoingEdges.ToList();
                int       length          = outgoingEdgeIds.Count;
                for (int i = 0; i < length; i++)
                {
                    T edgeId = outgoingEdgeIds[i];
                    Node <T, TActivity> headNode = EdgeHeadNodeLookup[edgeId];

                    // Remove the edge from the head node.
                    headNode.IncomingEdges.Remove(edgeId);
                    EdgeHeadNodeLookup.Remove(edgeId);

                    if (!headNode.IncomingEdges.Any())
                    {
                        if (headNode.NodeType == NodeType.Normal)
                        {
                            headNode.SetNodeType(NodeType.Start);
                        }
                        else if (headNode.NodeType == NodeType.End)
                        {
                            headNode.SetNodeType(NodeType.Isolated);
                        }
                    }

                    // Remove the edge from the tail node.
                    node.OutgoingEdges.Remove(edgeId);
                    EdgeTailNodeLookup.Remove(edgeId);

                    if (!node.OutgoingEdges.Any())
                    {
                        if (node.NodeType == NodeType.Normal)
                        {
                            node.SetNodeType(NodeType.End);
                        }
                        else if (node.NodeType == NodeType.Start)
                        {
                            node.SetNodeType(NodeType.Isolated);
                        }
                    }

                    // Remove the edge completely.
                    EdgeLookup.Remove(edgeId);
                }
            }
            return(true);
        }