Skip to content

Instantly share code, notes, and snippets.

@rodydavis
Last active September 14, 2020 22:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rodydavis/229a69fbc9294a58a46155edef677a8f to your computer and use it in GitHub Desktop.
Save rodydavis/229a69fbc9294a58a46155edef677a8f to your computer and use it in GitHub Desktop.
Dart Tracked Stream Controller
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:undo/undo.dart';
class TrackedStreamController<T> implements StreamSink<T> {
TrackedStreamController(
this._value, {
int maxUndoStack,
this.onRedo,
this.onUndo,
this.onValue,
void Function() onListen,
void Function() onPause,
void Function() onResume,
FutureOr<void> Function() onCancel,
bool sync = false,
}) {
_controller = StreamController<T>(
onListen: onListen,
onPause: onPause,
onResume: onResume,
onCancel: onCancel,
sync: sync,
);
_changeStack = ChangeStack(limit: maxUndoStack);
_controller.add(_value);
}
final ValueChanged<T> onUndo, onRedo, onValue;
ChangeStack _changeStack;
StreamController<T> _controller;
T _value;
@override
Future get done => _controller.done;
@override
void add(T event) {
_changeStack.add(Change(_value, () {
_controller.add(event);
}, (oldValue) {
_controller.add(oldValue);
}));
_value = event;
if (onValue != null) {
onValue(_value);
}
}
@override
void addError(Object event, [StackTrace stackTrace]) {
_controller.addError(event, stackTrace);
}
@override
Future addStream(Stream<T> event, {bool cancelOnError}) {
return _controller.addStream(
event,
cancelOnError: cancelOnError,
);
}
@override
Future close() => _controller.close();
/// Undo the last change
void undo() {
_changeStack.undo();
if (onUndo != null) {
onUndo(_value);
}
}
// Redo the previous change
void redo() {
_changeStack.redo();
if (onRedo != null) {
onRedo(_value);
}
}
// Checks whether the undo/redo stack is empty
bool get canUndo => _changeStack.canUndo;
// Checks wether the undo/redo stack is at the current change
bool get canRedo => _changeStack.canRedo;
/// Stream of Values
Stream<T> get stream => _controller.stream;
/// Current Value
T get value => _value;
/// Clear undo history
void clear() {
_changeStack.clearHistory();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment