dispatchNewList method
It replaces the current list with the new one. Differences are calculated and then dispatched to the controller.
Implementation
Future<void> dispatchNewList(T newList, {bool detectMoves = false}) async {
_processingList = newList;
_DiffResultDispatcher dr;
var futureOr = _computeDiffs(_currentList, newList, detectMoves);
if (futureOr is Future<_DiffResultDispatcher?>) {
dr = await futureOr;
} else {
dr = futureOr;
}
if (newList != _processingList || _processingList == null) {
return; // discard result
}
_oldList = _currentList;
_currentList = _processingList!;
_processingList = null;
final oldList = _oldList!;
final cl = _ChangeList(comparator.lengthOf(oldList));
Widget callOldListBuilder(List<_MovedRange> l, int index,
BuildContext context, AnimatedWidgetBuilderData data) {
int? oldIndex;
var i = index;
for (final e in l) {
if (i < e.length) {
oldIndex = e.from + i;
break;
}
i -= e.length;
}
assert(oldIndex != null);
return builder.call(context, oldList, oldIndex!, data);
}
controller.batch(() {
dr._dispatchUpdatesTo(
onInsert: (position, count) {
controller.notifyInsertedRange(position, count);
cl.replaceOrChange(position, 0, count);
},
onChange: (position, count) {
final l = cl.apply(position, count)!;
assert(l.isNotEmpty);
controller.notifyChangedRange(position, count,
(context, index, data) {
return callOldListBuilder(l, index, context, data);
});
cl.replaceOrChange(position, count, count);
},
onRemove: (position, count) {
final l = cl.apply(position, count)!;
assert(l.isNotEmpty);
controller.notifyRemovedRange(position, count,
(context, index, data) {
return callOldListBuilder(l, index, context, data);
});
cl.replaceOrChange(position, count, 0);
},
onReplace: (position, removeCount, insertCount) {
final l = cl.apply(position, removeCount)!;
assert(l.isNotEmpty);
controller.notifyReplacedRange(position, removeCount, insertCount,
(context, index, data) {
return callOldListBuilder(l, index, context, data);
});
cl.replaceOrChange(position, removeCount, insertCount);
},
onMove: (position, toPosition, count) {
controller.notifyMovedRange(position, count, toPosition);
cl.move(position, count, toPosition);
},
);
});
}