private IObservable <IOperationState <T> > GetModel <T>(ModelIdentifierBase id, ModelSource source, CancellationToken ct = default) where T : class { var operation = _loader.Load(id, source, ct: ct); operation .WhereResultChanged() .Where(state => state.ResultProgress == 100) .Subscribe(state => { var result = state.Result; var resultId = state.ResultIdentifier; if (id.Equals(resultId)) { // We want to run the updates within the synced AddOrUpdate, but only if we actually have updates for this model. UpdateContainer _ = null; if (_updates.TryGetValue(resultId, out _) && _ != null) { _updates.AddOrUpdate(resultId, (UpdateContainer)null, (__, modelUpdates) => { var updateableResult = result as IUpdateableModel <T>; modelUpdates.Original = updateableResult.CloneForUpdate(); modelUpdates.ForEach(entry => result = entry.Update(result) as T); modelUpdates.Updated = result; return(modelUpdates); } ); } } // Result from disk probably shouldn't overwrite result from server in the memory cache? if (_cache != null) { _cache.Set(resultId, result); } }); return(operation // TODO: Should we start with an empty operationstate ? .Select(state => { var isMatch = id.Equals(state.ResultIdentifier); return new OperationState <T>( isMatch ? state.Result as T : null, state.Progress, state.Error, state.IsCancelled, state.ResultSource, isMatch ? state.ResultIdentifier : null, isMatch ? state.ResultProgress : 0 ); }) .TakeWhile(s => s.Progress <= 100)); }
public override bool Equals(object obj) { var other = obj as OperationKey; return(Identifier.Equals(other.Identifier) && Source.Equals(other.Source)); }
public override bool Equals(object obj) { var other = obj as UpdateKey; return(Identifier.Equals(other.Identifier) && UpdateId.Equals(other.UpdateId)); }