Last active
September 14, 2020 22:30
-
-
Save rodydavis/229a69fbc9294a58a46155edef677a8f to your computer and use it in GitHub Desktop.
Dart Tracked Stream Controller
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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