public static void DispatchAllActions <T>(ReduxStore <T> store) where T : class, new() { DispatchAddTodoItemAction(store, 1, "Create unit tests"); DispatchSwitchUserAction(store, "Emily"); DispatchAddTodoItemAction(store, 2, "Create Models"); DispatchAddTodoItemAction(store, 3, "Refactor tests"); }
public static void DispatchSwitchUserAction <T>(ReduxStore <T> store, string newUser) where T : class, new() { store.Dispatch(new SwitchUserAction { NewUser = newUser }); }
public static void DispatchAddTodoItemAction <T>(ReduxStore <T> store, int id, string title) where T : class, new() { store.Dispatch(new AddTodoItemAction { TodoItem = new TodoItem { Id = id, Title = title } }); }
public void CanCreateAStoreWithEmptyState() { // Arrange var store = new ReduxStore <EmptyState>( Setup.EmptyStore.Reducers.CreateReducers() ); // Act // Assert Assert.NotNull(store.State); }
public static IServiceCollection AddRedux(this IServiceCollection services) { services.AddScoped(sp => { var store = new ReduxStore <MovieSearchState>(MovieSearchReducers.CreateReducers()); var effects = new MovieSearchEffects(store, sp.GetService <IOmdbMovieService>()); store.RegisterEffects(effects.SearchMovies); return(store); }); return(services); }
public void CanCreateAStoreWithDefaultState() { // Arrange var initialState = CreateInitialTodoListState(); var store = new ReduxStore <TodoListState>( Setup.TodoListStore.Reducers.CreateReducers(), initialState ); // Act // Assert Assert.Empty(store.State.TodoList); }
public async Task Handle(CustomerCreated notification, CancellationToken cancellationToken) { var @event = await _eventStore.GetEvent(notification.EventId); var entity = new Customer { Id = notification.AggregateId, Created = @event.TimeStamp }; var redux = new ReduxStore <Customer>(Customer.Reducer, entity); redux.Dispatch(notification.Action); await _context.Customers.AddAsync(entity, cancellationToken); await _context.SaveChangesAsync(cancellationToken); }
public async Task Handle(CustomerUpdated notification, CancellationToken cancellationToken) { var entity = await _context.Customers.FindAsync(notification.AggregateId); if (entity == null) { throw new NotFoundException(nameof(Customer), notification.AggregateId); } var redux = new ReduxStore <Customer>(Customer.Reducer, entity); foreach (var action in notification.Actions) { redux.Dispatch(action); } await _context.SaveChangesAsync(cancellationToken); }
/// <summary> /// Open Store DevTools in a separate window. /// </summary> /// <typeparam name="TState">Type of the state.</typeparam> /// <param name="store">Store to display information about.</param> /// <returns>True if the Store DevTools has been shown.</returns> public static async Task <bool> OpenDevToolsAsync <TState>(this ReduxStore <TState> store) where TState : class, new() { if (store == null || !store.TimeTravelEnabled) { return(false); } var appWindow = await AppWindow.TryCreateAsync(); var appWindowContentFrame = new Frame(); appWindowContentFrame.Navigate(typeof(DevToolsComponent)); var devToolsComponent = appWindowContentFrame.Content as DevToolsComponent; devToolsComponent.Initialize(store); // TODO : Set as options // Extend view into title bar appWindow.TitleBar.ExtendsContentIntoTitleBar = true; // TODO : Set as options // Set TitleBar properties (colors) appWindow.TitleBar.ButtonBackgroundColor = Colors.Transparent; appWindow.TitleBar.ButtonInactiveBackgroundColor = Colors.Transparent; appWindow.TitleBar.ButtonHoverBackgroundColor = Color.FromArgb(255, 72, 42, 203); appWindow.TitleBar.ButtonPressedBackgroundColor = Color.FromArgb(200, 72, 42, 203); appWindow.TitleBar.ButtonForegroundColor = Colors.Black; ElementCompositionPreview.SetAppWindowContent(appWindow, appWindowContentFrame); bool result = await appWindow.TryShowAsync(); appWindow.Closed += delegate { appWindowContentFrame.Content = null; appWindow = null; }; return(result); }
internal void Initialize <TState>(ReduxStore <TState> store) where TState : class, new() { // Observe UI events UndoButton.Events().Click .Subscribe(_ => store.Undo()); RedoButton.Events().Click .Subscribe(_ => store.Redo()); ResetButton.Events().Click .Subscribe(_ => store.Reset()); PlayPauseButton.Events().Click .Subscribe(_ => _devToolsStore.Dispatch(new TogglePlayPauseAction())); Slider.Events().ValueChanged .Where(_ => Slider.FocusState != Windows.UI.Xaml.FocusState.Unfocused) .Select(e => (int)e.NewValue) .DistinctUntilChanged() .Subscribe(newPosition => { _devToolsStore.Dispatch(new MoveToPositionAction { Position = newPosition }); }); ReduxActionInfosListView.Events().ItemClick .Subscribe(e => { int index = ReduxActionInfosListView.Items.IndexOf(e.ClickedItem); _devToolsStore.Dispatch(new SelectPositionAction { Position = index }); }); // Observe changes on DevTools state Observable.CombineLatest( _devToolsStore.Select(SelectCurrentPosition), _devToolsStore.Select(SelectPlaySessionActive), _devToolsStore.Select(SelectMaxPosition), store.ObserveCanUndo(), store.ObserveCanRedo(), Tuple.Create ) .Subscribe(x => { var(currentPosition, playSessionActive, maxPosition, canUndo, canRedo) = x; Slider.Value = currentPosition; Slider.Maximum = maxPosition; if (playSessionActive) { UndoButton.IsEnabled = false; RedoButton.IsEnabled = false; ResetButton.IsEnabled = false; PlayPauseButton.IsEnabled = true; Slider.IsEnabled = false; PlayPauseButton.Content = "\xE769"; } else { UndoButton.IsEnabled = canUndo; RedoButton.IsEnabled = canRedo; ResetButton.IsEnabled = canUndo || canRedo; PlayPauseButton.IsEnabled = canRedo; Slider.IsEnabled = maxPosition > 0; PlayPauseButton.Content = "\xE768"; } }); _devToolsStore.Select( CombineSelectors(SelectCurrentActions, SelectSelectedActionPosition) ) .Subscribe(x => { var(actions, selectedPosition) = x; ReduxActionInfosListView.ItemsSource = actions; ReduxActionInfosListView.SelectedIndex = Math.Clamp(selectedPosition, -1, actions.Count - 1); }); _devToolsStore.Select(SelectSelectedReduxAction) .Subscribe(reduxActionOption => { reduxActionOption.Match() .Some().Do(reduxAction => { var serializerSettings = new JsonSerializerSettings { ContractResolver = SuccinctContractResolver.Instance, ReferenceLoopHandling = ReferenceLoopHandling.Ignore, Formatting = Formatting.Indented }; SelectedReduxActionDataTextBlock.Text = JsonConvert.SerializeObject( reduxAction.Data, serializerSettings ); SelectedStateTextBlock.Text = JsonConvert.SerializeObject( reduxAction.NextState, serializerSettings ); SelectedDiffStateTextBlock.Text = "This feature will be available soon..."; }) .None().Do(() => { SelectedReduxActionDataTextBlock.Text = string.Empty; SelectedStateTextBlock.Text = string.Empty; SelectedDiffStateTextBlock.Text = string.Empty; }) .Exec(); }); _devToolsStore.ObserveAction <MoveToPositionAction>() .WithLatestFrom( _devToolsStore.Select(SelectCurrentPosition), Tuple.Create ) .Subscribe(x => { var(action, currentPosition) = x; if (action.Position < currentPosition) { for (int i = 0; i < currentPosition - action.Position; i++) { store.Undo(); } } if (action.Position > currentPosition) { for (int i = 0; i < action.Position - currentPosition; i++) { store.Redo(); } } }); _devToolsStore.Select(SelectPlaySessionActive) .Select(playSessionActive => playSessionActive ? Observable.Interval(TimeSpan.FromSeconds(1)) : Observable.Empty <long>() ) .Switch() .ObserveOnDispatcher() .Subscribe(_ => { bool canRedo = store.Redo(); if (!canRedo) { _devToolsStore.Dispatch(new TogglePlayPauseAction()); } }); // Observe changes on listened state var storeHistoryAtInitialization = store.GetHistory(); store.ObserveHistory() .StartWith(storeHistoryAtInitialization) .Subscribe(historyInfos => { var mementosOrderedByDate = historyInfos.PreviousStates .OrderBy(reduxMemento => reduxMemento.Date) .ToList(); // Set list of current actions // Set list of future (undone) actions _devToolsStore.Dispatch(new HistoryUpdated { CurrentActions = mementosOrderedByDate .Select((reduxMemento, index) => { int nextIndex = index + 1; var nextState = nextIndex < mementosOrderedByDate.Count ? mementosOrderedByDate[nextIndex].PreviousState : store.State; return(new ReduxActionInfo { Date = reduxMemento.Date, Type = reduxMemento.Action.GetType(), Data = reduxMemento.Action, PreviousState = reduxMemento.PreviousState, NextState = nextState }); }) .ToImmutableList(), FutureActions = historyInfos.FutureActions .Select(action => { return(new ReduxActionInfo { Type = action.GetType(), Data = action }); }) .ToImmutableList() }); }); _devToolsStore.Dispatch( new SelectPositionAction { Position = storeHistoryAtInitialization.PreviousStates.Count - 1 } ); }
public ManagerWithStore() { Store = new ReduxStore <TState>(); }
public ReduxMiddlewareTests() { _incrementingReducer = new FakeReducer <int>(Incrementer); _store = new ReduxStore <int>(_incrementingReducer, stateFactory); }
public async Task CreateSnapshots() { var customerSnapshotDeltas = await _eventStore.QuerySnapshotDeltas(AggregateType); foreach (var delta in customerSnapshotDeltas) { Customer customer = null; if (delta.LastSnapshotVersion > 0) { var snapShot = await _eventStore.GetSnapshot(delta.AggregateId, delta.LastSnapshotVersion); customer = JsonConvert.DeserializeObject <Customer>(snapShot.SerializedData); } else { customer = new Customer { Id = delta.AggregateId }; } var redux = new ReduxStore <Customer>(Customer.Reducer, customer); var @events = await _eventStore.GetEvents(delta.AggregateId, delta.LastSnapshotVersion, delta.CurrentVersion); foreach (var @event in @events) { switch (@event.Name) { case "CustomerCreated": customer.Created = @event.TimeStamp; redux.Dispatch(JsonConvert.DeserializeObject <CreateCustomer>(@event.Data)); break; case "CustomersFirstNameUpdated": redux.Dispatch(JsonConvert.DeserializeObject <UpdateCustomersFirstName>(@event.Data)); break; case "CustomersLastNameUpdated": redux.Dispatch(JsonConvert.DeserializeObject <UpdateCustomersLastName>(@event.Data)); break; case "CustomersPrefixUpdated": redux.Dispatch(JsonConvert.DeserializeObject <UpdateCustomersPrefix>(@event.Data)); break; case "CustomersTitleUpdated": redux.Dispatch(JsonConvert.DeserializeObject <UpdateCustomersTitle>(@event.Data)); break; default: break; } } await _eventStore.SaveSnapshot(new Snapshot { AggregateId = delta.AggregateId, SerializedData = JsonConvert.SerializeObject(redux.State), Version = delta.CurrentVersion }); } }
public MovieSearchEffects(ReduxStore <MovieSearchState> store, IOmdbMovieService omdbMovieService) { _store = store; _omdbMovieService = omdbMovieService; }
/// <summary> /// Enable the router feature to the specified store. /// </summary> /// <typeparam name="TState">Type of the state.</typeparam> /// <param name="store">Store used to store router information.</param> /// <param name="rootFrame">The root frame of the UWP application.</param> public static void EnableRouterFeature <TState>(this ReduxStore <TState> store, Frame rootFrame) where TState : class, IBaseRouterState, new() { // TODO : Find children frame in the current one for multi-layer navigation? // Add router navigation reducers var routerReducers = new[] { On <RouterNavigatingAction, RouterState>( (state, action) => state.With(new { rootFrame.CanGoBack, rootFrame.CanGoForward, }) ), On <RouterNavigatedAction, RouterState>( (state, action) => state.With(new { rootFrame.CanGoBack, rootFrame.CanGoForward, }) ), On <RouterErrorAction, RouterState>( (state, action) => state.With(new { rootFrame.CanGoBack, rootFrame.CanGoForward, }) ), On <RouterCancelAction, RouterState>( (state, action) => state.With(new { rootFrame.CanGoBack, rootFrame.CanGoForward, }) ) }; var reducers = CreateSubReducers <TState, RouterState>(routerReducers, SelectRouter); store.AddReducers(reducers); // Listen to router events var navigatingEffect = CreateEffect <TState>( () => rootFrame.Events().Navigating .Select(@event => { return(new RouterNavigatingAction { Event = new RouterNavigatingEvent { Cancel = @event.Cancel, NavigationMode = @event.NavigationMode, Parameter = @event.Parameter, SourcePageType = @event.SourcePageType } }); }), true ); var navigatedEffect = CreateEffect <TState>( () => rootFrame.Events().Navigated .Select(@event => { return(new RouterNavigatedAction { Event = new RouterNavigatedEvent { ContentType = @event.Content?.GetType(), SourcePageType = @event.SourcePageType, NavigationMode = @event.NavigationMode, Parameter = @event.Parameter, Uri = @event.Uri } }); }), true ); var navigationFailedEffect = CreateEffect <TState>( () => rootFrame.Events().NavigationFailed .Select(@event => { return(new RouterErrorAction { Event = new RouterErrorEvent { Exception = @event.Exception, Handled = @event.Handled, SourcePageType = @event.SourcePageType } }); }), true ); var navigationStoppedEffect = CreateEffect <TState>( () => rootFrame.Events().NavigationStopped .Select(@event => { return(new RouterCancelAction { Event = new RouterCancelEvent { ContentType = @event.Content?.GetType(), SourcePageType = @event.SourcePageType, NavigationMode = @event.NavigationMode, Parameter = @event.Parameter, Uri = @event.Uri } }); }), true ); // Add router navigation effects store.RegisterEffects( navigatingEffect, navigatedEffect, navigationFailedEffect, navigationStoppedEffect ); }
public MovieListViewModel( NavigationManager navigationManager, ILocalStorageService localStorageService, ReduxStore <MovieSearchState> movieSearchStore) { _navigationManager = navigationManager; _localStorageService = localStorageService; // Set initial value SearchText = movieSearchStore.State.SearchText; var source = new SourceCache <OmdbMovieSearchDto, string>(x => x.ImdbId) .DisposeWith(CleanUp); source.Connect() .Sort(SortExpressionComparer <OmdbMovieSearchDto> .Ascending(p => p.Title), SortOptimisations.ComparesImmutableValuesOnly) .Bind(Movies) .Subscribe(_ => UpdateState()) .DisposeWith(CleanUp); source.CountChanged .StartWith(0) .Select(x => x == 0) .ToPropertyEx(this, x => x.IsSourceEmpty) .DisposeWith(CleanUp); var searchTextObservable = this.WhenAnyValue(x => x.SearchText) .Skip(1) // Use throttle to prevent over requesting data .Throttle(TimeSpan.FromMilliseconds(250)) .Publish(); searchTextObservable .Where(string.IsNullOrEmpty) .Subscribe(_ => movieSearchStore.Dispatch(new ResetMovieSearchAction())) .DisposeWith(CleanUp); searchTextObservable .Where(x => !string.IsNullOrEmpty(x)) .Subscribe(x => movieSearchStore.Dispatch(new PerformMovieSearchAction(x))) .DisposeWith(CleanUp); searchTextObservable.Connect(); movieSearchStore .Select(MovieSearchSelectors.SelectIsSearching) .ToPropertyEx(this, x => x.IsSearching) .DisposeWith(CleanUp); movieSearchStore .Select(MovieSearchSelectors.SelectMovies) .Subscribe(x => source.Edit(list => { list.Clear(); list.AddOrUpdate(x); })) .DisposeWith(CleanUp); movieSearchStore .Select(MovieSearchSelectors.SelectSearchText) .Skip(1) .SelectMany(async x => { await SaveSearchTextsAsync(x) .ConfigureAwait(false); return(Unit.Default); }) .Subscribe() .DisposeWith(CleanUp); }
public static void DispatchResetAction <T>(ReduxStore <T> store) where T : class, new() { store.Dispatch(new ResetStateAction()); }
private static void Main() { var store = new ReduxStore <GameState>(RootReducer.CreateReducers(), true); store.ObserveAction().Subscribe(_ => { // Console.Clear(); PrintGameStats(store); }); #region Players Added const string Phar = "Phar"; const string Cainsith = "cainsith"; const string Jaxico = "Jaxico"; const string Sinsorium = "Sinsorium"; const string RarefiedLuck = "RarefiedLuck"; const string Psyberia = "Psyberia!"; const string SirSaltimus = "SirSaltimus"; const string Breadly = "Breadly"; const string DarkFalz = "DarkFalz"; const string iDrop = "iDrop"; const string SefiCompacto = "SefiCompacto"; const string Bullied = "Gets Bullied By Dori"; const string Cheez = "cheezburg"; const string Tzoonami = "tzoonami"; const string Dori = "ElsalvaDorian"; const string SaberRider = "SaberRider"; const string JaggerGascar = "JaggerGascar"; const string Vascosta = "Vascosta Rica"; const string Nub = "nub"; const string NetGlowGillie = "NetGlowGillie"; const string WolfGirl = "Wolfgirl1477"; const string KillJoy = "Kill Joy"; const string Canadian = "TheCanadian"; #endregion store.Dispatch(new SetIdentifierAction { Identifier = "EXAMPLE GAME" }); // Players Join #region Players Joined store.Dispatch(new AddPlayerAction { Identifier = Phar }); store.Dispatch(new AddPlayerAction { Identifier = Cainsith }); store.Dispatch(new AddPlayerAction { Identifier = Jaxico }); store.Dispatch(new AddPlayerAction { Identifier = Sinsorium }); store.Dispatch(new AddPlayerAction { Identifier = RarefiedLuck }); store.Dispatch(new AddPlayerAction { Identifier = Psyberia }); store.Dispatch(new AddPlayerAction { Identifier = SirSaltimus }); store.Dispatch(new AddPlayerAction { Identifier = Breadly }); store.Dispatch(new AddPlayerAction { Identifier = DarkFalz }); store.Dispatch(new AddPlayerAction { Identifier = iDrop }); store.Dispatch(new AddPlayerAction { Identifier = SefiCompacto }); store.Dispatch(new AddPlayerAction { Identifier = Bullied }); store.Dispatch(new AddPlayerAction { Identifier = Cheez }); store.Dispatch(new AddPlayerAction { Identifier = Tzoonami }); store.Dispatch(new AddPlayerAction { Identifier = Dori }); store.Dispatch(new AddPlayerAction { Identifier = "TEST PLAYER" }); store.Dispatch(new AddPlayerAction { Identifier = SaberRider }); store.Dispatch(new AddPlayerAction { Identifier = JaggerGascar }); store.Dispatch(new AddPlayerAction { Identifier = Vascosta }); store.Dispatch(new AddPlayerAction { Identifier = Nub }); store.Dispatch(new AddPlayerAction { Identifier = NetGlowGillie }); store.Dispatch(new AddPlayerAction { Identifier = WolfGirl }); store.Dispatch(new AddPlayerAction { Identifier = KillJoy }); store.Dispatch(new AddPlayerAction { Identifier = Canadian }); #endregion // Player Leaves store.Dispatch(new RemovePlayerAction { Identifier = "TEST PLAYER" }); // Assign Roles #region Player Assigns store.Dispatch(new AssignRoleAction { Identifier = Phar, RoleToAssign = new Bodyguard() }); store.Dispatch(new AssignRoleAction { Identifier = Sinsorium, RoleToAssign = new Hunter() }); store.Dispatch(new AssignRoleAction { Identifier = RarefiedLuck, RoleToAssign = new Werewolf() }); store.Dispatch(new AssignRoleAction { Identifier = Psyberia, RoleToAssign = new Witch() }); store.Dispatch(new AssignRoleAction { Identifier = SirSaltimus, RoleToAssign = new Sorceress() }); store.Dispatch(new AssignRoleAction { Identifier = Breadly, RoleToAssign = new Werewolf() }); store.Dispatch(new AssignRoleAction { Identifier = iDrop, RoleToAssign = new Seer() }); store.Dispatch(new AssignRoleAction { Identifier = Cheez, RoleToAssign = new Mayor() }); store.Dispatch(new AssignRoleAction { Identifier = Tzoonami, RoleToAssign = new Werewolf() }); store.Dispatch(new AssignRoleAction { Identifier = Dori, RoleToAssign = new Mason() }); store.Dispatch(new AssignRoleAction { Identifier = SaberRider, RoleToAssign = new Werewolf() }); store.Dispatch(new AssignRoleAction { Identifier = Vascosta, RoleToAssign = new Mason() }); store.Dispatch(new AssignRoleAction { Identifier = Nub, RoleToAssign = new Lycan() }); store.Dispatch(new AssignRoleAction { Identifier = NetGlowGillie, RoleToAssign = new Werewolf() }); store.Dispatch(new AssignRoleAction { Identifier = WolfGirl, RoleToAssign = new Mason() }); store.Dispatch(new AssignRoleAction { Identifier = KillJoy, RoleToAssign = new Prince() }); #endregion // Night 1 store.Dispatch(new SetNightAction()); // Day 1 store.Dispatch(new SetDayAction()); store.Dispatch(new VoteLynchAction { Identifier = Phar, Accusing = NetGlowGillie }); store.Dispatch(new ClearVoteAction { Identifier = Phar }); store.Dispatch(new VoteLynchAction { Identifier = Bullied, Accusing = Phar }); store.Dispatch(new VoteLynchAction { Identifier = Jaxico, Accusing = Bullied }); // Night 2 store.Dispatch(new SetNightAction()); store.Dispatch(new EliminateAction { Identifier = SirSaltimus, Reason = EliminationCause.Werewolves }); // Day 2 store.Dispatch(new SetDayAction()); store.Dispatch(new VoteLynchAction { Identifier = Phar, Accusing = Cheez }); store.Dispatch(new VoteLynchAction { Identifier = Bullied, Accusing = Cheez }); store.Dispatch(new VoteLynchAction { Identifier = Phar, Accusing = WolfGirl }); store.Dispatch(new VoteLynchAction { Identifier = Jaxico, Accusing = Bullied }); store.Dispatch(new VoteLynchAction { Identifier = Nub, Accusing = WolfGirl }); store.Dispatch(new VoteLynchAction { Identifier = Sinsorium, Accusing = WolfGirl }); store.Dispatch(new VoteLynchAction { Identifier = Bullied, Accusing = Jaxico }); store.Dispatch(new VoteLynchAction { Identifier = Bullied, Accusing = WolfGirl }); store.Dispatch(new VoteLynchAction { Identifier = SefiCompacto, Accusing = WolfGirl }); store.Dispatch(new VoteLynchAction { Identifier = Breadly, Accusing = WolfGirl }); store.Dispatch(new VoteLynchAction { Identifier = iDrop, Accusing = WolfGirl }); store.Dispatch(new VoteLynchAction { Identifier = Vascosta, Accusing = WolfGirl }); store.Dispatch(new VoteLynchAction { Identifier = NetGlowGillie, Accusing = WolfGirl }); store.Dispatch(new VoteLynchAction { Identifier = Tzoonami, Accusing = WolfGirl }); store.Dispatch(new VoteLynchAction { Identifier = RarefiedLuck, Accusing = WolfGirl }); store.Dispatch(new VoteLynchAction { Identifier = KillJoy, Accusing = WolfGirl }); store.Dispatch(new VoteLynchAction { Identifier = Bullied, Accusing = Jaxico }); store.Dispatch(new VoteLynchAction { Identifier = SaberRider, Accusing = Jaxico }); store.Dispatch(new EliminateAction { Identifier = WolfGirl, Reason = EliminationCause.LeftGame }); // Night 3 store.Dispatch(new SetNightAction()); store.Dispatch(new EliminateAction { Identifier = Cainsith, Reason = EliminationCause.Werewolves }); // Day 3 store.Dispatch(new SetDayAction()); store.Dispatch(new VoteLynchAction { Identifier = Nub, Accusing = Bullied }); store.Dispatch(new VoteLynchAction { Identifier = Bullied, Accusing = Nub }); store.Dispatch(new VoteLynchAction { Identifier = Jaxico, Accusing = iDrop }); store.Dispatch(new VoteLynchAction { Identifier = iDrop, Accusing = Jaxico }); store.Dispatch(new VoteLynchAction { Identifier = Jaxico, Accusing = Dori }); store.Dispatch(new VoteLynchAction { Identifier = Dori, Accusing = Jaxico }); store.Dispatch(new ClearVoteAction { Identifier = iDrop }); store.Dispatch(new ClearVoteAction { Identifier = Jaxico }); store.Dispatch(new ClearVoteAction { Identifier = Dori }); store.Dispatch(new VoteLynchAction { Identifier = SefiCompacto, Accusing = Bullied }); store.Dispatch(new VoteLynchAction { Identifier = Jaxico, Accusing = Bullied }); store.Dispatch(new VoteLynchAction { Identifier = Bullied, Accusing = Jaxico }); store.Dispatch(new VoteLynchAction { Identifier = Phar, Accusing = Sinsorium }); store.Dispatch(new ClearVoteAction { Identifier = Phar }); store.Dispatch(new VoteLynchAction { Identifier = Vascosta, Accusing = Bullied }); store.Dispatch(new VoteLynchAction { Identifier = Phar, Accusing = Vascosta }); store.Dispatch(new ClearVoteAction { Identifier = Bullied }); store.Dispatch(new VoteLynchAction { Identifier = Bullied, Accusing = Dori }); store.Dispatch(new VoteLynchAction { Identifier = Canadian, Accusing = Dori }); store.Dispatch(new VoteLynchAction { Identifier = NetGlowGillie, Accusing = Bullied }); store.Dispatch(new VoteLynchAction { Identifier = Tzoonami, Accusing = Bullied }); store.Dispatch(new VoteLynchAction { Identifier = KillJoy, Accusing = Bullied }); store.Dispatch(new VoteLynchAction { Identifier = Psyberia, Accusing = Dori }); store.Dispatch(new VoteLynchAction { Identifier = Dori, Accusing = Bullied }); store.Dispatch(new VoteLynchAction { Identifier = Cheez, Accusing = Bullied }); store.Dispatch(new VoteLynchAction { Identifier = Breadly, Accusing = Bullied }); store.Dispatch(new EliminateAction { Identifier = Bullied, Reason = EliminationCause.Lynching }); // Night 4 store.Dispatch(new SetNightAction()); store.Dispatch(new EliminateAction { Identifier = Phar, Reason = EliminationCause.Werewolves }); // Day 4 store.Dispatch(new SetDayAction()); store.Dispatch(new VoteLynchAction { Identifier = Jaxico, Accusing = KillJoy }); store.Dispatch(new VoteLynchAction { Identifier = KillJoy, Accusing = Jaxico }); store.Dispatch(new ClearVoteAction { Identifier = Jaxico }); store.Dispatch(new VoteLynchAction { Identifier = Jaxico, Accusing = Canadian }); store.Dispatch(new VoteLynchAction { Identifier = SefiCompacto, Accusing = KillJoy }); store.Dispatch(new VoteLynchAction { Identifier = Psyberia, Accusing = Canadian }); store.Dispatch(new VoteLynchAction { Identifier = SefiCompacto, Accusing = Canadian }); store.Dispatch(new VoteLynchAction { Identifier = Breadly, Accusing = Canadian }); store.Dispatch(new VoteLynchAction { Identifier = JaggerGascar, Accusing = KillJoy }); store.Dispatch(new VoteLynchAction { Identifier = KillJoy, Accusing = JaggerGascar }); store.Dispatch(new ClearVoteAction { Identifier = Breadly }); store.Dispatch(new ClearVoteAction { Identifier = KillJoy }); store.Dispatch(new VoteLynchAction { Identifier = Canadian, Accusing = Dori }); store.Dispatch(new VoteLynchAction { Identifier = DarkFalz, Accusing = KillJoy }); store.Dispatch(new VoteLynchAction { Identifier = iDrop, Accusing = Canadian }); store.Dispatch(new VoteLynchAction { Identifier = Cheez, Accusing = SefiCompacto }); store.Dispatch(new VoteLynchAction { Identifier = KillJoy, Accusing = SefiCompacto }); store.Dispatch(new VoteLynchAction { Identifier = Dori, Accusing = Canadian }); store.Dispatch(new EliminateAction { Identifier = Canadian, Reason = EliminationCause.Lynching }); // Night 5 store.Dispatch(new SetNightAction()); // Day 5 store.Dispatch(new SetDayAction()); store.Dispatch(new VoteLynchAction { Identifier = Nub, Accusing = Cheez }); store.Dispatch(new VoteLynchAction { Identifier = Jaxico, Accusing = Cheez }); store.Dispatch(new ClearVoteAction { Identifier = Jaxico }); store.Dispatch(new VoteLynchAction { Identifier = Jaxico, Accusing = KillJoy }); store.Dispatch(new VoteLynchAction { Identifier = SaberRider, Accusing = KillJoy }); store.Dispatch(new ClearVoteAction { Identifier = Jaxico }); store.Dispatch(new VoteLynchAction { Identifier = Psyberia, Accusing = SaberRider }); store.Dispatch(new VoteLynchAction { Identifier = Jaxico, Accusing = SaberRider }); store.Dispatch(new VoteLynchAction { Identifier = SefiCompacto, Accusing = SaberRider }); store.Dispatch(new VoteLynchAction { Identifier = Breadly, Accusing = SaberRider }); store.Dispatch(new VoteLynchAction { Identifier = Dori, Accusing = SaberRider }); store.Dispatch(new VoteLynchAction { Identifier = Vascosta, Accusing = SaberRider }); store.Dispatch(new VoteLynchAction { Identifier = JaggerGascar, Accusing = SaberRider }); store.Dispatch(new VoteLynchAction { Identifier = KillJoy, Accusing = SaberRider }); store.Dispatch(new VoteLynchAction { Identifier = DarkFalz, Accusing = SaberRider }); store.Dispatch(new VoteLynchAction { Identifier = SefiCompacto, Accusing = Dori }); store.Dispatch(new VoteLynchAction { Identifier = SefiCompacto, Accusing = SaberRider }); store.Dispatch(new VoteLynchAction { Identifier = Tzoonami, Accusing = SaberRider }); store.Dispatch(new EliminateAction { Identifier = SaberRider, Reason = EliminationCause.Lynching }); // Night 6 store.Dispatch(new SetNightAction()); store.Dispatch(new EliminateAction { Identifier = RarefiedLuck, Reason = EliminationCause.Witch }); store.Dispatch(new EliminateAction { Identifier = Dori, Reason = EliminationCause.Werewolves }); // Day 6 store.Dispatch(new SetDayAction()); store.Dispatch(new VoteLynchAction { Identifier = SefiCompacto, Accusing = Breadly }); store.Dispatch(new VoteLynchAction { Identifier = Nub, Accusing = Breadly }); store.Dispatch(new VoteLynchAction { Identifier = Jaxico, Accusing = Breadly }); store.Dispatch(new VoteLynchAction { Identifier = Vascosta, Accusing = Breadly }); store.Dispatch(new VoteLynchAction { Identifier = Sinsorium, Accusing = Breadly }); store.Dispatch(new VoteLynchAction { Identifier = KillJoy, Accusing = Breadly }); store.Dispatch(new VoteLynchAction { Identifier = Psyberia, Accusing = Breadly }); store.Dispatch(new VoteLynchAction { Identifier = DarkFalz, Accusing = Breadly }); store.Dispatch(new VoteLynchAction { Identifier = Cheez, Accusing = Breadly }); store.Dispatch(new VoteLynchAction { Identifier = JaggerGascar, Accusing = Breadly }); store.Dispatch(new VoteLynchAction { Identifier = Tzoonami, Accusing = Breadly }); store.Dispatch(new EliminateAction { Identifier = Breadly, Reason = EliminationCause.Lynching }); // Night 7 store.Dispatch(new SetNightAction()); store.Dispatch(new EliminateAction { Identifier = DarkFalz, Reason = EliminationCause.Werewolves }); // Day 7 store.Dispatch(new SetDayAction()); store.Dispatch(new VoteLynchAction { Identifier = Psyberia, Accusing = Tzoonami }); store.Dispatch(new VoteLynchAction { Identifier = Nub, Accusing = Tzoonami }); store.Dispatch(new VoteLynchAction { Identifier = Jaxico, Accusing = Tzoonami }); store.Dispatch(new VoteLynchAction { Identifier = Sinsorium, Accusing = Tzoonami }); store.Dispatch(new VoteLynchAction { Identifier = Vascosta, Accusing = Tzoonami }); store.Dispatch(new VoteLynchAction { Identifier = KillJoy, Accusing = Tzoonami }); store.Dispatch(new VoteLynchAction { Identifier = SefiCompacto, Accusing = Tzoonami }); store.Dispatch(new VoteLynchAction { Identifier = NetGlowGillie, Accusing = Tzoonami }); store.Dispatch(new VoteLynchAction { Identifier = JaggerGascar, Accusing = Tzoonami }); store.Dispatch(new EliminateAction { Identifier = Tzoonami, Reason = EliminationCause.Lynching }); // Night 8 store.Dispatch(new SetNightAction()); store.Dispatch(new EliminateAction { Identifier = KillJoy, Reason = EliminationCause.Werewolves }); // Day 8 store.Dispatch(new SetDayAction()); store.Dispatch(new VoteLynchAction { Identifier = SefiCompacto, Accusing = NetGlowGillie }); store.Dispatch(new VoteLynchAction { Identifier = iDrop, Accusing = NetGlowGillie }); store.Dispatch(new VoteLynchAction { Identifier = Sinsorium, Accusing = NetGlowGillie }); store.Dispatch(new VoteLynchAction { Identifier = Vascosta, Accusing = NetGlowGillie }); store.Dispatch(new VoteLynchAction { Identifier = Nub, Accusing = NetGlowGillie }); store.Dispatch(new VoteLynchAction { Identifier = Jaxico, Accusing = NetGlowGillie }); store.Dispatch(new VoteLynchAction { Identifier = Psyberia, Accusing = NetGlowGillie }); store.Dispatch(new EliminateAction { Identifier = NetGlowGillie, Reason = EliminationCause.Lynching }); // End Game store.Dispatch(new SetNightAction()); store.Dispatch(new EndGameAction()); }
public void ConnectToStore <T>(ReduxStore <T> store) where T : class, IImmutable, new() { var rootSelector = Selectors.CreateSelector((T state) => state); var onHistory = store.ObserveHistory() .WithLatestFrom(store.Select(rootSelector), (history, state) => (history, state)) .Select(pair => _selectHistoryRecords(pair.history, pair.state)); var onLatestEnsureHistory = EnsureManager .GetHistory() .Select(history => history.ToImmutableDictionary(session => session.Action)); onLatestEnsureHistory .Subscribe(val => _ensureSessions = val) .DisposedBy(this); MvvmRx.ApplyOnCollection(onHistory, this, Records, factory: Resolver.Resolve <HistoryRecordVm>, syncer: (model, vm) => vm.ReadModel(model, _ensureSessions), onRemove: vm => vm.Dispose()); var onCurrentHistoryRecord = Observable.CombineLatest( onHistory, MvvmRx.ObservePropertyValues(this, x => x.SelectedItem), (records, index) => (records, index)) .Select(pair => _pure_getSelectedHistoryRecord(pair.records, pair.index)) .Where(record => record != null); onCurrentHistoryRecord .Select(record => _pure_createJsonHierarchy(record.Action)) .ApplyOnProperty(this, x => x.Action); onCurrentHistoryRecord .Select(record => _pure_createJsonHierarchy(record.NextState)) .ApplyOnProperty(this, x => x.State); onCurrentHistoryRecord .Subscribe(record => Differ.ReadModel(record.PreviousState.ToJson(), record.NextState.ToJson())) .DisposedBy(this); var onEnsureSession = Observable.CombineLatest(onLatestEnsureHistory, onCurrentHistoryRecord, (history, record) => _pure_getEnsureSessionHistory(record, history)); onEnsureSession .Select(session => session?.Items ?.Select(item => Resolver.Resolve <EnsureItemVm>().ReadModel(item)) ?.ToObservableCollection() ?? new ObservableCollection <EnsureItemVm>() ) .ApplyOnProperty(this, x => x.EnsureItems); var onEnsureItem = Observable.CombineLatest( onEnsureSession, MvvmRx.ObservePropertyValues(this, x => x.SelectedEnsureItem), (session, index) => (session, index)) .Select(pair => _pure_getSelectedEnsureItem(pair.session, pair.index)); onEnsureItem.Select(item => _pure_createJsonHierarchy(item?.Context.Entity)) .ApplyOnProperty(this, x => x.EnsureItemState); onEnsureItem .Subscribe(item => EnsureDiffer.ReadModel(item?.Before.ToJson(), item?.After.ToJson())) .DisposedBy(this); }
public static void EnableRouterFeature <TState>(this ReduxStore <TState> store, Frame rootFrame) where TState : class, IBaseRouterState, new() { // TODO : Find children frame in the current one for multi-layer navigation? // Add router navigation reducers var routerReducers = new[] { On <RouterNavigating, RouterState>( (state, action) => state.With(new { rootFrame.CanGoBack, rootFrame.CanGoForward, }) ), On <RouterNavigated, RouterState>( (state, action) => state.With(new { rootFrame.CanGoBack, rootFrame.CanGoForward, }) ), On <RouterError, RouterState>( (state, action) => state.With(new { rootFrame.CanGoBack, rootFrame.CanGoForward, }) ), On <RouterCancel, RouterState>( (state, action) => state.With(new { rootFrame.CanGoBack, rootFrame.CanGoForward, }) ) }; var reducers = CreateSubReducers <TState, RouterState>(routerReducers, SelectRouter); store.AddReducers(reducers); // Listen to router events var navigatingEffect = CreateEffect <TState>( () => rootFrame.Events().Navigating .Select(@event => { return(new RouterNavigating { Event = @event }); }), true ); var navigatedEffect = CreateEffect <TState>( () => rootFrame.Events().Navigated .Select(@event => { return(new RouterNavigated { Event = @event }); }), true ); var navigationFailedEffect = CreateEffect <TState>( () => rootFrame.Events().NavigationFailed .Select(@event => { return(new RouterError { Event = @event }); }), true ); var navigationStoppedEffect = CreateEffect <TState>( () => rootFrame.Events().NavigationStopped .Select(@event => { return(new RouterCancel { Event = @event }); }), true ); // Add router navigation effects store.RegisterEffects( navigatingEffect, navigatedEffect, navigationFailedEffect, navigationStoppedEffect ); }
public void Initialize <TState>(ReduxStore <TState> store) where TState : class, new() { if (store.TimeTravelEnabled) { // TODO : Cannot activate History component } // Observe UI events UndoButton.Events().Click .Subscribe(_ => store.Undo()); RedoButton.Events().Click .Subscribe(_ => store.Redo()); ResetButton.Events().Click .Subscribe(_ => store.Reset()); PlayPauseButton.Events().Click .Subscribe(_ => _internalStore.Dispatch(new TogglePlayPauseAction())); Slider.Events().ValueChanged .Where(_ => Slider.FocusState != FocusState.Unfocused) .Subscribe(e => { int newPosition = (int)e.NewValue; _internalStore.Dispatch(new MoveToPositionAction { Position = newPosition }); }); // Observe changes on internal state _internalStore.Select(state => state.MaxPosition) .Subscribe(maxPosition => { Slider.Maximum = maxPosition; }); Observable.CombineLatest( _internalStore.Select(state => state.CurrentPosition), _internalStore.Select(state => state.PlaySessionActive), _internalStore.Select(state => state.MaxPosition), store.ObserveCanUndo(), store.ObserveCanRedo(), Tuple.Create ) .ObserveOnDispatcher() .Subscribe(x => { var(currentPosition, playSessionActive, maxPosition, canUndo, canRedo) = x; Slider.Value = currentPosition; if (playSessionActive) { UndoButton.IsEnabled = false; RedoButton.IsEnabled = false; ResetButton.IsEnabled = false; PlayPauseButton.IsEnabled = true; Slider.IsEnabled = false; PlayPauseButton.Content = "\xE769"; } else { UndoButton.IsEnabled = canUndo; RedoButton.IsEnabled = canRedo; ResetButton.IsEnabled = canUndo || canRedo; PlayPauseButton.IsEnabled = canRedo; Slider.IsEnabled = maxPosition > 0; PlayPauseButton.Content = "\xE768"; } }); _internalStore.ObserveAction <MoveToPositionAction>() .Subscribe(a => { if (a.Position < _internalStore.State.CurrentPosition) { for (int i = 0; i < _internalStore.State.CurrentPosition - a.Position; i++) { store.Undo(); } } if (a.Position > _internalStore.State.CurrentPosition) { for (int i = 0; i < a.Position - _internalStore.State.CurrentPosition; i++) { store.Redo(); } } }); // Observe changes on listened state var goForwardNormalActionOrigin = store.ObserveAction() .Select(action => new { Action = action, BreaksTimeline = true }); var goForwardRedoneActionOrigin = store.ObserveAction(ActionOriginFilter.Redone) .Select(action => new { Action = action, BreaksTimeline = false }); goForwardNormalActionOrigin.Merge(goForwardRedoneActionOrigin) .ObserveOnDispatcher() .Subscribe(x => { _internalStore.Dispatch(new GoForwardAction { Action = x.Action, BreaksTimeline = x.BreaksTimeline }); if (_internalStore.State.PlaySessionActive && !store.CanRedo) { _internalStore.Dispatch(new TogglePlayPauseAction()); } }); store.ObserveUndoneAction() .ObserveOnDispatcher() .Subscribe(_ => _internalStore.Dispatch(new GoBackAction())); store.ObserveReset() .ObserveOnDispatcher() .Subscribe(_ => _internalStore.Dispatch(new ResetAction())); _internalStore.Select(state => state.PlaySessionActive) .Select(playSessionActive => playSessionActive ? Observable.Interval(TimeSpan.FromSeconds(1)) : Observable.Empty <long>() ) .Switch() .ObserveOnDispatcher() .Subscribe(_ => { bool canRedo = store.Redo(); if (!canRedo) { _internalStore.Dispatch(new TogglePlayPauseAction()); } }); // Track redux actions _internalStore.ObserveAction() .Subscribe(action => { TrackReduxAction(action); }); }
private static void PrintGameStats(this ReduxStore <GameState> store) { var game = store.State; Console.Write("ID: "); WriteColorLine(game.Identifier, ConsoleColor.Yellow); Console.Write("DAY: "); WriteColorLine(game.Day, ConsoleColor.Yellow); Console.WriteLine("PHS: " + game.Phase); Console.WriteLine("PLC: " + game.Players.Count); // Calculate votes. var votes = game.GetLynchCandidates(); string lynchDeterminant; if (votes.Length == 0) { lynchDeterminant = "No One Will Be Lynched"; } else if (votes.Length == 1) { lynchDeterminant = $"Currently {votes[0]} will be determined to be lynched at EOD"; } else { lynchDeterminant = "Currently there is a tie between "; foreach (var player in votes) { lynchDeterminant += player + ", "; } } Console.WriteLine($"\n-- {lynchDeterminant} --\n"); Console.WriteLine("\t=== Players ==="); foreach (var player in game.Players.Select(entry => entry.Value)) { var padding = 24; Console.Write($"\tID: {player.Identifier.PadRight(padding)} | "); WriteColor($"ROLE: [ {player.Role.ToString()?.PadRight(12)} ] ", GetTeamRole(player)); Console.Write("| "); if (player.Alive) { WriteColor("ALIVE", ConsoleColor.Green); } else { WriteColor($"ELIMINATED [{player.CauseOfDeath}]\n", ConsoleColor.Red); } if (player.Alive) { switch (player.Accusation.Type) { case VoteType.None: Console.WriteLine(); break; case VoteType.Lynch: Console.WriteLine($" (Lynch {player.Accusation.Identifier})"); break; case VoteType.NoLynch: Console.WriteLine(" (No Lynch)"); break; default: throw new ArgumentOutOfRangeException(); } } } var history = store.GetHistory().PreviousStates; Console.WriteLine("\n\t=== Last 10 Actions ==="); foreach (var a in history.Take(5)) { Console.WriteLine($"\tTYPE: {new DateTimeOffset(a.Date).ToUnixTimeMilliseconds()} :: {a.Action}"); } Console.WriteLine(); }