0.1.3Updated 6 months ago
import type { Entity } from "@infinity-beyond/classes/entity.ts";

interface WaitingPromise {
  resolve: (...args: any[]) => void
  reject: (...args: any[]) => void
}

export class EntityWorker {
  private socket: WebSocket
  private static resolvers: Map<string, WaitingPromise> = new Map<string, WaitingPromise>()
  readonly uuid: string;

  constructor(uuid: string, socket: WebSocket, entity: typeof Entity) {
    this.uuid = uuid;
    this.socket = socket;

    this.socket.addEventListener('message', (ev) => {
      try {
        EntityWorker.receive(JSON.parse(ev.data));
      } catch(e: any) {
        console.error(`Could not parse incoming message! [${this.uuid}]`, e.message);
      }
    });

    this.socket.addEventListener('close', () => {
      console.warn(`♾️X Worker lost! [${uuid}]`);
      entity.__RemoveWorker(this);
    })

    console.log(`♾️  Worker initialized! [${this.uuid}]\n   Current workers: ${entity.__worker_count + 1}`);
  }

  static receive(data: I_ProcessorResponse) {
    const id = data.id;

    try {
      if(data.success) {
        this.resolvers.get(id)?.resolve(data.data);
      } else {
        this.resolvers.get(id)?.reject(data.error ?? data.message);
      }
    } finally {
      this.resolvers.delete(id);
    }
  }

  async dispatch(request: I_ProcessorRequest) {
    return new Promise((resolve, reject) => {
      this.socket.send(JSON.stringify(request));
      EntityWorker.resolvers.set(request.id, { reject, resolve });
    })
  }
}