Skip to content

Commit ce2a95a

Browse files
committed
refactor: remove GameTurnTimer, move logic to store
1 parent 2d71190 commit ce2a95a

File tree

11 files changed

+61
-85
lines changed

11 files changed

+61
-85
lines changed

src/modules/game/model/state.game.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { castDraft } from 'immer'
33
import { GameSettings } from '@/modules/game-settings'
44
import { ImmerStateCreator } from '@/shared/types/state'
55

6+
import { listenToTurnTimer } from './subscriptions'
67
import { GameState, GameBaseStateSlice } from './types'
78
import { GameService } from '../services/GameService'
89

@@ -20,7 +21,7 @@ export const createGameStateSlice: ImmerStateCreator<
2021
},
2122

2223
actions: {
23-
startGame: async (settings: GameSettings) => {
24+
prepareGame: async (settings: GameSettings) => {
2425
get().actions.resetGame()
2526

2627
const gameService = new GameService(settings)
@@ -30,6 +31,22 @@ export const createGameStateSlice: ImmerStateCreator<
3031
set({ players, cards, areCardsLoading: false })
3132
},
3233

34+
startGame: () => {
35+
get().turn.actions.startTurnTimer()
36+
37+
// TODO: refactor to observable that only emits on timer finished
38+
const unsubscribeFromTurnTimer = listenToTurnTimer((timer) => {
39+
if (timer === 0) {
40+
get().turn.actions.nextTurnPhase()
41+
}
42+
})
43+
44+
return () => {
45+
get().turn.actions.stopTurnTimer()
46+
unsubscribeFromTurnTimer()
47+
}
48+
},
49+
3350
resetGame: () => {
3451
get().turn.actions.resetTurn()
3552

src/modules/game/model/state.turn.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import { merge } from 'remeda'
2-
31
import { ImmerStateCreator } from '@/shared/types/state'
42

53
import { selectCurrentPlayer } from './selectors'
@@ -61,9 +59,21 @@ export const createTurnStateSlice: ImmerStateCreator<
6159

6260
setTurnPhase: (phase: GameTurnPhase) => {
6361
set((state) => {
64-
state.turn.timer = GAME_TURN_PHASE_TO_TIMER_VALUE[phase]
6562
state.turn.phase = phase
6663
})
64+
65+
get().turn.actions.resetTurnTimer()
66+
},
67+
68+
nextTurnPhase: () => {
69+
switch (get().turn.phase) {
70+
case GameTurnPhase.ACTION: {
71+
return get().turn.actions.endTurn()
72+
}
73+
case GameTurnPhase.COOLDOWN: {
74+
return get().turn.actions.nextTurn()
75+
}
76+
}
6777
},
6878

6979
startTurnTimer: () => {
@@ -85,8 +95,7 @@ export const createTurnStateSlice: ImmerStateCreator<
8595

8696
resetTurnTimer: () => {
8797
set((state) => {
88-
state.turn.timer =
89-
GAME_TURN_PHASE_TO_TIMER_VALUE[GameTurnPhase.ACTION]
98+
state.turn.timer = GAME_TURN_PHASE_TO_TIMER_VALUE[state.turn.phase]
9099
})
91100

92101
get().turn.actions.restartTurnTimer()
@@ -120,7 +129,7 @@ export const createTurnStateSlice: ImmerStateCreator<
120129

121130
resetTurn: () => {
122131
set((state) => {
123-
merge(state.turn, defaultState)
132+
state.turn = { ...state.turn, ...defaultState }
124133
})
125134
},
126135
},

src/modules/game/model/subscriptions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useGameState } from './state'
33

44
type GameStateListener<T> = (selectedState: T, previousSelectedState: T) => void
55

6-
export const listenForAllCardsCollected = (
6+
export const listenToAllCardsCollected = (
77
listener: GameStateListener<boolean>,
88
) =>
99
useGameState.subscribe((state) => {

src/modules/game/model/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export type GameTurnActions = {
3939
actions: {
4040
selectCard: (card: GameCard) => void
4141
setTurnPhase: (phase: GameTurnPhase) => void
42+
nextTurnPhase: () => void
4243
startTurnTimer: () => void
4344
stopTurnTimer: () => void
4445
restartTurnTimer: () => void
@@ -65,7 +66,8 @@ export type GameBaseState = {
6566

6667
export type GameBaseActions = {
6768
actions: {
68-
startGame: (settings: GameSettings) => void
69+
prepareGame: (settings: GameSettings) => Promise<void>
70+
startGame: () => () => void
6971
resetGame: () => void
7072
endGame: () => void
7173
registerCardRef: (element: HTMLElement) => () => void
Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,31 @@
11
import { useEffect } from 'react'
22
import { useNavigate } from 'react-router-dom'
33

4-
import { listenForAllCardsCollected, useGameActions } from '../..'
4+
import { useGameSettings } from '@/modules/game-settings'
5+
6+
import { listenToAllCardsCollected, useGameActions } from '../..'
57

68
export const useGameManager = () => {
79
const navigate = useNavigate()
8-
const { endGame } = useGameActions()
10+
const gameSettings = useGameSettings()
11+
const { startGame, endGame } = useGameActions()
912

1013
useEffect(() => {
11-
return listenForAllCardsCollected((areAllCardsCollected) => {
12-
if (areAllCardsCollected) {
13-
endGame()
14-
navigate('/scoreboard')
15-
}
16-
})
17-
}, [navigate, endGame])
14+
const unsubscribeFromGameEvents = startGame()
15+
16+
// TODO: refactor to use an observable that emits when game ends
17+
const unsubscribeFromAllCardsCollected = listenToAllCardsCollected(
18+
(areAllCardsCollected) => {
19+
if (areAllCardsCollected) {
20+
endGame()
21+
navigate('/scoreboard')
22+
}
23+
},
24+
)
25+
26+
return () => {
27+
unsubscribeFromGameEvents()
28+
unsubscribeFromAllCardsCollected()
29+
}
30+
}, [navigate, endGame, startGame, gameSettings])
1831
}

src/modules/game/ui/GameStartButton.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ export const GameStartButton = ({
1313
children,
1414
}: GameStartButtonProps) => {
1515
const gameSettings = useGameSettings()
16-
const { startGame } = useGameActions()
16+
const { prepareGame } = useGameActions()
1717

1818
const handleClick = () => {
19-
startGame(gameSettings)
19+
prepareGame(gameSettings)
2020
}
2121

2222
return (

src/modules/game/ui/GameTurnManager/GameTurnManager.tsx

Lines changed: 0 additions & 7 deletions
This file was deleted.

src/modules/game/ui/GameTurnManager/hooks.ts

Lines changed: 0 additions & 54 deletions
This file was deleted.

src/modules/game/ui/GameTurnManager/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/modules/game/ui/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,4 @@ export * from './GameOverlay'
44
export * from './GameStartButton'
55
export * from './GameNextTurnButton/GameNextTurnButton'
66
export * from './GameScoreboard'
7-
export * from './GameTurnManager'
87
export * from './GameTurnTimer'

src/pages/GamePage.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
GameNextTurnButton,
55
useAreCardsLoading,
66
GameManager,
7-
GameTurnManager,
87
GameTurnTimer,
98
} from '@/modules/game'
109
import { Loader } from '@/shared/ui/Loader'
@@ -22,7 +21,6 @@ export function GamePage() {
2221
) : (
2322
<>
2423
<GameManager />
25-
<GameTurnManager />
2624
<GameOverlay />
2725

2826
<div className="grid grid-cols-1 grid-rows-1 max-h-full w-full place-items-center gap-8 lg:justify-start">

0 commit comments

Comments
 (0)