Skip to content

Commit 296ae55

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 b1299af commit 296ae55

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
@@ -861,128 +861,147 @@ export class TrainrunSectionService implements OnDestroy {
861861
// 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)
862862
replaceIntermediateStopWithNode(
863863
trainrunSectionId: number,
864-
nodeId: number,
865-
stopDuration?: number,
866-
) {
867-
const trainrunSection1 = this.getTrainrunSectionFromId(trainrunSectionId);
864+
intermediateNodeId: number,
865+
initialStopDuration?: number,
866+
): TrainrunSection | null {
867+
// Before:
868+
// initialSourceNode ◄─[port]──[port]─► initialTargetNode
869+
// initialSection
870+
//
871+
// After:
872+
// initialSourceNode ◄-[port]──[port]─► intermediateNode ◄─[port]──[port]─► initialTargetNode
873+
// initialSection newSection
874+
875+
const initialSection = this.getTrainrunSectionFromId(trainrunSectionId);
868876
if (
869-
trainrunSection1.getSourceNodeId() === nodeId ||
870-
trainrunSection1.getTargetNodeId() === nodeId
877+
initialSection.getSourceNodeId() === intermediateNodeId ||
878+
initialSection.getTargetNodeId() === intermediateNodeId
871879
) {
872-
return {};
880+
// Early return if the intermediate node is already part of the trainrun section
881+
return null;
873882
}
874-
const origTravelTime = trainrunSection1.getTravelTime();
875-
const trainrunSection2 = this.copyTrainrunSection(
876-
trainrunSection1,
877-
trainrunSection1.getTrainrunId(),
878-
);
879-
const node1 = trainrunSection1.getSourceNode();
880-
const node2 = trainrunSection1.getTargetNode();
881-
const nodeIntermediate = this.nodeService.getNodeFromId(nodeId);
882-
const transition1: Transition = node1.getTransition(trainrunSection1.getId());
883-
const nonStop1 = transition1 !== undefined ? transition1.getIsNonStopTransit() : false;
884-
const transition2: Transition = node2.getTransition(trainrunSection1.getId());
885-
const nonStop2 = transition2 !== undefined ? transition2.getIsNonStopTransit() : false;
883+
// Create new section with same properties as initial section
884+
const newSection = this.copyTrainrunSection(initialSection, initialSection.getTrainrunId());
885+
886+
// Store initial values for later validation
887+
const initialTravelTime = initialSection.getTravelTime();
888+
const initialSourceNode = initialSection.getSourceNode();
889+
const initialTargetNode = initialSection.getTargetNode();
890+
891+
// Store initial transition properties for later validation
892+
const initialTargetNodeTransition = initialTargetNode.getTransition(initialSection.getId());
893+
const isInitialTargetNodeNonStop = initialTargetNodeTransition?.getIsNonStopTransit();
886894

887-
node2.replaceTrainrunSectionOnPort(trainrunSection1, trainrunSection2);
895+
// Update initial target node port to use new section instead of initial section
896+
initialTargetNode.replaceTrainrunSectionOnPort(initialSection, newSection);
888897

898+
// Update initial section to point from intermediate node to initial target node
889899
const portOrderingType = this.nodeService.getCurrentOrderingAlgorithm();
890-
trainrunSection1.setTargetNode(nodeIntermediate);
891-
nodeIntermediate.addPortWithRespectToOppositeNode(node1, trainrunSection1, portOrderingType);
892-
node1.reAlignPortWithRespectToOppositeNode(
893-
nodeIntermediate,
894-
trainrunSection1,
900+
const intermediateNode = this.nodeService.getNodeFromId(intermediateNodeId);
901+
initialSection.setTargetNode(intermediateNode);
902+
intermediateNode.addPortWithRespectToOppositeNode(
903+
initialSourceNode,
904+
initialSection,
905+
portOrderingType,
906+
);
907+
initialSourceNode.reAlignPortWithRespectToOppositeNode(
908+
intermediateNode,
909+
initialSection,
895910
portOrderingType,
896911
);
897912

898-
trainrunSection2.setSourceNode(nodeIntermediate);
899-
trainrunSection2.setTargetNode(node2);
900-
nodeIntermediate.addPortWithRespectToOppositeNode(node2, trainrunSection2, portOrderingType);
901-
node2.reAlignPortWithRespectToOppositeNode(
902-
nodeIntermediate,
903-
trainrunSection2,
913+
// Update new section to point from intermediate node to initial target node
914+
newSection.setSourceNode(intermediateNode);
915+
newSection.setTargetNode(initialTargetNode);
916+
intermediateNode.addPortWithRespectToOppositeNode(
917+
initialTargetNode,
918+
newSection,
919+
portOrderingType,
920+
);
921+
initialTargetNode.reAlignPortWithRespectToOppositeNode(
922+
intermediateNode,
923+
newSection,
904924
portOrderingType,
905925
);
906926

927+
// Add transitions and connections for new section
907928
this.nodeService.addTransitionToNodeForTrainrunSections(
908-
nodeIntermediate.getId(),
909-
trainrunSection1,
910-
trainrunSection2,
929+
intermediateNode.getId(),
930+
initialSection,
931+
newSection,
911932
);
912-
this.trainrunService.propagateConsecutiveTimesForTrainrun(trainrunSection1.getId());
933+
const initialSectionNewTargetTransition = initialTargetNode.getTransition(newSection.getId());
934+
if (initialSectionNewTargetTransition !== undefined) {
935+
initialSectionNewTargetTransition.setIsNonStopTransit(isInitialTargetNodeNonStop);
936+
}
913937

914-
const minHalteZeitFromNode = this.nodeService.getHaltezeit(
915-
nodeId,
916-
trainrunSection1.getTrainrun().getTrainrunCategory(),
938+
// Propagate times to ensure that the new section gets correct times based on the initial section
939+
this.trainrunService.propagateConsecutiveTimesForTrainrun(initialSection.getId());
940+
941+
// Calculate travel time using consecutive times in both directions
942+
let forwardTravelTime =
943+
initialSection.getTargetArrivalConsecutiveTime() -
944+
initialSection.getSourceDepartureConsecutiveTime();
945+
let backwardTravelTime =
946+
initialSection.getSourceArrivalConsecutiveTime() -
947+
initialSection.getTargetDepartureConsecutiveTime();
948+
forwardTravelTime = forwardTravelTime < 0 ? backwardTravelTime : forwardTravelTime;
949+
backwardTravelTime = backwardTravelTime < 0 ? forwardTravelTime : backwardTravelTime;
950+
const minimumCalculatedTravelTime = Math.min(forwardTravelTime, backwardTravelTime);
951+
const travelTimeIssue = !forwardTravelTime || !backwardTravelTime;
952+
953+
// Determine stop duration at intermediate node based on calculated travel time
954+
// and minimum haltezeit for the trainrun category at the intermediate node
955+
const minimumHalteZeitAtIntermediateNode = this.nodeService.getHaltezeit(
956+
intermediateNodeId,
957+
initialSection.getTrainrun().getTrainrunCategory(),
917958
);
918-
let travelTime1 =
919-
trainrunSection1.getTargetArrivalConsecutiveTime() -
920-
trainrunSection1.getSourceDepartureConsecutiveTime();
921-
let travelTime2 =
922-
trainrunSection1.getSourceArrivalConsecutiveTime() -
923-
trainrunSection1.getTargetDepartureConsecutiveTime();
924-
travelTime1 = travelTime1 < 0 ? travelTime2 : travelTime1;
925-
travelTime2 = travelTime2 < 0 ? travelTime1 : travelTime2;
926-
const calculatedTravelTime = Math.min(travelTime1, travelTime2);
927-
const halteZeit =
928-
stopDuration ?? Math.min(minHalteZeitFromNode, Math.max(0, calculatedTravelTime - 2));
929-
const travelTimeIssue = !travelTime1 || !travelTime2;
930-
const halteZeitIssue = minHalteZeitFromNode < halteZeit;
931-
const travelTime = Math.max(trainrunSection1.getTravelTime() - halteZeit, 0);
932-
const halfTravelTime = travelTime / 2;
933-
trainrunSection1.setTravelTime(travelTime - halfTravelTime);
934-
trainrunSection2.setTravelTime(halfTravelTime);
935-
936-
trainrunSection1.setTargetArrival(
959+
const stopDuration =
960+
initialStopDuration ??
961+
Math.min(minimumHalteZeitAtIntermediateNode, Math.max(0, minimumCalculatedTravelTime - 2));
962+
const halteZeitIssue = minimumHalteZeitAtIntermediateNode < stopDuration;
963+
964+
// Finally, set the times for both sections (order of setting times is important)
965+
const travelTime = Math.max(initialSection.getTravelTime() - stopDuration, 0);
966+
initialSection.setTravelTime(travelTime / 2);
967+
newSection.setTravelTime(travelTime / 2);
968+
initialSection.setTargetArrival(
937969
TrainrunSectionService.boundMinutesToOneHour(
938-
trainrunSection1.getSourceDeparture() + trainrunSection1.getTravelTime(),
970+
initialSection.getSourceDeparture() + initialSection.getTravelTime(),
939971
),
940972
);
941-
trainrunSection2.setSourceArrival(
973+
newSection.setSourceArrival(
942974
TrainrunSectionService.boundMinutesToOneHour(
943-
trainrunSection1.getTargetDeparture() + trainrunSection2.getTravelTime(),
975+
initialSection.getTargetDeparture() + newSection.getTravelTime(),
944976
),
945977
);
946-
trainrunSection1.setTargetDeparture(
947-
TrainrunSectionService.boundMinutesToOneHour(halteZeit + trainrunSection2.getSourceArrival()),
978+
initialSection.setTargetDeparture(
979+
TrainrunSectionService.boundMinutesToOneHour(stopDuration + newSection.getSourceArrival()),
948980
);
949-
trainrunSection2.setSourceDeparture(
950-
TrainrunSectionService.boundMinutesToOneHour(halteZeit + trainrunSection1.getTargetArrival()),
981+
newSection.setSourceDeparture(
982+
TrainrunSectionService.boundMinutesToOneHour(
983+
stopDuration + initialSection.getTargetArrival(),
984+
),
951985
);
952986

953-
if (
954-
halteZeitIssue ||
955-
trainrunSection1.getTravelTime() + trainrunSection2.getTravelTime() + halteZeit !==
956-
origTravelTime ||
957-
travelTimeIssue
958-
) {
987+
// Validate that the changes did not lead to inconsistencies in the times
988+
const finalTravelTimeIssue =
989+
initialSection.getTravelTime() + newSection.getTravelTime() + stopDuration !==
990+
initialTravelTime;
991+
if (travelTimeIssue || halteZeitIssue || finalTravelTimeIssue) {
959992
const title = $localize`:@@app.services.data.trainrunsection.intermediate-stop-replacement.title:Intermediate stop replacement`;
960993
const description = $localize`:@@app.services.data.trainrunsection.intermediate-stop-replacement.description:Intermediate stop replacement led to inconsistencies in the allocation of times!`;
961-
trainrunSection1.setTargetArrivalWarning(title, description);
962-
trainrunSection1.setTargetDepartureWarning(title, description);
963-
trainrunSection2.setSourceArrivalWarning(title, description);
964-
trainrunSection2.setSourceDepartureWarning(title, description);
965-
}
966-
967-
const transitionNew1 = node1.getTransition(trainrunSection1.getId());
968-
if (transitionNew1 !== undefined) {
969-
transitionNew1.setIsNonStopTransit(nonStop1);
970-
}
971-
const transitionNew2 = node2.getTransition(trainrunSection2.getId());
972-
if (transitionNew2 !== undefined) {
973-
transitionNew2.setIsNonStopTransit(nonStop2);
994+
initialSection.setTargetArrivalWarning(title, description);
995+
initialSection.setTargetDepartureWarning(title, description);
996+
newSection.setSourceArrivalWarning(title, description);
997+
newSection.setSourceDepartureWarning(title, description);
974998
}
975999

976-
this.trainrunService.propagateConsecutiveTimesForTrainrun(trainrunSection1.getId());
977-
9781000
this.nodeService.transitionsUpdated();
9791001
this.nodeService.connectionsUpdated();
9801002
this.nodeService.nodesUpdated();
9811003
this.trainrunSectionsUpdated();
982-
return {
983-
existingTrainrunSection: trainrunSection1,
984-
newTrainrunSection: trainrunSection2,
985-
};
1004+
return newSection;
9861005
}
9871006

9881007
addIntermediateStopOnTrainrunSection(trainrunSection: TrainrunSection) {

0 commit comments

Comments
 (0)