Initial flame_lua_runtime package
This commit is contained in:
77
lib/runtime/lifecycle/runtime_serial_queue.dart
Normal file
77
lib/runtime/lifecycle/runtime_serial_queue.dart
Normal file
@@ -0,0 +1,77 @@
|
||||
import 'dart:async' as async;
|
||||
|
||||
class RuntimeSerialQueue<T> {
|
||||
RuntimeSerialQueue({required this.onItem, bool Function()? shouldContinue})
|
||||
: _shouldContinue = shouldContinue;
|
||||
|
||||
final void Function(T item) onItem;
|
||||
final bool Function()? _shouldContinue;
|
||||
final List<T> _queue = [];
|
||||
int _head = 0;
|
||||
bool _disposed = false;
|
||||
bool _draining = false;
|
||||
|
||||
int get pendingCount => _queue.length - _head;
|
||||
|
||||
bool get isDraining => _draining;
|
||||
|
||||
bool get isDisposed => _disposed;
|
||||
|
||||
void enqueue(T item) {
|
||||
if (_disposed || !_canContinue()) {
|
||||
return;
|
||||
}
|
||||
_queue.add(item);
|
||||
_scheduleDrain();
|
||||
}
|
||||
|
||||
void clear() {
|
||||
_queue.clear();
|
||||
_head = 0;
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
_disposed = true;
|
||||
clear();
|
||||
}
|
||||
|
||||
void _scheduleDrain() {
|
||||
if (_draining) {
|
||||
return;
|
||||
}
|
||||
_draining = true;
|
||||
async.scheduleMicrotask(_drain);
|
||||
}
|
||||
|
||||
void _drain() {
|
||||
try {
|
||||
while (pendingCount > 0 && !_disposed && _canContinue()) {
|
||||
onItem(_queue[_head++]);
|
||||
_compactIfNeeded();
|
||||
}
|
||||
} finally {
|
||||
_draining = false;
|
||||
}
|
||||
|
||||
if (pendingCount > 0 && !_disposed && _canContinue()) {
|
||||
_scheduleDrain();
|
||||
}
|
||||
}
|
||||
|
||||
void _compactIfNeeded() {
|
||||
if (_head == 0) {
|
||||
return;
|
||||
}
|
||||
if (_head == _queue.length) {
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
if (_head < 32 || _head * 2 < _queue.length) {
|
||||
return;
|
||||
}
|
||||
_queue.removeRange(0, _head);
|
||||
_head = 0;
|
||||
}
|
||||
|
||||
bool _canContinue() => _shouldContinue?.call() ?? true;
|
||||
}
|
||||
Reference in New Issue
Block a user