Skip to content

Commit fd8c706

Browse files
committed
prevent repeat subscriptions in Game.jsx
also remove initialized mechanism, it seems to clash with react double-init in dev mode
1 parent 58605de commit fd8c706

File tree

6 files changed

+94
-102
lines changed

6 files changed

+94
-102
lines changed

src/main/client/src/Router.jsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import {
2-
useRef,
32
useState,
43
useEffect,
54
useContext,
@@ -79,23 +78,18 @@ function WithConnection() {
7978
let auth = useAuthStore(state => state.auth)
8079
let stompClient = useContext(StompContext)
8180
let [connected, setConnected] = useState(false)
82-
let initialized = useRef()
8381
useEffect(() => {
84-
if (initialized.current) {
85-
return
86-
}
8782
if (!auth.name) {
8883
return
8984
}
90-
initialized.current = true
9185
stompClient.onConnect = () => {
9286
setConnected(true)
9387
}
9488
stompClient.connectHeaders = {
9589
token: auth.token,
9690
}
9791
stompClient.activate()
98-
}, [initialized, stompClient, setConnected, auth])
92+
}, [stompClient, setConnected, auth])
9993
if (auth.state == "anonymous") {
10094
return <Navigate to={base + "/login"} />
10195
}

src/main/client/src/feature/game/Game.jsx

Lines changed: 80 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -66,53 +66,21 @@ import {
6666
} from "./BoardSettings.jsx"
6767

6868
export function Game() {
69+
let stompClient = useContext(StompContext)
70+
let auth = useAuthStore(state => state.auth)
71+
let navigate = useNavigate()
72+
let {gameId} = useParams()
6973
let [gameState, setGameState] = useState(initialState())
74+
let queueStatus = gameState.queueStatus
75+
let timesetting = gameState.timesetting
7076
let sidebarWidth = useLayoutStore(state => state.sidebarWidth.game)
71-
return (
72-
<div
73-
style={{ width: vw() - sidebarWidth }}
74-
className="h-full">
75-
<BoardSettings gameId={gameState.id} black={gameState.black} white={gameState.white} />
76-
<Board gameState={gameState} setGameState={setGameState} />
77-
<GamePanel gameState={gameState} setGameState={setGameState} />
78-
</div>
79-
)
80-
}
81-
82-
function Board({gameState, setGameState}) {
83-
let [cursor_x, setCursor_x] = useState(-1)
84-
let [cursor_y, setCursor_y] = useState(-1)
77+
let gameStateRef = useRef()
78+
gameStateRef.current = gameState
79+
let intervalIdRef = useRef()
8580
let timeRemaining = useTimeoutStore(state => state.timeRemaining)
86-
let timesetting = gameState.timesetting
8781
let setTimeRemaining = useTimeoutStore(state => state.setTimeRemaining)
8882
let timeRemainingRef = useRef()
8983
timeRemainingRef.current = timeRemaining
90-
let gameStateRef = useRef()
91-
gameStateRef.current = gameState
92-
let [ctrlKeyDown, setCtrlKeyDown] = useState(false)
93-
let zoom = useViewStateStore(state => state.zoom)
94-
let {gameId} = useParams()
95-
let navigate = useNavigate()
96-
let stompClient = useContext(StompContext)
97-
let auth = useAuthStore(state => state.auth)
98-
let cursorXref = useRef()
99-
cursorXref.current = cursor_x
100-
let cursorYref = useRef()
101-
cursorYref.current = cursor_y
102-
let id = gameState.id
103-
let lastMove = gameState.lastMove
104-
let queueStatus = gameState.queueStatus
105-
let myColor = gameState.myColor
106-
let counting = isCounting(gameState)
107-
let board = gameState.board
108-
let [forbidden_x, forbidden_y] = gameState.forbidden
109-
let canvasRef = useRef()
110-
let dragging = useLayoutStore(state => state.dragging)
111-
let muted = useMuteStore(state => state.muted)
112-
let howler = useRef()
113-
let end = gameHasEnded(gameState)
114-
let showMoveNumbers = ctrlKeyDown && (isKibitz(gameState, auth) || end)
115-
let intervalIdRef = useRef()
11684

11785
let resetCountdown = useCallback(() => {
11886
if (intervalIdRef.current) {
@@ -135,7 +103,6 @@ function Board({gameState, setGameState}) {
135103
}, 100)
136104
}
137105
}, 1000)
138-
139106
}, [setTimeRemaining, timesetting, stompClient])
140107

141108
useEffect(() => {
@@ -147,6 +114,74 @@ function Board({gameState, setGameState}) {
147114
}
148115
}, [resetCountdown])
149116

