// This is the universal update check // When an event knows exactly what changed (e.g. Text or SelectedItem), it need not call this // CONSIDER: How would this look with C# 7.0 patterns? public static IEnumerable <UIStateUpdate> GetUpdates(UIState oldState, UIState newState) { if (oldState is Ready) { if (newState is Ready) { yield break; } else if (newState is FunctionList) { // We generate an intermediate state (!?) var functionList = (FunctionList)newState; var formulaEdit = functionList.AsFormulaEdit(); yield return(new UIStateUpdate(oldState, formulaEdit, UIStateUpdate.UpdateType.FormulaEditStart)); yield return(new UIStateUpdate(formulaEdit, newState, UIStateUpdate.UpdateType.FunctionListShow)); } else if (newState is FormulaEdit) // But not FunctionList { yield return(new UIStateUpdate(oldState, newState, UIStateUpdate.UpdateType.FormulaEditStart)); } else if (newState is SelectDataSource) { // Go to Ready then to new state foreach (var update in GetUpdates(oldState, ReadyState)) { yield return(update); } yield return(new UIStateUpdate(ReadyState, newState, UIStateUpdate.UpdateType.SelectDataSourceShow)); } } else if (oldState is FunctionList) // and thus also FormulaEdit { if (newState is Ready) { // We generate an intermediate state (!?) var formulaEdit = ((FunctionList)oldState).AsFormulaEdit(); yield return(new UIStateUpdate(oldState, formulaEdit, UIStateUpdate.UpdateType.FunctionListHide)); yield return(new UIStateUpdate(formulaEdit, newState, UIStateUpdate.UpdateType.FormulaEditEnd)); } else if (newState is FunctionList) { var oldStateFL = (FunctionList)oldState; var newStateFL = (FunctionList)newState; foreach (var update in GetUpdates(oldStateFL, newStateFL)) { yield return(update); } } else if (newState is FormulaEdit) // but not FunctionList { var oldStateFE = ((FunctionList)oldState).AsFormulaEdit(); yield return(new UIStateUpdate(oldState, oldStateFE, UIStateUpdate.UpdateType.FunctionListHide)); var newStateFE = (FormulaEdit)newState; foreach (var update in GetUpdates(oldStateFE, newStateFE)) { yield return(update); } } else if (newState is SelectDataSource) { // Go to Ready then to new state foreach (var update in GetUpdates(oldState, ReadyState)) { yield return(update); } yield return(new UIStateUpdate(ReadyState, newState, UIStateUpdate.UpdateType.SelectDataSourceShow)); } } else if (oldState is FormulaEdit) // but not FunctionList { if (newState is Ready) { yield return(new UIStateUpdate(oldState, newState, UIStateUpdate.UpdateType.FormulaEditEnd)); } else if (newState is FunctionList) { // First process any FormulaEdit changes var oldStateFE = (FormulaEdit)oldState; var newStateFE = ((FunctionList)newState).AsFormulaEdit(); foreach (var update in GetUpdates(oldStateFE, newStateFE)) { yield return(update); } yield return(new UIStateUpdate(newStateFE, newState, UIStateUpdate.UpdateType.FunctionListShow)); } else if (newState is FormulaEdit) // but not FunctionList { var oldStateFE = (FormulaEdit)oldState; var newStateFE = (FormulaEdit)newState; foreach (var update in GetUpdates(oldStateFE, newStateFE)) { yield return(update); } } else if (newState is SelectDataSource) { // Go to Ready then to new state foreach (var update in GetUpdates(oldState, ReadyState)) { yield return(update); } yield return(new UIStateUpdate(ReadyState, newState, UIStateUpdate.UpdateType.SelectDataSourceShow)); } } else if (oldState is SelectDataSource) { if (newState is Ready) { yield return(new UIStateUpdate(oldState, newState, UIStateUpdate.UpdateType.SelectDataSourceHide)); } else if (newState is SelectDataSource) { var oldStateSDS = (SelectDataSource)oldState; var newStateSDS = (SelectDataSource)newState; if (oldStateSDS.SelectDataSourceWindow != newStateSDS.SelectDataSourceWindow) { yield return(new UIStateUpdate(oldState, newState, UIStateUpdate.UpdateType.SelectDataSourceWindowChange)); } } else { // Go to Ready, then to new state yield return(new UIStateUpdate(oldState, ReadyState, UIStateUpdate.UpdateType.SelectDataSourceHide)); foreach (var update in GetUpdates(ReadyState, newState)) { yield return(update); } } } }
public UIStateUpdate(UIState oldState, UIState newState, UpdateType update) { OldState = oldState; NewState = newState; Update = update; IsEnabled = false; }
// Filter the states changes (on the automation thread) and then raise changes (on the main thread) void OnStateChanged(UIState newStateOrNull = null) { var oldState = CurrentState; if (newStateOrNull == null) newStateOrNull = ReadCurrentState(); // Debug.Print($"NEWSTATE: {newStateOrNull.ToString()}"); CurrentState = newStateOrNull; var updates = new List<UIStateUpdate>(); // TODO: Improve perf for common single-update case foreach (var update in UIState.GetUpdates(oldState, CurrentState)) { Logger.Monitor.Verbose($">> {update.LogString()}"); // First we raise the preview event on this thread // allowing listeners to enable the main-thread event for this update StateUpdatePreview?.Invoke(this, update); if (update.IsEnabled) updates.Add(update); } if (updates.Count > 0) _syncContextMain.Post(RaiseStateUpdates, updates); }
// This is the universal update check // When an event knows exactly what changed (e.g. Text or SelectedItem), it need not call this // CONSIDER: How would this look with C# 7.0 patterns? public static IEnumerable<UIStateUpdate> GetUpdates(UIState oldState, UIState newState) { if (oldState is Ready) { if (newState is Ready) { yield break; } else if (newState is FunctionList) { // We generate an intermediate state (!?) var functionList = (FunctionList)newState; var formulaEdit = functionList.AsFormulaEdit(); yield return new UIStateUpdate(oldState, formulaEdit, UIStateUpdate.UpdateType.FormulaEditStart); yield return new UIStateUpdate(formulaEdit, newState, UIStateUpdate.UpdateType.FunctionListShow); } else if (newState is FormulaEdit) // But not FunctionList { yield return new UIStateUpdate(oldState, newState, UIStateUpdate.UpdateType.FormulaEditStart); } else if (newState is SelectDataSource) { // Go to Ready then to new state foreach (var update in GetUpdates(oldState, ReadyState)) yield return update; yield return new UIStateUpdate(ReadyState, newState, UIStateUpdate.UpdateType.SelectDataSourceShow); } } else if (oldState is FunctionList) // and thus also FormulaEdit { if (newState is Ready) { // We generate an intermediate state (!?) var formulaEdit = ((FunctionList)oldState).AsFormulaEdit(); yield return new UIStateUpdate(oldState, formulaEdit, UIStateUpdate.UpdateType.FunctionListHide); yield return new UIStateUpdate(formulaEdit, newState, UIStateUpdate.UpdateType.FormulaEditEnd); } else if (newState is FunctionList) { var oldStateFL = (FunctionList)oldState; var newStateFL = (FunctionList)newState; foreach (var update in GetUpdates(oldStateFL, newStateFL)) yield return update; } else if (newState is FormulaEdit) // but not FunctionList { var oldStateFE = ((FunctionList)oldState).AsFormulaEdit(); yield return new UIStateUpdate(oldState, oldStateFE, UIStateUpdate.UpdateType.FunctionListHide); var newStateFE = (FormulaEdit)newState; foreach (var update in GetUpdates(oldStateFE, newStateFE)) yield return update; } else if (newState is SelectDataSource) { // Go to Ready then to new state foreach (var update in GetUpdates(oldState, ReadyState)) yield return update; yield return new UIStateUpdate(ReadyState, newState, UIStateUpdate.UpdateType.SelectDataSourceShow); } } else if (oldState is FormulaEdit) // but not FunctionList { if (newState is Ready) { yield return new UIStateUpdate(oldState, newState, UIStateUpdate.UpdateType.FormulaEditEnd); } else if (newState is FunctionList) { // First process any FormulaEdit changes var oldStateFE = (FormulaEdit)oldState; var newStateFE = ((FunctionList)newState).AsFormulaEdit(); foreach (var update in GetUpdates(oldStateFE, newStateFE)) yield return update; yield return new UIStateUpdate(newStateFE, newState, UIStateUpdate.UpdateType.FunctionListShow); } else if (newState is FormulaEdit) // but not FunctionList { var oldStateFE = (FormulaEdit)oldState; var newStateFE = (FormulaEdit)newState; foreach (var update in GetUpdates(oldStateFE, newStateFE)) yield return update; } else if (newState is SelectDataSource) { // Go to Ready then to new state foreach (var update in GetUpdates(oldState, ReadyState)) yield return update; yield return new UIStateUpdate(ReadyState, newState, UIStateUpdate.UpdateType.SelectDataSourceShow); } } else if (oldState is SelectDataSource) { if (newState is Ready) { yield return new UIStateUpdate(oldState, newState, UIStateUpdate.UpdateType.SelectDataSourceHide); } else if (newState is SelectDataSource) { var oldStateSDS = (SelectDataSource)oldState; var newStateSDS = (SelectDataSource)newState; if (oldStateSDS.SelectDataSourceWindow != newStateSDS.SelectDataSourceWindow) yield return new UIStateUpdate(oldState, newState, UIStateUpdate.UpdateType.SelectDataSourceWindowChange); } else { // Go to Ready, then to new state yield return new UIStateUpdate(oldState, ReadyState, UIStateUpdate.UpdateType.SelectDataSourceHide); foreach (var update in GetUpdates(ReadyState, newState)) yield return update; } } }