import { BufferLocation, BufferSize, Char, Color } from "./base.ts"; type DisplayKeyEvent = { key: string }; type DisplayClickEvent = { click: BufferLocation }; type DisplaySizeEvent = { size: BufferSize }; type DisplayEvent = Readonly< | DisplayKeyEvent | DisplayClickEvent | DisplaySizeEvent >; type DisplayEventCombined = Partial< & DisplayKeyEvent & DisplayClickEvent & DisplaySizeEvent >; /** * Display protocol, to allow the UI to draw things on "screen" */ export class Display { private events: DisplayEvent[] = []; private known_size = { w: 0, h: 0 }; /** * Init the display (will be the first method called) */ async init(): Promise { this.known_size = await this.getSize(); } /** * Restore the display as before *init* */ async uninit(): Promise { } /** * Get the current grid size */ async getSize(): Promise { return { w: 0, h: 0 }; } /** * Setup the palette for color display * * If the display supports the whole RGB range, it may return the array as-is. * If the display only supports a limited palette, it may return only supported colors. * * From this call forward, colors will be received by numbered index in the returned array. */ async setupPalette(colors: readonly Color[]): Promise { return []; } /** * Set the cursor visibility */ async setCursorVisibility(visible: boolean): Promise { } /** * Flush the display */ async flush(): Promise { } /** * Draw a single character on screen */ async setChar(at: BufferLocation, char: Char): Promise { } /** * Push a new event */ async pushEvent(event: DisplayEvent): Promise { if (!this.events.some((ev) => sameEvent(ev, event))) { this.events.push(event); } } /** * Get the queued events */ async getEvents(auto_resize = true): Promise { // TODO check only a few cycles? if (auto_resize) { const size = await this.getSize(); if (size.w != this.known_size.w || size.h != this.known_size.h) { this.known_size = size; await this.pushEvent({ size }); } } const result = this.events; this.events = []; return result; } } function sameEvent(ev1: DisplayEventCombined, ev2: DisplayEventCombined) { return ev1.key == ev2.key && ev1.click?.x == ev2.click?.x && ev1.click?.y == ev2.click?.y && ev1.size?.w == ev2.size?.w && ev1.size?.h == ev2.size?.h; }