Added ElectificationResolver propagation queue

*ElectificationResolver now uses a propagation queue to handle propagations from all routes "simultaneously" and reduce conflicts propagation
This commit is contained in:
izawartka 2025-07-11 01:16:16 +02:00
parent adb1a4078f
commit 2d5c0baba6

View File

@ -14,9 +14,11 @@ class RouteTrack {
export default class ElectrificationResolver { export default class ElectrificationResolver {
static hasWarnings = false; static hasWarnings = false;
static propagationQueue = [];
static resolveScenery(scenery) { static resolveScenery(scenery) {
ElectrificationResolver.hasWarnings = false; ElectrificationResolver.hasWarnings = false;
ElectrificationResolver.propagationQueue = [];
try { try {
const routeTracks = this._findRouteTracks(scenery); const routeTracks = this._findRouteTracks(scenery);
@ -24,12 +26,13 @@ export default class ElectrificationResolver {
routeTracks.forEach(routeTrack => { routeTracks.forEach(routeTrack => {
this._propagate( this._propagate(
scenery,
routeTrack.track, routeTrack.track,
[], [],
routeTrack.electrified ? ElectrificationStatus.ELECTRIFIED : ElectrificationStatus.NON_ELECTRIFIED routeTrack.electrified ? ElectrificationStatus.ELECTRIFIED : ElectrificationStatus.NON_ELECTRIFIED
); );
}); });
this._runResolution();
} catch (error) { } catch (error) {
scenery.electrificationResolved = ElectrificationResolutionStatus.ERROR; scenery.electrificationResolved = ElectrificationResolutionStatus.ERROR;
SceneryParserLog.warn('electrificationResolverError', `Error resolving electrification: ${error.message}`); SceneryParserLog.warn('electrificationResolverError', `Error resolving electrification: ${error.message}`);
@ -110,7 +113,18 @@ export default class ElectrificationResolver {
}); });
} }
static _propagate(scenery, track, skipTrackIds, status) { static _runResolution() {
while(ElectrificationResolver.propagationQueue.length > 0) {
const { track, skipTrackIds, status } = ElectrificationResolver.propagationQueue.shift();
ElectrificationResolver._resolveTrack(track, skipTrackIds, status);
}
}
static _propagate(track, skipTrackIds, status) {
ElectrificationResolver.propagationQueue.push({ track, skipTrackIds, status });
}
static _resolveTrack(track, skipTrackIds, status) {
if (track.electrificationStatus === status) return; // already set if (track.electrificationStatus === status) return; // already set
if (Constants.parser.skipElectrificationErrorsPropagation && status === ElectrificationStatus.CONFLICT) { if (Constants.parser.skipElectrificationErrorsPropagation && status === ElectrificationStatus.CONFLICT) {
return; return;
@ -148,13 +162,13 @@ export default class ElectrificationResolver {
propagation.forEach(nextTrack => { propagation.forEach(nextTrack => {
if (skipTrackIds.includes(nextTrack.id)) return; if (skipTrackIds.includes(nextTrack.id)) return;
this._propagate(scenery, nextTrack, nextSkipIds, track.electrificationStatus); this._propagate(nextTrack, nextSkipIds, track.electrificationStatus);
}); });
// Additional propagation for double switches // Additional propagation for double switches
if (!track.switch || track.switch.def?.[2]?.length <= 2 || track.hasNEVP) return; if (!track.switch || track.switch.def?.[2]?.length <= 2 || track.hasNEVP) return;
const otherSwitchTrack = track.switch.trackA === track ? track.switch.trackB : track.switch.trackA; const otherSwitchTrack = track.switch.trackA === track ? track.switch.trackB : track.switch.trackA;
this._propagate(scenery, otherSwitchTrack, [track.id, ...propagation.map(track => track.id)], track.electrificationStatus); this._propagate(otherSwitchTrack, [track.id, ...propagation.map(track => track.id)], track.electrificationStatus);
} }
}; };