/// <summary> /// Performs a Depth-First traversal over the cached segment geometry structure. At each /// traversed segment, the given `visitor` is notified. It then can update the current `state`. /// </summary> /// <param name="initialSegmentGeometry">Specifies the segment at which the traversal /// should start.</param> /// <param name="nextNodeIsStartNode">Specifies if the next node to traverse is the start /// node of the initial segment.</param> /// <param name="direction">Specifies if traffic should be able to flow towards the initial /// segment (Incoming) or should be able to flow from the initial segment (Outgoing) or /// in both directions (Both).</param> /// <param name="maximumDepth">Specifies the maximum depth to explore. At a depth of 0, no /// segment will be traversed (event the initial segment will be omitted).</param> /// <param name="visitorFun">Specifies the stateful visitor that should be notified as soon as /// a traversable segment (which has not been traversed before) is found.</param> public static IEnumerable <ushort> Traverse(ushort initialSegmentId, TraverseDirection direction, TraverseSide side, SegmentStopCriterion stopCrit, SegmentVisitor visitorFun) { ExtSegment initialSeg = Constants.ManagerFactory.ExtSegmentManager.ExtSegments[initialSegmentId]; if (!initialSeg.valid) { return(null); } // Log._Debug($"SegmentTraverser: Traversing initial segment {initialSegmentId}"); if (!visitorFun( new SegmentVisitData( ref initialSeg, ref initialSeg, false, false, true))) { return(null); } HashSet <ushort> visitedSegmentIds = new HashSet <ushort>(); visitedSegmentIds.Add(initialSegmentId); IExtSegmentEndManager extSegEndMan = Constants.ManagerFactory.ExtSegmentEndManager; ref NetSegment initialSegment = ref initialSegmentId.ToSegment();
/// <summary> /// Performs a Depth-First traversal over the cached segment geometry structure. At each /// traversed segment, the given `visitor` is notified. It then can update the current `state`. /// </summary> /// <param name="initialSegmentGeometry">Specifies the segment at which the traversal /// should start.</param> /// <param name="nextNodeIsStartNode">Specifies if the next node to traverse is the start /// node of the initial segment.</param> /// <param name="direction">Specifies if traffic should be able to flow towards the initial /// segment (Incoming) or should be able to flow from the initial segment (Outgoing) or /// in both directions (Both).</param> /// <param name="maximumDepth">Specifies the maximum depth to explore. At a depth of 0, no /// segment will be traversed (event the initial segment will be omitted).</param> /// <param name="visitorFun">Specifies the stateful visitor that should be notified as soon as /// a traversable segment (which has not been traversed before) is found.</param> public static IEnumerable <ushort> Traverse(ushort initialSegmentId, TraverseDirection direction, TraverseSide side, SegmentStopCriterion stopCrit, SegmentVisitor visitorFun) { ExtSegment initialSeg = Constants.ManagerFactory.ExtSegmentManager.ExtSegments[initialSegmentId]; if (!initialSeg.valid) { return(null); } // Log._Debug($"SegmentTraverser: Traversing initial segment {initialSegmentId}"); if (!visitorFun( new SegmentVisitData( ref initialSeg, ref initialSeg, false, false, true))) { return(null); } HashSet <ushort> visitedSegmentIds = new HashSet <ushort>(); visitedSegmentIds.Add(initialSegmentId); IExtSegmentEndManager extSegEndMan = Constants.ManagerFactory.ExtSegmentEndManager; ushort startNodeId = Constants.ServiceFactory.NetService.GetSegmentNodeId(initialSegmentId, true); TraverseRec( ref initialSeg, ref extSegEndMan.ExtSegmentEnds[extSegEndMan.GetIndex(initialSegmentId, true)], ref startNodeId.ToNode(), true, direction, side, stopCrit, visitorFun, visitedSegmentIds); ushort endNodeId = Constants.ServiceFactory.NetService.GetSegmentNodeId(initialSegmentId, false); TraverseRec( ref initialSeg, ref extSegEndMan.ExtSegmentEnds[extSegEndMan.GetIndex(initialSegmentId, false)], ref endNodeId.ToNode(), false, direction, side, stopCrit, visitorFun, visitedSegmentIds); // Log._Debug($"SegmentTraverser: Traversal finished."); return(visitedSegmentIds); }
public void OnRoomEnter(TraverseDirection direction, bool isFirstEntry) { foreach (var e in EventActionsOnEnter) { e.Call((RoomEnteranceDirection)((int)direction), isFirstEntry); } }
/// <summary> /// Performs a Depth-First traversal over the cached segment geometry structure. At each traversed segment, the given `visitor` is notified. It then can update the current `state`. /// </summary> /// <param name="initialSegmentGeometry">Specifies the segment at which the traversal should start.</param> /// <param name="nextNodeIsStartNode">Specifies if the next node to traverse is the start node of the initial segment.</param> /// <param name="direction">Specifies if traffic should be able to flow towards the initial segment (Incoming) or should be able to flow from the initial segment (Outgoing) or in both directions (Both).</param> /// <param name="maximumDepth">Specifies the maximum depth to explore. At a depth of 0, no segment will be traversed (event the initial segment will be omitted).</param> /// <param name="visitor">Specifies the stateful visitor that should be notified as soon as a traversable segment (which has not been traversed before) is found.</param> public static void Traverse(ushort initialSegmentId, TraverseDirection direction, TraverseSide side, SegmentStopCriterion stopCrit, SegmentVisitor visitor) { ExtSegment initialSeg = Constants.ManagerFactory.ExtSegmentManager.ExtSegments[initialSegmentId]; if (!initialSeg.valid) { return; } //Log._Debug($"SegmentTraverser: Traversing initial segment {initialSegmentId}"); if (visitor(new SegmentVisitData(ref initialSeg, ref initialSeg, false, false, true))) { HashSet <ushort> visitedSegmentIds = new HashSet <ushort>(); visitedSegmentIds.Add(initialSegmentId); IExtSegmentEndManager extSegEndMan = Constants.ManagerFactory.ExtSegmentEndManager; ushort startNodeId = Constants.ServiceFactory.NetService.GetSegmentNodeId(initialSegmentId, true); Constants.ServiceFactory.NetService.ProcessNode(startNodeId, delegate(ushort nId, ref NetNode node) { TraverseRec(ref initialSeg, ref extSegEndMan.ExtSegmentEnds[extSegEndMan.GetIndex(initialSegmentId, true)], ref node, true, direction, side, stopCrit, visitor, visitedSegmentIds); return(true); }); ushort endNodeId = Constants.ServiceFactory.NetService.GetSegmentNodeId(initialSegmentId, false); Constants.ServiceFactory.NetService.ProcessNode(endNodeId, delegate(ushort nId, ref NetNode node) { TraverseRec(ref initialSeg, ref extSegEndMan.ExtSegmentEnds[extSegEndMan.GetIndex(initialSegmentId, false)], ref node, false, direction, side, stopCrit, visitor, visitedSegmentIds); return(true); }); } //Log._Debug($"SegmentTraverser: Traversal finished."); }
public void Traverse(TraverseDirection direction) { switch (direction) { case TraverseDirection.Up: StartCoroutine(TraverseCoroutine(direction, CurrentRoom.RoomUp, RoomTargetDown, RoomTargetUp)); break; case TraverseDirection.Down: StartCoroutine(TraverseCoroutine(direction, CurrentRoom.RoomDown, RoomTargetUp, RoomTargetDown)); break; case TraverseDirection.Left: StartCoroutine(TraverseCoroutine(direction, CurrentRoom.RoomLeft, RoomTargetRight, RoomTargetLeft)); break; case TraverseDirection.Right: StartCoroutine(TraverseCoroutine(direction, CurrentRoom.RoomRight, RoomTargetLeft, RoomTargetRight)); break; default: Debug.LogError($"Undefined traverse direction {direction}"); break; } }
public NodeInfo TraverseTree(TraverseDirection Direction) { switch (Direction) { case TraverseDirection.TRAVERSE_LEFT: Position = Position.LeftNode; break; case TraverseDirection.TRAVERSE_RIGHT: Position = Position.RightNode; break; case TraverseDirection.TRAVERSE_UP: Position = Position.ParentNode; break; case TraverseDirection.TRAVERSE_ROOT: Position = Root; break; default: break; } if (Position == null) { ConsoleColor TempColor = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Null node! Repositioning to Root...\n"); Console.ForegroundColor = TempColor; Position = Root; } return(new NodeInfo(Position)); }
private static void Walk(Device current, TraverseDirection direction, List <string> path) { string nextDeviceId = null; switch (direction) { case TraverseDirection.PrimaryParent: nextDeviceId = current.PrimaryParent; break; case TraverseDirection.SecondaryParent: nextDeviceId = current.SecondaryParent; break; case TraverseDirection.PowerSourceParent: if (current.EvaluationContext.RelationLookup.ContainsKey(current.DeviceName)) { var relation = current.EvaluationContext.RelationLookup[current.DeviceName].FirstOrDefault( p => p.Value.Association == AssociationType.PowerSource && p.Value.Direction == DirectionType.DirectUpstream); if (relation.Value != null) { nextDeviceId = relation.Value.ToDeviceName; } } break; case TraverseDirection.Child: foreach (var fromDeviceName in current.EvaluationContext.RelationLookup.Keys) { if (current.EvaluationContext.RelationLookup[fromDeviceName].ContainsKey(current.DeviceName)) { nextDeviceId = fromDeviceName; break; } } break; case TraverseDirection.Redundant: nextDeviceId = current.RedundantDeviceNames; break; } if (!string.IsNullOrEmpty(nextDeviceId) && current.EvaluationContext.DeviceLookup.ContainsKey(nextDeviceId)) { if (path.Contains(nextDeviceId)) { // circular path.Add(nextDeviceId); path.Add("!!"); return; } path.Add(nextDeviceId); var nextDevice = current.EvaluationContext.DeviceLookup[nextDeviceId]; Walk(nextDevice, direction, path); } }
public void SetDirection(TraverseDirection direction) { this.direction = direction; if (reachDestinationFirst) { return; } DispatchEvent(new Event("NextWaypoint").SetData(current)); }
public Leaf GetLeaf(TraverseDirection direction) { var left = direction == TraverseDirection.CounterClockwise; var node = left ? Left : Right; while (!node.IsLeaf) { node = left ? ((Node)node).Right : ((Node)node).Left; } return((Leaf)node); }
public static List <string> Traverse(this Device device, TraverseDirection direction) { if (device.EvaluationContext == null) { throw new InvalidOperationException("device evaluation context is not initialized"); } var path = new List <string>() { device.DeviceName }; Walk(device, direction, path); return(path); }
public IList <IMod> Traverse(TraverseDirection direction = TraverseDirection.SubToBase, bool throwOnCycle = true) { if (throwOnCycle) { CheckForCycles(); } var result = TraverseCore().Distinct(); if (direction == TraverseDirection.BaseToSub) { result = result.Reverse(); } return(result.ToList()); }
public Node GetParent(TraverseDirection direction) { var parent = (Node)Parent; INode node = this; while ((direction == TraverseDirection.CounterClockwise ? parent.Left : parent.Right) == node) { if (parent.Parent == null) { return(null); } node = parent; parent = (Node)parent.Parent; } return(parent); }
public void ReverseDirection() { if (direction == TraverseDirection.Forward) { direction = TraverseDirection.Backward; } if (direction == TraverseDirection.Backward) { direction = TraverseDirection.Forward; } if (reachDestinationFirst) { return; } DispatchEvent(new Event("NextWaypoint").SetData(current)); }
private IEnumerator TraverseCoroutine(TraverseDirection direction, Room targetRoom, Transform currentRoomTarget, Transform destinationRoomTarget) { float traverseDuration = targetRoom == CurrentRoom ? TraverseDuration * 2f : TraverseDuration; StartCoroutine(TeleportPlayer(direction, targetRoom, traverseDuration)); foreach (var textShow in FindObjectsOfType <ShowTextAction>()) { textShow.CancelShow(); } Sfx.TraverseEffect(traverseDuration); if (targetRoom != null) { if (targetRoom == CurrentRoom) { IsTraversing = true; const float coeff = 0.75f; TraverseDuration *= coeff; yield return(StartCoroutine(RoomMoveCoroutine(CurrentRoom, RoomTargetMiddle, currentRoomTarget, true, true))); yield return(StartCoroutine(RoomMoveCoroutine(CurrentRoom, destinationRoomTarget, RoomTargetMiddle, true, true))); ChangeCurrentRoom(targetRoom); IsTraversing = false; TraverseDuration *= 1 / coeff; } else // Different room { IsTraversing = true; StartCoroutine(RoomMoveCoroutine(CurrentRoom, RoomTargetMiddle, currentRoomTarget, true, false)); StartCoroutine(RoomMoveCoroutine(targetRoom, destinationRoomTarget, RoomTargetMiddle, true, true)); StartCoroutine(CoverCoroutine(targetRoom)); ChangeCurrentRoom(targetRoom); yield return(new WaitForSeconds(TraverseDuration)); IsTraversing = false; } } else { Debug.LogError($"No target room defined for room {CurrentRoom}"); } }
/// <summary> /// Performs a Depth-First traversal over the cached segment geometry structure. At each traversed segment, the given `visitor` is notified. It then can update the current `state`. /// </summary> /// <param name="initialSegmentGeometry">Specifies the segment at which the traversal should start.</param> /// <param name="nextNodeIsStartNode">Specifies if the next node to traverse is the start node of the initial segment.</param> /// <param name="direction">Specifies if traffic should be able to flow towards the initial segment (Incoming) or should be able to flow from the initial segment (Outgoing) or in both directions (Both).</param> /// <param name="maximumDepth">Specifies the maximum depth to explore. At a depth of 0, no segment will be traversed (event the initial segment will be omitted).</param> /// <param name="visitor">Specifies the stateful visitor that should be notified as soon as a traversable segment (which has not been traversed before) is found.</param> public static void Traverse(ushort initialSegmentId, TraverseDirection direction, IVisitor <SegmentGeometry> visitor) { SegmentGeometry initialGeometry = SegmentGeometry.Get(initialSegmentId); if (initialGeometry == null) { return; } if (visitor.Visit(initialGeometry)) { HashSet <ushort> visitedSegmentIds = new HashSet <ushort>(); visitedSegmentIds.Add(initialSegmentId); TraverseRec(initialGeometry, true, direction, visitor, visitedSegmentIds); TraverseRec(initialGeometry, false, direction, visitor, visitedSegmentIds); } }
void NextWaypoint(Event e) { // If the new destination is the same as the current don't continue // If there is no waypoint group set don't continue if ((AIDestination)e.data != current || !waypointGroup) { return; } // Set an empty destination AIDestination destination = null; // If patrolling is enabled toggle directions if needed if (patrol) { if (direction == TraverseDirection.Forward && current == waypointGroup.GetLastWaypoint()) { direction = TraverseDirection.Backward; } else if (direction == TraverseDirection.Backward && current == waypointGroup.GetFirstWaypoint()) { direction = TraverseDirection.Forward; } } // If the direction is forward get the next waypoint if (direction == TraverseDirection.Forward) { destination = waypointGroup.GetNextWaypoint(current); } // If the direction is backward get the previous waypoint else if (direction == TraverseDirection.Backward) { destination = waypointGroup.GetPreviousWaypoint(current); } // If we have a destination set the new destination if (destination != null) { current = destination; brain.SetDestination(current.position); } }
/// <summary> /// Performs a Depth-First traversal over the cached segment geometry structure. At each traversed segment, the given `visitor` is notified. It then can update the current `state`. /// </summary> /// <param name="initialSegmentGeometry">Specifies the segment at which the traversal should start.</param> /// <param name="nextNodeIsStartNode">Specifies if the next node to traverse is the start node of the initial segment.</param> /// <param name="direction">Specifies if traffic should be able to flow towards the initial segment (Incoming) or should be able to flow from the initial segment (Outgoing) or in both directions (Both).</param> /// <param name="maximumDepth">Specifies the maximum depth to explore. At a depth of 0, no segment will be traversed (event the initial segment will be omitted).</param> /// <param name="visitor">Specifies the stateful visitor that should be notified as soon as a traversable segment (which has not been traversed before) is found.</param> public static void Traverse(ushort initialSegmentId, TraverseDirection direction, TraverseSide side, SegmentStopCriterion stopCrit, SegmentVisitor visitor) { SegmentGeometry initialSegGeometry = SegmentGeometry.Get(initialSegmentId); if (initialSegGeometry == null) { return; } Log._Debug($"SegmentTraverser: Traversing initial segment {initialSegGeometry.SegmentId}"); if (visitor(new SegmentVisitData(initialSegGeometry, initialSegGeometry, false, false, true))) { HashSet <ushort> visitedSegmentIds = new HashSet <ushort>(); visitedSegmentIds.Add(initialSegmentId); TraverseRec(initialSegGeometry, true, true, direction, side, stopCrit, visitor, visitedSegmentIds); TraverseRec(initialSegGeometry, false, false, direction, side, stopCrit, visitor, visitedSegmentIds); } Log._Debug($"SegmentTraverser: Traversal finished."); }
public static void Traverse(ushort initialSegmentId, TraverseDirection direction, TraverseSide side, LaneStopCriterion laneStopCrit, SegmentStopCriterion segStopCrit, NetInfo.LaneType?laneTypeFilter, VehicleInfo.VehicleType?vehicleTypeFilter, SegmentLaneVisitor laneVisitor) { IList <LanePos> initialSortedLanes = null; SegmentTraverser.Traverse(initialSegmentId, direction, side, segStopCrit, delegate(SegmentVisitData segData) { bool isInitialSeg = segData.initial; bool reverse = !isInitialSeg && segData.viaStartNode == segData.viaInitialStartNode; bool ret = false; Constants.ServiceFactory.NetService.ProcessSegment(segData.curGeo.SegmentId, delegate(ushort segmentId, ref NetSegment segment) { Log._Debug($"SegmentLaneTraverser: Reached segment {segmentId}: isInitialSeg={isInitialSeg} viaStartNode={segData.viaStartNode} viaInitialStartNode={segData.viaInitialStartNode} reverse={reverse}"); IList <LanePos> sortedLanes = Constants.ServiceFactory.NetService.GetSortedLanes(segmentId, ref segment, null, laneTypeFilter, vehicleTypeFilter, reverse); if (isInitialSeg) { initialSortedLanes = sortedLanes; } else if (initialSortedLanes == null) { throw new ApplicationException("Initial list of sorted lanes not set."); } else if (sortedLanes.Count != initialSortedLanes.Count && (laneStopCrit & LaneStopCriterion.LaneCount) != LaneStopCriterion.None) { Log._Debug($"SegmentLaneTraverser: Stop criterion reached @ {segmentId}: {sortedLanes.Count} current vs. {initialSortedLanes.Count} initial lanes"); return(false); } for (int i = 0; i < sortedLanes.Count; ++i) { Log._Debug($"SegmentLaneTraverser: Traversing segment lane {sortedLanes[i].laneIndex} @ {segmentId} (id {sortedLanes[i].laneId}, pos {sortedLanes[i].position})"); if (!laneVisitor(new SegmentLaneVisitData(segData, i, sortedLanes[i], initialSortedLanes[i]))) { return(false); } } ret = true; return(true); }); return(ret); }); }
private IEnumerator TeleportPlayer(TraverseDirection direction, Room targetRoom, float traverseDuration) { Player.transform.SetParent(CurrentRoom.transform); StartCoroutine(FadePlayer(PlayerFadeType.Hide, traverseDuration * 0.3f)); yield return(new WaitForSeconds(traverseDuration / 2f)); Vector3 offset = new Vector3(0.49f, -0.49f, 0.0f); Vector3Int cellPos = Grid.WorldToCell(Player.transform.position + offset); switch (direction) { case TraverseDirection.Up: cellPos = new Vector3Int(cellPos.x, -5, 0); break; case TraverseDirection.Down: cellPos = new Vector3Int(cellPos.x, 4, 0); break; case TraverseDirection.Left: cellPos = new Vector3Int(4, cellPos.y, 0); break; case TraverseDirection.Right: cellPos = new Vector3Int(-5, cellPos.y, 0); break; } Player.transform.localPosition = Grid.CellToWorld(cellPos) - offset; Player.transform.SetParent(targetRoom.transform, false); StartCoroutine(FadePlayer(PlayerFadeType.Show, traverseDuration * 0.3f)); yield return(new WaitForSeconds(traverseDuration / 2f)); Player.transform.SetParent(null); CurrentRoom.OnRoomEnter(direction, _isFirstEntry); }
public override bool Read() { // First call to Read if (ReadState == System.Xml.ReadState.Initial) { nodeStack.Push(rootNode); currentNode = rootNode.GetFirstChild(); return(CheckReadStateAndReturn()); } if (xmlReader != null) { var result = xmlReader.Read(); if (result && xmlReader.Depth > 0) { return(result); } else { xmlReader.Close(); textReader.Dispose(); xmlReader = null; textReader = null; } } switch (traverseDirection) { case TraverseDirection.Down: // As long as there're children go down (depth first) if (currentNode.HasChildren) { nodeStack.Push(currentNode); currentNode = currentNode.GetFirstChild(); } else { var parent = nodeStack.Peek(); var lastChild = parent.GetLastChild(); if (currentNode.IsSame(lastChild)) { // Time to move back up nodeStack.Pop(); traverseDirection = TraverseDirection.Up; currentNode.Dispose(); currentNode = parent; } else { // There're still siblings left to visit var nextSibling = currentNode.GetNextSibling(); currentNode.Dispose(); currentNode = nextSibling; } // Avoid double disposal GC.SuppressFinalize(lastChild); } break; case TraverseDirection.Up: // See if we can find siblings (need to have a parent) if (nodeStack.Count > 1) { var parent = nodeStack.Peek(); var lastChild = parent.GetLastChild(); if (currentNode.IsSame(lastChild)) { // No sibling left, go further up nodeStack.Pop(); currentNode.Dispose(); currentNode = parent; } else { // There's a sibling, try to traverse down again (depth first) traverseDirection = TraverseDirection.Down; var nextSibling = currentNode.GetNextSibling(); currentNode.Dispose(); currentNode = nextSibling; } // Avoid double disposal GC.SuppressFinalize(lastChild); } else { // No parent left, we have to be the root -> EOF currentNode.Dispose(); currentNode = null; readState = System.Xml.ReadState.EndOfFile; return(false); } break; } if (currentNode != null) { // See if this node defines a new namespace if (currentNode.HasElementAttributes()) { attributeMap = currentNode.GetElementAttributes(); switch (traverseDirection) { case TraverseDirection.Down: for (int i = 0; i < attributeMap.Count; i++) { string key, value; if (attributeMap.TryGetKey(i, out key) && attributeMap.TryGetValue(i, out value)) { if (key.StartsWith("xmlns")) { var prefix = GetPrefix(key); namespaceManager.AddNamespace(prefix, value); } } } namespaceManager.PushScope(); break; case TraverseDirection.Up: namespaceManager.PopScope(); break; } } else { attributeMap = null; } } return(CheckReadStateAndReturn()); }
private static void TraverseRec(SegmentGeometry prevGeometry, bool exploreStartNode, TraverseDirection direction, IVisitor <SegmentGeometry> visitor, HashSet <ushort> visitedSegmentIds) { // collect next segment ids to traverse ushort[] nextSegmentIds; switch (direction) { case TraverseDirection.Both: default: nextSegmentIds = prevGeometry.GetConnectedSegments(exploreStartNode); break; case TraverseDirection.Incoming: nextSegmentIds = prevGeometry.GetIncomingSegments(exploreStartNode); break; case TraverseDirection.Outgoing: nextSegmentIds = prevGeometry.GetOutgoingSegments(exploreStartNode); break; } ushort prevNodeId = prevGeometry.GetNodeId(exploreStartNode); // explore next segments foreach (ushort nextSegmentId in nextSegmentIds) { if (nextSegmentId == 0 || visitedSegmentIds.Contains(nextSegmentId)) { continue; } visitedSegmentIds.Add(nextSegmentId); SegmentGeometry nextSegmentGeometry = SegmentGeometry.Get(nextSegmentId); if (nextSegmentGeometry != null && visitor.Visit(nextSegmentGeometry)) { bool nextNodeIsStartNode = nextSegmentGeometry.StartNodeId() != prevNodeId; TraverseRec(nextSegmentGeometry, nextNodeIsStartNode, direction, visitor, visitedSegmentIds); } } }
private static void TraverseRec(SegmentGeometry prevSegGeometry, bool exploreStartNode, bool viaInitialStartNode, TraverseDirection direction, TraverseSide side, SegmentStopCriterion stopCrit, SegmentVisitor visitor, HashSet <ushort> visitedSegmentIds) { Log._Debug($"SegmentTraverser: Traversing segment {prevSegGeometry.SegmentId}"); // collect next segment ids to traverse if (direction == TraverseDirection.None) { throw new ArgumentException($"Invalid direction {direction} given."); } if (side == TraverseSide.None) { throw new ArgumentException($"Invalid side {side} given."); } HashSet <ushort> nextSegmentIds = new HashSet <ushort>(); switch (direction) { case TraverseDirection.AnyDirection: default: if (side == TraverseSide.AnySide) { nextSegmentIds.UnionWith(prevSegGeometry.GetConnectedSegments(exploreStartNode)); } else { if ((side & TraverseSide.Left) != TraverseSide.None) { nextSegmentIds.UnionWith(prevSegGeometry.GetLeftSegments(exploreStartNode)); } if ((side & TraverseSide.Straight) != TraverseSide.None) { nextSegmentIds.UnionWith(prevSegGeometry.GetStraightSegments(exploreStartNode)); } if ((side & TraverseSide.Right) != TraverseSide.None) { nextSegmentIds.UnionWith(prevSegGeometry.GetRightSegments(exploreStartNode)); } } break; case TraverseDirection.Incoming: if (side == TraverseSide.AnySide) { nextSegmentIds.UnionWith(prevSegGeometry.GetIncomingSegments(exploreStartNode)); } else { if ((side & TraverseSide.Left) != TraverseSide.None) { nextSegmentIds.UnionWith(prevSegGeometry.GetIncomingLeftSegments(exploreStartNode)); } if ((side & TraverseSide.Straight) != TraverseSide.None) { nextSegmentIds.UnionWith(prevSegGeometry.GetIncomingStraightSegments(exploreStartNode)); } if ((side & TraverseSide.Right) != TraverseSide.None) { nextSegmentIds.UnionWith(prevSegGeometry.GetIncomingRightSegments(exploreStartNode)); } } break; case TraverseDirection.Outgoing: if (side == TraverseSide.AnySide) { nextSegmentIds.UnionWith(prevSegGeometry.GetOutgoingSegments(exploreStartNode)); } else { if ((side & TraverseSide.Left) != TraverseSide.None) { nextSegmentIds.UnionWith(prevSegGeometry.GetOutgoingLeftSegments(exploreStartNode)); } if ((side & TraverseSide.Straight) != TraverseSide.None) { nextSegmentIds.UnionWith(prevSegGeometry.GetOutgoingStraightSegments(exploreStartNode)); } if ((side & TraverseSide.Right) != TraverseSide.None) { nextSegmentIds.UnionWith(prevSegGeometry.GetOutgoingRightSegments(exploreStartNode)); } } break; } nextSegmentIds.Remove(0); Log._Debug($"SegmentTraverser: Fetched next segments to traverse: {nextSegmentIds.CollectionToString()}"); if (nextSegmentIds.Count >= 2 && (stopCrit & SegmentStopCriterion.Junction) != SegmentStopCriterion.None) { Log._Debug($"SegmentTraverser: Stop criterion reached @ {prevSegGeometry.SegmentId}: {nextSegmentIds.Count} connected segments"); return; } ushort prevNodeId = prevSegGeometry.GetNodeId(exploreStartNode); // explore next segments foreach (ushort nextSegmentId in nextSegmentIds) { if (nextSegmentId == 0 || visitedSegmentIds.Contains(nextSegmentId)) { continue; } visitedSegmentIds.Add(nextSegmentId); SegmentGeometry nextSegGeometry = SegmentGeometry.Get(nextSegmentId); if (nextSegGeometry != null) { Log._Debug($"SegmentTraverser: Traversing segment {nextSegGeometry.SegmentId}"); if (visitor(new SegmentVisitData(prevSegGeometry, nextSegGeometry, viaInitialStartNode, prevNodeId == nextSegGeometry.StartNodeId(), false))) { bool nextNodeIsStartNode = nextSegGeometry.StartNodeId() != prevNodeId; TraverseRec(nextSegGeometry, nextNodeIsStartNode, viaInitialStartNode, direction, side, stopCrit, visitor, visitedSegmentIds); } } } }
private static void TraverseRec(ref ExtSegment prevSeg, ref ExtSegmentEnd prevSegEnd, ref NetNode node, bool viaInitialStartNode, TraverseDirection direction, TraverseSide side, SegmentStopCriterion stopCrit, SegmentVisitor visitorFun, HashSet <ushort> visitedSegmentIds) { // Log._Debug($"SegmentTraverser: Traversing segment {prevSegEnd.segmentId}"); // collect next segment ids to traverse if (direction == TraverseDirection.None) { throw new ArgumentException($"Invalid direction {direction} given."); } if (side == TraverseSide.None) { throw new ArgumentException($"Invalid side {side} given."); } IExtSegmentManager extSegMan = Constants.ManagerFactory.ExtSegmentManager; IExtSegmentEndManager extSegEndMan = Constants.ManagerFactory.ExtSegmentEndManager; HashSet <ushort> nextSegmentIds = new HashSet <ushort>(); for (int i = 0; i < 8; ++i) { ushort nextSegmentId = node.GetSegment(i); if (nextSegmentId == 0 || nextSegmentId == prevSegEnd.segmentId) { continue; } bool nextIsStartNode = (bool)Constants.ServiceFactory.NetService.IsStartNode( nextSegmentId, prevSegEnd.nodeId); ExtSegmentEnd nextSegEnd = extSegEndMan.ExtSegmentEnds[extSegEndMan.GetIndex(nextSegmentId, nextIsStartNode)]; if (direction == TraverseDirection.AnyDirection || (direction == TraverseDirection.Incoming && nextSegEnd.incoming) || (direction == TraverseDirection.Outgoing && nextSegEnd.outgoing)) { if (side == TraverseSide.AnySide) { nextSegmentIds.Add(nextSegmentId); } else { ArrowDirection dir = extSegEndMan.GetDirection( ref prevSegEnd, nextSegmentId); if (((side & TraverseSide.Left) != TraverseSide.None && dir == ArrowDirection.Left) || ((side & TraverseSide.Straight) != TraverseSide.None && dir == ArrowDirection.Forward) || ((side & TraverseSide.Right) != TraverseSide.None && dir == ArrowDirection.Right)) { nextSegmentIds.Add(nextSegmentId); } } } } nextSegmentIds.Remove(0); // Log._Debug($"SegmentTraverser: Fetched next segments to traverse: // {nextSegmentIds.CollectionToString()}"); if (nextSegmentIds.Count >= 2 && (stopCrit & SegmentStopCriterion.Junction) != SegmentStopCriterion.None) { // Log._Debug($"SegmentTraverser: Stop criterion reached @ {prevSegEnd.segmentId}: // {nextSegmentIds.Count} connected segments"); return; } // explore next segments foreach (ushort nextSegmentId in nextSegmentIds) { if (visitedSegmentIds.Contains(nextSegmentId)) { continue; } visitedSegmentIds.Add(nextSegmentId); // Log._Debug($"SegmentTraverser: Traversing segment {nextSegmentId}"); ushort nextStartNodeId = Constants.ServiceFactory.NetService.GetSegmentNodeId(nextSegmentId, true); if (!visitorFun( new SegmentVisitData( ref prevSeg, ref extSegMan.ExtSegments[nextSegmentId], viaInitialStartNode, prevSegEnd.nodeId == nextStartNodeId, false))) { continue; } bool nextNodeIsStartNode = nextStartNodeId != prevSegEnd.nodeId; ExtSegmentEnd nextSegEnd = extSegEndMan.ExtSegmentEnds[extSegEndMan.GetIndex(nextSegmentId, nextNodeIsStartNode)]; Constants.ServiceFactory.NetService.ProcessNode( nextSegEnd.nodeId, (ushort nId, ref NetNode nextNode) => { TraverseRec( ref extSegMan.ExtSegments[nextSegmentId], ref nextSegEnd, ref nextNode, viaInitialStartNode, direction, side, stopCrit, visitorFun, visitedSegmentIds); return(true); }); } // end foreach }
private static void TraverseRec(SegmentGeometry prevSegGeometry, bool exploreStartNode, bool viaInitialStartNode, TraverseDirection direction, SegmentStopCriterion stopCrit, SegmentVisitor visitor, HashSet <ushort> visitedSegmentIds) { // collect next segment ids to traverse ushort[] nextSegmentIds; int numConnectedSegments; switch (direction) { case TraverseDirection.Both: default: nextSegmentIds = prevSegGeometry.GetConnectedSegments(exploreStartNode); numConnectedSegments = prevSegGeometry.CountOtherSegments(exploreStartNode); break; case TraverseDirection.Incoming: nextSegmentIds = prevSegGeometry.GetIncomingSegments(exploreStartNode); numConnectedSegments = prevSegGeometry.CountIncomingSegments(exploreStartNode); break; case TraverseDirection.Outgoing: nextSegmentIds = prevSegGeometry.GetOutgoingSegments(exploreStartNode); numConnectedSegments = prevSegGeometry.CountOutgoingSegments(exploreStartNode); break; } if (numConnectedSegments >= 2 && (stopCrit & SegmentStopCriterion.Junction) != SegmentStopCriterion.None) { Log._Debug($"SegmentTraverser: Stop criterion reached @ {prevSegGeometry.SegmentId}: {numConnectedSegments} connected segments"); return; } ushort prevNodeId = prevSegGeometry.GetNodeId(exploreStartNode); // explore next segments foreach (ushort nextSegmentId in nextSegmentIds) { if (nextSegmentId == 0 || visitedSegmentIds.Contains(nextSegmentId)) { continue; } visitedSegmentIds.Add(nextSegmentId); SegmentGeometry nextSegGeometry = SegmentGeometry.Get(nextSegmentId); if (nextSegGeometry != null) { Log._Debug($"SegmentTraverser: Traversing segment {nextSegGeometry.SegmentId}"); if (visitor(new SegmentVisitData(prevSegGeometry, nextSegGeometry, viaInitialStartNode, prevNodeId == nextSegGeometry.StartNodeId(), false))) { bool nextNodeIsStartNode = nextSegGeometry.StartNodeId() != prevNodeId; TraverseRec(nextSegGeometry, nextNodeIsStartNode, viaInitialStartNode, direction, stopCrit, visitor, visitedSegmentIds); } } } }
public static void Traverse(ushort initialSegmentId, TraverseDirection direction, TraverseSide side, LaneStopCriterion laneStopCrit, SegmentStopCriterion segStopCrit, NetInfo.LaneType?laneTypeFilter, VehicleInfo.VehicleType?vehicleTypeFilter, SegmentLaneVisitor laneVisitor) { IList <LanePos> initialSortedLanes = null; //------------------------------------- // Function applies via SegmentTraverser //------------------------------------- bool VisitorFun(SegmentVisitData segData) { bool isInitialSeg = segData.Initial; bool reverse = !isInitialSeg && segData.ViaStartNode == segData.ViaInitialStartNode; bool ret = false; //------------------------------------- // Function applies for each segment //------------------------------------- bool VisitorProcessFun(ushort segmentId, ref NetSegment segment) { // Log._Debug($"SegmentLaneTraverser: Reached segment {segmentId}: // isInitialSeg={isInitialSeg} viaStartNode={segData.viaStartNode} // viaInitialStartNode={segData.viaInitialStartNode} reverse={reverse}"); ExtSegmentManager extSegmentManager = ExtSegmentManager.Instance; IList <LanePos> sortedLanes = extSegmentManager.GetSortedLanes( segmentId, ref segment, null, laneTypeFilter, vehicleTypeFilter, reverse); if (isInitialSeg) { initialSortedLanes = sortedLanes; } else if (initialSortedLanes == null) { throw new ApplicationException("Initial list of sorted lanes not set."); } else if (sortedLanes.Count != initialSortedLanes.Count && (laneStopCrit & LaneStopCriterion.LaneCount) != LaneStopCriterion.None) { // Log._Debug($"SegmentLaneTraverser: Stop criterion reached @ {segmentId}: // {sortedLanes.Count} current vs. {initialSortedLanes.Count} initial lanes"); return(false); } for (int i = 0; i < sortedLanes.Count; ++i) { // Log._Debug($"SegmentLaneTraverser: Traversing segment lane // {sortedLanes[i].laneIndex} @ {segmentId} (id {sortedLanes[i].laneId}, // pos {sortedLanes[i].position})"); if (!laneVisitor( new SegmentLaneVisitData( segData, i, sortedLanes[i], initialSortedLanes[i]))) { return(false); } } ret = true; return(true); } ushort currentSegmentId = segData.CurSeg.segmentId; VisitorProcessFun(currentSegmentId, ref currentSegmentId.ToSegment()); return(ret); } SegmentTraverser.Traverse(initialSegmentId, direction, side, segStopCrit, VisitorFun); }
public override bool Read() { // First call to Read if (ReadState == System.Xml.ReadState.Initial) { var rootNode = this.document.Root; this.nodeStack.Push(rootNode); currentNode = rootNode.FirstChild; return(CheckReadStateAndReturn()); } if (xmlReader != null) { var result = xmlReader.Read(); if (result && xmlReader.Depth > 0) { return(result); } else { xmlReader.Close(); textReader.Dispose(); xmlReader = null; textReader = null; } } switch (traverseDirection) { case TraverseDirection.Down: // As long as there're children go down (depth first) if (currentNode.HasChildren) { nodeStack.Push(currentNode); currentNode = currentNode.FirstChild; } else { var parent = nodeStack.Peek(); using (var lastChild = parent.LastChild) { if (currentNode.IsSame(lastChild)) { // Time to move back up nodeStack.Pop(); traverseDirection = TraverseDirection.Up; currentNode.Dispose(); currentNode = parent; } else { // There're still siblings left to visit var nextSibling = currentNode.NextSibling; currentNode.Dispose(); currentNode = nextSibling; } } } break; case TraverseDirection.Up: // See if we can find siblings (need to have a parent) if (nodeStack.Count > 1) { var parent = nodeStack.Peek(); using (var lastChild = parent.LastChild) { if (currentNode.IsSame(lastChild)) { // No sibling left, go further up nodeStack.Pop(); currentNode.Dispose(); currentNode = parent; } else { // There's a sibling, try to traverse down again (depth first) traverseDirection = TraverseDirection.Down; var nextSibling = currentNode.NextSibling; currentNode.Dispose(); currentNode = nextSibling; } } } else { // No parent left, we have to be the root -> EOF currentNode.Dispose(); currentNode = null; readState = System.Xml.ReadState.EndOfFile; return(false); } break; } if (currentNode != null) { // See if this node defines a new namespace if (currentNode.IsElement && currentNode.HasAttributes) { attributeMap = currentNode.GetAttributes(); switch (traverseDirection) { case TraverseDirection.Down: foreach (var entry in attributeMap) { var key = entry.Key; var value = entry.Value; if (key.StartsWith("xmlns")) { var prefix = GetLocalName(key); namespaceManager.AddNamespace(prefix, value); break; } } namespaceManager.PushScope(); break; case TraverseDirection.Up: namespaceManager.PopScope(); break; } } else { attributeMap = null; } } return(CheckReadStateAndReturn()); }
/// <summary> /// Changes the state of all objects in the object graph. /// </summary> internal void ChangeState(ObjectState desiredState, TraverseDirection direction, HashSet<object> visitedOjects) { switch (desiredState) { case ObjectState.Modified: if (State == ObjectState.Unchanged) State = ObjectState.Modified; break; case ObjectState.Deleted: if (State == ObjectState.New) State = ObjectState.DeletedNew; else State = ObjectState.Deleted; break; default: State = desiredState; break; } if (visitedOjects.Contains(this)) return; visitedOjects.Add(this); if ((direction == TraverseDirection.Up || direction == TraverseDirection.UpDown) && _productGroup != null) { _productGroup.ChangeState(desiredState, direction, visitedOjects); } }