Skip to content

Instantly share code, notes, and snippets.

@angelhdzdev
Last active April 14, 2021 06:17
Show Gist options
  • Save angelhdzdev/6d8f3c0130711a46418cf719e92011a3 to your computer and use it in GitHub Desktop.
Save angelhdzdev/6d8f3c0130711a46418cf719e92011a3 to your computer and use it in GitHub Desktop.
Having fun with Timers, Dart, HTML, CSS (with Flex) on Dartpad
import "dart:async";
import "dart:core";
import "dart:html";
class TimerEvent {
final int currentCount;
TimerEvent(this.currentCount);
}
class TimerFinishedEvent extends TimerEvent {
TimerFinishedEvent(int currentCount) : super(currentCount);
}
class TimerTickEvent extends TimerEvent {
TimerTickEvent(int currentCount) : super(currentCount);
}
class TimerLoopEvent extends TimerEvent {
TimerLoopEvent(int currentCount) : super(currentCount);
}
class SimpleTimer {
int _from = 0;
int _to = 0;
int _currentCount = 0;
bool _looping = false;
bool _isLooping = false;
int delay = 1000;
late Timer _timer;
final _controller = StreamController<TimerEvent>();
SimpleTimer({this.delay = 1000});
bool get isActive => _timer.isActive;
void from(int value) {
_from = value;
}
void to(int value) {
_to = value;
}
void at(int delay) {
this.delay = delay;
}
void listen(Function callback) {
_controller.stream.listen((TimerEvent event) {
callback(event);
});
}
void start({looping = false}) {
try {
if (_timer.isActive && !_looping) {
print("Warning: You can not start an already active timer.");
}
} catch(e) {
if (e.runtimeType.toString() == "LateError") {
//Ignore.
}
}
reset();
_looping = looping;
_delegateCreateTimer();
}
void _delegateCreateTimer() {
_timer = Timer.periodic(Duration(milliseconds: delay), _tick);
}
void stop() {
if (_timer.isActive) {
_timer.cancel();
}
}
void dispose() {
_controller.close();
}
void reset() {
_currentCount = _from;
}
void _tick(Timer timer) {
if (_isLooping) {
_controller.sink.add(TimerLoopEvent(_currentCount));
_isLooping = false;
reset();
}
if (_currentCount >= _to) {
if (_looping) {
_isLooping = true;
} else {
_controller.sink.add(TimerFinishedEvent(_currentCount));
stop();
return;
}
}
_controller.sink.add(TimerTickEvent(_currentCount));
_currentCount ++;
}
int get currentCount => _currentCount;
}
class Reactive<T> {
late T _value;
Reactive(T initialValue) {
_value = initialValue;
}
T get value => _value;
set value(T newValue) => _value = newValue;
}
void main() {
//Fields
final startButton = querySelector(".start-button") as ButtonElement;
final stopButton = querySelector(".stop-button") as ButtonElement;
final fromInput = querySelector(".from") as InputElement;
final toInput = querySelector(".to") as InputElement;
final atInput = querySelector(".at") as InputElement;
final loopingCheckbox = querySelector(".looping-checkbox") as InputElement;
final timer = SimpleTimer();
final from = Reactive<int>(0);
final to = Reactive<int>(0);
final at = Reactive<int>(0);
final looping = Reactive<bool>(false);
//Logic
timer.listen((TimerEvent event) {
if (event is TimerFinishedEvent) {
print("Finished!");
print("Count: ${event.currentCount}");
stopButton.hidden = !stopButton.hidden;
startButton.hidden = ! startButton.hidden;
}
if (event is TimerTickEvent) {
print("Tick...");
print("Count: ${event.currentCount}");
}
if (event is TimerLoopEvent) {
print("Loopped!");
}
});
stopButton.onClick.listen((MouseEvent event) {
stopButton.hidden = !stopButton.hidden;
startButton.hidden = ! startButton.hidden;
timer.stop();
});
startButton.onClick.listen((MouseEvent event) {
stopButton.hidden = !stopButton.hidden;
startButton.hidden = ! startButton.hidden;
from.value = int.parse(fromInput.value!);
to .value = int.parse(toInput.value!);
at.value = int.parse(atInput.value!);
looping.value = loopingCheckbox.checked as bool;
timer
..from(from.value)
..to(to.value)
..at(at.value)
..start(looping: looping.value);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment