/**
* createGameEventPublisher
* ゲーム系ユースケースから利用する送信関数群を生成する
*/
import { Server } from "socket.io";
import { protocol } from "@repo/shared";
import type { gridMapTypes, playerTypes, roomTypes } from "@repo/shared";
import { createEmitToRoom } from "@server/network/adapters/socketEmitters";
import type { GameOutputPort } from "@server/domains/game/application/ports/gameUseCasePorts";
import type { CommonHandlerContext } from "../CommonHandler";
type RoomId = roomTypes.Room["roomId"];
type SocketId = playerTypes.PlayerData["id"];
type PongPayload = { clientTime: number; serverTime: number };
type GameStartPayload = { startTime: number };
type CurrentPlayersPayload = playerTypes.PlayerData[];
type UpdatePlayerPayload = playerTypes.PlayerData;
type MapCellUpdatesPayload = gridMapTypes.CellUpdate[];
/** ゲーム進行中イベントの送信インターフェース */
export type GameEventPublisher = Omit<GameOutputPort, "publishPlayerRemovedToRoom">;
/** 切断時に配信するゲームイベントの送信インターフェース */
export type GameDisconnectPublisher = Pick<GameOutputPort, "publishPlayerRemovedToRoom">;
/** 共通送信コンテキストからゲームイベント送信関数群を生成する */
export const createGameEventPublisher = (common: CommonHandlerContext): GameEventPublisher => {
return {
publishPongToSocket: (payload: PongPayload) => {
common.emitToSocket(protocol.SocketEvents.PONG, payload);
},
publishUpdatePlayerToRoom: (roomId: RoomId, playerData: UpdatePlayerPayload) => {
common.emitToRoom(roomId, protocol.SocketEvents.UPDATE_PLAYER, playerData);
},
publishMapCellUpdatesToRoom: (roomId: RoomId, cellUpdates: MapCellUpdatesPayload) => {
common.emitToRoom(roomId, protocol.SocketEvents.UPDATE_MAP_CELLS, cellUpdates);
},
publishGameEndToRoom: (roomId: RoomId) => {
common.emitToRoom(roomId, protocol.SocketEvents.GAME_END);
},
publishGameStartToRoom: (roomId: RoomId, payload: GameStartPayload) => {
common.emitToRoom(roomId, protocol.SocketEvents.GAME_START, payload);
},
publishCurrentPlayersToSocket: (players: CurrentPlayersPayload) => {
common.emitToSocket(protocol.SocketEvents.CURRENT_PLAYERS, players);
},
publishGameStartToSocket: (payload: GameStartPayload) => {
common.emitToSocket(protocol.SocketEvents.GAME_START, payload);
},
};
};
/** ゲーム切断時の送信関数群を生成する */
export const createGameDisconnectPublisher = (io: Server): GameDisconnectPublisher => {
const emitToRoom = createEmitToRoom(io);
return {
publishPlayerRemovedToRoom: (roomId: RoomId, removedPlayerId: SocketId) => {
emitToRoom(roomId, protocol.SocketEvents.REMOVE_PLAYER, removedPlayerId);
},
};
};