Skip to content
LogMan.ts 2.32 KiB
Newer Older
Grant's avatar
Grant committed
import { PixelLogger } from "./Logger";

interface UserEvents {
  pixel_place: { x: number; y: number; hex: string };
  pixel_undo: { x: number; y: number; hex?: string };
  mod_fill: {
    from: [x: number, y: number];
    to: [x: number, y: number];
    hex: string;
  };
  mod_override: { x: number; y: number; hex: string };
  mod_rollback: { x: number; y: number; hex?: string };
  mod_rollback_undo: { x: number; y: number; hex?: string };
}

interface SystemEvents {
  canvas_size: { width: number; height: number };
Grant's avatar
Grant committed
  canvas_freeze: object;
  canvas_unfreeze: object;
Grant's avatar
Grant committed
}

/**
 * Handle logs that should be written to a text file
 *
 * This could be used as an EventEmitter in the future, but as of right now
 * it just adds typing to logging of these events
 *
 * TODO: better name, this one is not it
 *
 * @see #57
 */
class LogMan_ {
  log<EventName extends keyof SystemEvents>(
    event: EventName,
    data: SystemEvents[EventName]
  ): void;
  log<EventName extends keyof UserEvents>(
    event: EventName,
    user: string,
    data: UserEvents[EventName]
  ): void;
  log<EventName extends keyof UserEvents | keyof SystemEvents>(
    event: EventName,
    ...params: EventName extends keyof UserEvents
      ? [user: string, data: UserEvents[EventName]]
      : EventName extends keyof SystemEvents
        ? [data: SystemEvents[EventName]]
        : never
  ): void {
Grant's avatar
Grant committed
    const parts: string[] = [];
Grant's avatar
Grant committed

    if (params.length === 2) {
      // user event
Grant's avatar
Grant committed
      const user = params[0] as string;
Grant's avatar
Grant committed
      parts.push(user, event);

      if (event === "mod_fill") {
        // this event format has a different line format
Grant's avatar
Grant committed
        const data: UserEvents["mod_fill"] = params[1] as any;
Grant's avatar
Grant committed

        parts.push(data.from.join(","), data.to.join(","), data.hex);
      } else {
Grant's avatar
Grant committed
        const data: UserEvents[Exclude<keyof UserEvents, "mod_fill">] =
Grant's avatar
Grant committed
          params[1] as any;
        parts.push(...[data.x, data.y, data.hex || "unset"].map((a) => a + ""));
      }
    } else {
      // system event

      parts.push("system", event);

      switch (event) {
Grant's avatar
Grant committed
        case "canvas_size": {
          const data: SystemEvents["canvas_size"] = params[0] as any;
          const { width, height } = data;
Grant's avatar
Grant committed
          parts.push(width + "", height + "");
          break;
Grant's avatar
Grant committed
        }
Grant's avatar
Grant committed
      }
    }

    PixelLogger.info(parts.join("\t"));
  }
}

export const LogMan = new LogMan_();