example/lib/preload/ali_sliding_window.dart (108 lines of code) (raw):

// Copyright © 2025 Alibaba Cloud. All rights reserved. // // Author: keria // Date: 2025/2/28 // Brief: 滑动窗口模版类 /// A generic class that manages sliding window loading and cancellation for a collection of items. /// /// 一个滑动窗口的功能,用于管理和处理待执行的数据操作。 class AliSlidingWindow<T> { /// Function to execute an item. /// /// 执行项目的回调函数 final void Function(T item) execute; /// Function to cancel an item. /// /// 取消项目的回调函数,可选 final void Function(T item)? cancel; /// Function to check if an item is valid. /// /// 检查项目是否有效的回调函数 final bool Function(T item) isValid; /// The extra information used to identify the source of data. /// /// 额外信息,用于标识数据来源 final String extra; /// The window range for managing sliding window loading and cancellation. /// /// 滑动窗口的范围 final List<int> _windowItems; /// The list of items to be managed. /// /// 待管理的项目列表 final List<T> _itemList = []; /// The set of items that have been executed. /// /// 已执行的项目集合 final Set<T> _executedItemSets = {}; /// The current index in the item list. /// /// 当前项目列表中的索引 int _currentIndex = -1; /// Constructor for SlidingWindowManager with specified left and right window sizes. /// /// 构造函数,指定左右窗口大小 AliSlidingWindow.withWindowSize( int leftWindowSize, int rightWindowSize, this.execute, this.cancel, { bool Function(T)? isValid, this.extra = '', }) : assert(leftWindowSize >= 0), assert(rightWindowSize >= 0), isValid = isValid ?? _defaultIsValid<T>(), _windowItems = _getWindowRange(leftWindowSize, rightWindowSize); /// Constructor for SlidingWindowManager with custom window items. /// /// 构造函数,指定自定义窗口范围 AliSlidingWindow.withCustomItems( List<int> items, this.execute, this.cancel, { bool Function(T)? isValid, this.extra = '', }) : isValid = isValid ?? _defaultIsValid<T>(), _windowItems = List.from(items); /// Default implementation for isValid. /// /// 默认的 isValid 实现。 static bool Function(T) _defaultIsValid<T>() { return (T item) => true; } /// Set the items to be managed. /// /// 设置需要管理的项目列表 void setItems(List<T> items) { cancelAll(); _itemList.clear(); for (var item in items) { if (isValid(item)) { _itemList.add(item); } } } /// Add new items to the existing item list. /// /// 向现有项目列表中添加新项目 void addItems(List<T> items) { for (var item in items) { if (isValid(item)) { _itemList.add(item); } } } /// Move to a specified position in the item list and execute new items. /// /// 移动到指定位置并执行新项目 void moveTo(int position) { if (position < 0 || position >= _itemList.length) return; if (_currentIndex == position) return; final currentWindow = getWindowIndices(position); if (currentWindow.isEmpty) return; final previousWindow = getWindowIndices(_currentIndex); final toLoad = _difference(currentWindow, previousWindow); final toCancel = _difference(previousWindow, currentWindow); _processItems(toCancel, _cancelItem); _processItems(toLoad, _executeItem); _currentIndex = position; } /// Process a list of items using the provided processor function. /// /// 使用提供的处理器函数处理项目列表 void _processItems(List<T> items, void Function(T item) processor) { for (var item in items) { if (item != null) processor(item); } } /// Cancel an item. /// /// 取消单个项目 void _cancelItem(T item) { if (_executedItemSets.contains(item)) { _executedItemSets.remove(item); cancel?.call(item); } } /// Execute an item. /// /// 执行单个项目 void _executeItem(T item) { if (!_executedItemSets.contains(item)) { _executedItemSets.add(item); execute(item); } } /// Get items within the sliding window based on the current position. /// /// 根据当前位置获取滑动窗口内的项目 List<T> getWindowIndices(int position) { if (position < 0 || position >= _itemList.length) return []; final windowIndices = <T>[]; for (var offset in _windowItems) { final index = position + offset; if (index >= 0 && index < _itemList.length) { windowIndices.add(_itemList[index]); } } return windowIndices; } /// Release resources, cancel all ongoing operations. /// /// 释放资源,取消所有正在进行的操作 void release() { cancelAll(); _currentIndex = -1; } /// Cancel all ongoing operations and clear the item list. /// /// 取消所有正在进行的操作并清空项目列表 void cancelAll() { for (var item in _executedItemSets) { cancel?.call(item); } _executedItemSets.clear(); _itemList.clear(); } /// Retrieve the current position in the item list. /// /// 获取当前项目列表中的位置 int getCurrentPosition() => _currentIndex; /// Helper method to generate window range. /// /// 辅助方法,生成滑动窗口的范围 static List<int> _getWindowRange(int leftWindowSize, int rightWindowSize) { final totalSize = leftWindowSize + rightWindowSize + 1; return List.generate(totalSize, (i) => i - leftWindowSize); } /// Helper method to calculate the difference between two lists. /// /// 辅助方法,用于计算两个列表的差集 List<T> _difference(List<T> list1, List<T> list2) { final set2 = Set.from(list2); return list1.where((item) => !set2.contains(item)).toList(); } }