Skip to content

Commit 146e0c6

Browse files
committed
iterator: add backwardIterator and NonStopBackwardIterator
Signed-off-by: Louis Greiner <[email protected]>
1 parent dba6b01 commit 146e0c6

File tree

3 files changed

+104
-3
lines changed

3 files changed

+104
-3
lines changed

src/app/models/node.model.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,31 @@ export class Node {
384384
return undefined;
385385
}
386386

387+
getPreviousTrainrunSection(trainrunSection: TrainrunSection): TrainrunSection {
388+
let transition = this.getTransitions().find((trans: Transition) => {
389+
const t = this.getPortOfTrainrunSection(trainrunSection.getId());
390+
if (t === undefined) {
391+
return false;
392+
}
393+
return trans.getPortId2() === t.getId();
394+
});
395+
if (transition !== undefined) {
396+
return this.getPort(transition.getPortId1()).getTrainrunSection();
397+
}
398+
transition = this.getTransitions().find((trans: Transition) => {
399+
const t = this.getPortOfTrainrunSection(trainrunSection.getId());
400+
if (t === undefined) {
401+
return false;
402+
}
403+
return trans.getPortId1() === t.getId();
404+
});
405+
if (transition !== undefined) {
406+
return this.getPort(transition.getPortId2()).getTrainrunSection();
407+
}
408+
409+
return undefined;
410+
}
411+
387412
isEndNode(trainrunSection: TrainrunSection): boolean {
388413
const port = this.getPortOfTrainrunSection(trainrunSection.getId());
389414
if (port === undefined) {

src/app/services/data/trainrun.service.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@ import {DataService} from "./data.service";
1717
import {Node} from "../../models/node.model";
1818
import {TrainrunSection} from "../../models/trainrunsection.model";
1919
import {GeneralViewFunctions} from "../../view/util/generalViewFunctions";
20-
import {NonStopTrainrunIterator, TrainrunIterator} from "../util/trainrun.iterator";
20+
import {
21+
BackwardNonStopTrainrunIterator,
22+
BackwardTrainrunIterator,
23+
NonStopTrainrunIterator,
24+
TrainrunIterator,
25+
} from "../util/trainrun.iterator";
2126
import {LogService} from "../../logger/log.service";
2227
import {LabelService} from "./label.service";
2328
import {FilterService} from "../ui/filter.service";
@@ -691,6 +696,18 @@ export class TrainrunService {
691696
};
692697
}
693698

699+
getFirstNonStopTrainrunSection(trainrunSection: TrainrunSection): TrainrunSection {
700+
// starts at the target node, goes backwards to find the first section that is not a non-stop section
701+
const iterator = this.getBackwardNonStopIterator(
702+
trainrunSection.getTargetNode(),
703+
trainrunSection,
704+
);
705+
while (iterator.hasNext()) {
706+
iterator.next();
707+
}
708+
return iterator.current().trainrunSection;
709+
}
710+
694711
sumTravelTimeUpToLastNonStopNode(node: Node, trainrunSection: TrainrunSection): number {
695712
let summedTravelTime = 0;
696713
const iterator = this.getNonStopIterator(node, trainrunSection);
@@ -760,6 +777,14 @@ export class TrainrunService {
760777
return new NonStopTrainrunIterator(this.logService, node, trainrunSection);
761778
}
762779

780+
public getBackwardIterator(node: Node, trainrunSection: TrainrunSection) {
781+
return new BackwardTrainrunIterator(this.logService, node, trainrunSection);
782+
}
783+
784+
public getBackwardNonStopIterator(node: Node, trainrunSection: TrainrunSection) {
785+
return new BackwardNonStopTrainrunIterator(this.logService, node, trainrunSection);
786+
}
787+
763788
// For each trainrun, get iterator from the smallest consecutiveTime.
764789
public getRootIterators(): Map<number, TrainrunIterator> {
765790
const trainrunSections = this.trainrunSectionService.getTrainrunSections();

src/app/services/util/trainrun.iterator.ts

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ export class TrainrunIterator {
1313
protected currentElement: TrainrunSectionNodePair = null;
1414
protected pointerElement: TrainrunSectionNodePair = null;
1515

16-
private visitedNodes: TrainrunSectionNodePair[] = [];
16+
protected visitedNodes: TrainrunSectionNodePair[] = [];
1717

1818
constructor(
19-
private logService: LogService,
19+
protected logService: LogService,
2020
private startNode: Node,
2121
private startTrainrunSection: TrainrunSection,
2222
) {
@@ -73,6 +73,45 @@ export class TrainrunIterator {
7373
}
7474
}
7575

76+
export class BackwardTrainrunIterator extends TrainrunIterator {
77+
public next(): TrainrunSectionNodePair {
78+
const currentElement = Object.assign({}, this.pointerElement);
79+
const trainrunSection = this.pointerElement.node.getPreviousTrainrunSection(
80+
this.pointerElement.trainrunSection,
81+
);
82+
83+
if (trainrunSection === undefined) {
84+
this.pointerElement = new TrainrunSectionNodePair(undefined, undefined);
85+
this.currentElement = currentElement;
86+
return this.currentElement;
87+
}
88+
89+
const node = this.pointerElement.node.getOppositeNode(trainrunSection);
90+
this.pointerElement = new TrainrunSectionNodePair(node, trainrunSection);
91+
92+
if (
93+
this.visitedNodes.find(
94+
(element) =>
95+
element.node.getId() === node.getId() &&
96+
element.trainrunSection.getId() === trainrunSection.getId(),
97+
) !== undefined
98+
) {
99+
// The trainrun has a loop -> early break the avoid unfinitiy iterating
100+
this.currentElement = Object.assign({}, this.pointerElement);
101+
this.pointerElement = new TrainrunSectionNodePair(undefined, undefined);
102+
// log the issue
103+
this.logService.error(
104+
$localize`:@@app.services.util.trainrun-iteration.error.infinity-loop:Iterator has detected an infinity loop. The iteration terminated early!`,
105+
new Error().stack,
106+
);
107+
return this.currentElement;
108+
}
109+
this.visitedNodes.push(this.currentElement);
110+
this.currentElement = currentElement;
111+
return this.currentElement;
112+
}
113+
}
114+
76115
export class NonStopTrainrunIterator extends TrainrunIterator {
77116
public next(): TrainrunSectionNodePair {
78117
if (!this.pointerElement.node.isNonStop(this.pointerElement.trainrunSection)) {
@@ -84,3 +123,15 @@ export class NonStopTrainrunIterator extends TrainrunIterator {
84123
return super.next();
85124
}
86125
}
126+
127+
export class BackwardNonStopTrainrunIterator extends BackwardTrainrunIterator {
128+
public next(): TrainrunSectionNodePair {
129+
if (!this.pointerElement.node.isNonStop(this.pointerElement.trainrunSection)) {
130+
// The trainrun has a stop and break the backward iteration
131+
this.currentElement = Object.assign({}, this.pointerElement);
132+
this.pointerElement = new TrainrunSectionNodePair(undefined, undefined);
133+
return this.currentElement;
134+
}
135+
return super.next();
136+
}
137+
}

0 commit comments

Comments
 (0)