CoreTextPlace/logic/board.ts
2024-12-28 20:41:19 +08:00

93 lines
2.7 KiB
TypeScript

import type { SectionData, SectionPosition } from "../types/section.ts";
import type {
BoardConfig,
BoardData,
CharacterPosition,
FullBoard,
} from "../types/board.ts";
import { applyChange, createSection } from "./section.ts";
import type { BoardChange } from "../types/change.ts";
export function createBoard(config: BoardConfig): BoardData {
const sections: SectionData[][] = Array(config.ySections)
.fill(0)
.map((_, sy) =>
Array(config.xSections)
.fill(0)
.map((_, sx) => createSection({ sx, sy }, config))
);
return { config, sections };
}
export function locateSection(
{ x, y }: CharacterPosition,
config: BoardConfig,
): SectionPosition {
return {
sx: Math.floor(x / config.sectionWidth),
sy: Math.floor(y / config.sectionHeight),
};
}
export function applyChangeOnBoard(change: BoardChange, board: BoardData) {
const { sx, sy } = locateSection(change, board.config);
const section = board.sections[sy][sx];
applyChange(change, section);
}
export function renderFullBoard(data: BoardData): FullBoard {
const totalLineCount = data.config.sectionHeight * data.config.ySections;
const lineLength = data.config.sectionWidth * data.config.xSections;
const chLines: string[][] = Array(totalLineCount);
const colorLines: string[][] = Array(totalLineCount);
const bgColorLines: string[][] = Array(totalLineCount);
const widthLines: number[][] = Array(totalLineCount);
for (let y = 0; y < totalLineCount; y++) {
const chLine: string[] = [];
const colorLine: string[] = [];
const bgColorLine: string[] = [];
const widthLine: number[] = [];
let charsToSkip = 0;
for (let x = 0; x < lineLength; x++) {
if (charsToSkip > 0) {
charsToSkip--;
continue;
}
const { sx, sy } = locateSection({ x, y }, data.config);
const section = data.sections[sy][sx];
const xInSection = x % data.config.sectionWidth;
const yInSection = y % data.config.sectionHeight;
const cCh = section.ch[yInSection][xInSection];
const cCo = section.color[yInSection][xInSection];
const cBg = section.bgColor[yInSection][xInSection];
const cWd = section.width[yInSection][xInSection];
chLine.push(cCh);
colorLine.push(cCo);
bgColorLine.push(cBg);
widthLine.push(cWd);
charsToSkip += cWd - 1;
}
chLines[y] = chLine;
colorLines[y] = colorLine;
bgColorLines[y] = bgColorLine;
widthLines[y] = widthLine;
}
return {
w: lineLength,
h: totalLineCount,
ch: ([] as string[]).concat(...chLines).flat(),
color: ([] as string[]).concat(...colorLines).flat(),
bg_color: ([] as string[]).concat(...bgColorLines).flat(),
width: ([] as number[]).concat(...widthLines).flat(),
};
}