Skip to content

Commit b27b470

Browse files
bedaHovorkaclaude
andcommitted
Fix FrameSimulationLifecycleTest: fire run-listeners directly in MockSimulationContext.run()
ContextTransformer.createSimulationContext() freezes the delegate before returning, so delegate.freeze() in run() hit the if (!frozen) guard and was a no-op — no PropertyChangeEvent ever fired and the 3 FrameSimulationLifecycleTest latches timed out. Override addPropertyChangeListener/removePropertyChangeListener to maintain a shadow runListeners list. run() now fires ContextChangeEvent("frozen", false, true) from runListeners directly, bypassing the frozen-state guard. Listeners are still also delegated to the underlying DefaultSimulationContext so Frame's statusBar listener continues to receive real property-change events. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 58137f6 commit b27b470

1 file changed

Lines changed: 19 additions & 4 deletions

File tree

core-test/src/commonMain/kotlin/cz/vutbr/fit/interlockSim/testutil/MockSimulationContext.kt

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import cz.vutbr.fit.interlockSim.objects.core.Cell
2323
import cz.vutbr.fit.interlockSim.objects.core.Cell.Segment
2424
import cz.vutbr.fit.interlockSim.objects.core.DynamicPathSeparator
2525
import cz.vutbr.fit.interlockSim.objects.core.OrientedPathSeparator
26+
import cz.vutbr.fit.interlockSim.objects.core.ContextChangeEvent
27+
import cz.vutbr.fit.interlockSim.objects.core.ContextPropertyChangeListener
2628
import cz.vutbr.fit.interlockSim.objects.core.Track
2729
import cz.vutbr.fit.interlockSim.objects.core.TrackFacility
2830
import cz.vutbr.fit.interlockSim.objects.tracks.DynamicTrack
@@ -44,6 +46,7 @@ class MockSimulationContext(
4446
private val workers: MutableMap<DynamicInOut, InOutWorker> = mutableMapOf()
4547
private val enabledReports: MutableCollection<ReportType> = mutableListOf()
4648
private var stopped: Boolean = false
49+
private var runListeners: List<ContextPropertyChangeListener> = emptyList()
4750

4851
/**
4952
* On-demand cache for [DynamicTrack] wrappers.
@@ -81,12 +84,24 @@ class MockSimulationContext(
8184
return delegate.getInOuts()
8285
}
8386

87+
override fun addPropertyChangeListener(listener: ContextPropertyChangeListener) {
88+
runListeners = runListeners + listener
89+
delegate.addPropertyChangeListener(listener)
90+
}
91+
92+
override fun removePropertyChangeListener(listener: ContextPropertyChangeListener) {
93+
runListeners = runListeners - listener
94+
delegate.removePropertyChangeListener(listener)
95+
}
96+
8497
override fun run() {
8598
stopped = false
86-
// Freeze the delegate to fire the "frozen" PropertyChangeEvent so callers
87-
// waiting on addPropertyChangeListener (e.g. FrameSimulationLifecycleTest)
88-
// get notified that the simulation has "started". freeze() is idempotent.
89-
delegate.freeze()
99+
// Fire directly from runListeners so callers waiting on addPropertyChangeListener
100+
// (e.g. FrameSimulationLifecycleTest) are notified when simulation starts.
101+
// Cannot rely on delegate.freeze() because ContextTransformer already freezes the
102+
// delegate at creation time, making freeze() a no-op here.
103+
val event = ContextChangeEvent("frozen", false, true)
104+
runListeners.forEach { it.propertyChange(event) }
90105
}
91106

92107
override fun stop() {

0 commit comments

Comments
 (0)