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); } }
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); }
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); } }
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 (NodeLookup.ContainsKey(activity.Id)) { return(false); } if (dependencies.Contains(activity.Id)) { return(false); } // Create a new Isolated node for the activity. var node = new Node <T, TActivity>(NodeType.Isolated, activity); NodeLookup.Add(node.Id, node); // We expect dependencies at some point. if (dependencies.Any()) { 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); } } ResolveUnsatisfiedSuccessorActivities(node.Id); return(true); }