Skip to content

Commit

Permalink
Merge pull request #177 from dxw/separate-round-and-turn-machine
Browse files Browse the repository at this point in the history
Separate "turn" responsibility to TurnMachine
  • Loading branch information
yndajas authored Aug 5, 2024
2 parents f88e8d3 + ebb2b65 commit 9f12cac
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 43 deletions.
43 changes: 3 additions & 40 deletions server/machines/round.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,15 @@
import { assign, setup } from "xstate";
import type { Answer, Question } from "../@types/entities";
import type { Question } from "../@types/entities";
import questions from "../data/questions.json";

const context = {
answers: [] as Answer[],
questions: questions as Question[],
selectedQuestion: {} as Question | undefined,
};

type Context = typeof context;

type PlayerSubmitsAnswerEvent = {
type: "playerSubmitsAnswer";
answer: Answer;
};

type Events = PlayerSubmitsAnswerEvent;

const dynamicParamFuncs = {
addAnswer: ({
context,
event,
}: { context: Context; event: PlayerSubmitsAnswerEvent }) => {
return { currentAnswers: context.answers, newAnswer: event.answer };
},
setQuestion: ({ context }: { context: Context }) => {
return { questions: context.questions };
},
Expand All @@ -32,17 +18,9 @@ const dynamicParamFuncs = {
const roundMachine = setup({
types: {} as {
context: Context;
events: Events;
},

actions: {
// add this one to dynamicParamFuncs
addAnswer: assign({
answers: (_, params: ReturnType<typeof dynamicParamFuncs.addAnswer>) => [
...params.currentAnswers,
params.newAnswer,
],
}),
setQuestion: assign({
selectedQuestion: (
_,
Expand All @@ -58,26 +36,11 @@ const roundMachine = setup({
}).createMachine({
context,
id: "round",
initial: "roundStart",
initial: "turn",
states: {
roundStart: {
turn: {
entry: [{ type: "setQuestion", params: dynamicParamFuncs.setQuestion }],
on: {
playerSubmitsAnswer: {
actions: { type: "addAnswer", params: dynamicParamFuncs.addAnswer },
target: "countdown",
},
},
},
countdown: {
on: {
playerSubmitsAnswer: {
actions: { type: "addAnswer", params: dynamicParamFuncs.addAnswer },
},
},
after: { [15000]: { target: "finished" } },
},
finished: { type: "final" },
},
});

Expand Down
65 changes: 65 additions & 0 deletions server/machines/turn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { assign, setup } from "xstate";
import type { Answer, Question } from "../@types/entities";

const context = {
answers: [] as Answer[],
selectedQuestion: {} as Question | undefined,
};

type Context = typeof context;

type PlayerSubmitsAnswerEvent = {
type: "playerSubmitsAnswer";
answer: Answer;
};

type Events = PlayerSubmitsAnswerEvent;

const dynamicParamFuncs = {
addAnswer: ({
context,
event,
}: { context: Context; event: PlayerSubmitsAnswerEvent }) => {
return { currentAnswers: context.answers, newAnswer: event.answer };
},
};

const turnMachine = setup({
types: {} as {
context: Context;
events: Events;
},
actions: {
addAnswer: assign({
answers: (_, params: ReturnType<typeof dynamicParamFuncs.addAnswer>) => [
...params.currentAnswers,
params.newAnswer,
],
}),
},
}).createMachine({
context,
id: "turn",
initial: "noAnswers",
states: {
noAnswers: {
on: {
playerSubmitsAnswer: {
actions: { type: "addAnswer", params: dynamicParamFuncs.addAnswer },
target: "answerSubmitted",
},
},
},
answerSubmitted: {
on: {
playerSubmitsAnswer: {
actions: { type: "addAnswer", params: dynamicParamFuncs.addAnswer },
},
},
after: { [15000]: { target: "finished" } },
},
finished: { type: "final" },
},
});

export { turnMachine };
23 changes: 20 additions & 3 deletions server/models/round.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { type Actor, createActor } from "xstate";
import { type Actor, type InspectionEvent, createActor } from "xstate";
import type { Answer, Question } from "../@types/entities";
import { context, roundMachine } from "../machines/round";
import { turnMachine } from "../machines/turn";
import type { SocketServer } from "../socketServer";
import { machineLogger } from "../utils/loggingUtils";

class Round {
machine: Actor<typeof roundMachine>;
server: SocketServer;
turnMachine: Actor<typeof turnMachine> | undefined;

constructor(server: SocketServer) {
this.server = server;
Expand All @@ -16,10 +18,12 @@ class Round {
});
this.machine.subscribe((state) => {
switch (state.value) {
case "roundStart": {
case "turn": {
// maybe we should rename this as it's not listening...
this.server.onQuestionSet(
this.machine.getSnapshot().context.selectedQuestion as Question,
);
this.initialiseTurnMachine();
break;
}
default:
Expand All @@ -29,8 +33,21 @@ class Round {
this.machine.start();
}

initialiseTurnMachine() {
this.turnMachine = createActor(turnMachine, {
inspect: (inspectionEvent: InspectionEvent) => {
machineLogger(inspectionEvent);
},
input: {
selectedQuestion: this.machine.getSnapshot().context
.selectedQuestion as Question,
},
});
this.turnMachine.start();
}

addAnswer(answer: Answer) {
this.machine.send({ type: "playerSubmitsAnswer", answer });
this.turnMachine?.send({ type: "playerSubmitsAnswer", answer });
}
}

Expand Down

0 comments on commit 9f12cac

Please sign in to comment.