import { Entity } from "./entity"; export enum EventType { INITIAL_STATE = "INITIAL_STATE", SET_CONTROLLABLE = "SET_CONTROLLABLE", ENTITY_BORN = "ENTITY_BORN", ENTITY_DEATH = "ENTITY_DEATH", ENTITY_POSITION_UPDATE = "ENTITY_POSITION_UPDATE", } export interface Event { event_type: EventType; data: any; } export interface EntityPositionUpdateEvent extends Event { event_type: EventType.ENTITY_POSITION_UPDATE; data: { id: string; position: { x: number; y: number; }; }; } export interface InitialStateEvent extends Event { event_type: EventType.INITIAL_STATE; data: { world: { width: number; height: number }; entities: Record; }; } export interface SetControllableEvent extends Event { event_type: EventType.SET_CONTROLLABLE; data: { id: string; client_id: string; }; } export interface EntityBornEvent extends Event { event_type: EventType.ENTITY_BORN; data: { entity: Entity; }; } export interface EntityDeathEvent extends Event { event_type: EventType.ENTITY_DEATH; data: { id: string; }; } export interface EventQueue { peek(): Event[]; clear(): void; } export interface EventPublisher { add(event: Event): void; publish(): void; } export class WebSocketEventQueue implements EventQueue { private queue: Event[]; constructor(websocket: WebSocket) { this.queue = []; this.listen_to(websocket); } public peek() { return this.queue; } public clear() { this.queue = []; } private listen_to(websocket: WebSocket) { websocket.onmessage = ({ data }) => { this.queue = this.queue.concat(JSON.parse(data)); }; } } export class WebsocketEventPublisher implements EventPublisher { private queue: Event[]; constructor(private readonly websocket: WebSocket) { this.queue = []; } public add(event: Event) { this.queue.push(event); } public publish() { if (this.queue.length === 0) { return; } this.websocket.send(JSON.stringify(this.queue)); this.queue = []; } }