Merge pull request #248 from khankuan/master

Consecutive toggle
This commit is contained in:
Dan Abramov 2016-04-02 18:17:11 +01:00
commit 72b59c3f0a
2 changed files with 39 additions and 0 deletions

View File

@ -1,4 +1,5 @@
import difference from 'lodash/difference'; import difference from 'lodash/difference';
import union from 'lodash/union';
export const ActionTypes = { export const ActionTypes = {
PERFORM_ACTION: 'PERFORM_ACTION', PERFORM_ACTION: 'PERFORM_ACTION',
@ -7,6 +8,7 @@ export const ActionTypes = {
COMMIT: 'COMMIT', COMMIT: 'COMMIT',
SWEEP: 'SWEEP', SWEEP: 'SWEEP',
TOGGLE_ACTION: 'TOGGLE_ACTION', TOGGLE_ACTION: 'TOGGLE_ACTION',
SET_ACTIONS_ACTIVE: 'SET_ACTIONS_ACTIVE',
JUMP_TO_STATE: 'JUMP_TO_STATE', JUMP_TO_STATE: 'JUMP_TO_STATE',
IMPORT_STATE: 'IMPORT_STATE' IMPORT_STATE: 'IMPORT_STATE'
}; };
@ -45,6 +47,10 @@ export const ActionCreators = {
return { type: ActionTypes.TOGGLE_ACTION, id }; return { type: ActionTypes.TOGGLE_ACTION, id };
}, },
setActionsActive(start, end, active=true) {
return { type: ActionTypes.SET_ACTIONS_ACTIVE, start, end, active };
},
jumpToState(index) { jumpToState(index) {
return { type: ActionTypes.JUMP_TO_STATE, index }; return { type: ActionTypes.JUMP_TO_STATE, index };
}, },
@ -244,6 +250,22 @@ function liftReducerWith(reducer, initialCommittedState, monitorReducer, options
minInvalidatedStateIndex = stagedActionIds.indexOf(actionId); minInvalidatedStateIndex = stagedActionIds.indexOf(actionId);
break; break;
} }
case ActionTypes.SET_ACTIONS_ACTIVE: {
// Toggle whether an action with given ID is skipped.
// Being skipped means it is a no-op during the computation.
const { start, end, active } = liftedAction;
const actionIds = [];
for (let i = start; i < end; i++) actionIds.push(i);
if (active) {
skippedActionIds = difference(skippedActionIds, actionIds);
} else {
skippedActionIds = union(skippedActionIds, actionIds);
}
// Optimization: we know history before this action hasn't changed
minInvalidatedStateIndex = stagedActionIds.indexOf(start);
break;
}
case ActionTypes.JUMP_TO_STATE: { case ActionTypes.JUMP_TO_STATE: {
// Without recomputing anything, move the pointer that tell us // Without recomputing anything, move the pointer that tell us
// which state is considered the current one. Useful for sliders. // which state is considered the current one. Useful for sliders.

View File

@ -109,6 +109,23 @@ describe('instrument', () => {
expect(store.getState()).toBe(1); expect(store.getState()).toBe(1);
}); });
it('should set multiple action skip', () => {
// actionId 0 = @@INIT
store.dispatch({ type: 'INCREMENT' });
store.dispatch({ type: 'INCREMENT' });
store.dispatch({ type: 'INCREMENT' });
expect(store.getState()).toBe(3);
liftedStore.dispatch(ActionCreators.setActionsActive(1, 3, false));
expect(store.getState()).toBe(1);
liftedStore.dispatch(ActionCreators.setActionsActive(0, 2, true));
expect(store.getState()).toBe(2);
liftedStore.dispatch(ActionCreators.setActionsActive(0, 1, true));
expect(store.getState()).toBe(2);
});
it('should sweep disabled actions', () => { it('should sweep disabled actions', () => {
// actionId 0 = @@INIT // actionId 0 = @@INIT
store.dispatch({ type: 'INCREMENT' }); store.dispatch({ type: 'INCREMENT' });