@@ -13,8 +13,6 @@ import {
1313 useStored ,
1414} from '@prisel/state' ;
1515import {
16- playersAmbient ,
17- providePlayersAmbient ,
1816 provideRoomNameAmbient ,
1917 roomIdAmbient ,
2018 roomNameAmbient ,
@@ -23,7 +21,8 @@ import {
2321import { isInRoom , isSystemAction , playerExitRoomEvent , systemActionRequestEvent } from './events' ;
2422import { Player } from './player' ;
2523import { emitPlayerJoinEvent , emitPlayerLeaveEvent } from './roomEvent' ;
26- import { CreateGame , RoomType } from './serverConfig' ;
24+ import { CreateGame , CreateTurnOrder , RoomType } from './serverConfig' ;
25+ import { RoundRobin , TurnOrder } from './turnOrder' ;
2726import { broadcast } from './utils/broadcast' ;
2827import { pipe } from './utils/pipe' ;
2928import { getPlayerInfo , getRoomStateSnapshot2 } from './utils/stateUtils' ;
@@ -64,30 +63,34 @@ const [roomStateToken, provideRoomStateToken] = newAmbient<{ current: number }>(
6463
6564export function RoomState ( props : {
6665 onCreateGame : CreateGame ;
67- createEvent ?: { player : Player ; request : Request } ;
66+ createRoomEvent ?: { player : Player ; request : Request } ;
67+ onCreateTurnOrder ?: CreateTurnOrder ;
6868} ) : StateFuncReturn {
69- const players = useStored < Player [ ] > ( [ ] ) ; // TODO: players will change
7069 const roomStateToken = useStored ( 0 ) ;
7170
72- const { onCreateGame, createEvent } = props ;
71+ const {
72+ onCreateGame,
73+ createRoomEvent : createEvent ,
74+ onCreateTurnOrder = ( players ) => new RoundRobin ( players ) ,
75+ } = props ;
7376
7477 useSideEffect ( ( ) => {
75- const inspector = run (
78+ const turnOrder = onCreateTurnOrder ( [ ] ) ;
79+ run (
7680 pipe (
77- newState ( PreoccupiedRoomState , { onCreateGame, createEvent } ) ,
78- providePlayersAmbient ( players ) ,
81+ newState ( PreoccupiedRoomState , { onCreateGame, createEvent, turnOrder } ) ,
7982 provideRoomStateToken ( roomStateToken ) ,
8083 ) ,
8184 ) ;
82- return inspector . exit ;
8385 } , [ ] ) ;
8486}
8587
8688export function PreoccupiedRoomState ( props : {
8789 onCreateGame : CreateGame ;
8890 createEvent ?: { player : Player ; request : Request } ;
91+ turnOrder : TurnOrder ;
8992} ) : StateFuncReturn {
90- const { onCreateGame, createEvent } = props ;
93+ const { onCreateGame, createEvent, turnOrder } = props ;
9194 const [ roomName , setRoomName ] = useLocalState ( 'room' ) ;
9295 const [ host , setHost ] = useLocalState < Player > ( ) ;
9396 const [ occupied , setOccupied ] = useLocalState ( false ) ;
@@ -109,7 +112,7 @@ export function PreoccupiedRoomState(props: {
109112 }
110113 const { roomName } = payload ;
111114 setRoomName ( roomName ) ;
112- addPlayer ( player ) ;
115+ addPlayer ( turnOrder , player ) ;
113116 setOccupied ( true ) ;
114117 setHost ( player ) ;
115118
@@ -121,7 +124,7 @@ export function PreoccupiedRoomState(props: {
121124 id : getAmbient ( roomIdAmbient ) ,
122125 } ,
123126 roomState : getRoomStateSnapshot2 (
124- getAmbient ( playersAmbient ) . current ,
127+ turnOrder . getAllPlayers ( ) ,
125128 updateRoomStateToken ( ) ,
126129 player . getId ( ) ,
127130 ) ,
@@ -137,7 +140,7 @@ export function PreoccupiedRoomState(props: {
137140 player . respond ( Response . forRequest ( request ) . setFailure ( 'No payload' ) . build ( ) ) ;
138141 return ;
139142 }
140- addPlayer ( player ) ;
143+ addPlayer ( turnOrder , player ) ;
141144 setOccupied ( true ) ;
142145 setHost ( player ) ;
143146 const previousToken = getRoomStateToken ( ) ;
@@ -150,15 +153,15 @@ export function PreoccupiedRoomState(props: {
150153 id,
151154 } ,
152155 roomState : getRoomStateSnapshot2 (
153- getAmbient ( playersAmbient ) . current ,
156+ turnOrder . getAllPlayers ( ) ,
154157 token ,
155158 player . getId ( ) ,
156159 ) ,
157160 } )
158161 . build ( ) ,
159162 ) ;
160163 broadcast (
161- getAmbient ( playersAmbient ) . current ,
164+ turnOrder . getAllPlayers ( ) ,
162165 Packet . forSystemAction ( priselpb . SystemActionType . ROOM_STATE_CHANGE )
163166 . setPayload ( 'roomStateChangePayload' , {
164167 change : {
@@ -177,13 +180,17 @@ export function PreoccupiedRoomState(props: {
177180 if ( occupied && host ) {
178181 return provideRoomNameAmbient (
179182 roomName ,
180- newState ( OccupiedRoomState , { host, onCreateGame } ) ,
183+ newState ( OccupiedRoomState , { host, onCreateGame, turnOrder } ) ,
181184 ) ;
182185 }
183186}
184187
185- function OccupiedRoomState ( props : { host : Player ; onCreateGame : CreateGame } ) : StateFuncReturn {
186- const { onCreateGame } = props ;
188+ function OccupiedRoomState ( props : {
189+ host : Player ;
190+ onCreateGame : CreateGame ;
191+ turnOrder : TurnOrder ;
192+ } ) : StateFuncReturn {
193+ const { onCreateGame, turnOrder } = props ;
187194 const [ host , setHost ] = useLocalState ( props . host ) ;
188195 const [ gameStarted , setGameStarted ] = useLocalState ( false ) ;
189196 const [ allPlayerLeft , setAllPlayerLeft ] = useLocalState ( false ) ;
@@ -197,7 +204,7 @@ function OccupiedRoomState(props: { host: Player; onCreateGame: CreateGame }): S
197204 player . respond ( Response . forRequest ( request ) . setFailure ( 'No payload' ) . build ( ) ) ;
198205 return ;
199206 }
200- addPlayer ( player ) ;
207+ addPlayer ( turnOrder , player ) ;
201208 const previousToken = getRoomStateToken ( ) ;
202209 const token = updateRoomStateToken ( ) ;
203210 player . respond (
@@ -208,15 +215,15 @@ function OccupiedRoomState(props: { host: Player; onCreateGame: CreateGame }): S
208215 id : getAmbient ( roomIdAmbient ) ,
209216 } ,
210217 roomState : getRoomStateSnapshot2 (
211- getAmbient ( playersAmbient ) . current ,
218+ turnOrder . getAllPlayers ( ) ,
212219 token ,
213220 host . getId ( ) ,
214221 ) ,
215222 } )
216223 . build ( ) ,
217224 ) ;
218225 broadcast (
219- getAmbient ( playersAmbient ) . current ,
226+ turnOrder . getAllPlayers ( ) ,
220227 Packet . forSystemAction ( priselpb . SystemActionType . ROOM_STATE_CHANGE )
221228 . setPayload ( 'roomStateChangePayload' , {
222229 change : {
@@ -247,11 +254,11 @@ function OccupiedRoomState(props: { host: Player; onCreateGame: CreateGame }): S
247254 return ;
248255 }
249256
250- const createGameResult = onCreateGame ( { players : getAmbient ( playersAmbient ) } ) ;
257+ const createGameResult = onCreateGame ( { turnOrder } ) ;
251258 if ( typeof createGameResult === 'function' ) {
252259 player . respond ( Response . forRequest ( request ) . build ( ) ) ;
253260 broadcast (
254- getAmbient ( playersAmbient ) . current ,
261+ turnOrder . getAllPlayers ( ) ,
255262 Packet . forSystemAction ( priselpb . SystemActionType . ANNOUNCE_GAME_START ) . build ( ) ,
256263 ) ;
257264 run ( createGameResult ) . onComplete ( ( ) => {
@@ -268,29 +275,44 @@ function OccupiedRoomState(props: { host: Player; onCreateGame: CreateGame }): S
268275 } ) ;
269276
270277 useEventHandler ( leaveRequestEvent , ( { player, packet : request } ) => {
271- removePlayer ( player ) ;
278+ removePlayer ( turnOrder , player ) ;
272279 player . respond ( Response . forRequest ( request ) . build ( ) ) ;
273- updateRoomStateAfterPlayerLeave ( player , host , setHost , setAllPlayerLeft ) ;
280+ updateRoomStateAfterPlayerLeave (
281+ player ,
282+ player . equals ( host ) ,
283+ turnOrder ,
284+ setHost ,
285+ setAllPlayerLeft ,
286+ ) ;
274287 } ) ;
275288 // if player disconnect without leaving the room first
276289 useEventHandler ( playerExitRoomEvent , ( player ) => {
277- removePlayer ( player ) ;
278- updateRoomStateAfterPlayerLeave ( player , host , setHost , setAllPlayerLeft ) ;
290+ removePlayer ( turnOrder , player ) ;
291+ updateRoomStateAfterPlayerLeave (
292+ player ,
293+ player . equals ( host ) ,
294+ turnOrder ,
295+ setHost ,
296+ setAllPlayerLeft ,
297+ ) ;
279298 } ) ;
280299 if ( allPlayerLeft ) {
281300 switch ( getAmbient ( roomTypeAmbient ) ) {
282301 case RoomType . DEFAULT :
283302 // single room mode, we will allow reentrance
284- return newState ( AllPlayerLeftRoomState , { onCreateGame } ) ;
303+ return newState ( AllPlayerLeftRoomState , { onCreateGame, turnOrder } ) ;
285304 case RoomType . MULTI :
286305 // multi room mode, we will end the room
287306 return endState ( ) ;
288307 }
289308 }
290309}
291310
292- export function AllPlayerLeftRoomState ( props : { onCreateGame : CreateGame } ) : StateFuncReturn {
293- const { onCreateGame } = props ;
311+ export function AllPlayerLeftRoomState ( props : {
312+ onCreateGame : CreateGame ;
313+ turnOrder : TurnOrder ;
314+ } ) : StateFuncReturn {
315+ const { onCreateGame, turnOrder } = props ;
294316 const [ host , setHost ] = useLocalState < Player > ( ) ;
295317 const [ occupied , setOccupied ] = useLocalState ( false ) ;
296318 const id = getAmbient ( roomIdAmbient ) ;
@@ -301,7 +323,7 @@ export function AllPlayerLeftRoomState(props: { onCreateGame: CreateGame }): Sta
301323 player . respond ( Response . forRequest ( request ) . setFailure ( 'No payload' ) . build ( ) ) ;
302324 return ;
303325 }
304- addPlayer ( player ) ;
326+ addPlayer ( turnOrder , player ) ;
305327 setOccupied ( true ) ;
306328 setHost ( player ) ;
307329 const previousToken = getRoomStateToken ( ) ;
@@ -314,15 +336,15 @@ export function AllPlayerLeftRoomState(props: { onCreateGame: CreateGame }): Sta
314336 id : getAmbient ( roomIdAmbient ) ,
315337 } ,
316338 roomState : getRoomStateSnapshot2 (
317- getAmbient ( playersAmbient ) . current ,
339+ turnOrder . getAllPlayers ( ) ,
318340 token ,
319341 player . getId ( ) ,
320342 ) ,
321343 } )
322344 . build ( ) ,
323345 ) ;
324346 broadcast (
325- getAmbient ( playersAmbient ) . current ,
347+ turnOrder . getAllPlayers ( ) ,
326348 Packet . forSystemAction ( priselpb . SystemActionType . ROOM_STATE_CHANGE )
327349 . setPayload ( 'roomStateChangePayload' , {
328350 change : {
@@ -339,30 +361,30 @@ export function AllPlayerLeftRoomState(props: { onCreateGame: CreateGame }): Sta
339361 } ) ;
340362
341363 if ( occupied && host ) {
342- return newState ( OccupiedRoomState , { host, onCreateGame } ) ;
364+ return newState ( OccupiedRoomState , { host, onCreateGame, turnOrder } ) ;
343365 }
344366}
345367
346368function updateRoomStateAfterPlayerLeave (
347369 player : Player ,
348- host : Player ,
370+ isHostLeft : boolean ,
371+ turnOrder : TurnOrder ,
349372 setHost : SetLocalState < Player > ,
350373 setAllPlayerLeft : SetLocalState < boolean > ,
351374) {
352- const players = getAmbient ( playersAmbient ) . current ;
353- if ( players . length === 0 ) {
375+ if ( turnOrder . size === 0 ) {
354376 // all player left.
355377 setAllPlayerLeft ( true ) ;
356378 return ;
357379 }
358380 const previousToken = getRoomStateToken ( ) ;
359381 const token = updateRoomStateToken ( ) ;
360- if ( player . equals ( host ) ) {
361- // host left. We will replace host
362- const newHost = players [ 0 ] ;
382+ if ( isHostLeft ) {
383+ // host left. We will choose the current player as host
384+ const newHost = turnOrder . getCurrentPlayer ( ) ! ! ;
363385 setHost ( newHost ) ;
364386 broadcast (
365- players ,
387+ turnOrder . getAllPlayers ( ) ,
366388 Packet . forSystemAction ( priselpb . SystemActionType . ROOM_STATE_CHANGE )
367389 . setPayload ( 'roomStateChangePayload' , {
368390 change : {
@@ -383,7 +405,7 @@ function updateRoomStateAfterPlayerLeave(
383405 }
384406 // player left
385407 broadcast (
386- players ,
408+ turnOrder . getAllPlayers ( ) ,
387409 Packet . forSystemAction ( priselpb . SystemActionType . ROOM_STATE_CHANGE )
388410 . setPayload ( 'roomStateChangePayload' , {
389411 change : {
@@ -409,14 +431,15 @@ function updateRoomStateToken(): string {
409431 return `${ token . current } ` ;
410432}
411433
412- function addPlayer ( player : Player ) {
413- const players = getAmbient ( playersAmbient ) ;
434+ function addPlayer ( turnOrder : TurnOrder , player : Player ) {
414435 player . setRoomId ( getAmbient ( roomIdAmbient ) ) ;
415- players . current . push ( player ) ;
436+ turnOrder . addPlayer ( player ) ;
416437}
417438
418- function removePlayer ( player : Player ) {
419- const players = getAmbient ( playersAmbient ) ;
439+ function removePlayer ( turnOrder : TurnOrder , player : Player ) {
420440 player . clearRoomId ( ) ;
421- players . current = players . current . filter ( ( target ) => ! target . equals ( player ) ) ;
441+ if ( player . equals ( turnOrder . getCurrentPlayer ( ) ) ) {
442+ turnOrder . giveTurnToNext ( ) ;
443+ }
444+ turnOrder . removePlayer ( player ) ;
422445}
0 commit comments