versatile_timer 1.0.0 copy "versatile_timer: ^1.0.0" to clipboard
versatile_timer: ^1.0.0 copied to clipboard

outdated

VersatileTimer is designed to support many use cases where a stream of timed events is required.

VersatileTimer #

VersatileTimer is designed to support many use cases where a stream of timed events is required.

It offers a set of common functionality, plus a number of options to determine how the output 'ticks' are generated from a given input.

Examples are described below, and also given in the 'example' directory.

Common Functionality #

  • Timer start, stop, pause and resume
  • Configurable 'tick' interval
  • Speed change (that is, changing the tick interval) while running
  • Listeners for the timer state
  • User definable transformers to modify an input prior to output, or mute it (prevent its output)
  • A single configuration may be repeated n times, or run continuously.

Specific Functionality #

These options are provided by different implementations of TickFilter and currently support these broad categories.

  • Fixed input FixedInputFilter: A single input value is defined by the user
  • Data input: IndexedFilter: A list of data is supplied by the user, and the tick count used as an index to look up the data
  • Pattern input: PatternFilter: A user supplied configuration defines a pattern, and the output is generated from that pattern. This is a very flexible method of providing a structured output from a static input.

In the examples below, various instances of ExampleMonitor are used to track the output, see the 'examples' folder.

Fixed Input #

A FixedTimer encapsulates the configuration of a VersatileTimer with a FixedFilter. This uses a fixed value input, which is then transferred to the output via an optional transformer.

Example 1

This example outputs a stream of 3 'Ho' Strings at a 10ms intervals.

Future<void> runLimitedFixedInputTimer() async {
  
  final timer = FixedTimer<String,String>(
    tickInterval: const Duration(milliseconds: 10),
    inputValue: 'Ho',
    maxTicks: 3,
  );
  final monitor = ExampleMonitor<String,String>(timer);
  monitor.monitor(timer.output);
  await timer.start();
  await timer.waitUntilFinished();

}

Example 2

Here we use a transformer (Inhibit1) to do two things - to modify the output, and also mute the output by returning null when the count is 1

class Inhibit1 implements FixedTransform<String,String> {
  @override
  String? transform({required int count, required String input}) {
    final String? r= count == 1 ? null : '$input:$count';
    return r;
  }
}
class OddNumbersOnly implements FixedTransform<int, int> {
  @override
  int? transform({required int count, required int input}) {
    final int r = count % 2;
    return r == 0 ? null : count;
  }
}
Future<void> runLimitedFixedInputTimerTransformed() async {
  final timer = FixedTimer<String,String>(
    tickInterval: const Duration(milliseconds: 10),
    inputValue: 'Ho',
    maxTicks: 3,
    transformer: Inhibit1(),
  );
  final monitor = ExampleMonitor<String,String>(timer);
  monitor.monitor(timer.output);
  await timer.start();
  await timer.waitUntilFinished();
}

Data Input #

This implementation takes a list of data as input and then uses the timer to read through the items and output the item via an optional transformer. The timer's overall count is used as an index to lookup data items. Without a transformer, as shown here, the data is passed directly to the output.

Example

This example will generate the toString representation of the three Data items, each 100ms apart on the output stream.

Future<void> runIndexedTimer() async {
  final timer = IndexedTimer<Data, Data>(
    data: const [
      Data(quantity: 1, product: 'a'),
      Data(quantity: 2, product: 'b'),
      Data(quantity: 3, product: 'c'),
    ],
    tickInterval: const Duration(milliseconds: 100),
  );
  final monitor = ExampleMonitor<Data,Data>(timer);
  monitor.monitor(timer.output);
  await timer.start();
  await timer.waitUntilFinished();
}

Pattern Input #

This approach uses a PatternConfig to define a potentially deeply nested structure as a pattern for output. This could be used to generate an output of considerable complexity, with sections of it being repeated as required. WeightedTimer provides a good example of this, and it outputs a stream of values of variable 'weight'.

This, or a variation of this, could be used to control for example, volume or intensity.

Future<void> runWeightedTimerWithGroups() async {
  final timer = WeightedTimer<Weight>(
    tickInterval: const Duration(milliseconds: 100),
    config: const WeightedConfig(
      repeat: 2,
      pattern: [
        Group(
          label: 'Group A',
          pattern: [
            Group(label: 'Group B',
              pattern: [
                Weight(10, repeat: 3,label: 'step B1'),
                Weight(20, repeat: 2,label: 'step B2'),
              ],
            ),
            Weight(1, repeat: 2, label: 'step A1'),
            Weight(3, repeat: 4, label: 'step A2'),
          ],
        ),
      ],
    ),
    transformer: const WeightTransformer(),
  );
  final monitor = ExampleMonitor<Weight,Weight>(timer);
  monitor.monitor(timer.output);
  await timer.start();
  await timer.waitUntilFinished();
}

Contributions #

  • Usage examples would be especially welcome, just a brief description of how you use the library would be great
  • Code contributions are welcome, provided they include unit tests.
0
likes
30
points
15
downloads

Publisher

verified publishertakkan.org

Weekly Downloads

VersatileTimer is designed to support many use cases where a stream of timed events is required.

Repository (GitLab)
View/report issues

License

BSD-3-Clause (license)

Dependencies

logger

More

Packages that depend on versatile_timer