Improve updating following and fix potential crash.

This commit is contained in:
2025-10-06 10:17:01 +08:00
parent c438a84537
commit e0ea449c17
4 changed files with 216 additions and 13 deletions

58
lib/utils/channel.dart Normal file
View File

@@ -0,0 +1,58 @@
import 'dart:async';
import 'dart:collection';
class Channel<T> {
final Queue<T> _queue;
final int size;
Channel(this.size) : _queue = Queue<T>();
Completer? _releaseCompleter;
Completer? _pushCompleter;
var currentSize = 0;
var isClosed = false;
Future<void> push(T item) async {
if (currentSize >= size) {
_releaseCompleter ??= Completer();
return _releaseCompleter!.future.then((_) {
if (isClosed) {
return;
}
_queue.addLast(item);
currentSize++;
});
}
_queue.addLast(item);
currentSize++;
_pushCompleter?.complete();
_pushCompleter = null;
}
Future<T?> pop() async {
while (_queue.isEmpty) {
if (isClosed) {
return null;
}
_pushCompleter ??= Completer();
await _pushCompleter!.future;
}
var item = _queue.removeFirst();
currentSize--;
if (_releaseCompleter != null && currentSize < size) {
_releaseCompleter!.complete();
_releaseCompleter = null;
}
return item;
}
void close() {
isClosed = true;
_pushCompleter?.complete();
_releaseCompleter?.complete();
}
}