rohd icon indicating copy to clipboard operation
rohd copied to clipboard

Allow immediate scheduling of an action within the same delta cycle

Open AdamRose66 opened this issue 4 months ago • 5 comments

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.

AdamRose66 avatar Mar 04 '24 15:03 AdamRose66