Goal 3 SP3: emit CollisionWarning.BlockEntryViolation when a train enters an already occupied block.
Parent: #610
Deliverables
Modified files:
core/src/commonMain/kotlin/cz/vutbr/fit/interlockSim/objects/tracks/DynamicTrackBlock.kt — emit CollisionWarning.BlockEntryViolation before throwing on double-occupancy attempt
core/src/commonMain/kotlin/cz/vutbr/fit/interlockSim/sim/collision/DefaultCollisionDetectionService.kt — listen for BlockEntryViolation and trigger auto-halt/train pause
Design note
DynamicTrackBlock.enter() keeps its existing requireSimulation(occupant == null) safety invariant — it still throws if the block is already occupied. Goal 3 adds an emit-before-throw: immediately before the collision check, enter() calls emitCustom(CollisionWarning.BlockEntryViolation(...)). The existing safety behavior (throw) is preserved, so existing tests keep passing.
Acceptance criteria
- A second train entering an occupied block emits a
BlockEntryViolation warning before the existing requireSimulation failure.
- If
autoHaltTrainOnViolation is true, the service calls the entering train's halt callback.
- Existing
SimpleTrackEnterLeaveTest and DynamicTrackBlockTest still pass unchanged.
Tests
BlockEntryViolationWarningTest
Quality gate
./gradlew :core:test :core:integrationTest :core:detekt :core:ktlintCheck
Depends on
#611 Goal 3 SP1
Downstream link
Goal 9 SP3 (#585) uses BlockEntryViolation as the worst-case signal for resolution ranking.
Goal 3 SP3: emit
CollisionWarning.BlockEntryViolationwhen a train enters an already occupied block.Parent: #610
Deliverables
Modified files:
core/src/commonMain/kotlin/cz/vutbr/fit/interlockSim/objects/tracks/DynamicTrackBlock.kt— emitCollisionWarning.BlockEntryViolationbefore throwing on double-occupancy attemptcore/src/commonMain/kotlin/cz/vutbr/fit/interlockSim/sim/collision/DefaultCollisionDetectionService.kt— listen forBlockEntryViolationand trigger auto-halt/train pauseDesign note
DynamicTrackBlock.enter()keeps its existingrequireSimulation(occupant == null)safety invariant — it still throws if the block is already occupied. Goal 3 adds an emit-before-throw: immediately before the collision check,enter()callsemitCustom(CollisionWarning.BlockEntryViolation(...)). The existing safety behavior (throw) is preserved, so existing tests keep passing.Acceptance criteria
BlockEntryViolationwarning before the existingrequireSimulationfailure.autoHaltTrainOnViolationis true, the service calls the entering train's halt callback.SimpleTrackEnterLeaveTestandDynamicTrackBlockTeststill pass unchanged.Tests
BlockEntryViolationWarningTestQuality gate
./gradlew :core:test :core:integrationTest :core:detekt :core:ktlintCheckDepends on
#611 Goal 3 SP1
Downstream link
Goal 9 SP3 (#585) uses
BlockEntryViolationas the worst-case signal for resolution ranking.