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