Skip to content

Commit

Permalink
split plugin.setup into setupG and setupCtx
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolodavis committed Jan 4, 2019
1 parent d2d44f9 commit 9df8145
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 12 deletions.
10 changes: 6 additions & 4 deletions docs/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ A plugin is an object that contains the following fields.
},

// Optional.
// Called during setup. The return value is merged
// with the initial value of G. This is typically
// used to store state that is managed by this
setup: ctx => state,
// Called during setup in order to add state to G.
setupG: (G, ctx) => G,

// Optional.
// Called during setup in order to add state to ctx.
setupCtx: (ctx) => ctx,
}
```

Expand Down
27 changes: 23 additions & 4 deletions src/core/plugins/main.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,39 @@ import { makeMove } from '../action-creators';

describe('plugins', () => {
let game;
let reducer;

beforeAll(() => {
game = Game({
moves: {
A: G => G,
},

plugins: [{ fnWrap: () => () => ({ plugin: true }) }],
plugins: [
{
fnWrap: () => G => ({ ...G, fnWrap: true }),
setupG: G => ({ ...G, initG: true }),
setupCtx: ctx => ({ ...ctx, initCtx: true }),
},
],
});

reducer = CreateGameReducer({ game });
});

test('setupG', () => {
const state = reducer(undefined, { type: 'init' });
expect(state.G).toMatchObject({ initG: true });
});

test('setupCtx', () => {
const state = reducer(undefined, { type: 'init' });
expect(state.ctx).toMatchObject({ initCtx: true });
});

test('plugin is invoked', () => {
const reducer = CreateGameReducer({ game });
test('fnWrap', () => {
let state = reducer(undefined, { type: 'init' });
state = reducer(state, makeMove('A'));
expect(state.G).toEqual({ plugin: true });
expect(state.G).toMatchObject({ fnWrap: true });
});
});
2 changes: 1 addition & 1 deletion src/core/plugins/plugin-player.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export default initPlayerState => ({
};
},

setup: (G, ctx) => {
setupG: (G, ctx) => {
let players = {};
for (let i = 0; i < ctx.numPlayers; i++) {
const playerState = {};
Expand Down
2 changes: 1 addition & 1 deletion src/core/plugins/plugin-player.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { makeMove, gameEvent } from '../action-creators';

describe('default values', () => {
test('playerState is not passed', () => {
const value = PluginPlayer().setup({}, { numPlayers: 2 });
const value = PluginPlayer().setupG({}, { numPlayers: 2 });
expect(value).toEqual({ players: { '0': {}, '1': {} } });
});
});
Expand Down
13 changes: 11 additions & 2 deletions src/core/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,21 @@ export function CreateGameReducer({
}
ctx._random = { seed };

// Pass ctx through all the plugins that want to modify it.
game.plugins
.filter(plugin => plugin.setupCtx !== undefined)
.forEach(plugin => {
ctx = plugin.setupCtx(ctx);
});

// Augment ctx with the enhancers (TODO: move these into plugins).
const apiCtx = new ContextEnhancer(ctx, game, ctx.currentPlayer);
let ctxWithAPI = apiCtx.attachToContext(ctx);

// Pass G through all the plugins that want to modify it.
let initialG = game.setup(ctxWithAPI, setupData);
game.plugins.filter(plugin => plugin.setup !== undefined).forEach(plugin => {
initialG = plugin.setup(initialG, ctxWithAPI);
game.plugins.filter(plugin => plugin.setupG !== undefined).forEach(plugin => {
initialG = plugin.setupG(initialG, ctxWithAPI);
});

const initial = {
Expand Down

0 comments on commit 9df8145

Please sign in to comment.