veilidchat/lib/chat/cubits/reconciliation/author_input_source.dart

77 lines
2.6 KiB
Dart
Raw Normal View History

2024-05-31 18:27:50 -04:00
import 'dart:math';
import 'package:async_tools/async_tools.dart';
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:meta/meta.dart';
2024-05-30 23:25:47 -04:00
import 'package:veilid_support/veilid_support.dart';
import '../../../proto/proto.dart' as proto;
2024-05-31 18:27:50 -04:00
@immutable
class InputWindow {
const InputWindow(
{required this.elements, required this.first, required this.last});
final IList<OnlineElementState<proto.Message>> elements;
final int first;
final int last;
}
2024-05-30 23:25:47 -04:00
class AuthorInputSource {
2024-05-31 18:27:50 -04:00
AuthorInputSource.fromCubit(
{required DHTLogStateData<proto.Message> cubitState,
required this.cubit}) {
_currentWindow = InputWindow(
elements: cubitState.elements,
first: cubitState.tail - cubitState.elements.length,
last: cubitState.tail - 1);
}
////////////////////////////////////////////////////////////////////////////
InputWindow get currentWindow => _currentWindow;
2024-05-30 23:25:47 -04:00
2024-05-31 18:27:50 -04:00
Future<AsyncValue<bool>> updateWindow(
int currentPosition, int windowLength) async =>
cubit.operate((reader) async {
// See if we're beyond the input source
if (currentPosition < 0 || currentPosition >= reader.length) {
return const AsyncValue.data(false);
}
// Slide the window if we need to
var first = _currentWindow.first;
var last = _currentWindow.last;
if (currentPosition < first) {
// Slide it backward, current position is now last
first = max((currentPosition - windowLength) + 1, 0);
last = currentPosition;
} else if (currentPosition > last) {
// Slide it forward, current position is now first
first = currentPosition;
last = min((currentPosition + windowLength) - 1, reader.length - 1);
} else {
return const AsyncValue.data(true);
}
// Get another input batch futher back
final nextWindow = await cubit.loadElementsFromReader(
reader, last + 1, (last + 1) - first);
final asErr = nextWindow.asError;
if (asErr != null) {
return AsyncValue.error(asErr.error, asErr.stackTrace);
}
final asLoading = nextWindow.asLoading;
if (asLoading != null) {
return const AsyncValue.loading();
}
_currentWindow = InputWindow(
elements: nextWindow.asData!.value, first: first, last: last);
return const AsyncValue.data(true);
});
////////////////////////////////////////////////////////////////////////////
2024-05-30 23:25:47 -04:00
final DHTLogCubit<proto.Message> cubit;
2024-05-31 18:27:50 -04:00
late InputWindow _currentWindow;
2024-05-30 23:25:47 -04:00
}