Skip to content

Commit d141fa6

Browse files
committed
refactor(service): rewrite replaceIntermediateStopWithNode with approriate names and comments
This method was very painful to read and understand. Signed-off-by: Louis Greiner <louis.greiner@proton.me>
1 parent c2fd444 commit d141fa6

File tree

2 files changed

+111
-96
lines changed

2 files changed

+111
-96
lines changed

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

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,13 +134,9 @@ export class DataService implements OnDestroy {
134134
);
135135

136136
this.trainrunSectionService.getTrainrunSectionFromId(currentSection.id).setNumberOfStops(0);
137-
const {existingTrainrunSection, newTrainrunSection} =
138-
this.trainrunSectionService.replaceIntermediateStopWithNode(
139-
currentSection.id,
140-
newNode.getId(),
141-
);
142-
143-
currentSection = newTrainrunSection.getDto();
137+
currentSection = this.trainrunSectionService
138+
.replaceIntermediateStopWithNode(currentSection.id, newNode.getId())
139+
.getDto();
144140
}
145141
}
146142
}

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

Lines changed: 108 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -872,128 +872,147 @@ export class TrainrunSectionService implements OnDestroy {
872872
// this function is no longer used for its original purpose (drag a node that only existed inside numberOfStops and create it inside the real graph)
873873
replaceIntermediateStopWithNode(
874874
trainrunSectionId: number,
875-
nodeId: number,
876-
stopDuration?: number,
877-
) {
878-
const trainrunSection1 = this.getTrainrunSectionFromId(trainrunSectionId);
875+
intermediateNodeId: number,
876+
initialStopDuration?: number,
877+
): TrainrunSection | null {
878+
// Before:
879+
// initialSourceNode ◄─[port]──[port]─► initialTargetNode
880+
// initialSection
881+
//
882+
// After:
883+
// initialSourceNode ◄-[port]──[port]─► intermediateNode ◄─[port]──[port]─► initialTargetNode
884+
// initialSection newSection
885+
886+
const initialSection = this.getTrainrunSectionFromId(trainrunSectionId);
879887
if (
880-
trainrunSection1.getSourceNodeId() === nodeId ||
881-
trainrunSection1.getTargetNodeId() === nodeId
888+
initialSection.getSourceNodeId() === intermediateNodeId ||
889+
initialSection.getTargetNodeId() === intermediateNodeId
882890
) {
883-
return {};
891+
// Early return if the intermediate node is already part of the trainrun section
892+
return null;
884893
}
885-
const origTravelTime = trainrunSection1.getTravelTime();
886-
const trainrunSection2 = this.copyTrainrunSection(
887-
trainrunSection1,
888-
trainrunSection1.getTrainrunId(),
889-
);
890-
const node1 = trainrunSection1.getSourceNode();
891-
const node2 = trainrunSection1.getTargetNode();
892-
const nodeIntermediate = this.nodeService.getNodeFromId(nodeId);
893-
const transition1: Transition = node1.getTransition(trainrunSection1.getId());
894-
const nonStop1 = transition1 !== undefined ? transition1.getIsNonStopTransit() : false;
895-
const transition2: Transition = node2.getTransition(trainrunSection1.getId());
896-
const nonStop2 = transition2 !== undefined ? transition2.getIsNonStopTransit() : false;
894+
// Create new section with same properties as initial section
895+
const newSection = this.copyTrainrunSection(initialSection, initialSection.getTrainrunId());
896+
897+
// Store initial values for later validation
898+
const initialTravelTime = initialSection.getTravelTime();
899+
const initialSourceNode = initialSection.getSourceNode();
900+
const initialTargetNode = initialSection.getTargetNode();
901+
902+
// Store initial transition properties for later validation
903+
const initialTargetNodeTransition = initialTargetNode.getTransition(initialSection.getId());
904+
const isInitialTargetNodeNonStop = initialTargetNodeTransition?.getIsNonStopTransit();
897905

898-
node2.replaceTrainrunSectionOnPort(trainrunSection1, trainrunSection2);
906+
// Update initial target node port to use new section instead of initial section
907+
initialTargetNode.replaceTrainrunSectionOnPort(initialSection, newSection);
899908

909+
// Update initial section to point from intermediate node to initial target node
900910
const portOrderingType = this.nodeService.getCurrentOrderingAlgorithm();
901-
trainrunSection1.setTargetNode(nodeIntermediate);
902-
nodeIntermediate.addPortWithRespectToOppositeNode(node1, trainrunSection1, portOrderingType);
903-
node1.reAlignPortWithRespectToOppositeNode(
904-
nodeIntermediate,
905-
trainrunSection1,
911+
const intermediateNode = this.nodeService.getNodeFromId(intermediateNodeId);
912+
initialSection.setTargetNode(intermediateNode);
913+
intermediateNode.addPortWithRespectToOppositeNode(
914+
initialSourceNode,
915+
initialSection,
916+
portOrderingType,
917+
);
918+
initialSourceNode.reAlignPortWithRespectToOppositeNode(
919+
intermediateNode,
920+
initialSection,
906921
portOrderingType,
907922
);
908923

909-
trainrunSection2.setSourceNode(nodeIntermediate);
910-
trainrunSection2.setTargetNode(node2);
911-
nodeIntermediate.addPortWithRespectToOppositeNode(node2, trainrunSection2, portOrderingType);
912-
node2.reAlignPortWithRespectToOppositeNode(
913-
nodeIntermediate,
914-
trainrunSection2,
924+
// Update new section to point from intermediate node to initial target node
925+
newSection.setSourceNode(intermediateNode);
926+
newSection.setTargetNode(initialTargetNode);
927+
intermediateNode.addPortWithRespectToOppositeNode(
928+
initialTargetNode,
929+
newSection,
930+
portOrderingType,
931+
);
932+
initialTargetNode.reAlignPortWithRespectToOppositeNode(
933+
intermediateNode,
934+
newSection,
915935
portOrderingType,
916936
);
917937

938+
// Add transitions and connections for new section
918939
this.nodeService.addTransitionToNodeForTrainrunSections(
919-
nodeIntermediate.getId(),
920-
trainrunSection1,
921-
trainrunSection2,
940+
intermediateNode.getId(),
941+
initialSection,
942+
newSection,
922943
);
923-
this.trainrunService.propagateConsecutiveTimesForTrainrun(trainrunSection1.getId());
944+
const initialSectionNewTargetTransition = initialTargetNode.getTransition(newSection.getId());
945+
if (initialSectionNewTargetTransition !== undefined) {
946+
initialSectionNewTargetTransition.setIsNonStopTransit(isInitialTargetNodeNonStop);
947+
}
924948

925-
const minHalteZeitFromNode = this.nodeService.getHaltezeit(
926-
nodeId,
927-
trainrunSection1.getTrainrun().getTrainrunCategory(),
949+
// Propagate times to ensure that the new section gets correct times based on the initial section
950+
this.trainrunService.propagateConsecutiveTimesForTrainrun(initialSection.getId());
951+
952+
// Calculate travel time using consecutive times in both directions
953+
let forwardTravelTime =
954+
initialSection.getTargetArrivalConsecutiveTime() -
955+
initialSection.getSourceDepartureConsecutiveTime();
956+
let backwardTravelTime =
957+
initialSection.getSourceArrivalConsecutiveTime() -
958+
initialSection.getTargetDepartureConsecutiveTime();
959+
forwardTravelTime = forwardTravelTime < 0 ? backwardTravelTime : forwardTravelTime;
960+
backwardTravelTime = backwardTravelTime < 0 ? forwardTravelTime : backwardTravelTime;
961+
const minimumCalculatedTravelTime = Math.min(forwardTravelTime, backwardTravelTime);
962+
const travelTimeIssue = !forwardTravelTime || !backwardTravelTime;
963+
964+
// Determine stop duration at intermediate node based on calculated travel time
965+
// and minimum haltezeit for the trainrun category at the intermediate node
966+
const minimumHalteZeitAtIntermediateNode = this.nodeService.getHaltezeit(
967+
intermediateNodeId,
968+
initialSection.getTrainrun().getTrainrunCategory(),
928969
);
929-
let travelTime1 =
930-
trainrunSection1.getTargetArrivalConsecutiveTime() -
931-
trainrunSection1.getSourceDepartureConsecutiveTime();
932-
let travelTime2 =
933-
trainrunSection1.getSourceArrivalConsecutiveTime() -
934-
trainrunSection1.getTargetDepartureConsecutiveTime();
935-
travelTime1 = travelTime1 < 0 ? travelTime2 : travelTime1;
936-
travelTime2 = travelTime2 < 0 ? travelTime1 : travelTime2;
937-
const calculatedTravelTime = Math.min(travelTime1, travelTime2);
938-
const halteZeit =
939-
stopDuration ?? Math.min(minHalteZeitFromNode, Math.max(0, calculatedTravelTime - 2));
940-
const travelTimeIssue = !travelTime1 || !travelTime2;
941-
const halteZeitIssue = minHalteZeitFromNode < halteZeit;
942-
const travelTime = Math.max(trainrunSection1.getTravelTime() - halteZeit, 0);
943-
const halfTravelTime = travelTime / 2;
944-
trainrunSection1.setTravelTime(travelTime - halfTravelTime);
945-
trainrunSection2.setTravelTime(halfTravelTime);
946-
947-
trainrunSection1.setTargetArrival(
970+
const stopDuration =
971+
initialStopDuration ??
972+
Math.min(minimumHalteZeitAtIntermediateNode, Math.max(0, minimumCalculatedTravelTime - 2));
973+
const halteZeitIssue = minimumHalteZeitAtIntermediateNode < stopDuration;
974+
975+
// Finally, set the times for both sections (order of setting times is important)
976+
const travelTime = Math.max(initialSection.getTravelTime() - stopDuration, 0);
977+
initialSection.setTravelTime(travelTime / 2);
978+
newSection.setTravelTime(travelTime / 2);
979+
initialSection.setTargetArrival(
948980
TrainrunSectionService.boundMinutesToOneHour(
949-
trainrunSection1.getSourceDeparture() + trainrunSection1.getTravelTime(),
981+
initialSection.getSourceDeparture() + initialSection.getTravelTime(),
950982
),
951983
);
952-
trainrunSection2.setSourceArrival(
984+
newSection.setSourceArrival(
953985
TrainrunSectionService.boundMinutesToOneHour(
954-
trainrunSection1.getTargetDeparture() + trainrunSection2.getTravelTime(),
986+
initialSection.getTargetDeparture() + newSection.getTravelTime(),
955987
),
956988
);
957-
trainrunSection1.setTargetDeparture(
958-
TrainrunSectionService.boundMinutesToOneHour(halteZeit + trainrunSection2.getSourceArrival()),
989+
initialSection.setTargetDeparture(
990+
TrainrunSectionService.boundMinutesToOneHour(stopDuration + newSection.getSourceArrival()),
959991
);
960-
trainrunSection2.setSourceDeparture(
961-
TrainrunSectionService.boundMinutesToOneHour(halteZeit + trainrunSection1.getTargetArrival()),
992+
newSection.setSourceDeparture(
993+
TrainrunSectionService.boundMinutesToOneHour(
994+
stopDuration + initialSection.getTargetArrival(),
995+
),
962996
);
963997

964-
if (
965-
halteZeitIssue ||
966-
trainrunSection1.getTravelTime() + trainrunSection2.getTravelTime() + halteZeit !==
967-
origTravelTime ||
968-
travelTimeIssue
969-
) {
998+
// Validate that the changes did not lead to inconsistencies in the times
999+
const finalTravelTimeIssue =
1000+
initialSection.getTravelTime() + newSection.getTravelTime() + stopDuration !==
1001+
initialTravelTime;
1002+
if (travelTimeIssue || halteZeitIssue || finalTravelTimeIssue) {
9701003
const title = $localize`:@@app.services.data.trainrunsection.intermediate-stop-replacement.title:Intermediate stop replacement`;
9711004
const description = $localize`:@@app.services.data.trainrunsection.intermediate-stop-replacement.description:Intermediate stop replacement led to inconsistencies in the allocation of times!`;
972-
trainrunSection1.setTargetArrivalWarning(title, description);
973-
trainrunSection1.setTargetDepartureWarning(title, description);
974-
trainrunSection2.setSourceArrivalWarning(title, description);
975-
trainrunSection2.setSourceDepartureWarning(title, description);
976-
}
977-
978-
const transitionNew1 = node1.getTransition(trainrunSection1.getId());
979-
if (transitionNew1 !== undefined) {
980-
transitionNew1.setIsNonStopTransit(nonStop1);
981-
}
982-
const transitionNew2 = node2.getTransition(trainrunSection2.getId());
983-
if (transitionNew2 !== undefined) {
984-
transitionNew2.setIsNonStopTransit(nonStop2);
1005+
initialSection.setTargetArrivalWarning(title, description);
1006+
initialSection.setTargetDepartureWarning(title, description);
1007+
newSection.setSourceArrivalWarning(title, description);
1008+
newSection.setSourceDepartureWarning(title, description);
9851009
}
9861010

987-
this.trainrunService.propagateConsecutiveTimesForTrainrun(trainrunSection1.getId());
988-
9891011
this.nodeService.transitionsUpdated();
9901012
this.nodeService.connectionsUpdated();
9911013
this.nodeService.nodesUpdated();
9921014
this.trainrunSectionsUpdated();
993-
return {
994-
existingTrainrunSection: trainrunSection1,
995-
newTrainrunSection: trainrunSection2,
996-
};
1015+
return newSection;
9971016
}
9981017

9991018
addIntermediateStopOnTrainrunSection(trainrunSection: TrainrunSection) {

0 commit comments

Comments
 (0)