117+
useEffect(() => {
118+
let sub = stompClient.subscribe("/topic/move/" + gameId, (message) => {
119+
let move = JSON.parse(message.body)
120+
let newState = addMove(gameStateRef.current, move)
121+
setGameState(newState)
122+
resetCountdown()
123+
})
124+
return () => {
125+
sub.unsubscribe()
126+
}
127+
}, [gameStateRef, setGameState, stompClient, gameId, resetCountdown])
128+
129+
useEffect(() => {
130+
if (queueStatus === "up_to_date") {
131+
return
132+
}
133+
doTry(async () => {
134+
let game = await tfetch("/api/game/" + gameId, {
135+
headers: {
136+
"Authorization": "Bearer " + auth.token,
137+
},
138+
})
139+
setGameState(createGameState(game, auth))
140+
}, () => navigate(base + "/lobby"))
141+
}, [setGameState, queueStatus, auth, gameId, navigate])
142+
143+
if (!gameState.board.length) {
144+
return <div>Loading...</div>
145+
}
146+
147+
return (
148+
<div
149+
style={{ width: vw() - sidebarWidth }}
150+
className="h-full">
151+
<BoardSettings gameId={gameId} black={gameState.black} white={gameState.white} />
152+
<Board
153+
resetCountdown={resetCountdown}
154+
timeRemaining={timeRemaining}
155+
gameState={gameState}
156+
setGameState={setGameState} />
157+
<GamePanel gameState={gameState} setGameState={setGameState} />
158+
</div>
159+
)
160+
}
161+
162+
function Board({gameState, setGameState, resetCountdown, timeRemaining}) {
163+
let [cursor_x, setCursor_x] = useState(-1)
164+
let [cursor_y, setCursor_y] = useState(-1)
165+
let [ctrlKeyDown, setCtrlKeyDown] = useState(false)
166+
let zoom = useViewStateStore(state => state.zoom)
167+
let auth = useAuthStore(state => state.auth)
168+
let stompClient = useContext(StompContext)
169+
let cursorXref = useRef()
170+
cursorXref.current = cursor_x
171+
let cursorYref = useRef()
172+
cursorYref.current = cursor_y
173+
let lastMove = gameState.lastMove
174+
let myColor = gameState.myColor
175+
let counting = isCounting(gameState)
176+
let board = gameState.board
177+
let [forbidden_x, forbidden_y] = gameState.forbidden
178+
let canvasRef = useRef()
179+
let dragging = useLayoutStore(state => state.dragging)
180+
let muted = useMuteStore(state => state.muted)
181+
let howler = useRef()
182+
let end = gameHasEnded(gameState)
183+
let showMoveNumbers = ctrlKeyDown && (isKibitz(gameState, auth) || end)
184+
150185
let playClickSound = useCallback(() => {
151186
if (muted) {
152187
return
@@ -336,7 +371,7 @@ function Board({gameState, setGameState}) {
336371
...move,
337372
color: myColor,
338373
n: gameState.moves.length,
339-
}))
374+
}))
340375
}
341376
resetCountdown()
342377
playClickSound()
@@ -366,7 +401,7 @@ function Board({gameState, setGameState}) {
366401
if (showMoveNumbers) {
367402
paintMoveNumbers(context, board)
368403
} else if (!counting && !end) {
369-
paintLastMove(context, lastMove, timeRemainingRef.current)
404+
paintLastMove(context, lastMove, timeRemaining)
370405
} else if (lastMove && !lastMove.action) {
371406
paintNumber(context, lastMove.x, lastMove.y, lastMove.n + 1, lastMove.color)
372407
}
@@ -388,34 +423,7 @@ function Board({gameState, setGameState}) {
388423
if (!showMoveNumbers && !counting && !end) {
389424
paintShadow(context, cursor_x, cursor_y, currentColor(gameState))
390425
}
391-
}, [gameState, context, cursor_x, cursor_y, ctrlKeyDown, canvasRef, auth, board, counting, forbidden_x, forbidden_y, lastMove, isCursorInBounds, getCountingGroup, showMoveNumbers, end])
392-
393-
useEffect(() => {
394-
if (id === gameId && queueStatus === "up_to_date") {
395-
return
396-
}
397-
doTry(async () => {
398-
let game = await tfetch("/api/game/" + gameId, {
399-
headers: {
400-
"Authorization": "Bearer " + auth.token,
401-
},
402-
})
403-
setGameState(createGameState(game, auth))
404-
}, () => navigate(base + "/lobby"))
405-
}, [setGameState, queueStatus, auth, id, gameId, navigate])
406-
407-
useEffect(() => {
408-
let sub = stompClient.subscribe("/topic/move/" + gameId, (message) => {
409-
let move = JSON.parse(message.body)
410-
setGameState(addMove(gameState, move))
411-
resetCountdown()
412-
})
413-
return sub.unsubscribe
414-
}, [gameState, setGameState, stompClient, gameId, resetCountdown])
415-
416-
if (!board.length) {
417-
return <div>Loading...</div>
418-
}
426+
}, [gameState, timeRemaining, context, cursor_x, cursor_y, ctrlKeyDown, canvasRef, auth, board, counting, forbidden_x, forbidden_y, lastMove, isCursorInBounds, getCountingGroup, showMoveNumbers, end])
419427

