import 'dart:async'; import 'package:flutter/foundation.dart'; typedef EventCallback = Future Function(Data data); abstract class BaseEvent { EventType type; Data data; /// Constructor. BaseEvent(this.type, this.data); /// Consume this event. @visibleForTesting Future consume() async { final cb = findCallback(type); if (cb == null) { return null; } else { return cb(data); } } EventCallback? findCallback(EventType type); } abstract class BaseEventLoop { final List> _evts = []; Timer? _timer; List> get evts => _evts; Future onReady() async { // Poll every 100ms. _timer = Timer.periodic(Duration(milliseconds: 100), _handleTimer); } /// An Event is about to be consumed. Future onPreConsume(BaseEvent evt) async {} /// An Event was consumed. Future onPostConsume(BaseEvent evt) async {} /// Events are all handled and cleared. Future onEventsClear() async {} /// Events start to consume. Future onEventsStartConsuming() async {} Future _handleTimer(Timer timer) async { if (_evts.isEmpty) { return; } timer.cancel(); _timer = null; // Handle the logic. await onEventsStartConsuming(); while (_evts.isNotEmpty) { final evt = _evts.first; _evts.remove(evt); await onPreConsume(evt); await evt.consume(); await onPostConsume(evt); } await onEventsClear(); // Now events are all processed. _timer = Timer.periodic(Duration(milliseconds: 100), _handleTimer); } Future close() async { _timer?.cancel(); } void pushEvent(BaseEvent evt) { _evts.add(evt); } void clear() { _evts.clear(); } }