0 purchases
versatile timer
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.
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.
Note that all of these support the use of a transformer to modify the input, and/or mute selected
ticks, thereby preventing them from being output.
Usage #
To monitor the output of the timer you can use something like this:
class ExampleMonitor<IN, OUT> {
ExampleMonitor(this.timer);
final VersatileTimer<IN, OUT> timer;
int count = 0;
void monitor(Stream<OUT> stream) {
stream.listen((data) {
count++;
// ignore: noop_primitive_operations
print(data.toString());
});
}
}
copied to clipboard
Fixed Input #
To generate a stream of 100 'ticks' at 10ms intervals, where each tick is the current $count.
Output ony those where $count is an odd number - thus the output will actually only be 50 ticks,
each at 20ms intervals. The inputValue is irrelevant here, because the transformer does not use it,
but would often be used as part or all of the output.
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> main() async {
final timer = FixedTimer<String, String>(
tickInterval: const Duration(milliseconds: 10),
inputValue: 1,
maxTicks: 100,
transformer: OddNumbersOnly(),
);
final monitor = ExampleMonitor<String, String>(timer);
monitor.monitor(timer.output);
await timer.start();
await timer.waitUntilFinished();
}
copied to clipboard
Data Input #
Lookup from a list of data, and output a tick every 100ms containing the data element. No
transformer is needed here, as we are just transferring the input data to the output. This method is
useful, for example, for drawing a chart in slow motion.
Future<void> main() 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();
}
copied to clipboard
Pattern Input #
Generate a pattern of integers like this: 1,1,3,3,3,3,1,1,3,3,3,3
This relies heavily on the repeat property of each step.
Complex patterns be defined by using nestable Groups, potentially creating a deeply nested
pattern. See example/pattern_example.dart
Future<void> main() async {
final timer = WeightedTimer<int>(
tickInterval: const Duration(milliseconds: 100),
config: const WeightedConfig(
repeat: 2,
pattern: [
Weight(1, repeat: 2, label: 'step 1'),
Weight(3, repeat: 4),
],
),
transformer: const WeightValueTransformer(),
);
final monitor = ExampleMonitor<Weight, int>(timer);
monitor.monitor(timer.output);
await timer.start();
await timer.waitUntilFinished();
}
copied to clipboard
Waiting to Complete #
A timer may be set to run continuously, by setting its continuous property to true. It would then
run until the [stop] or [pause] method is called.
If continuous is false, then the timer will run until either [maxTicks] is reached, or in the case
of the IndexedTimer, the data runs out.
Depending on your use case, you can use one of these to await a particular completion state:
await timer.waitUntilFinished(): This will wait until the timer reaches
a [TimerState.finished]
state. This occurs only when a natural finish is reached, when all [repeat]s of all [maxTicks] is
completed. It does NOT occur when the [stop] method is called.
await timer.waitUntilStopped(): This will wait until the timer reaches a [TimerState.stopped]
state. This occurs only when the [stop] method is called.
await timer.waitUntilDone: This will wait until the timer reaches either
a [TimerState.finished]
or a [TimerState.stopped] is reached.
Examples #
See the examples tab, and the 'example' directory.
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.
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.