You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
hexmap/common/src/reducers/SyncedStateReducer.ts

50 lines
2.1 KiB

import {SyncedState} from "../state/SyncedState";
import {isMapAction, MapAction} from "../actions/MapAction";
import {hexMapReducer} from "./HexMapReducer";
import {isUserAction, UserAction} from "../actions/UserAction";
import {userReducer} from "./UserReducer";
import {exhaustivenessCheck} from "../util/TypeUtils";
import {SyncableAction} from "../actions/ServerAction";
export function syncedStateReducer(state: SyncedState, action: (MapAction|UserAction)): SyncedState {
if (isMapAction(action)) {
const newMap = hexMapReducer(state.map, action)
return newMap === state.map ? state : {
...state,
map: newMap
}
} else if (isUserAction(action)) {
const newUser = userReducer(state.user, action)
return newUser === state.user ? state : {
...state,
user: newUser
}
}
exhaustivenessCheck(action)
}
interface SyncableActionApplicationResults<T> {
state: SyncedState
appliedActions: readonly T[]
}
/** Applies a sequence of actions, skipping failed actions, and returns an array of the successful ones. */
export function applySyncableActions<T extends SyncableAction>(state: SyncedState, actions: readonly T[]): SyncableActionApplicationResults<T> {
return actions.reduce(({state, appliedActions}: SyncableActionApplicationResults<T>, action) => {
// Save our breath by reusing the actions array if this is the last action in the list.
const resultActions = (appliedActions.length === actions.length - 1) ? actions : [...appliedActions, action]
try {
const newState = syncedStateReducer(state, action)
if (newState === state) {
// Act as if it wasn't there - it did nothing.
return { state, appliedActions }
}
return {
state: newState,
appliedActions: resultActions
}
} catch (e) {
// Just skip it - continue as if it wasn't there, and don't let the exception escape.
return { state, appliedActions }
}
}, {state: state, appliedActions: []})
}