Optimize ansi character writing
This commit is contained in:
parent
b0a8e2b5b7
commit
65a06d40d4
3 changed files with 38 additions and 12 deletions
36
ansi.ts
36
ansi.ts
|
@ -7,6 +7,8 @@ import { Display } from "./display.ts";
|
|||
export class AnsiTerminalDisplay implements Display {
|
||||
private palette_bg: readonly Uint8Array[] = [];
|
||||
private palette_fg: readonly Uint8Array[] = [];
|
||||
private width = 1;
|
||||
private state = { x: -1, y: -1, f: -1, b: -1 }; // current location and color
|
||||
|
||||
constructor(
|
||||
private writer: Deno.Writer = Deno.stdout,
|
||||
|
@ -16,6 +18,7 @@ export class AnsiTerminalDisplay implements Display {
|
|||
|
||||
async getSize(): Promise<BufferSize> {
|
||||
const size = Deno.consoleSize(Deno.stdout.rid);
|
||||
this.width = size.columns;
|
||||
return {
|
||||
w: size.columns,
|
||||
h: size.rows,
|
||||
|
@ -39,13 +42,32 @@ export class AnsiTerminalDisplay implements Display {
|
|||
}
|
||||
|
||||
async setChar(at: BufferLocation, char: Char): Promise<void> {
|
||||
// TODO do not move the cursor if already at good location
|
||||
// TODO do not change the color if already good
|
||||
const fg = this.palette_fg[char.fg];
|
||||
const bg = this.palette_bg[char.bg];
|
||||
await this.writer.write(fg);
|
||||
await this.writer.write(bg);
|
||||
await this.writer.write(escape(`[${at.y};${at.x}H${char.ch}`));
|
||||
let { x, y, f, b } = this.state;
|
||||
|
||||
if (f != char.fg) {
|
||||
f = char.fg;
|
||||
await this.writer.write(this.palette_fg[f]);
|
||||
}
|
||||
|
||||
if (b != char.bg) {
|
||||
b = char.bg;
|
||||
await this.writer.write(this.palette_bg[b]);
|
||||
}
|
||||
|
||||
if (x != at.x || y != at.y) {
|
||||
x = at.x;
|
||||
y = at.y;
|
||||
await this.writer.write(escape(`[${at.y};${at.x}H`));
|
||||
}
|
||||
|
||||
await this.writer.write(new TextEncoder().encode(char.ch));
|
||||
|
||||
x += 1;
|
||||
if (x > this.width) {
|
||||
x = 0;
|
||||
y += 1;
|
||||
}
|
||||
this.state = { x, y, f, b };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
10
mod.ts
10
mod.ts
|
@ -1,11 +1,15 @@
|
|||
import { AnsiTerminalDisplay } from "./ansi.ts";
|
||||
import { TextUI } from "./ui.ts";
|
||||
import { TextUI, UIPalette } from "./ui.ts";
|
||||
export { TextUI } from "./ui.ts";
|
||||
|
||||
export async function createTextUI(): Promise<TextUI> {
|
||||
export type UIConfig = {
|
||||
palette: UIPalette;
|
||||
};
|
||||
|
||||
export async function createTextUI(config: UIConfig): Promise<TextUI> {
|
||||
// TODO detect platform
|
||||
var display = new AnsiTerminalDisplay();
|
||||
var ui = new TextUI(display);
|
||||
await ui.init();
|
||||
await ui.init(config.palette);
|
||||
return ui;
|
||||
}
|
||||
|
|
4
ui.ts
4
ui.ts
|
@ -44,8 +44,8 @@ export class TextUI {
|
|||
async flush(): Promise<void> {
|
||||
// TODO only dirty chars
|
||||
const { w, h } = this.screen.getSize();
|
||||
for (let x = 0; x < w; x++) {
|
||||
for (let y = 0; y < h; y++) {
|
||||
for (let y = 0; y < h; y++) {
|
||||
for (let x = 0; x < w; x++) {
|
||||
await this.display.setChar({ x, y }, this.screen.get({ x, y }));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue