I want to implement an autosave function. I have two Observables:
IObservable<Unit> changes
: emits an item every time the user edits a textIObservable<Unit> saves
: emits a save event every time a save button is pressedNow i want to combine those to into a 3rd stream writeBack. This stream has a subscriber, that writes the current text into a database.
How do i create the writeBack stream, so that it fullfills the following properties?
I want to make sure to only write back unsaved changes. I dont want to save the text if:
This should do it. First we identify times we may want to save:
var saveTriggers = changes.Throttle(TimeSpan.FromSeconds(3))
.Merge(saves);
Next we filter those out to make sure they meet your logic: At least one edit between each save, and the save can't come first. The SkipWhile
is just there to make sure that Saves that precede changes are ignored. The Scan
counts the number of changes between each save. We only care when that number goes to 0 (indicating a save was triggered). And DistinctUntilChanged
filters out consecutive saves.
var actualSaves = saveTriggers.Select(_ => EventType.SaveTrigger)
.Merge(changes.Select(_ => EventType.Edit))
.SkipWhile(et => et == EventType.SaveTrigger)
.Scan(0, (editCount, eventType) => eventType == EventType.SaveTrigger ? 0 : editCount + 1)
.DistinctUntilChanged()
.Where(count => count == 0)
.Select(_ => Unit.Default);
and using enum class
enum EventType
{
SaveTrigger,
Edit
}