Closed AdamRose66 closed 6 months ago
@AdamRose66 can you help me understand the difference in functionality and use case between this new registerImmediateAction
and injectAction
?
@AdamRose66 can you help me understand the difference in functionality and use case between this new
registerImmediateAction
andinjectAction
?
I tend to think in terms of delta cycles:
The name of this test describes it quite well:
test(
'immediate action occurs at same time, before injected'
' and before next delta',
The test deliberately registers the events in the opposite order to the one in which they will occur:
// next delta
Simulator.registerAction(100, () {
expect(Simulator.time, 100);
testLog.add('delta');
});
// next microtask ( end of this delta )
Simulator.injectAction(() {
expect(Simulator.time, 100);
testLog.add('injected');
});
// immediate
Simulator.registerImmediateAction(() {
expect(Simulator.time, 100);
testLog.add('immediate');
});
And then the test checks the correct ordering:
final List<String> expectedLog = [
...
'immediate',
'injected',
'delta',
...
];
Really only injectAction and registerAction are actual modelling constructs. registerImmediate is a way to await "genuine time consuming functions" without advancing simulation time or the delta cycle. It's a kind of temporary opt out from the simulator.
So in the Rohme code:
simulator.run((simulator) async {
Future.delayed(tickTime(5), () async {
expect(simulator.elapsedTicks, 5);
// subscribe(.) consumes actual wall clock time, needed to receive the entire stream
// but does not consume simulation time.
await simulator.immediate(() => subscribe(publisher) );
expect(simulator.elapsedTicks, 5);
});
Future.delayed(tickTime(10), () async {
expect(simulator.elapsedTicks, 10);
});
});
subscribe() consumes actual wall clock time ( it reads the whole of an async* stream where the data are separated by a quarter of a second of real, wall clock time ) but "await simulator.immediate(() => subscribe(publisher) );" consumes no simulation time.
Doesn't injectAction
offer the same capabilities? A function that does not return a Future
passed to injectAction
will not block progress on the Simulator, and one that does return a Future
will block progress.
Possibly !
But after the await, you would be in the shadow land between one delta cycle and the next.
I will experiment with that.
You're right. injectAction( action ) works. It also works if we schedule it in the next delta cycle using registerAction( _RohdSimulator.time , action ). So no modifications to the Rohd simulator are needed.
Description & Motivation
This is a Rohme inspired enhancement to enable things like external IO inside a non Future timer callback.
The Rohme call simulator.immediate( action ) is a thinish wrapper around the new Rohd call Simulator.registerImmediateAction( action ). It just wraps a Completer around the underlying action:
This preserves the ability to do things like
in Rohme, but also provides the ability to do "genuinely asynchronous" communication in zero simulation time, as shown above.
Testing
Two new test in test/simulator_test.dart.
Backwards-compatibility
No issues expected. All existing tests pass and API changes are incremental.
Documentation
Documentation is inline.