rohd
rohd copied to clipboard
Allow immediate scheduling of an action within the same delta cycle
Description & Motivation
This is a Rohme inspired enhancement to enable things like external IO inside a non Future timer callback.
// an async* stream generator, consuming actual wall clock time
var publisher = publish(loops, Duration(milliseconds: 250));
Simulator simulator = Simulator(clockPeriod: SimDuration(picoseconds: 10));
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);
});
});
await simulator.elapse(SimDuration(picoseconds: 1000));
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:
import 'package:rohd/rohd.dart' as rohd show Simulator;
typedef _RohdSim = rohd.Simulator;
class Simulator
{
...
Future<void> immediate(dynamic Function() action) async {
Completer<void> completer = Completer();
_RohdSim.registerImmediateAction(() async {
await action();
completer.complete();
});
await completer.future;
}
}
This preserves the ability to do things like
simulator.run((simulator) async {
Future.delayed( tickTime(10) , () async {
a();
await Future.delayed( tickTime( 10 ) );
b();
});
Future.delayed( tickTime(11) , () async {
c();
await Future.delayed( tickTime( 10 ) );
d();
});
});
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.