420428
return (
421429
<div className="grid h-full">

src/main/client/src/feature/game/state.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,13 @@ export function countingComplete({dim, state, baseBoard}) {
6565
return true
6666
}
6767

68-
export function currentPlayer({moves, white, black, handicap}) {
69-
if (handicap > moves.length) {
68+
export function isCurrentlyPlacingHandicapStones({moves, handicap}) {
69+
return moves.length < handicap
70+
}
71+
72+
export function currentPlayer(baseState) {
73+
let {moves, white, black} = baseState
74+
if (isCurrentlyPlacingHandicapStones(baseState)) {
7075
return black
7176
}
7277
if (!moves.length) {
@@ -83,10 +88,11 @@ export function isKibitz({black, white}, auth) {
8388
return black !== auth.name && white !== auth.name
8489
}
8590

86-
export function currentColor({moves, handicap}) {
87-
if (handicap > moves.length) {
91+
export function currentColor(baseState) {
92+
if (isCurrentlyPlacingHandicapStones(baseState)) {
8893
return BLACK
8994
}
95+
let {moves} = baseState
9096
if (!moves.length) {
9197
return BLACK
9298
}

src/main/client/src/feature/lobby/ActiveGames.jsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import {
2-
useRef,
32
useState,
43
useEffect,
54
useContext,
@@ -25,12 +24,7 @@ export function ActiveGames() {
2524
let stompClient = useContext(StompContext)
2625
let navigate = useNavigate()
2726
let auth = useAuthStore(state => state.auth)
28-
let initialized = useRef()
2927
useEffect(() => {
30-
if (initialized.current) {
31-
return
32-
}
33-
initialized.current = true
3428
doTry(async () => {
3529
let r = await tfetch("/api/lobby/active_games", {
3630
headers: {
@@ -46,7 +40,7 @@ export function ActiveGames() {
4640
return () => {
4741
sub1.unsubscribe()
4842
}
49-
}, [auth, initialized, stompClient, navigate])
43+
}, [auth, stompClient, navigate])
5044
return (
5145
<div>
5246
<div className="grid grid-cols-[max-content_max-content_max-content]">

src/main/client/src/feature/lobby/Lobby.jsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,7 @@ export function Lobby() {
5454
let auth = useAuthStore(state => state.auth)
5555
let newGameRef = useRef()
5656
let stompClient = useContext(StompContext)
57-
let initialized = useRef()
5857
useEffect(() => {
59-
if (initialized.current) {
60-
return
61-
}
62-
initialized.current = true
6358
let sub = stompClient.subscribe("/topic/gamestart", (message) => {
6459
let r = JSON.parse(message.body)
6560
if (r.players.includes(auth.name)) {
@@ -69,7 +64,7 @@ export function Lobby() {
6964
return () => {
7065
sub.unsubscribe()
7166
}
72-
}, [auth, initialized, stompClient, navigate])
67+
}, [auth, stompClient, navigate])
7368
return (
7469
<div onClick={(event) => setLobbyState(handleLobbyClick(lobbyState, event))} className="h-full">
7570
<div className={twJoin(

src/main/client/src/feature/lobby/OpenGames.jsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,8 @@ export function OpenGames({lobbyState, setLobbyState}) {
4444
let acceptableGame = getAcceptData(lobbyState)
4545
let stompClient = useContext(StompContext)
4646
let auth = useAuthStore(state => state.auth)
47-
let initialized = useRef()
4847
let acceptDialogRef = useRef()
4948
useEffect(() => {
50-
if (initialized.current) {
51-
return
52-
}
53-
initialized.current = true
5449
doTry(async () => {
5550
let r = await tfetch("/api/lobby/open_games", {
5651
headers: {
@@ -66,7 +61,7 @@ export function OpenGames({lobbyState, setLobbyState}) {
6661
return () => {
6762
sub1.unsubscribe()
6863
}
69-
}, [auth, initialized, stompClient])
64+
}, [auth, stompClient])
7065
return (
7166
<div>
7267
<div className="grid grid-cols-[max-content_max-content_max-content]">

0 commit comments

Comments
 (0)