๋ฉ๋ชจ๋ฆฌ
ํ์ฌ ๋ฒํผ๋ ํนํ ํฐ ์คํฌ๋กค๋ฐฑ์ด ์ค์ ๋ ์ฌ๋ฌ ํฐ๋ฏธ๋์ ์์ํ๋ ์์ฉ ํ๋ก๊ทธ๋จ์ ๊ฒฝ์ฐ ๋๋ฌด ๋ง์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฐจ์งํฉ๋๋ค. ์๋ฅผ ๋ค์ด 5000๊ฐ์ ์คํฌ๋กค๋ฐฑ์ด ์ฑ์์ง 160x24 ํฐ๋ฏธ๋์ ์ฌ์ฉํ๋ ๋ฐ๋ชจ๋ ์ฝ 34MB์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ์ฉํฉ๋๋ค(https://github.com/Microsoft/vscode/issues/29840#issuecomment-314539964 ์ฐธ์กฐ). ์ด๋ ๋จ์ผ ํฐ๋ฏธ๋์ด๊ณ 1080p ๋ชจ๋ํฐ๋ ๋ ๋์ ํฐ๋ฏธ๋์ ์ฌ์ฉํฉ๋๋ค. ๋ํ ํธ๋ฃจ์ปฌ๋ฌ(https://github.com/sourcelair/xterm.js/issues/484)๋ฅผ ์ง์ํ๊ธฐ ์ํด ๊ฐ ์บ๋ฆญํฐ๋ 2๊ฐ์ ์ถ๊ฐ number
์ ํ์ ์ ์ฅํด์ผ ํ๋ฉฐ ์ด๋ ํ์ฌ ๋ฉ๋ชจ๋ฆฌ ์๋น์ ๊ฑฐ์ ๋ ๋ฐฐ์
๋๋ค. ๋ฒํผ์.
ํ ํ ์คํธ์ ๋๋ฆฐ ๊ฐ์ ธ์ค๊ธฐ
ํ ์ค์ ์ค์ ํ ์คํธ๋ฅผ ์ ์ํ๊ฒ ๊ฐ์ ธ์์ผ ํ๋ ๋ ๋ค๋ฅธ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ์ด๊ฒ์ด ๋๋ฆฐ ์ด์ ๋ ๋ฐ์ดํฐ๊ฐ ๋ฐฐ์น๋๋ ๋ฐฉ์ ๋๋ฌธ์ ๋๋ค. ํ์๋ ๊ฐ๊ฐ ๋จ์ผ ๋ฌธ์์ด์ด ์๋ ๋ฌธ์ ๋ฐฐ์ด์ด ํฌํจ๋ฉ๋๋ค. ๋ฐ๋ผ์ ๋ฌธ์์ด์ ๊ตฌ์ฑํ ๋ค์ ์ฆ์ ๊ฐ๋น์ง ์์ง์ ์ํํฉ๋๋ค. ์ด์ ์๋ ํ ์คํธ๊ฐ ๋ผ์ธ ๋ฒํผ์์ (์์๋๋ก) ๋น๊ฒจ์ง๊ณ DOM์ ๋ ๋๋ง๋๊ธฐ ๋๋ฌธ์ ์ด ์์ ์ ์ ํ ์ํํ ํ์๊ฐ ์์์ต๋๋ค. ๊ทธ๋ฌ๋ xterm.js๋ฅผ ๋์ฑ ๊ฐ์ ํจ์ ๋ฐ๋ผ ์ ํ ๋ฐ ๋งํฌ์ ๊ฐ์ ๊ธฐ๋ฅ์ด ๋ชจ๋ ์ด ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค์ง๋ง ์ด๊ฒ์ ์ ์ ๋ ์ ์ฉํ ์ผ์ด ๋๊ณ ์์ต๋๋ค. ๋ค์ 160x24/5000 ์คํฌ๋กค๋ฐฑ ์์ ๋ฅผ ์ฌ์ฉํ๋ฉด Mid-2014 Macbook Pro์์ ์ ์ฒด ๋ฒํผ๋ฅผ ๋ณต์ฌํ๋ ๋ฐ 30-60ms๊ฐ ๊ฑธ๋ฆฝ๋๋ค.
๋ฏธ๋๋ฅผ ์์ํฉ๋๋ค
๋ฏธ๋์ ๋ ๋ค๋ฅธ ์ ์ฌ์ ์ธ ๋ฌธ์ ๋ ๋ฒํผ์ ์๋ ๋ฐ์ดํฐ์ ์ผ๋ถ ๋๋ ์ ์ฒด๋ฅผ ๋ณต์ ํด์ผ ํ ์ ์๋ ์ผ๋ถ ๋ทฐ ๋ชจ๋ธ์ ๋์ ํ ๋ ์ด๋ฌํ ์ข ๋ฅ์ ๊ฒ์ด ๋ฆฌํ๋ก์ฐ๋ฅผ ๊ตฌํํ๋ ๋ฐ ํ์ํ๋ค๋ ๊ฒ์ ๋๋ค(https://github.com/sourcelair /xterm.js/issues/622) ์ ์ ํ๊ฒ(https://github.com/sourcelair/xterm.js/pull/644#issuecomment-298058556) ์คํฌ๋ฆฐ ๋ฆฌ๋๋ฅผ ์ ๋๋ก ์ง์ํ๋ ๋ฐ ํ์ํ ์๋ ์์ต๋๋ค(https://github.com). /sourcelair/xterm.js/issues/731). ๋ฉ๋ชจ๋ฆฌ์ ๊ดํด์๋ ์ฝ๊ฐ์ ํ๋ค๋ฆผ์ ์ฌ์ง๊ฐ ์๋ ๊ฒ์ด ํ์คํ ์ข์ ๊ฒ์ ๋๋ค.
์ด ํ ๋ก ์ https://github.com/sourcelair/xterm.js/issues/484 ์์ ์์๋์์ผ๋ฉฐ ๋ ์์ธํ ์ค๋ช ํ๊ณ ๋ช ๊ฐ์ง ์ถ๊ฐ ์๋ฃจ์ ์ ์ ์ํฉ๋๋ค.
๋๋ ์๊ฐ์ด ์๊ณ ๋์ ๋๋ ๊ฐ์ ์ ๋ณด์ธ๋ค๋ฉด ์๋ฃจ์ 3์ผ๋ก ๊ธฐ์ธ๊ณ ์๋ฃจ์ 5๋ก ์ด๋ํ๊ณ ์์ต๋๋ค. ๋ชจ๋ ํผ๋๋ฐฑ์ ์ํฉ๋๋ค! /cc @jerch , @mofux , @rauchg , @parisk
์ด๊ฒ์ ๊ธฐ๋ณธ์ ์ผ๋ก truecolor fg ๋ฐ b๊ฐ ์ถ๊ฐ๋ ํ์ฌ ์ฐ๋ฆฌ๊ฐ ํ๋ ์ผ์ ๋๋ค.
// [0]: charIndex
// [1]: width
// [2]: attributes
// [3]: truecolor bg
// [4]: truecolor fg
type CharData = [string, number, number, number, number];
type LineData = CharData[];
์ฅ์
๋จ์
์ด๊ฒ์ ๋ผ์ธ์ด ์๋ ๋ผ์ธ์ ๋ํด ๋ฌธ์์ด์ ์ ์ฅํฉ๋๋ค. ์ด๊ฒ์ ์ ํ ๋ฐ ์ฐ๊ฒฐ์์ ๋งค์ฐ ํฐ ์ด๋์ ๋ณผ ์ ์์ผ๋ฉฐ ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ๋ผ์ธ์ ์ ์ฒด ๋ฌธ์์ด์ ๋น ๋ฅด๊ฒ ์ก์ธ์คํ ์ ์๊ฒ ๋จ์ ๋ฐ๋ผ ๋ ์ ์ฉํ ๊ฒ์ ๋๋ค.
interface ILineData {
// This would provide fast access to the entire line which is becoming more
// and more important as time goes on (selection and links need to construct
// this currently). This would need to reconstruct text whenever charData
// changes though. We cannot lazily evaluate text due to the chars not being
// stored in CharData
text: string;
charData: CharData[];
}
// [0]: charIndex
// [1]: attributes
// [2]: truecolor bg
// [3]: truecolor fg
type CharData = Int32Array;
์ฅ์
Int32Array
์ฌ์ฉ์ผ๋ก ์ธํด ์ค๋๋ณด๋ค ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ฎ์ต๋๋ค.๋จ์
์์ฑ์ ๊ฐ์ ธ์ ๋ฒ์์ ์ฐ๊ฒฐํฉ๋๋ค. ์์ฑ์ด ์ค๋ณต๋ ์ ์์ผ๋ฏ๋ก ์์ฐจ์ ์ผ๋ก ๋ฐฐ์นํ ์ ์์ต๋๋ค.
type LineData = CharData[]
// [0]: The character
// [1]: The width
type CharData = [string, number];
class CharAttributes {
public readonly _start: [number, number];
public readonly _end: [number, number];
private _data: Int32Array;
// Getters pull data from _data (woo encapsulation!)
public get flags(): number;
public get truecolorBg(): number;
public get truecolorFg(): number;
}
class Buffer extends CircularList<LineData> {
// Sorted list since items are almost always pushed to end
private _attributes: CharAttributes[];
public getAttributesForRows(start: number, end: number): CharAttributes[] {
// Binary search _attributes and return all visible CharAttributes to be
// applied by the renderer
}
}
์ฅ์
.flags
๋์ [0]
).๋จ์
์ฌ๊ธฐ์ ์์ด๋์ด๋ ์ผ๋ฐ์ ์ผ๋ก ํ ํฐ๋ฏธ๋ ์ธ์ ์ ์คํ์ผ์ด ๋ง์ง ์๋ค๋ ์ฌ์ค์ ํ์ฉํ๋ ๊ฒ์ด๋ฏ๋ก ํ์ํ ๋งํผ ์ ๊ฒ ๋ง๋ค๊ณ ์ฌ์ฌ์ฉํด์๋ ์ ๋ฉ๋๋ค.
// [0]: charIndex
// [1]: width
type CharData = [string, number, CharAttributes];
type LineData = CharData[];
class CharAttributes {
private _data: Int32Array;
// Getters pull data from _data (woo encapsulation!)
public get flags(): number;
public get truecolorBg(): number;
public get truecolorFg(): number;
}
interface ICharAttributeCache {
// Never construct duplicate CharAttributes, figuring how the best way to
// access both in the best and worst case is the tricky part here
getAttributes(flags: number, fg: number, bg: number): CharAttributes;
}
์ฅ์
.flags
๋์ [0]
).๋จ์
type LineData = CharData[]
// [0]: The character
// [1]: The width
type CharData = [string, number];
class CharAttributes {
private _data: Int32Array;
// Getters pull data from _data (woo encapsulation!)
public get flags(): number;
public get truecolorBg(): number;
public get truecolorFg(): number;
}
interface CharAttributeEntry {
attributes: CharAttributes,
start: [number, number],
end: [number, number]
}
class Buffer extends CircularList<LineData> {
// Sorted list since items are almost always pushed to end
private _attributes: CharAttributeEntry[];
private _attributeCache: ICharAttributeCache;
public getAttributesForRows(start: number, end: number): CharAttributeEntry[] {
// Binary search _attributes and return all visible CharAttributeEntry's to
// be applied by the renderer
}
}
interface ICharAttributeCache {
// Never construct duplicate CharAttributes, figuring how the best way to
// access both in the best and worst case is the tricky part here
getAttributes(flags: number, fg: number, bg: number): CharAttributes;
}
์ฅ์
.flags
๋์ [0]
).๋จ์
CharAttributes
ํ๋๋ฅผ ์ ์งํ๊ณ ์๋ค๋ฉด ์บ์๋ฅผ ํฌํจํ ๊ฐ์น๊ฐ ์์ ์๋ ์์ต๋๋ค.CharAttributeEntry
๊ฐ์ฒด์ ์ถ๊ฐ ์ค๋ฒํค๋์ด๊ฒ์ 3์ ์๋ฃจ์
์ ์ทจํ์ง๋ง ๋ผ์ธ ํ
์คํธ์ ๋ํ ๋น ๋ฅธ ์ก์ธ์ค๋ฅผ ์ํด ๋๋ฆฌ๊ฒ ํ๊ฐํ๋ ํ
์คํธ ๋ฌธ์์ด์ ์ถ๊ฐํฉ๋๋ค. CharData
์๋ ๋ฌธ์๋ฅผ ์ ์ฅํ๊ณ ์๊ธฐ ๋๋ฌธ์ ๋๋ฆฌ๊ฒ ํ๊ฐํ ์ ์์ต๋๋ค.
type LineData = {
text: string,
CharData[]
}
// [0]: The character
// [1]: The width
type CharData = [string, number];
class CharAttributes {
public readonly _start: [number, number];
public readonly _end: [number, number];
private _data: Int32Array;
// Getters pull data from _data (woo encapsulation!)
public get flags(): number;
public get truecolorBg(): number;
public get truecolorFg(): number;
}
class Buffer extends CircularList<LineData> {
// Sorted list since items are almost always pushed to end
private _attributes: CharAttributes[];
public getAttributesForRows(start: number, end: number): CharAttributes[] {
// Binary search _attributes and return all visible CharAttributes to be
// applied by the renderer
}
// If we construct the line, hang onto it
public getLineText(line: number): string;
}
์ฅ์
.flags
๋์ [0]
).๋จ์
Int32Array
๋ด๋ถ์ int๋ก ์ ์ฅํ๋ฉด int๋ฅผ ๋ฌธ์๋ก ๋ค์ ๋ณํํ๋ ๋ฐ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฌ๋ฏ๋ก ์๋ํ์ง ์์ต๋๋ค.ํผํฉ๋ ์ ์๋ ๋ ๋ค๋ฅธ ์ ๊ทผ ๋ฐฉ์: indexeddb, websql ๋๋ ํ์ผ ์์คํ API๋ฅผ ์ฌ์ฉํ์ฌ ๋นํ์ฑ ์คํฌ๋กค๋ฐฑ ํญ๋ชฉ์ ๋์คํฌ๋ก ํ์ด์ง ์์ํฉ๋๋ค ๐ค
ํ๋ฅญํ ์ ์์ ๋๋ค. 3. ํธ๋ฃจ ์ปฌ๋ฌ๋ ์ง์ํ๋ฉด์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ฝํ ์ ์์ผ๋ฏ๋ก ํ์ฌ๋ก์๋ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ด๋ผ๋ ์ ์ ๋์ํฉ๋๋ค.
๊ฑฐ๊ธฐ์ ๋๋ฌํ๊ณ ์ํฉ์ด ๊ณ์ํด์ ์ ์งํ๋๋ค๋ฉด 5. ์์ ์ ์ํ ๋๋ก ์ต์ ํํ๊ฑฐ๋ ๊ทธ ๋น์ ๋ง์์ ๋ ์ค๋ฅด๋ ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ์ต์ ํํ ์ ์์ต๋๋ค.
3. ๋ฉ์ ธ์๐.
@mofux , ๋์คํฌ ์ ์ฅ์ ์ง์ ๊ธฐ์ ์ ์ฌ์ฉํ์ฌ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์ค์ด๋ ์ฌ์ฉ ์ฌ๋ก๊ฐ ๋ถ๋ช ํ ์์ง๋ง, ์ด๋ ์ฌ์ฉ์์๊ฒ ๋์คํฌ ์ ์ฅ์ ์ฌ์ฉ ๊ถํ์ ์์ฒญํ๋ ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ํ์ํฌ ์ ์์ต๋๋ค.
๋ฏธ๋ ์ง์์ ๊ดํ์ฌ:
์๊ฐํ๋ฉด ํ ์๋ก tty ๋ฐ์ดํฐ๋ฅผ ๊ตฌ๋ฌธ ๋ถ์ํ๊ณ , ๋ผ์ธ ๋ฒํผ๋ฅผ ์ ์งํ๊ณ , ๋งํฌ๋ฅผ ์ฐ๊ฒฐํ๊ณ , ๊ฒ์ ํ ํฐ์ ์ผ์น์ํค๋ ๋ฑ์ ํ๋ ์์
์ ๋ชจ๋ ์ํํ๋ WebWorker
์๋ค๋ ์๊ฐ์ด ๋ ๋ง์ด ๋ญ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก UI๋ฅผ ์ฐจ๋จํ์ง ์๊ณ ๋ณ๋์ ๋ฐฑ๊ทธ๋ผ์ด๋ ์ค๋ ๋์์ ๋ฌด๊ฑฐ์ด ์์
์ ์ํํฉ๋๋ค. ํ์ง๋ง ์ด๊ฒ์ ์๋ง๋ 4.0 ๋ฆด๋ฆฌ์ค์ ๋ํ ๋ณ๋์ ๋
ผ์์ ์ผ๋ถ์ฌ์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค ๐
์์ผ๋ก WebWorker์ ๋ํด +100์ด์ง๋ง ๋ชจ๋ ๋ธ๋ผ์ฐ์ ์์ ์ฌ์ฉํ ์ ์๋ ๊ฒ์ ์๋๊ธฐ ๋๋ฌธ์ ์ง์ํ๋ ๋ธ๋ผ์ฐ์ ์ ๋ณ๊ฒฝ ๋ชฉ๋ก ๋ฒ์ ์ด ํ์ํ๋ค๊ณ ์๊ฐํฉ๋๋ค...
Int32Array
๋ผ๊ณ ๋งํ๋ฉด ํ๊ฒฝ์์ ์ง์ํ์ง ์๋ ๊ฒฝ์ฐ ์ผ๋ฐ ๋ฐฐ์ด์ด ๋ฉ๋๋ค.
@mofux ์์ผ๋ก WebWorker
์ ์ข์ ์๊ฐ ๐
@AndrienkoAleksandr ์, WebWorker
๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ๊ธฐ๋ฅ ๊ฐ์ง๋ฅผ ํตํด ๋์๋ ์ง์ํด์ผ ํฉ๋๋ค.
์์ฐ ๋ฆฌ์คํธ ์ข๋ค์ :)
๋๋ ๋ํ ์ผ๋ฐ์ ์ธ ํฐ๋ฏธ๋ ์ฌ์ฉ์ 90% ์ด์์ ๋ํด ๋ฉ๋ชจ๋ฆฌ ์๋น๋ฅผ ํฌ๊ฒ ์ค์ผ ๊ฒ์ ์ฝ์ํ๊ธฐ ๋๋ฌธ์ 3 ์ ๊ธฐ๋๋ ๊ฒฝํฅ์ด ์์ต๋๋ค. ์ด ๋จ๊ณ์์ Imho ๋ฉ๋ชจ๋ฆฌ ์ต์ ํ๊ฐ ์ฃผ์ ๋ชฉํ๊ฐ ๋์ด์ผ ํฉ๋๋ค. ์ด ์ธ์๋ ํน์ ์ฌ์ฉ ์ฌ๋ก์ ๋ํ ์ถ๊ฐ ์ต์ ํ๊ฐ ์ ์ฉ๋ ์ ์์ต๋๋ค(๋ด ์๊ฐ: ncurses์ ๊ฐ์ "์บ๋ฒ์ค์ ๊ฐ์ ์ฑ"์ ์๋ง์ ๋จ์ผ ์
์
๋ฐ์ดํธ๋ฅผ ์ฌ์ฉํ๊ณ ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ [start, end]
๋ชฉ๋ก์ ๋ค์ ์ ํ์ํฌ ๊ฒ์
๋๋ค) .
@AndrienkoAleksandr ๋ค, ์น ์์ ์ ์์ด๋์ด๋ ๋ฉ์ธ ์ค๋ ๋์์ _์ผ๋ถ_ ๋ถ๋ด์ ๋์ด์ค ์ ์๊ธฐ ๋๋ฌธ์ ์ข์ํฉ๋๋ค. ์ฌ๊ธฐ์ ๋ฌธ์ ๋ (์ํ๋ ๋ชจ๋ ๋์ ์์คํ ์์ ์ง์๋์ง ์์ ์ ์๋ค๋ ์ฌ์ค ์ธ์๋) _some_์ ๋๋ค. JS ๋ถ๋ถ์ ๋ชจ๋ ์ต์ ํ์์ ๋ ์ด์ ๊ทธ๋ ๊ฒ ํฐ ๋ฌธ์ ๊ฐ ์๋๋๋ค. xterm.js๋ ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ๋ณด์์์ต๋๋ค. ์ค์ ๋ฌธ์ ๋ ์ฑ๋ฅ ์ธก๋ฉด์์ ๋ธ๋ผ์ฐ์ ์ ๋ ์ด์์/๋ ๋๋ง์ ๋๋ค...
@mofux ์ผ๋ถ "์ธ๋ถ ๋ฉ๋ชจ๋ฆฌ"์ ๋ํ ํ์ด์ง์ ์ข์ ์๊ฐ์ด์ง๋ง xterm.js๊ฐ ์๋ "๋ํํ ํฐ๋ฏธ๋ ์์ ฏ"์ด ์๋๋ผ ๋ ๋์ ์ถ์ํ์ ์ผ๋ถ์ฌ์ผ ํฉ๋๋ค. ์ด๊ฒ์ imho ์ ๋์จ์ผ๋ก ๋ฌ์ฑํ ์ ์์ต๋๋ค.
์ฃผ์ ์ธ: ๋ฐฐ์ด ๋ typedarrays ๋ asm.js๋ก ๋ช ๊ฐ์ง ํ
์คํธ๋ฅผ ํ์ต๋๋ค. ๋ด๊ฐ ๋งํ ์์๋ ๊ฒ์ - OMG, ๊ฐ๋จํ ๋ณ์๋ก๋ ๋ฐ ์ธํธ์ ๊ฒฝ์ฐ 1 : 1,5 : 10
์ ๊ฐ์ต๋๋ค (FF์์๋ ํจ์ฌ ๋). ์์ํ JS ์๋๊ฐ ์ ๋ง ์ํ๊ธฐ ์์ํ๋ฉด "asm ์ฌ์ฉ"์ด ๋์์ด ๋ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ทผ๋ณธ์ ์ธ ๋ณํ๋ฅผ ์๋ฏธํ๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ์ตํ์ ์๋จ์ผ๋ก ์๊ฐํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์น ์ด์
๋ธ๋ฆฌ๋ ์์ง ๋ฐฐ์กํ ์ค๋น๊ฐ ๋์ง ์์์ต๋๋ค.
์ฃผ์ ์ธ: ๋ฐฐ์ด ๋ typedarrays ๋ asm.js๋ก ๋ช ๊ฐ์ง ํ ์คํธ๋ฅผ ํ์ต๋๋ค. ๋ด๊ฐ ๋งํ ์์๋ ๊ฒ์ - OMG, ๊ฐ๋จํ ๊ฐ๋ณ๋ก๋ ๋ฐ ์ธํธ์ ๊ฒฝ์ฐ 1 : 1,5 : 10๊ณผ ๊ฐ์ต๋๋ค (FF์์๋ ํจ์ฌ ๋)
@jerch ๋ ๋ฐฐ์ด ๋ typedarrays๊ฐ 1:1์์ 1:5
์ผํ๋ก ์ข์ ์บ์น - ๋๋ 10:15:100
์๋ ํ๋ช
ํจ์ ์๋ฏธํ์ต๋๋ค. ๊ทธ๋ฌ๋ FF ์ ํ ๋ฐฐ์ด์์๋ง ์ผ๋ฐ ๋ฐฐ์ด๋ณด๋ค ์ฝ๊ฐ ๋น ๋ฆ
๋๋ค. asm์ FF, ์นํท(Safari), ๊น๋ฐ์/V8(Chrome, Opera)๋ก ํ
์คํธ๋ ๋ชจ๋ ๋ธ๋ผ์ฐ์ ์์ js ์ด๋ ์ด๋ณด๋ค 10๋ฐฐ ์ด์ ๋น ๋ฆ
๋๋ค.
@jerch cool, ๋ ๋์ ๋ฉ๋ชจ๋ฆฌ์ ํจ๊ป typedarrays์ 50% ์๋ ํฅ์์ ์ง๊ธ์ผ๋ก์๋ ํ์คํ ํฌ์ํ ๊ฐ์น๊ฐ ์์ต๋๋ค.
๋ฉ๋ชจ๋ฆฌ ์ ์ฝ์ ๋ํ ์์ด๋์ด - ๋ชจ๋ ๋ฌธ์์ ๋ํด width
๋ฅผ ์ ๊ฑฐํ ์ ์์ต๋๋ค. ๋ ์ ๋ ดํ wcwidth ๋ฒ์ ์ ๊ตฌํํ๋ ค๊ณ ํฉ๋๋ค.
@jerch ์ฐ๋ฆฌ๋ ๊ทธ๊ฒ์ ๊ฝค ๋ง์ด ์ ๊ทผํด์ผ ํ๊ณ ๊ทธ๊ฒ์ ์ง์ฐ ๋ก๋ํ๊ฑฐ๋ ์ด๋ค ๊ฒ๋ ํ ์ ์์ต๋๋ค. ์๋ํ๋ฉด ๋ฆฌํ๋ก์ฐ๊ฐ ์ฌ ๋ ๋ฒํผ์ ์๋ ๋ชจ๋ ๋ฌธ์์ ๋๋น๊ฐ ํ์ํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๊ฒ์ด ๋น ๋ฅด๋๋ผ๋ ์ฐ๋ฆฌ๋ ์ฌ์ ํ ๊ทธ๊ฒ์ ์ ์งํ๊ธฐ๋ฅผ ์ํ ๊ฒ์ ๋๋ค.
์ง์ ๋์ง ์์ ๊ฒฝ์ฐ 1๋ก ๊ฐ์ ํ๊ณ ์ ํ ์ฌํญ์ผ๋ก ๋ง๋๋ ๊ฒ์ด ๋ ๋์ ์ ์์ต๋๋ค.
type CharData = [string, number?]; // not sure if this is valid syntax
[
// 'a'
['a'],
// 'ๆ'
['ๆ', 2],
// after wide
['', 0],
...
]
@Tyriar ์ - ์ด๋ฏธ ์์ฑ
์๋ ํฅ์์ ์กฐํ ํ
์ด๋ธ์ ๋ํด 16k ๋ฐ์ดํธ์ ๋น์ฉ์ผ๋ก ๋ด ์ปดํจํฐ์์ 10~15๋ฐฐ์
๋๋ค. ์ฌ์ ํ ํ์ํ ๊ฒฝ์ฐ ๋์ ์กฐํฉ์ด ๊ฐ๋ฅํ ์๋ ์์ต๋๋ค.
์์ผ๋ก ๋ ๋ง์ ํ๋๊ทธ๋ฅผ ์ง์ํ ์์ ์ ๋๋ค: https://github.com/sourcelair/xterm.js/issues/580
๋ ๋ค๋ฅธ ์๊ฐ: ํฐ๋ฏธ๋์ ๋งจ ์๋ ๋ถ๋ถ( Terminal.ybase
~ Terminal.ybase + Terminal.rows
)๋ง ๋์ ์
๋๋ค. ๋ฐ์ดํฐ์ ๋๋ถ๋ถ์ ๊ตฌ์ฑํ๋ ์คํฌ๋กค๋ฐฑ์ ์์ ํ ์ ์ ์
๋๋ค. ์๋ง๋ ์ด๊ฒ์ ํ์ฉํ ์ ์์ ๊ฒ์
๋๋ค. ์ต๊ทผ๊น์ง ์ด๊ฒ์ ๋ชฐ๋์ง๋ง ํ ์ญ์ (DL, CSI Ps M)์ ๊ฐ์ ๊ฒ์กฐ์ฐจ๋ ์คํฌ๋กค๋ฐฑ์ ๋ค์ ์๋๋ก ๊ฐ์ ธ์ค์ง ์๊ณ ์คํ๋ ค ๋ค๋ฅธ ํ์ ์ฝ์
ํฉ๋๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก ์๋ก ์คํฌ๋กค(SU, CSI Ps S)ํ๋ฉด Terminal.scrollTop
์ ํญ๋ชฉ์ด ์ญ์ ๋๊ณ Terminal.scrollBottom
ํญ๋ชฉ์ด ์ฝ์
๋ฉ๋๋ค.
ํฐ๋ฏธ๋์ ํ๋จ ๋์ ๋ถ๋ถ์ ๋ ๋ฆฝ์ ์ผ๋ก ๊ด๋ฆฌํ๊ณ ์ค์ด ๋ฐ๋ ค ๋์ฌ ๋ ๋ค๋ก ์คํฌ๋กคํ๋ฉด ์๋นํ ์ด๋์ ์ป์ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ํ๋จ ๋ถ๋ถ์ ์์ฑ ์์ , ๋ ๋น ๋ฅธ ์ก์ธ์ค ๋ฑ์ ์ ํธํ๊ธฐ ์ํด ๋ ์ฅํฉํ ์ ์๋ ๋ฐ๋ฉด ์คํฌ๋กค๋ฐฑ์ ์์์ ์ ์ํ ์์นด์ด๋ธ ํ์์ ๋ ๊ฐ๊น์ต๋๋ค.
๋ ๋ค๋ฅธ ์๊ฐ: CharAttributeEntry
๋ฅผ ํ์ผ๋ก ์ ํํ๋ ๊ฒ์ด ๋๋ถ๋ถ์ ์์ฉ ํ๋ก๊ทธ๋จ์ด ์๋ํ๋ ๋ฐฉ์์ด๋ฏ๋ก ๋ ๋์ ์์ด๋์ด์ผ ์ ์์ต๋๋ค. ๋ํ ํฐ๋ฏธ๋ ํฌ๊ธฐ๊ฐ ์กฐ์ ๋๋ฉด ๋์ผํ ์คํ์ผ์ ๊ณต์ ํ์ง ์๋ "๋น" ํจ๋ฉ์ด ์ค๋ฅธ์ชฝ์ ์ถ๊ฐ๋ฉ๋๋ค.
์:
๋นจ๊ฐ์/๋ น์ diff์ ์ค๋ฅธ์ชฝ์๋ ์คํ์ผ์ด ์ง์ ๋์ง ์์ "๋น" ์ ์ด ์์ต๋๋ค.
@ํฐ๋ฆฌ์๋ฅด
์ด ๋ฌธ์ ๋ฅผ ์์ ๋ก ๋๋๋ฆด ๊ธฐํ๊ฐ ์์ต๋๊น? ์ ์ด๋ ์ถ๋ ฅ ์ง์ฝ์ ์ธ ํ๋ก๊ทธ๋จ์ ๊ฒฝ์ฐ ํฐ๋ฏธ๋ ๋ฐ์ดํฐ๋ฅผ ์ ์งํ๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ๋ง์ ๋ฉ๋ชจ๋ฆฌ์ ์๊ฐ์ ์ ์ฝํ ์ ์์ต๋๋ค. 2/3/4์ ์ผ๋ถ ํ์ด๋ธ๋ฆฌ๋๋ ์
๋ ฅ ๋ฌธ์์ด์ ๋จ์ผ ๋ฌธ์๋ฅผ ๋ถํ ํ๊ณ ์ ์ฅํ๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์๋ค๋ฉด ์์ฒญ๋ ์ฒ๋ฆฌ๋ ํฅ์์ ์ ๊ณตํฉ๋๋ค. ๋ํ ์์ฑ์ด ๋ณ๊ฒฝ๋ ํ์๋ง ์ ์ฅํ๋ฉด ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ฝํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค.
์์:
์๋ก์ด ํ์๋ฅผ ์ฌ์ฉํ๋ฉด ์์ฑ์ ์ด์ง๋ฝํ์ง ์๊ณ ์
๋ ฅ ๋ฌธ์๋ฅผ ์ ์ฅํ ์ ์์ต๋๋ค. ์๋ํ๋ฉด ํด๋น ๋ฌธ์์ด์ ์ค๊ฐ์ ๋ณ๊ฒฝ๋์ง ์๋๋ค๋ ๊ฒ์ ์๊ณ ์๊ธฐ ๋๋ฌธ์
๋๋ค. ํด๋น ๋ฌธ์์ด์ ์์ฑ์ wcwidth(์, ์ค ๋ฐ๊ฟ์ ์ฐพ์ผ๋ ค๋ฉด ์ฌ์ ํ ํ์ํจ) ๋ฐ ์ค ๋ฐ๊ฟ ๋ฐ ์ค์ง์ ํจ๊ป ๋ค๋ฅธ ๋ฐ์ดํฐ ๊ตฌ์กฐ ๋๋ ์์ฑ์ ์ ์ฅํ ์ ์์ต๋๋ค. ์ด๊ฒ์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฐ์ดํฐ๊ฐ ์์ ๋ ๋ ์
๋ชจ๋ธ์ ํฌ๊ธฐํฉ๋๋ค.
๋ฌธ์ ๋ ํฐ๋ฏธ๋ ๋ฐ์ดํฐ์ ๋๋ฆด๋ค์ด ํํ(์: ๋ ๋๋ฌ ๋๋ ์ผ๋ถ ์ด์ค์ผ์ดํ ์ํ์ค/์ฌ์ฉ์๊ฐ ์ปค์๋ฅผ ์ด๋ํ๋ ค๋ ๊ฒฝ์ฐ)์ด ์์๋์ด ๋ฐ์ํฉ๋๋ค. ๊ทธ๋ฐ ์ผ์ด ๋ฐ์ํ๋ฉด ์ฌ์ ํ ์
๊ณ์ฐ์ ์ํํด์ผ ํ์ง๋ง ํฐ๋ฏธ๋ cols ๋ฐ rows ๋ด์ ๋ด์ฉ์ ๋ํด์๋ง ์ด ์์
์ ์ํํ๋ ๊ฒ์ผ๋ก ์ถฉ๋ถํด์ผ ํฉ๋๋ค. (์คํฌ๋กค๋ ์ฝํ
์ธ ์ ๋ํด์๋ ์์ง ํ์คํ์ง ์์ผ๋ฏ๋ก ๋ ์บ์์ ์ ์ฅํ ์ ์๊ณ ๋ค์ ๊ทธ๋ฆฌ๋ ๋น์ฉ์ด ์ ๋ ดํ ์ ์์ต๋๋ค.)
@jerch 2์ฃผ ํ์ ์ธ์ ๊ฐ ํ๋ผํ์์ @mofux๋ฅผ ๋ง๋ ์์ ์ด๋ฉฐ ์ด๋ฅผ ๋ค๋ฃจ๋ ํ ์คํธ ์์ฑ์ด ์ฒ๋ฆฌ๋๋ ๋ฐฉ์์ ๋ํ ๋ด๋ถ ๊ฐ์ ์์ ์ ์์/์์ํ ์์ ์ ๋๋ค ๐
https://github.com/xtermjs/xterm.js/pull/1460#issuecomment -390500944์์
๋ชจ๋ ๋ฌธ์๊ฐ ๋ ๋ฒ ํ๊ฐ๋์ด์ผ ํ๊ธฐ ๋๋ฌธ์ ์๊ณ ๋ฆฌ์ฆ์ ๋ค์ ๋น์๋๋ค.
@jerch ๋ฒํผ์์ ๋ ๋น ๋ฅธ ํ
์คํธ ์ก์ธ์ค์ ๋ํ ์์ด๋์ด๊ฐ ์์ผ๋ฉด ์๋ ค์ฃผ์ญ์์ค. ํ์ฌ ๋๋ถ๋ถ์ ์๋ค์ํผ ๋จ์ผ ๋ฌธ์์ด์ง๋ง ArrayBuffer
, ๋ฌธ์์ด ๋ฑ์ด ๋ ์ ์์ต๋๋ค. ์ ๋ ์ฐ๋ฆฌ๊ฐ ์ด๋ป๊ฒ๋ ๋ณ๊ฒฝํ ์ ์๋ ์คํฌ๋กค๋ฐฑ์ ์ด์ ์ ๋ ํ์ฉํ๋ ๊ฒ์ ๋ํด ์๊ฐํด์ผ ํ๋ค๊ณ ์๊ฐํ์ต๋๋ค.
๊ธ์, ๋๋ ๊ณผ๊ฑฐ์ ArrayBuffers๋ก ๋ง์ ๊ฒ์ ์คํํ์ต๋๋ค.
Array
๋ณด๋ค ์ฝ๊ฐ ๋์ฉ๋๋ค(์์ง ๊ณต๊ธ์
์ฒด์ ์ํด ์ต์ ํ๋์ง ์์ ์ ์์)new UintXXArray
๋ []
์ฌ์ฉํ ๋ฆฌํฐ๋ด ๋ฐฐ์ด ์์ฑ๋ณด๋ค ํจ์ฌ ๋์ฉ๋๋ค.TextEncoder
๋ถ๋ถ์ ์ผ๋ก ๊ฐ๋ฅ).ArrayBuffer
์ ๋ํ ๋ด ๋ฐ๊ฒฌ์ ๋ณํ ํจ๋ํฐ๋ก ์ธํด ๋ฌธ์์ด ๋ฐ์ดํฐ์ ์ฌ์ฉํ์ง ์๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ด๋ก ์ ์ผ๋ก ํฐ๋ฏธ๋์ node-pty์์ ํฐ๋ฏธ๋ ๋ฐ์ดํฐ๊น์ง ArrayBuffer
๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค(์ด๋ ํ๋ก ํธ์๋๋ก ๊ฐ๋ ๋์ค์ ์ฌ๋ฌ ๋ณํ์ ์ ์ฅํ ์ ์์). ๋ ๋๋ง์ด ๊ทธ๋ฐ ์์ผ๋ก ์ํ๋ ์ ์๋์ง ํ์คํ์ง ์์ ๊ฒฝ์ฐ ํญ์ ์ต์ข
uint16_t
์์ string
๋ก์ ๋ณํ์ด ํ์ํฉ๋๋ค. ๊ทธ๋ฌ๋ ๋ง์ง๋ง ๋ฌธ์์ด ์์ฑ์ ์ ์ฅ๋ ๋ฐํ์์ ๋๋ถ๋ถ์ ๋จน์ด์น์ฐ๊ณ ํฐ๋ฏธ๋์ ๋ด๋ถ์ ์ผ๋ก ์ถ์
ํ C-ish ์ง์น์ผ๋ก ๋ง๋ค ๊ฒ์
๋๋ค. ๋ฐ๋ผ์ ๋๋ ์ด ์ ๊ทผ ๋ฐฉ์์ ํฌ๊ธฐํ์ต๋๋ค.
TL;DR ArrayBuffer
๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ๋ฏธ๋ฆฌ ํ ๋นํ๊ณ ์ฌ์ฌ์ฉํ ์ ์๋ค๋ฉด ๋ ์ข์ต๋๋ค. ๋ค๋ฅธ ๋ชจ๋ ๊ฒฝ์ฐ์๋ ์ผ๋ฐ ๋ฐฐ์ด์ด ๋ ์ข์ต๋๋ค. ๋ฌธ์์ด์ ArrayBuffers์ ์์ถํ ๊ฐ์น๊ฐ ์์ต๋๋ค.
๋ด๊ฐ ์๊ฐํด ๋ธ ์๋ก์ด ์์ด๋์ด๋ ๊ฐ๋ฅํ ํ ๋ฌธ์์ด ์์ฑ์ ์ค์ด๋ ค๋ ์๋์
๋๋ค. ๋ถ์พํ ๋ถํ ๋ฐ ์กฐ์ธ์ ํผํ๋ ค๊ณ ํฉ๋๋ค. ์๋ก์ด InputHandler.print
๋ฉ์๋, wcwidth ๋ฐ line stop์ ์ผ๋์ ๋๊ณ ์์ ๋ ๋ฒ์งธ ์์ด๋์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํฉ๋๋ค.
print
์ด์ ์ฌ๋ฌ ํฐ๋ฏธ๋ ๋ผ์ธ๊น์ง ์ ์ฒด ๋ฌธ์์ด์ ๊ฐ์ ธ์ต๋๋ค.wcwidth(string) % cols
๋งํผ ์ปค์ ์ด๋\n
(ํ๋ ์ค ๋ฐ๊ฟ): ์ปค์๋ฅผ ํ ์ค ์์ผ๋ก ์ด๋, ํฌ์ธํฐ ๋ชฉ๋ก์ ์์น๋ฅผ โโํ๋ ์ค ๋ฐ๊ฟ์ผ๋ก ํ์\r
: ๋ง์ง๋ง ์ค ๋ด์ฉ(ํ์ฌ ์ปค์ ์์น์์ ๋ง์ง๋ง ์ค ๋ฐ๊ฟ๊น์ง)์ ์ผ๋ถ ์ค ๋ฒํผ์ ๋ก๋ํ์ฌ ๋ฎ์ด์๋๋ค.\r
์ผ์ด์ค์๋ ๋ถ๊ตฌํ๊ณ ์์ ๊ฐ์ด ๋ฐ์ดํฐ๊ฐ ํ๋ฆ
๋๋ค. ์
์ถ์ํ๋ ๋ฌธ์์ด ๋ถํ ์ด ํ์ํ์ง ์์ต๋๋ค.cols
x rows
ํํ์ ์์ฒญํ์ง ์๋ ํ ์์ฑ ๋ณ๊ฒฝ์ ๋ฌธ์ ๊ฐ ๋์ง ์์ต๋๋ค(์ ์ฒด ๋ฌธ์์ด๊ณผ ํจ๊ป ์ ์ฅ๋๋ attr ํ๋๊ทธ๋ง ๋ณ๊ฒฝํจ).Btw wcwidths๋ ์์ ์๊ณ ๋ฆฌ์ฆ์ ํ์ ์งํฉ์ด๋ฏ๋ก ๋ฏธ๋์ ์๋ก ๋ฐ๊ฟ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ด์ ์ํํ ๋ถ๋ถ 1 - ๋๊ตฐ๊ฐ cols
x rows
๋ด์์ ์ปค์๋ฅผ ์ด๋ํ๋ ค๊ณ ํฉ๋๋ค.
cols
์ค๋ฐ๊ฟ์์ ๋ค๋ก ์ด๋ - ํ์ฌ ํฐ๋ฏธ๋ ๋ด์ฉ์ ์์์ด์ ์ํํ ๋ถ๋ถ 2 - ๋ ๋๋ฌ๊ฐ ๋ฌด์ธ๊ฐ๋ฅผ ๊ทธ๋ฆฌ๊ธฐ๋ฅผ ์ํฉ๋๋ค.
์ฅ์ :
InputHandler
๋ฐฉ๋ฒ์ ์ต์ ํ๋จ - print
๋จ์ :
InputHandler
๋ฐฉ๋ฒ์ ์ด ํ๋ฆ ๋ชจ๋ธ์ ์ค๋จํ๊ณ ์ค๊ฐ ์
์ถ์ํ๊ฐ ํ์ํ๋ค๋ ์๋ฏธ์์ ์ํํฉ๋๋ค.๊ธ์, ์ด๊ฒ์ ๋ง์ ์ธ๋ถ ์ฌํญ์ด ์์ง ๋ค๋ฃจ์ด์ง์ง ์์๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ ๊ฐ๋ฅํ atm๊ณผ๋ ๊ฑฐ๋ฆฌ๊ฐ ๋จผ ์์ด๋์ด์ ๋๋ต์ ์ธ ์ด์์ ๋๋ค. ํนํ "์ํํ" ๋ถ๋ถ์ ๋ง์ ์ฑ๋ฅ ๋ฌธ์ ๋ก ์ธํด ๋ถ์พํด์ง ์ ์์ต๋๋ค(์: ๋ ๋์ gc ๋์ ๋ฑ์ผ๋ก ๋ฒํผ ์ฑ๋ฅ ์ ํ).
@jerch
๋ฌธ์์ด์ ArrayBuffers์ ์์ถํ ๊ฐ์น๊ฐ ์์ต๋๋ค.
Monaco๋ ArrayBuffer
s์ ๋ฒํผ๋ฅผ ์ ์ฅํ๊ณ ๊ฝค ๊ณ ์ฑ๋ฅ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์์ง ๊ตฌํ์ ๋ํด ์์ธํ ์ดํด๋ณด์ง๋ ์์์ต๋๋ค.
ํนํ ๋ถ์พํ ๋ถํ ๋ฐ ์กฐ์ธ์ ํผํ๋ ค๊ณ ํฉ๋๋ค.
์ด๋ ๊ฒ?
์ ๋ ์คํฌ๋กค๋ฐฑ์ด ์ด๋ป๊ฒ๋ ๋ถ๋ณ์ด๋ผ๋ ์ด์ ์ ๋ ๋ง์ด ํ์ฉํ๋ ๊ฒ์ ๋ํด ์๊ฐํด์ผ ํ๋ค๊ณ ์๊ฐํ์ต๋๋ค.
ํ ๊ฐ์ง ์์ด๋์ด๋ ๋ทฐํฌํธ ์น์
์์ ์คํฌ๋กค๋ฐฑ์ ๋ถ๋ฆฌํ๋ ๊ฒ์ด์์ต๋๋ค. ์ค์ด ์คํฌ๋กค๋ฐฑ์ผ๋ก ์ด๋ํ๋ฉด ์คํฌ๋กค๋ฐฑ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ก ํธ์๋ฉ๋๋ค. 2๊ฐ์ CircularList
๊ฐ์ฒด๋ฅผ ์์ํ ์ ์์ต๋๋ค. ํ๋๋ ๋ผ์ธ์ด ์ ๋ ๋ณ๊ฒฝ๋์ง ์๋๋ก ์ต์ ํ๋๊ณ ๋ค๋ฅธ ํ๋๋ ๊ทธ ๋ฐ๋์
๋๋ค.
@Tyriar ์คํฌ๋กค
@ํฐ๋ฆฌ์๋ฅด
๋ณํ์ ํ๋๋ก ์ ํํ ์ ์๋ค๋ฉด ArrayBuffer์ ๋ฌธ์์ด์ ์ ์ฅํ๋ ๊ฒ์ด ํฉ๋ฆฌ์ ์
๋๋ค. ๊ทธ๊ฒ์ ๋ชจ๋ ๊ณณ์์ ๋ฌธ์์ด์ ์ฒ๋ฆฌํ๋ ๊ฒ๋ณด๋ค ์ฝ๊ฐ ๋ซ์ต๋๋ค. ์ด๊ฒ์ node-pty๊ฐ ์์ ๋ฐ์ดํฐ๋ ์ ๊ณตํ ์ ์๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฅํฉ๋๋ค(๋ํ websocket๋ ์์ ๋ฐ์ดํฐ๋ฅผ ์ ๊ณตํ ์ ์์).
ํนํ ๋ถ์พํ ๋ถํ ๋ฐ ์กฐ์ธ์ ํผํ๋ ค๊ณ ํฉ๋๋ค.
์ด๋ ๊ฒ?
์ ์ฒด ์ ๊ทผ ๋ฐฉ์์ _minimize_ ๋ถํ ์ ์ ํ ํผํ๋ ๊ฒ ์
๋๋ค. ์๋ฌด๋ ๋ฒํผ๋ง๋ ๋ฐ์ดํฐ๋ก ์ปค์ ์ ํ๋ฅผ ์์ฒญํ์ง ์์ผ๋ฉด ๋ฌธ์์ด์ด ๋ถํ ๋์ง ์๊ณ ๋ ๋๋ฌ๋ก ๋ฐ๋ก ์ด๋ํ ์ ์์ต๋๋ค(์ง์๋๋ ๊ฒฝ์ฐ). ์
๋ถํ ๋ฐ ๋์ค์ ์กฐ์ธ์ด ์ ํ ์์ต๋๋ค.
@jerch ๊ธ์, ๋ทฐํฌํธ๊ฐ ํ์ฅ๋๋ฉด ํ ์ ์์ต๋๋ค. ์ค์ ์ญ์ ํ ๋ ์คํฌ๋กค๋ฐฑ์ ๊ฐ์ ธ์ฌ ์๋ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๊ฒ์ด ์ฌ๋ฐ๋ฅธ ํ๋์ธ์ง 100% ํ์ ํ ์๋ ์์ต๋๋ค.
@Tyriar ์ ๋ง๋ค. ํ์๋ ํ์คํ์ง ์์ง๋ง ๊ธฐ๋ณธ xterm์ ์ค์ ๋ง์ฐ์ค ๋๋ ์คํฌ๋กค ๋ง๋ ์คํฌ๋กค์๋ง ์ด๋ฅผ ํ์ฉํ๋ค๊ณ ์๊ฐํฉ๋๋ค. SD/SU์กฐ์ฐจ๋ ์คํฌ๋กค ๋ฒํผ ์ฝํ ์ธ ๋ฅผ "ํ์ฑ" ํฐ๋ฏธ๋ ๋ทฐํฌํธ๋ก ๋ค์ ์ด๋ํ์ง ์์ต๋๋ค.
ArrayBuffer๊ฐ ์ฌ์ฉ๋๋ monaco ํธ์ง๊ธฐ์ ์์ค๋ฅผ ์๋ ค ์ฃผ์๊ฒ ์ต๋๊น? ๋ด๊ฐ ์ง์ ์ฐพ์ ์ ์๋ ๊ฒ ๊ฐ์ต๋๋ค : ํ๋น๋ฌด:
ํ ๊ทธ๋ฅ TextEncoder/Decoder ์ฌ์์ ๋ค์ ์ฝ๊ณ node-pty์์ ํ๋ก ํธ์๋๊น์ง ArrayBuffers๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ ์์ ์์ ์ด๋ ค์ด ๋ฐฉ์์ผ๋ก ๋ฒ์ญํ์ง ์๋ ํ ๊ธฐ๋ณธ์ ์ผ๋ก utf-8์ ๊ณ ์ ๋์ด ์์ต๋๋ค. xterm.js utf-8์ ์ธ์ํ๊ฒ ๋ง๋์๊ฒ ์ต๋๊น? Idk, ์ด๊ฒ์ ๋ ๋์ ์ ๋์ฝ๋ ๋ฌธ์์ ๋ํ ๋ง์ ์ค๊ฐ ์ฝ๋ ํฌ์ธํธ ๊ณ์ฐ์ ํฌํจํฉ๋๋ค. Proside - ASCII ๋ฌธ์์ ๋ํ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ฝํฉ๋๋ค.
@rebornix monaco๊ฐ ๋ฒํผ๋ฅผ ์ ์ฅํ๋ ์์น์ ๋ํ ํฌ์ธํฐ๋ฅผ ์ค ์ ์์ต๋๊น?
๋ค์์ ์ ํ์ด ์ง์ ๋ ๋ฐฐ์ด๊ณผ ์ ํ์์ ๋ํ ๋ช ๊ฐ์ง ์ซ์์ ๋๋ค(์ฑํํ๊ธฐ ๋ ์ฌ์).
print
์์
์ด 190MB/s์์ 290MB/s๋ก ์ ํํฉ๋๋ค.print
์์
์ด 190MB/s์์ 320MB/s๋ก ์ ํํฉ๋๋ค.์ ๋ฐ์ ์ผ๋ก UTF-16์ด ํจ์ฌ ๋ ๋์ ์ฑ๋ฅ์ ๋ณด์ด์ง๋ง ํ์๊ฐ ์ด์ ์ต์ ํ๋์ด ์๊ธฐ ๋๋ฌธ์ ์์ํ๋ ๊ฒ์ ๋๋ค. UTF-8์ ์ค๊ฐ ์ฝ๋ ํฌ์ธํธ ๊ณ์ฐ์ ์ด๋ ค์์ ๊ฒช์ต๋๋ค.
๋ฌธ์์ด์์ ํ์ํ๋ ๋ฐฐ์ด๋ก์ ๋ณํ์ ๋ด ๋ฒค์น๋งํฌ ls -lR /usr/lib
์ JS ๋ฐํ์์ ~4% ์๋ชจํฉ๋๋ค( InputHandler.parse
๋ฃจํ๋ฅผ ํตํด ์ํ๋๋ ํญ์ 100ms ๋ฏธ๋ง). ๋๋ ์ญ๋ณํ์ ํ
์คํธํ์ง ์์๋ค(์ด๊ฒ์ ์๋ฌต์ ์ผ๋ก atm in InputHandller.print
์์ ์
์์ค์ผ๋ก ์ํ๋จ). ์ ์ฒด ๋ฐํ์์ ๋ฌธ์์ด๋ณด๋ค ์ฝ๊ฐ ๋์ฉ๋๋ค(ํ์์ ์ ์ฅ๋ ์๊ฐ์ ๋ณํ ์๊ฐ์ ๋ณด์ํ์ง ์์ต๋๋ค). ๋ค๋ฅธ ๋ถ๋ถ๋ ๋ฐฐ์ด์ ์ธ์ํ๋ ํ์์ธ ๊ฒฝ์ฐ ๋ณ๊ฒฝ๋ ์ ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ํด๋น ์คํฌ๋ฆฐ์ท( ls -lR /usr/lib
ํ
์คํธ):
๋ฌธ์์ด๋ก:
Uint16Array ์ฌ์ฉ:
EscapeSequenceParser.parse
์ฐจ์ด์ ์ ์ ์ํ์ญ์์ค. ์ด๋ ํ์ํ๋ ๋ฐฐ์ด์์ ์ด์ต์ ์ป์ ์ ์์ต๋๋ค(~30% ๋ ๋น ๋ฆ). InputHandler.parse
๋ ๋ณํ์ ์ํํ๋ฏ๋ก ํ์ํ๋ ๋ฐฐ์ด ๋ฒ์ ์์๋ ๋ ๋์ฉ๋๋ค. ๋ํ GC Minor๋ ํ์ํ๋ ๋ฐฐ์ด์ ๋ํด ๋ ๋ง์ ์์
์ ์ํํฉ๋๋ค(๋ฐฐ์ด์ ๋ฒ๋ฆฌ๊ธฐ ๋๋ฌธ์).
ํธ์ง: ์คํฌ๋ฆฐ์ท์์ ๋ ๋ค๋ฅธ ์ธก๋ฉด์ ๋ณผ ์ ์์ต๋๋ค. GC๋ ~20% ๋ฐํ์๊ณผ ๊ด๋ จ๋๊ณ ์ฅ๊ธฐ ์คํ ํ๋ ์(๋นจ๊ฐ์ ํ๋๊ทธ)์ ๋ชจ๋ GC์ ๊ด๋ จ๋ฉ๋๋ค.
๋ ๋ค๋ฅธ ๋ค์ ๊ธ์ง์ ์ธ ์์ด๋์ด:
int8
์์ int16
์์ int32
๋ก 4๊ฐ์ ํฌ๋ช
์ค์์น์ ๋ฐฐ์์ธ ๊ฒฝ์ฐ ์ ํ์ด ๊ฐ๋ฅํฉ๋๋ค. ํ ๋น์๋ Uint8Array
์์ ์ฌ์ฉ ๊ฐ๋ฅํ ์ธ๋ฑ์ค๋ฅผ ๋ฐํํฉ๋๋ค. ์ด ํฌ์ธํฐ๋ ๊ฐ๋จํ ๋นํธ ์ด๋์ ์ํด Uint16Array
๋๋ Uint32Array
์์น๋ก ๋ณํ๋ ์ ์์ต๋๋ค.uint16_t
์ ํ์ผ๋ก ๋ฉ๋ชจ๋ฆฌ์ ์๋๋ค.InputHandler
๋ฉ์๋๋ฅผ ํธ์ถํฉ๋๋ค.struct Cell {
uint32_t *char_start; // start pointer of cell content (JS with pointers hurray!)
uint8_t length; // length of content (8 bit here is sufficient)
uint32_t attr; // text attributes (might grow to hold true color someday)
uint8_t width; // wcwidth (maybe merge with other member, always < 4)
..... // some other cell based stuff
}
์ฅ์ :
malloc
๋ฐ free
๋น์ฉ์ด ๊ฑฐ์ ์์(ํ ๋น์/ํ ๋น์์ ์๋ฆฌํจ์ ๋ฐ๋ผ ๋ค๋ฆ)๋จ์ :
:์๋ค:
๊ตฌํํ๊ธฐ ์ด๋ ค์ด ์ฌ๋ฏธ, ๋ชจ๋ ๊ฒ์ด ๋ณ๊ฒฝ๋ฉ๋๋ค ๐
์ด๊ฒ์ Monaco๊ฐ ์๋ํ๋ ๋ฐฉ์์ ๋ ๊ฐ๊น์ต๋๋ค. ์บ๋ฆญํฐ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ธฐ ์ํ ์ ๋ต์ ๋ ผ์ํ๋ ์ด ๋ธ๋ก๊ทธ ๊ฒ์๋ฌผ์ ๊ธฐ์ตํ์ต๋๋ค. https://code.visualstudio.com/blogs/2017/02/08/syntax-highlighting-optimizations
๋ค ๊ธฐ๋ณธ์ ์ผ๋ก ๊ฐ์ ์๊ฐ์ ๋๋ค.
monaco๊ฐ ๋ฒํผ๋ฅผ ์ ์ฅํ๋ ์์น์ ๋ํ ๋ด ๋๋ต์ด ๋๋ฌด ๋ฆ์ง ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
Alex์ ์ ๋ Array Buffer๋ฅผ ์ ํธํ๋ฉฐ ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์ฐ์ํ ์ฑ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ArrayBuffer๋ฅผ ์ฌ์ฉํ๋ ์ผ๋ถ ์ฅ์:
V8 ๋ฌธ์์ด์ ์กฐ์ํ๊ธฐ ์ฝ๊ธฐ ๋๋ฌธ์ ๋ฐฐ์ด ๋ฒํผ ๋์ ํ ์คํธ ๋ฒํผ์ ๊ฐ๋จํ ๋ฌธ์์ด์ ์ฌ์ฉํฉ๋๋ค.
์ปค๋ฐ์ด ์ถ๊ฐ๋ ๋ ๊นจ์ง์ง ์๋๋ก @rebornix ์ ๋งํฌ๋ฅผ ๊ณ ์
๋ค์ ๋ชฉ๋ก์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ๋ฐ/๋๋ ๋ฐํ์์ ์ค์ด๋ ๋ฐ ๋์์ด ๋ ์ ์๋ ํฅ๋ฏธ๋ก์ด ๊ฐ๋ ์ ๊ฐ๋ตํ๊ฒ ์์ฝํ ๊ฒ์ ๋๋ค.
์ฌ๊ธฐ์์ ํฉ๊ณ๋ฅผ ๊ตฌํ๋ ค๋ฉด ํ ์คํธ ์์ฑ์ "๋ณํฉ"ํ ์ ์๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
์ฝ๋๋ ์ฃผ๋ก ๋ฒํผ ๋ฐ์ดํฐ์ ๋ํ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ฝํ๋ค๋ ์์ด๋์ด์ ์ํด ์ฃผ๋๋ฉ๋๋ค(๋ฐํ์์ ๋ฌธ์ ๊ฐ ๋ ๊ฒ์ด๋ฉฐ, ์์ง ํ
์คํธ๋์ง๋ ์์์ต๋๋ค). ํนํ ์ ๊ฒฝ๊ณผ ๋ฐฐ๊ฒฝ์ ๋ํด RGB๊ฐ ์๋ ํ
์คํธ ์์ฑ(ํ ๋ฒ ์ง์๋จ)์ xterm.js๊ฐ ์
๋ ์ด์์๋ณ๋ก ํ์ฌ ์
์ ์ํด ๋ง์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋จน๊ฒ ๋ง๋ค ๊ฒ์
๋๋ค. ์ด ์ฝ๋๋ ์์ฑ์ ๋ํ ํฌ๊ธฐ ์กฐ์ ๊ฐ๋ฅํ ์ฐธ์กฐ ๊ณ์ฐ ์ํ๋ผ์ค๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฅผ ์ฐํํ๋ ค๊ณ ํฉ๋๋ค. ๋จ์ผ ํฐ๋ฏธ๋์ ๊ฑฐ์ 1๋ฐฑ๋ง ๊ฐ ์ด์์ ์
์ ๋ณด์ ํ ์ ์์ผ๋ฏ๋ก ๋ชจ๋ ์
์ด ๋ค๋ฅธ ๊ฒฝ์ฐ ์ํ๋ผ์ค๊ฐ 1M * entry_size
์ฆ๊ฐํ๋ฏ๋ก ์ด๊ฒ์ ์ต์
์ด ์๋๋๋ค.
์ ์์ฒด๋ ์์ฑ ์ํ๋ผ์ค์ ์ธ๋ฑ์ค๋ฅผ ๋ณด์ ํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค. ์ ๋ณ๊ฒฝ ์ ์ด์ ์ธ๋ฑ์ค๋ฅผ ์ฐธ์กฐ ํด์ ํ๊ณ ์ ์ธ๋ฑ์ค๋ฅผ ์ฐธ์กฐํด์ผ ํฉ๋๋ค. ์ํ๋ผ์ค ์ธ๋ฑ์ค๋ ํฐ๋ฏธ๋ ๊ฐ์ฒด์ ์์ฑ ์์ฑ์ ๋์ฒดํ๊ณ SGR์์ ์์ฒด์ ์ผ๋ก ๋ณ๊ฒฝ๋ฉ๋๋ค.
์ํ๋ผ์ค๋ ํ์ฌ ํ ์คํธ ์์ฑ๋ง ๋ค๋ฃจ์ง๋ง ํ์ํ ๊ฒฝ์ฐ ๋ชจ๋ ์ ์์ฑ์ผ๋ก ํ์ฅ๋ ์ ์์ต๋๋ค. ํ์ฌ ํฐ๋ฏธ๋ ๋ฒํผ๊ฐ ์์ฑ ๋ฐ์ดํฐ์ ๋ํด 2๊ฐ์ 32๋นํธ ์ซ์(ํ์ฌ ๋ฒํผ ๋์์ธ์์ RGB๊ฐ ์๋ 4๊ฐ)๋ฅผ ๋ณด์ ํ๋ ๋์ ์ํ๋ผ์ค๋ ์ด๋ฅผ ๋จ ํ๋์ 32๋นํธ ์ซ์๋ก ์ค์ ๋๋ค. ์ํ๋ผ์ค ํญ๋ชฉ๋ ์ถ๊ฐ๋ก ํฌ์ฅํ ์ ์์ต๋๋ค.
interface TextAttributes {
flags: number;
foreground: number;
background: number;
}
const enum AtlasEntry {
FLAGS = 1,
FOREGROUND = 2,
BACKGROUND = 3
}
class TextAttributeAtlas {
/** data storage */
private data: Uint32Array;
/** flag lookup tree, not happy with that yet */
private flagTree: any = {};
/** holds freed slots */
private freedSlots: number[] = [];
/** tracks biggest idx to shortcut new slot assignment */
private biggestIdx: number = 0;
constructor(size: number) {
this.data = new Uint32Array(size * 4);
}
private setData(idx: number, attributes: TextAttributes): void {
this.data[idx] = 0;
this.data[idx + AtlasEntry.FLAGS] = attributes.flags;
this.data[idx + AtlasEntry.FOREGROUND] = attributes.foreground;
this.data[idx + AtlasEntry.BACKGROUND] = attributes.background;
if (!this.flagTree[attributes.flags])
this.flagTree[attributes.flags] = [];
if (this.flagTree[attributes.flags].indexOf(idx) === -1)
this.flagTree[attributes.flags].push(idx);
}
/**
* convenient method to inspect attributes at slot `idx`.
* For better performance atlas idx and AtlasEntry
* should be used directly to avoid number conversions.
* <strong i="10">@param</strong> {number} idx
* <strong i="11">@return</strong> {TextAttributes}
*/
getAttributes(idx: number): TextAttributes {
return {
flags: this.data[idx + AtlasEntry.FLAGS],
foreground: this.data[idx + AtlasEntry.FOREGROUND],
background: this.data[idx + AtlasEntry.BACKGROUND]
};
}
/**
* Returns a slot index in the atlas for the given text attributes.
* To be called upon attributes changes, e.g. by SGR.
* NOTE: The ref counter is set to 0 for a new slot index, thus
* values will get overwritten if not referenced in between.
* <strong i="12">@param</strong> {TextAttributes} attributes
* <strong i="13">@return</strong> {number}
*/
getSlot(attributes: TextAttributes): number {
// find matching attributes slot
const sameFlag = this.flagTree[attributes.flags];
if (sameFlag) {
for (let i = 0; i < sameFlag.length; ++i) {
let idx = sameFlag[i];
if (this.data[idx + AtlasEntry.FOREGROUND] === attributes.foreground
&& this.data[idx + AtlasEntry.BACKGROUND] === attributes.background) {
return idx;
}
}
}
// try to insert into a previously freed slot
const freed = this.freedSlots.pop();
if (freed) {
this.setData(freed, attributes);
return freed;
}
// else assign new slot
for (let i = this.biggestIdx; i < this.data.length; i += 4) {
if (!this.data[i]) {
this.setData(i, attributes);
if (i > this.biggestIdx)
this.biggestIdx = i;
return i;
}
}
// could not find a valid slot --> resize storage
const data = new Uint32Array(this.data.length * 2);
for (let i = 0; i < this.data.length; ++i)
data[i] = this.data[i];
const idx = this.data.length;
this.data = data;
this.setData(idx, attributes);
return idx;
}
/**
* Increment ref counter.
* To be called for every terminal cell, that holds `idx` as text attributes.
* <strong i="14">@param</strong> {number} idx
*/
ref(idx: number): void {
this.data[idx]++;
}
/**
* Decrement ref counter. Once dropped to 0 the slot will be reused.
* To be called for every cell that gets removed or reused with another value.
* <strong i="15">@param</strong> {number} idx
*/
unref(idx: number): void {
this.data[idx]--;
if (!this.data[idx]) {
let treePart = this.flagTree[this.data[idx + AtlasEntry.FLAGS]];
treePart.splice(treePart.indexOf(this.data[idx]), 1);
}
}
}
let atlas = new TextAttributeAtlas(2);
let a1 = atlas.getSlot({flags: 12, foreground: 13, background: 14});
atlas.ref(a1);
// atlas.unref(a1);
let a2 = atlas.getSlot({flags: 12, foreground: 13, background: 15});
atlas.ref(a2);
let a3 = atlas.getSlot({flags: 13, foreground: 13, background: 16});
atlas.ref(a3);
let a4 = atlas.getSlot({flags: 13, foreground: 13, background: 16});
console.log(atlas);
console.log(a1, a2, a3, a4);
console.log('a1', atlas.getAttributes(a1));
console.log('a2', atlas.getAttributes(a2));
console.log('a3', atlas.getAttributes(a3));
console.log('a4', atlas.getAttributes(a4));
ํธ์งํ๋ค:
๋ฐํ์ ํจ๋ํฐ๋ ๊ฑฐ์ 0์
๋๋ค. ls -lR /usr/lib
์ฌ์ฉํ ๋ฒค์น๋งํฌ์ ๊ฒฝ์ฐ ~2.3์ด์ ์ด ๋ฐํ์์ 1๋ฐ๋ฆฌ์ด ๋ฏธ๋ง์ ์ถ๊ฐํฉ๋๋ค. ํฅ๋ฏธ๋ก์ด ์ฐธ๊ณ ์ฌํญ - ์ด ๋ช
๋ น์ 5MB ๋ฐ์ดํฐ ์ถ๋ ฅ์ ์ํด 64๊ฐ ๋ฏธ๋ง์ ๋ค๋ฅธ ํ
์คํธ ์์ฑ ์ฌ๋กฏ์ ์ค์ ํ๊ณ ์์ ํ ๊ตฌํ๋๋ฉด 20MB ์ด์์ ์ ์ฝํฉ๋๋ค.
๋ฒํผ์ ๋ํ ๋ช ๊ฐ์ง ๋ณ๊ฒฝ ์ฌํญ์ ํ ์คํธํ๊ธฐ ์ํด ํ๋กํ ํ์ PR์ ๋ง๋ค์์ต๋๋ค(๋ณ๊ฒฝ ์ฌํญ์ ๋ํ ์ผ๋ฐ์ ์ธ ์์ด๋์ด๋ https://github.com/xtermjs/xterm.js/pull/1528#issue-196949371 ์ฐธ์กฐ).
@jerch "์ํ๋ผ์ค"๊ฐ ํญ์ "ํ ์ค์ฒ ์ํ๋ผ์ค"๋ฅผ ์๋ฏธํ๋๋ก ์ํ๋ผ์ค๋ผ๋ ๋จ์ด๋ฅผ ๋ฉ๋ฆฌํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์คํ ์ด๋ ์บ์ ๊ฐ์ ๊ฒ์ด ๋ ๋์๊น์?
์ค, "์บ์"๋ ๊ด์ฐฎ์ต๋๋ค.
ํ ์คํธ๋ฒ ๋ PR์ ๋๋ฌ์ต๋๋ค. ๋ค์ ๋๋ต์ ์ธ ์์ฝ์ ๋ฐฐ๊ฒฝ์ ์ป์ผ๋ ค๋ฉด PR ๋๊ธ๋ ์ดํด๋ณด์ญ์์ค.
์ ์:
AttributeCache
๋ฅผ ๊ตฌ์ถํฉ๋๋ค. ํธ๋ฃจ ์ปฌ๋ฌ ์ฌ์๋ ํฌํจํ ์ ์๋ ์ด๊ธฐ ์ฐธ์กฐ ์นด์ดํ
๋ฒ์ ์ #1528์ ์ฐธ์กฐํ์ญ์์ค. ์ฌ๋ฌ ํฐ๋ฏธ๋ ์ฑ์์ ์ถ๊ฐ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ฅํด์ผ ํ๋ ๊ฒฝ์ฐ ๋ค๋ฅธ ํฐ๋ฏธ๋ ์ธ์คํด์ค ๊ฐ์ ์บ์๋ฅผ ๊ณต์ ํ ์๋ ์์ต๋๋ค.StringStorage
๋ฅผ ๋น๋ํฉ๋๋ค. #1530์ ๋ฒ์ ์ ํฌ์ธํฐ ์๋ฏธ๋ฅผ "์ค๋ฒ๋ก๋"ํ์ฌ ๋จ์ผ ๋ฌธ์ ๋ฌธ์์ด์ ์ ์ฅํ๋ ๊ฒ์ ๋ฐฉ์งํฉ๋๋ค. wcwidth
๋ ์ฌ๊ธฐ๋ก ์ฎ๊ฒจ์ผ ํฉ๋๋ค.CharData
๋ฅผ [number, string, number, number]
์์ [number, number]
์ถ์ํฉ๋๋ค. ์ฌ๊ธฐ์ ์ซ์๋ ๋ค์์ ๋ํ ํฌ์ธํฐ(์ธ๋ฑ์ค ๋ฒํธ)์
๋๋ค.AttributeCache
ํญ๋ชฉStringStorage
ํญ๋ชฉ์์ฑ์ ๋ง์ด ๋ณ๊ฒฝ๋์ง ์์ ๊ฒ์ด๋ฏ๋ก ๋จ์ผ 32๋นํธ ์ซ์๋ ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ๋ง์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ฝํฉ๋๋ค. StringStorage
ํฌ์ธํฐ๋ ๋จ์ผ ๋ฌธ์์ ๋ํ ์ค์ ์ ๋์ฝ๋ ์ฝ๋ํฌ์ธํธ์ด๋ฏ๋ก CharData
์ code
ํญ๋ชฉ์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ค์ ๋ฌธ์์ด์ StringStorage.getString(idx)
๋ก ์ก์ธ์คํ ์ ์์ต๋๋ค. ๋ค๋ฒ์งธ ํ๋ wcwidth
์ CharData
์ก์ธ์ค ํ ์ StringStorage.wcwidth(idx)
(์์ง ๊ตฌํ๋์ง ์์). ์น์ฐ๋์์ ๊ฑฐ์ ๋ฐํ์ ๋ฒ๊ธ์ด code
๊ณผ wcwidth
์์ CharData
(# 1529์์ ํ
์คํธ๊ฐ).
CharData
๋ฅผ ๊ณ ๋ฐ๋ Int32Array
๊ธฐ๋ฐ ๋ฒํผ ๊ตฌํ์ผ๋ก ์ด๋ํฉ๋๋ค. ์คํ
ํด๋์ค(์์ ํ ๊ธฐ๋ฅ๊ณผ๋ ๊ฑฐ๋ฆฌ๊ฐ ๋ฉ์)๋ก #1530์์ ํ
์คํธํ ๊ฒฐ๊ณผ ์ต์ข
์ด์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.ls -lR /usr/lib
์คํฌ๋ฆฝํธ ๋ฐํ์์ด 1.3์ด๋ก ๋จ์ด์ก์ต๋๋ค(๋ง์คํฐ๋ 2.1์ด์). ์ด์ ๋ฒํผ๋ ์ปค์ ์ฒ๋ฆฌ๋ฅผ ์ํด ์ฌ์ ํ ํ์ฑํ๋์ด ์์ต๋๋ค. ์ ๊ฑฐ๋๋ฉด ๋ฐํ์์ด 1์ด ๋ฏธ๋ง์ผ๋ก ๋จ์ด์ง ๊ฒ์ผ๋ก ์์๋ฉ๋๋ค.๋จ์ - 4๋จ๊ณ๋ ๋ฒํผ ์ธํฐํ์ด์ค์์ ์ฝ๊ฐ์ ์ฌ์์ ์ด ํ์ํ๊ธฐ ๋๋ฌธ์ ์๋นํ ๋ง์ ์์ ์ ๋๋ค. ๊ทธ๋ฌ๋ ์ด๋ด - RAM์ 80%๋ฅผ ์ ์ฝํ๊ณ ์ฌ์ ํ ๋ฐํ์ ์ฑ๋ฅ์ ์ป๋ ๋ฐ๋ ํฐ ๋ฌธ์ ๊ฐ ๋์ง ์์ต๋๊น? :์๋ค:
๋ด๊ฐ ์ฐ์ฐํ ๋ฐ๊ฒฌํ ๋ ๋ค๋ฅธ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ๋ฐ๋ก ํ์ฌ ๋น ์ ํํ์ ๋๋ค. Imho a cell์ 3๊ฐ์ง ์ํ๋ฅผ ๊ฐ์ง ์ ์์ต๋๋ค.
blankLine
๋ฐ eraseChar
์์ ์ฌ์ฉ๋์ง๋ง ๋ด์ฉ์ผ๋ก ๊ณต๋ฐฑ ์ด ์์ต๋๋ค.์ฌ๊ธฐ์ ๋ด๊ฐ ๋ณผ ์ ์๋ ๋ฌธ์ ๋ ๋น ์
์ด ๊ณต๋ฐฑ์ด ์ฝ์
๋ ์ผ๋ฐ ์
๊ณผ ๊ตฌ๋ณ๋์ง ์๊ณ ๋ฒํผ ์์ค(๋์ผํ ๋ด์ฉ, ๋์ผํ ๋๋น)์์ ๋์ผํ๊ฒ ๋ณด์
๋๋ค. ๋๋ ๋ ๋๋ฌ/์ถ๋ ฅ ์ฝ๋๋ฅผ ์์ฑํ์ง ์์์ง๋ง ์ด๊ฒ์ด ์ถ๋ ฅ ํ๋ก ํธ์์ ์ด์ํ ์ํฉ์ผ๋ก ์ด์ด์ง ๊ฒ์ผ๋ก ์์ํฉ๋๋ค. ํนํ ์ค์ ์ค๋ฅธ์ชฝ ๋์ ์ฒ๋ฆฌํ๋ ๊ฒ์ด ๋ฒ๊ฑฐ๋ก์ธ ์ ์์ต๋๋ค.
15๊ฐ์ ์ด์ด ์๋ ํฐ๋ฏธ๋, ๋จผ์ ์ผ๋ถ ๋ฌธ์์ด ์ถ๋ ฅ์ด ๋ํ๋์์ต๋๋ค.
1: 'H', 'e', 'l', 'l', 'o', ' ', 't', 'e', 'r', 'm', 'i', 'n', 'a', 'l', ' '
2: 'w', 'o', 'r', 'l', 'd', '!', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '
ls
์๋ ํด๋ ๋ชฉ๋ก๊ณผ ๋น๊ต:
1: 'R', 'e', 'a', 'd', 'm', 'e', '.', 'm', 'd', ' ', ' ', ' ', ' ', ' ', ' '
2: 'f', 'i', 'l', 'e', 'A', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '
์ฒซ ๋ฒ์งธ ์๋ 'terminal'์ด๋ผ๋ ๋จ์ด ๋ค์ ์ค์ ๊ณต๋ฐฑ ์ ํฌํจํ๊ณ , ๋ ๋ฒ์งธ ์๋ 'Readme.md' ๋ค์ ์ ์ ๊ฑด๋๋ฆฌ์ง ์์ต๋๋ค. ๋ฒํผ ์์ค์์ ํํ๋๋ ๋ฐฉ์์ ํ์ค ์ผ์ด์ค๊ฐ ํ๋ฉด์ ํฐ๋ฏธ๋ ์ถ๋ ฅ์ผ๋ก ๋ฌผ๊ฑด์ ์ธ์ํ๋ ๋ฐ ์๋ฒฝํ์ง๋ง(์ด์จ๋ ๋ฐฉ์ ๊ฐ์ ธ์์ผ ํจ), ๋ง์ฐ์ค ์ ํ๊ณผ ๊ฐ์ ์ฝํ ์ธ ๋ฌธ์์ด์ ์ฒ๋ฆฌํ๋ ค๋ ๋๊ตฌ์ ๊ฒฝ์ฐ ๋๋ ๋ฆฌํ ๋ก์ฐ ๊ด๋ฆฌ์๋ ๋ ์ด์ ๊ณต๊ฐ์ด ์ด๋์์ ์๋์ง ๋ช ํํ์ง ์์ต๋๋ค.
์ด๊ฒ์ ๋ค์ ์ง๋ฌธ์ผ๋ก ์ด์ด์ง๋๋ค. ์ค์ ์ค์ ๋ด์ฉ ๊ธธ์ด(์ผ์ชฝ์์ ๋ฌด์ธ๊ฐ๋ฅผ ํฌํจํ๋ ์ ์ ์)๋ฅผ ๊ฒฐ์ ํ๋ ๋ฐฉ๋ฒ์ ๋ฌด์์ ๋๊น? ๊ฐ๋จํ ์ ๊ทผ ๋ฐฉ์์ ์ค๋ฅธ์ชฝ์์ ๋น ์ ์ ์ธ๋๋ฐ, ์์ ์ด์ค ์๋ฏธ๋ ์ด๊ฒ์ ๊ฒฐ์ ํ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋ญ๋๋ค.
์ ์:
์ด๊ฒ์ ๋น ์
์ ๋ค๋ฅธ ์๋ฆฌ ํ์์๋ฅผ ์ฌ์ฉํ์ฌ ์ฝ๊ฒ ๊ณ ์น ์ ์์ต๋๋ค(์: ์ ์ด ๋ฌธ์ ๋๋ ๋น ๋ฌธ์์ด). ํ์ํ ๊ฒฝ์ฐ ๋ ๋๋ง ํ๋ก์ธ์ค์์ ๊ต์ฒดํฉ๋๋ค. ํ๋ฉด ๋ ๋๋ฌ๋ ์ด๋ฌํ ์
์ ์ ํ ์ฒ๋ฆฌํ ํ์๊ฐ ์์ ์๋ ์๊ธฐ ๋๋ฌธ์(์ถ๋ ฅ์ด ์์ฑ๋๋ ๋ฐฉ์์ ๋ฐ๋ผ ๋ค๋ฆ) ์ด๋ก๋ถํฐ ์ด์ ์ ์ป์ ์๋ ์์ต๋๋ค.
Btw, ์์ ๋ํ๋ ๋ฌธ์์ด์ ๊ฒฝ์ฐ isWrapped
๋ฌธ์ ๋ ๋ฐ์ํฉ๋๋ค. ์ด๋ ๋ฆฌํ๋ก์ฐ ํฌ๊ธฐ ์กฐ์ ๋๋ ์ฌ๋ฐ๋ฅธ ๋ณต์ฌ ๋ฐ ๋ถ์ฌ๋ฃ๊ธฐ ์ ํ ์ฒ๋ฆฌ์ ํ์์ ์
๋๋ค. Imho ์ฐ๋ฆฌ๋ ๊ทธ๊ฒ์ ์ ๊ฑฐ ํ ์ ์์ง๋ง at๋ณด๋ค ๋ ์ ํตํฉํด์ผํฉ๋๋ค.
@jerch ์ธ์์ ์ธ ์ํ! : ์ค๋ง์ผ :
1 ๋จ์ผ ํฐ๋ฏธ๋ ์ ์ ์คํ์ผ์ ์ง์ ํ๋ ๋ฐ ํ์ํ ๋ชจ๋ ๊ฒ์ ๋ณด์ ํ๋ AttributeCache๋ฅผ ๊ตฌ์ถํฉ๋๋ค. ํธ๋ฃจ ์ปฌ๋ฌ ์ฌ์๋ ํฌํจํ ์ ์๋ ์ด๊ธฐ ์ฐธ์กฐ ์นด์ดํ ๋ฒ์ ์ #1528์ ์ฐธ์กฐํ์ญ์์ค. ์ฌ๋ฌ ํฐ๋ฏธ๋ ์ฑ์์ ์ถ๊ฐ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ฅํด์ผ ํ๋ ๊ฒฝ์ฐ ๋ค๋ฅธ ํฐ๋ฏธ๋ ์ธ์คํด์ค ๊ฐ์ ์บ์๋ฅผ ๊ณต์ ํ ์๋ ์์ต๋๋ค.
#1528์ ๋ํ ์๊ฒฌ์ ์์ฑํ์ต๋๋ค.
2 ์งง์ ํฐ๋ฏธ๋ ์ฝํ ์ธ ๋ฐ์ดํฐ ๋ฌธ์์ด์ ๋ณด๊ดํ StringStorage๋ฅผ ๊ตฌ์ถํฉ๋๋ค. #1530์ ๋ฒ์ ์ ํฌ์ธํฐ ์๋ฏธ๋ฅผ "์ค๋ฒ๋ก๋"ํ์ฌ ๋จ์ผ ๋ฌธ์ ๋ฌธ์์ด์ ์ ์ฅํ๋ ๊ฒ์ ๋ฐฉ์งํฉ๋๋ค. wcwidth๋ฅผ ์ฌ๊ธฐ๋ก ์ฎ๊ฒจ์ผ ํฉ๋๋ค.
#1530์ ๋ํ ์๊ฒฌ์ ์์ฑํ์ต๋๋ค.
4 ์ถ์๋ CharData๋ฅผ ๋ฐ๋๊ฐ ๋์ Int32Array ๊ธฐ๋ฐ ๋ฒํผ ๊ตฌํ์ผ๋ก ์ด๋ํฉ๋๋ค. ์คํ ํด๋์ค(์์ ํ ๊ธฐ๋ฅ๊ณผ๋ ๊ฑฐ๋ฆฌ๊ฐ ๋ฉ์)๋ก #1530์์ ํ ์คํธํ ๊ฒฐ๊ณผ ์ต์ข ์ด์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์์ง ์ด ์์ด๋์ด๊ฐ ์์ ํ ํ๋ฆฌ์ง๋ ์์์ง๋ง, ์ฐ๋ฆฌ๊ฐ ๋ฆฌํ๋ก์ฐ๋ฅผ ๊ตฌํํ ๋ ์ฐ๋ฆฌ๋ฅผ ํ๋ค๊ฒ ํ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์ด ๊ฐ ๋จ๊ณ๋ฅผ ์์๋๋ก ์ํํ ์ ์์ผ๋ฏ๋ก 3๋จ๊ณ๋ฅผ ์๋ฃํ ํ ์ผ์ด ์ด๋ป๊ฒ ์งํ๋๋์ง ํ์ธํ๊ณ ์ด ์์ ์ ์ํํ๋ ๊ฒ์ด ํ๋นํ์ง ํ์ธํ ์ ์์ต๋๋ค.
๋ด๊ฐ ์ฐ์ฐํ ๋ฐ๊ฒฌํ ๋ ๋ค๋ฅธ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ๋ฐ๋ก ํ์ฌ ๋น ์ ํํ์ ๋๋ค. Imho ์ธํฌ๋ 3๊ฐ์ ์ํ๋ฅผ ๊ฐ์ง ์ ์์ต๋๋ค
๋ค์์ ์ด https://github.com/xtermjs/xterm.js/issues/1286 , :+1: ๊ณต๋ฐฑ ์ ๊ณผ "๋น" ์ ์ ๊ตฌ๋ณํ๋ ๋ฒ๊ทธ์ ์์ ๋๋ค.
Btw, ์์ ๋ํ๋ ๋ฌธ์์ด์ ๊ฒฝ์ฐ์๋ isWrapped ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค. ์ด๋ ๋ฆฌํ๋ก์ฐ ํฌ๊ธฐ ์กฐ์ ๋๋ ์ฌ๋ฐ๋ฅธ ๋ณต์ฌ ๋ฐ ๋ถ์ฌ๋ฃ๊ธฐ ์ ํ ์ฒ๋ฆฌ์ ํ์์ ์ ๋๋ค. Imho ์ฐ๋ฆฌ๋ ๊ทธ๊ฒ์ ์ ๊ฑฐ ํ ์ ์์ง๋ง at๋ณด๋ค ๋ ์ ํตํฉํด์ผํฉ๋๋ค.
CircularList์๋ ๋ํ๋์ง ์์ ํ๋ง ํฌํจ๋๋ฏ๋ก https://github.com/xtermjs/xterm.js/issues/622 ๋ฅผ ์ฒ๋ฆฌํ ๋ isWrapped
์ฌ๋ผ์ง๋ ๊ฒ์ ๋ด
๋๋ค.
์์ง ์ด ์์ด๋์ด๊ฐ ์์ ํ ํ๋ฆฌ์ง๋ ์์์ง๋ง, ์ฐ๋ฆฌ๊ฐ ๋ฆฌํ๋ก์ฐ๋ฅผ ๊ตฌํํ ๋ ์ฐ๋ฆฌ๋ฅผ ํ๋ค๊ฒ ํ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์ด ๊ฐ ๋จ๊ณ๋ฅผ ์์๋๋ก ์ํํ ์ ์์ผ๋ฏ๋ก 3๋จ๊ณ๋ฅผ ์๋ฃํ ํ ์ผ์ด ์ด๋ป๊ฒ ์งํ๋๋์ง ํ์ธํ๊ณ ์ด ์์ ์ ์ํํ๋ ๊ฒ์ด ํ๋นํ์ง ํ์ธํ ์ ์์ต๋๋ค.
์, ์ ๋ ๋น์ ๊ณผ ํจ๊ปํฉ๋๋ค(์ด ์์ ํ ๋ค๋ฅธ ์ ๊ทผ ๋ฐฉ์์ ๊ฐ์ง๊ณ ๋ ธ๋ ๊ฒ์ ์ฌ์ ํ โโ์ฌ๋ฏธ์์ต๋๋ค). 1๊ณผ 2๋ ์ ํ๋ ์ ์๊ณ 3์ 1 ๋๋ 2์ ๋ฐ๋ผ ์ ์ฉ๋ ์ ์์ต๋๋ค. 4๋ ์ ํ ์ฌํญ์ด๋ฉฐ ํ์ฌ ๋ฒํผ ๋ ์ด์์์ ๊ณ ์ํ ์ ์์ต๋๋ค. ๋ฉ๋ชจ๋ฆฌ ์ ์ฝ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
CircularList
: 50% ์ ์ฝ(~5.5MB ์ค ~2.8MB)1. ๊ตฌํํ๊ธฐ๊ฐ ๋งค์ฐ ์ฝ์ต๋๋ค. ๋ ํฐ scrollBack์ ์ฌ์ฉํ๋ ๋ฉ๋ชจ๋ฆฌ ๋์์ https://github.com/xtermjs/xterm.js/pull/1530#issuecomment -403542479์ ํ์๋ ๊ฒ์ฒ๋ผ ์ฌ์ ํ ๋์ ์ค์ผ์ผ๋ง์ ํ์ํ์ง๋ง ๋ ์ ๋
ํ ์์ค์
๋๋ค.
2. ๊ตฌํํ๊ธฐ๊ฐ ์ฝ๊ฐ ๋ ์ด๋ ต์ง๋ง(๋ผ์ธ ์์ค์์ ๋ ๋ง์ ๊ฐ์ ์ฐธ์กฐ๊ฐ ํ์ํจ) Buffer
์ ์์ API๋ฅผ ๊ทธ๋๋ก ์ ์งํ๋ ๊ฒ์ด ๊ฐ๋ฅํฉ๋๋ค. Imho ์ต์
- ํฐ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ฅํ๊ณ ํตํฉํ๊ธฐ ์ฝ์ต๋๋ค.
3. ๊ตฌํํ๊ธฐ ์ด๋ ค์ด ์ต์
2๋ณด๋ค 5% ๋ ๋ง์ ๋ฉ๋ชจ๋ฆฌ ์ ์ฅ์ ๋ชจ๋ API๋ฅผ ๋ณ๊ฒฝํ๋ฏ๋ก ๋ง ๊ทธ๋๋ก ์ ์ฒด ์ฝ๋ ๊ธฐ๋ฐ์ ๋ณ๊ฒฝํฉ๋๋ค. ํ๋ฌธ์ ๊ด์ฌ์ด๋ ์ง๋ฃจํ ๋น์ค๋ ๋ ์ ์ํด ์ํธ๋ฅผ ๋ ๊ตฌํํฉ๋๋ค.
@Tyriar ์น ์ด์ ๋ธ๋ฆฌ ์ฌ์ฉ์ ์ํด ๋ น์ผ๋ก ๋ช ๊ฐ์ง ์ถ๊ฐ ํ ์คํธ๋ฅผ ์ํํ๊ณ ํ์๋ฅผ ๋ค์ ์์ฑํ์ต๋๋ค. ๋ด ๋ น ๊ธฐ์ ์ ์์ง ๋ ๊น์ด ๋ค์ด๊ฐ์ง ์์๊ธฐ ๋๋ฌธ์ ์ฝ๊ฐ "๋ น์ด ์ฌ์์ต๋๋ค". ๋ฐ๋ผ์ ๋ค์์ ์ฝํ ๋ น ์ฝ๋์ ๊ฒฐ๊ณผ์ผ ์ ์์ต๋๋ค. ๊ฒฐ๊ณผ:
์ ์ฒด ํต์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ น(๋๋ ๋ค๋ฅธ wasm ๊ฐ๋ฅ ์ธ์ด)์ผ๋ก ๋ค์ ์์ฑํ์ง ์์ผ๋ ค๋ฉด wasm lang imho๋ก ์ด๋ํ์ฌ ์๋ฌด ๊ฒ๋ ์ป์ ์ ์์ต๋๋ค. ์์ฆ wasm lang์ ์ฅ์ ์ ๋๋ถ๋ถ์ด ๋ช ์์ ๋ฉ๋ชจ๋ฆฌ ์ฒ๋ฆฌ๋ฅผ ์ง์ํ๋ค๋ ์ฌ์ค(๋ฒํผ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐ ๋์์ด ๋ ์ ์์)์ด๊ณ , ๋จ์ ์ ์ฃผ๋ก TS/JS ์ค์ฌ ํ๋ก์ ํธ์ ์์ ํ ๋ค๋ฅธ ์ธ์ด๋ฅผ ๋์ ํ๋ค๋ ๊ฒ์ ๋๋ค(์ฝ๋ ์ถ๊ฐ์ ๋ํ ๋์ ์ฅ๋ฒฝ) ๊ทธ๋ฆฌ๊ณ wasm๊ณผ JS ๋๋ ๊ฐ์ ๋ฒ์ญ ๋น์ฉ.
TL;DR
xterm.js๋ DOM ๋ฐ ์ด๋ฒคํธ์ ๊ฐ์ ์ผ๋ฐ์ ์ธ JS ํญ๋ชฉ์ ๊ด๋ฒ์ํ๊ฒ ์ ์ฉ๋์ด ํต์ฌ ๋ถ๋ถ์ ๋ค์ ์์ฑํ๋ ๊ฒฝ์ฐ์๋ ์น ์ด์
๋ธ๋ฆฌ์์ ๋ฌด์์ด๋ ์ป์ ์ ์์ต๋๋ค.
@jerch ์ข์ ์กฐ์ฌ : ์ค๋ง์ผ :
JS์์ wasm์ผ๋ก์ ํธ์ถ์ ์ฝ๊ฐ์ ์ค๋ฒํค๋๋ฅผ ์์ฑํ๊ณ ์์ ๋ชจ๋ ์ด์ ์ ๋จน์ต๋๋ค. ์ค์ ๋ก๋ ~20% ๋๋ ธ์ต๋๋ค.
์ด๊ฒ์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ด ์
์ฅ์ ์๋ ค์ค ๋ชจ๋์ฝ์ ์ฃผ์ ๋ฌธ์ ์ด๊ธฐ๋ ํ์ต๋๋ค. ๊ฐ๋ฅํ ํ ArrayBuffer
์์
ํ๋ ๊ฒ์ด ์ฑ๋ฅ๊ณผ ๋จ์์ฑ(๊ฐ๋จํ ์ํ, ์ง์
์ฅ๋ฒฝ) ์ฌ์ด์์ ์ต์์ ๊ท ํ์ ์ ๊ณตํด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
@Tyriar RGB ๋ฐ์ดํฐ๋ฅผ ๋ณด๊ดํ AttributeStorage๋ฅผ ๋ง๋ค๋ ค๊ณ ํฉ๋๋ค. BST์ ๋ํด์๋ ์์ง ํ์คํ์ง ์์ต๋๋ค. ํฐ๋ฏธ๋ ์ธ์
์์ ๋ช ๊ฐ์ง ์์ ์ค์ ๋ง ์๋ ์ผ๋ฐ์ ์ธ ์ฌ์ฉ ์ฌ๋ก์ ๊ฒฝ์ฐ ๋ฐํ์์ ๋ ๋๋น ์ง ๊ฒ์
๋๋ค. ์์์ด ์ฃผ์ด์ง ์๊ณ๊ฐ์ ์ด๊ณผํ๋ฉด ๋ฐํ์ ๋๋กญ์ธ์ด ๋ ์ ์์ต๋๋ค. ๋ํ ๋ฉ๋ชจ๋ฆฌ ์๋น๊ฐ ๋ค์ ๋ง์ด ์ฆ๊ฐํ์ง๋ง ์์ฑ์ ๋ชจ๋ ๋จ์ผ ์
๊ณผ ํจ๊ป ์ ์ฅ๋์ง ์๊ณ ํ ๋ฒ๋ง ์ ์ฅ๋๊ธฐ ๋๋ฌธ์ ์ฌ์ ํ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ฝํฉ๋๋ค.
ํ์ฌ fg
๋ฐ bg
256์ ๊ฐ์ด 8๋นํธ๊ฐ ์๋ 9๋นํธ ๊ธฐ๋ฐ์ธ ์ด์ ๋ฅผ ์๊ณ ์์ต๋๊น? ์ถ๊ฐ ๋นํธ๋ ๋ฌด์์ ์ฌ์ฉ๋ฉ๋๊น? ์ฌ๊ธฐ: https://github.com/xtermjs/xterm.js/blob/6691f809069a549b4808cd2e055398d2da15db37/src/InputHandler.ts#L1596
attr
์ ํ์ฌ ๋นํธ ๋ ์ด์์์ ์๋ ค์ฃผ์๊ฒ ์ต๋๊น? StringStorage ํฌ์ธํฐ์ ๋ํ "์ด์ค ์๋ฏธ"์ ๊ฐ์ ์ ์ฌํ ์ ๊ทผ ๋ฐฉ์์ ์ฌ์ฉํ๋ฉด ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ ์ ์ฝํ ์ ์์ง๋ง attr
์ MSB๋ ํฌ์ธํฐ ๊ตฌ๋ถ์ ์ํด ์์ฝ๋๊ณ ๋ค๋ฅธ ์ฉ๋๋ก๋ ์ฌ์ฉ๋์ง ์์์ผ ํฉ๋๋ค. ์ด๊ฒ์ ๋์ค์ ์ถ๊ฐ ์์ฑ ํ๋๊ทธ๋ฅผ ์ง์ํ ๊ฐ๋ฅ์ฑ์ ์ ํํ ์ ์์ต๋๋ค( FLAGS
์ด๋ฏธ 7๋นํธ๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์). ์ฐ๋ฆฌ๋ ์ฌ์ ํ ์ฌ ๊ฐ๋ฅ์ฑ์ด ์๋ ๋ช ๊ฐ์ง ๊ธฐ๋ณธ ํ๋๊ทธ๋ฅผ ๋์น๊ณ ์์ต๋๊น?
๋ฒํผ๋ผ๋ ์ฉ์ด์ 32๋นํธ attr
์ซ์๋ ๋ค์๊ณผ ๊ฐ์ด ํจํน๋ ์ ์์ต๋๋ค.
# 256 indexed colors
32: 0 (no RGB color)
31..25: flags (7 bits)
24..17: fg (8 bits, see question above)
16..9: bg
8..1: unused
# RGB colors
32: 1 (RGB color)
31..25: flags (7 bits)
24..1: pointer to RGB data (address space is 2^24, which should be sufficient)
์ด๋ฐ ์์ผ๋ก ์ ์ฅ์๋ ๋ ๊ฐ์ 32๋นํธ ์ซ์๋ก RGB ๋ฐ์ดํฐ๋ฅผ ๋ณด์ ํด์ผ ํ๋ ๋ฐ๋ฉด ํ๋๊ทธ๋ attr
์ซ์์ ๋จธ๋ฌด๋ฅผ ์ ์์ต๋๋ค.
@jerch ๊ทธ๋์ ๋ ์ ๊ฐ ์ด๋ฉ์ผ์ ๋ณด๋๋๋ฐ ์คํธํํฐ์ ๋ ๋จนํ๋๋ด์ ๐
ํ์ฌ fg ๋ฐ bg 256 ์์ ๊ฐ์ด 8๋นํธ๊ฐ ์๋ 9๋นํธ ๊ธฐ๋ฐ์ธ ์ด์ ๋ฅผ ์๊ณ ์์ต๋๊น? ์ถ๊ฐ ๋นํธ๋ ๋ฌด์์ ์ฌ์ฉ๋ฉ๋๊น?
๊ธฐ๋ณธ fg/bg ์์(์ด๋์ธ ์๋ ๋ฐ์ ์ ์์)์ ์ฌ์ฉ๋๋ ๊ฒ ๊ฐ์์ ์ค์ ๋ก๋ 257๊ฐ์ง ์์์ ๋๋ค.
https://github.com/xtermjs/xterm.js/pull/756/files
attr์ ํ์ฌ ๋นํธ ๋ ์ด์์์ ์๋ ค์ฃผ์๊ฒ ์ต๋๊น?
๋๋ ์ด๊ฒ์ด๋ผ๊ณ ์๊ฐํ๋ค:
19+: flags (see `FLAGS` enum)
18..18: default fg flag
17..10: 256 fg
9..9: default bg flag
8..1: 256 bg
์ด์ PR https://github.com/xtermjs/xterm.js/pull/756/files ์์ ๋ด๊ฐ ํธ๋ฃจ์ปฌ๋ฌ์ ๋ํด ์๊ฒ ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
/**
* Character data, the array's format is:
* - string: The character.
* - number: The width of the character.
* - number: Flags that decorate the character.
*
* truecolor fg
* | inverse
* | | underline
* | | |
* 0b 0 0 0 0 0 0 0
* | | | |
* | | | bold
* | | blink
* | invisible
* truecolor bg
*
* - number: Foreground color. If default bit flag is set, color is the default
* (inherited from the DOM parent). If truecolor fg flag is true, this
* is a 24-bit color of the form 0xxRRGGBB, if not it's an xterm color
* code ranging from 0-255.
*
* red
* | blue
* 0x 0 R R G G B B
* | |
* | green
* default color bit
*
* - number: Background color. The same as foreground color.
*/
export type CharData = [string, number, number, number, number];
๊ทธ๋์ ์ด๊ฒ์๋ 2๊ฐ์ ๊น๋ฐ์ด ์์์ต๋๋ค. ํ๋๋ ๊ธฐ๋ณธ ์์(๋ชจ๋ ์์ ๋นํธ๋ฅผ ๋ฌด์ํ ์ง ์ฌ๋ถ)์ด๊ณ ๋ค๋ฅธ ํ๋๋ ํธ๋ฃจ์ปฌ๋ฌ(256 ๋๋ 16mil ์์์ ์ํํ ์ง ์ฌ๋ถ)์ ๋๋ค.
์ด๊ฒ์ ๋์ค์ ์ถ๊ฐ ์์ฑ ํ๋๊ทธ๋ฅผ ์ง์ํ ๊ฐ๋ฅ์ฑ์ ์ ํํ ์ ์์ต๋๋ค(FLAGS๋ ์ด๋ฏธ 7๋นํธ๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์). ์ฐ๋ฆฌ๋ ์ฌ์ ํ ์ฌ ๊ฐ๋ฅ์ฑ์ด ์๋ ๋ช ๊ฐ์ง ๊ธฐ๋ณธ ํ๋๊ทธ๋ฅผ ๋์น๊ณ ์์ต๋๊น?
์, ์๋ฅผ ๋ค์ด https://github.com/xtermjs/xterm.js/issues/580, https://github.com/xtermjs/xterm.js/issues/1145์ ๊ฐ์ด ์ถ๊ฐ ํ๋๊ทธ๋ฅผ ์ํ ๊ณต๊ฐ์ด ํ์ํฉ๋๋ค. ๊ฐ๋ฅํ๋ฉด ์ต์ํ 3๋นํธ ์ด์์ผ๋ก ๋์ญ์์ค.
attr ์์ฒด ๋ด๋ถ์ ํฌ์ธํฐ ๋ฐ์ดํฐ ๋์ rgb ๋ฐ์ดํฐ์ ๋ํ ์ฐธ์กฐ๋ฅผ ๋ณด์ ํ๋ ๋ค๋ฅธ ๋งต์ด ์์ ์ ์์ต๋๊น? mapAttrIdxToRgb: { [idx: number]: RgbData
@Tyriar ์ฃ์กํฉ๋๋ค. ๋ฉฐ์น ๋์ ์จ๋ผ์ธ ์ํ๊ฐ ์๋์๊ณ ์ด๋ฉ์ผ์ด ์คํธ ํํฐ์ ์ํด ๋จนํ๊น๋ด ๋๋ ต์ต๋๋ค. ๋ค์ ๋ณด๋ด์ฃผ์๊ฒ ์ต๋๊น? :๋ถํ๋ค:
attrs ์ ์ฅ์์ ๋ํ ๋ ์๋ฆฌํ ์กฐํ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ก ์ฝ๊ฐ ๋์์ต๋๋ค. ๊ณต๊ฐ ๋ฐ ๊ฒ์/์ฝ์
๋ฐํ์๊ณผ ๊ด๋ จํ์ฌ ๊ฐ์ฅ ์ ๋งํ ๊ฒ์ ๋ ์ ๋ ดํ ๋์์ผ๋ก ๋๋ฌด์ ๊ฑด๋๋ฐ๊ธฐ ๋ชฉ๋ก์
๋๋ค. ์ด๋ก ์ ใ
ใ
ใ
ใ
์ค์ ๋ก ์ด๋ ์ชฝ๋ ๋์๊ฒ ๋งค์ฐ ์ด์ํด ๋ณด์ด๋ ๊ฐ๋จํ ๋ฐฐ์ด ๊ฒ์์ ๋ฅ๊ฐํ ์ ์์ต๋๋ค(์ฝ๋ ์ด๋๊ฐ์ ๋ฒ๊ทธ๊ฐ ์์ต๋๊น?)
๋๋ ํ
์คํธ ํ์ผ์ ์ฌ๊ธฐ https://gist.github.com/jerch/ff65f3fb4414ff8ac84a947b3a1eec58์ ์
๋ก๋ํ์ต๋๋ค. ์ด๋ ์ด ๋ ์ผ์ชฝ์ผ๋ก ๊ธฐ์ธ์ด์ง ์ -๊ฒ์ ํธ๋ฆฌ, ์ต๋ 10M ํญ๋ชฉ(๊ฑฐ์ ์์ ํ ์ฃผ์ ์ง์ ๊ณต๊ฐ)์ ํ
์คํธํฉ๋๋ค. ์ฌ์ ํ ์ด๋ ์ด๋ LLRB์ ๋นํด ํจ์ฌ ์์ ์์ง๋ง ์์ต๋ถ๊ธฐ์ ์ ์ฝ 10M์ผ ๊ฒ์ผ๋ก ์๊ฐํฉ๋๋ค. ๋ด 7๋
๋ ๋
ธํธ๋ถ์์ ํ
์คํธํ์ผ๋ฉฐ ๋๊ตฐ๊ฐ๊ฐ ํ
์คํธํ ์๋ ์๊ณ ๋ ์ ํ
์คํธํ ์ ์์ต๋๋ค. impl/tests์ ๋ช ๊ฐ์ง ๋ฒ๊ทธ๋ฅผ ์๋ ค์ฃผ์ธ์.
๋ค์์ ๋ช ๊ฐ์ง ๊ฒฐ๊ณผ์ ๋๋ค(์ฐ์ ๋ฒํธ ํฌํจ):
prefilled time for inserting 1000 * 1000 (summed up, ms)
items array LLRB
100-10000 3.5 - 5 ~13
100000 ~12 ~15
1000000 8 ~18
10000000 20-25 21-28
๋๋ฅผ ์ ๋ง ๋๋ผ๊ฒ ํ ๊ฒ์ ์ ํ ๋ฐฐ์ด ๊ฒ์์ด ํ์ ์์ญ์์ ์ ํ ์ฑ์ฅ์ ๋ณด์ฌ์ฃผ์ง ์๋๋ค๋ ์ฌ์ค์ด๋ฉฐ ~4ms์์ ์ต๋ 10k ํญ๋ชฉ์ด ์์ ์ ์ด๋ผ๋ ๊ฒ์ ๋๋ค(์บ์ ๊ด๋ จ์ผ ์ ์์). 10M ํ ์คํธ๋ ๋ ๋ค ์์๋ณด๋ค ๋ ๋์ ๋ฐํ์์ ๋ณด์ฌ์ค๋๋ค. ์๋ง๋ mem ํ์ด์ง์ผ๋ก ์ธํ ๊ฒ์ผ ์ ์์ต๋๋ค. ์๋ง๋ JS๋ JIT์ ๋ชจ๋ opt/deopts๊ฐ ๋ฐ์ํ๋ ๊ธฐ๊ณ์์ ๋ฉ๋ฆฌ ๋จ์ด์ ธ ์์ง๋ง ์ฌ์ ํ ๋ณต์ก์ฑ ๋จ๊ณ๋ฅผ ์ ๊ฑฐํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค(LLRB๊ฐ ๋จ์ผ _n_์์ ๋ฌด๊ฑฐ์ ๋ณด์ด๋ฏ๋ก O( n) ๋ O(logn) ์์ชฝ)
๋ฌด์์ ๋ฐ์ดํฐ์ Btw๋ ๊ทธ ์ฐจ์ด๊ฐ ํจ์ฌ ๋ ๋์ฉ๋๋ค.
๊ธฐ๋ณธ fg/bg ์์(์ด๋์ธ ์๋ ๋ฐ์ ์ ์์)์ ์ฌ์ฉ๋๋ ๊ฒ ๊ฐ์์ ์ค์ ๋ก๋ 257๊ฐ์ง ์์์ ๋๋ค.
์ด๊ฒ์ 8๊ฐ์ ํ๋ ํธ ์์ ์ค ํ๋์์ SGR 39
๋๋ SGR 49
๋ฅผ ๊ตฌ๋ณํ๋ ๊ฒ์
๋๊น?
attr ์์ฒด ๋ด๋ถ์ ํฌ์ธํฐ ๋ฐ์ดํฐ ๋์ rgb ๋ฐ์ดํฐ์ ๋ํ ์ฐธ์กฐ๋ฅผ ๋ณด์ ํ๋ ๋ค๋ฅธ ๋งต์ด ์์ ์ ์์ต๋๊น? mapAttrIdxToRgb: { [idx: ๋ฒํธ]: RgbData
์ด๊ฒ์ ์ถ๊ฐ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๊ณผ ํจ๊ป ๋ ๋ค๋ฅธ ๊ฐ์ ์ฐธ์กฐ๋ฅผ ์๊ฐํฉ๋๋ค. ์์ ํ ์คํธ๋ฅผ ํตํด ํ๋๊ทธ๋ฅผ ํญ์ attr์ ์ ์งํ๋ ๊ฒ๊ณผ RGB ๋ฐ์ดํฐ์ ํจ๊ป ์คํ ๋ฆฌ์ง์ ์ ์ฅํ๋ ๊ฒ์ ์ฐจ์ด์ ๋ ํ ์คํธํ์ต๋๋ค. 1M ํญ๋ชฉ์ ๊ฒฝ์ฐ ์ฐจ์ด๊ฐ ~0.5ms์ด๋ฏ๋ก ์ด ๋ณต์กํ ์์ฑ ์ค์ ์ ์ฌ์ฉํ์ง ์๊ณ ๋์ RGB๊ฐ ์ค์ ๋๋ฉด ํ๋๊ทธ๋ฅผ ์ ์ฅ์์ ๋ณต์ฌํฉ๋๋ค. ๊ทธ๋๋ ์ง์ ์์ฑ ๋ ํฌ์ธํฐ ์ฌ์ด์ 32๋นํธ ๊ตฌ๋ณ์ ์ ํํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด RGB๊ฐ ์๋ ์ ์ ๋ํ ์ ์ฅ์ด ์ ํ ๋ฐฉ์ง๋๊ธฐ ๋๋ฌธ์ ๋๋ค.
๋ํ fg/bg์ ๋ํ ๊ธฐ๋ณธ 8๊ฐ์ ํ๋ ํธ ์์์ด ํ์ฌ ๋ฒํผ์์ ์ถฉ๋ถํ ํํ๋์ง ์๋๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ด๋ก ์ ์ผ๋ก ํฐ๋ฏธ๋์ ๋ค์ ์์ ๋ชจ๋๋ฅผ ์ง์ํด์ผ ํฉ๋๋ค.
SGR 39
+ SGR 49
fg/bg์ ๊ธฐ๋ณธ ์์(์ฌ์ฉ์ ์ ์ ๊ฐ๋ฅ)SGR 30-37
+ SGR 40-47
fg/bg์ฉ 8๊ฐ์ง ๋ฎ์ ์์ ํ๋ ํธ(์ฌ์ฉ์ ์ ์ ๊ฐ๋ฅ)SGR 90-97
+ SGR 100-107
fg/bg์ฉ 8๊ฐ์ง ํ์ด ์ปฌ๋ฌ ํ๋ ํธ(์ฌ์ฉ์ ์ ์ ๊ฐ๋ฅ)SGR 38;5;n
+ SGR 48;5;n
fg/bg๋ฅผ ์ํ 256๊ฐ์ ์ธ๋ฑ์ค ํ๋ ํธ(์ฌ์ฉ์ ์ ์ ๊ฐ๋ฅ)SGR 38;2;r;g;b
+ SGR 48;2;r;g;b
fg/bg์ฉ RGB(์ฌ์ฉ์ ์ ์ ๋ถ๊ฐ)์ต์
2.) ๋ฐ 3.)์ ๋จ์ผ ๋ฐ์ดํธ๋ก ๋ณํฉํ ์ ์์ต๋๋ค(๋จ์ผ 16์ fg/bg ํ๋ ํธ๋ก ์ฒ๋ฆฌ). 4.)๋ 2๋ฐ์ดํธ, 5.)๋ ๋ง์ง๋ง์ผ๋ก 6๋ฐ์ดํธ๋ฅผ ๋ ์ฌ์ฉํฉ๋๋ค. ์์ ๋ชจ๋๋ฅผ ๋ํ๋ด๊ธฐ ์ํด์๋ ์ฌ์ ํ ์ฝ๊ฐ์ ๋นํธ๊ฐ ํ์ํฉ๋๋ค.
์ด๋ฅผ ๋ฒํผ ์์ค์ ๋ฐ์ํ๋ ค๋ฉด ๋ค์์ด ํ์ํฉ๋๋ค.
bits for
2 fg color mode (0: default, 1: 16 palette, 2: 256, 3: RGB)
2 bg color mode (0: default, 1: 16 palette, 2: 256, 3: RGB)
8 fg color for 16 palette and 256
8 bg color for 16 palette and 256
10 flags (currently 7, 3 more reserved for future usage)
----
30
๋ฐ๋ผ์ 32๋นํธ ์ซ์์ 30๋นํธ๊ฐ ํ์ํ๊ณ 2๋นํธ๋ ๋ค๋ฅธ ์ฉ๋๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค. 32๋ฒ์งธ ๋นํธ๋ ๋น RGB ์ ์ ๋ํ ์ ์ฅ์ ์๋ตํ๋ ํฌ์ธํฐ ๋ ์ง์ ์์ฑ ํ๋๊ทธ๋ฅผ ๋ณด์ ํ ์ ์์ต๋๋ค.
๋ํ ๊ตฌํ ์ธ๋ถ ์ฌํญ์ ์ธ๋ถ์ ๋
ธ์ถํ์ง ์๋๋ก attr ์ก์ธ์ค๋ฅผ ํธ๋ฆฌํ ํด๋์ค๋ก ๋ง๋ฌด๋ฆฌํ๋ ๊ฒ์ด ์ข์ต๋๋ค(์์ ํ
์คํธ ํ์ผ ์ฐธ์กฐ, ์ด๋ฅผ ๋ฌ์ฑํ๊ธฐ ์ํ ์ด๊ธฐ ๋ฒ์ ์ TextAttributes
ํด๋์ค๊ฐ ์์).
์ฃ์กํฉ๋๋ค. ๋ฉฐ์น ๋์ ์จ๋ผ์ธ ์ํ๊ฐ ์๋์ด์ ์คํธ ํํฐ์ ์ด๋ฉ์ผ์ด ๊ฑธ๋ฆฐ ๊ฒ ๊ฐ์ต๋๋ค. ๋ค์ ๋ณด๋ด์ฃผ์๊ฒ ์ต๋๊น?
ํ๋ด๋ค
์ค btw ๋ฐฐ์ด ๋ llrb ๊ฒ์์ ๋ํ ์์ ์ซ์๋ ์ฐ๋ ๊ธฐ์ ๋๋ค. ์ต์ ํ ํ๋ก๊ทธ๋จ์ด for ๋ฃจํ์์ ์ด์ํ ์์ ์ ์ํํ์ฌ ๋ง์ณ ์ก๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ฝ๊ฐ ๋ค๋ฅธ ํ ์คํธ ์ค์ ์ ์ฌ์ฉํ๋ฉด ํจ์ฌ ๋ ์ผ์ฐ ์ฑ์ฅํ๋ O(n) ๋ O(log n)์ ๋ช ํํ๊ฒ ๋ณด์ฌ์ค๋๋ค(1000๊ฐ์ ์์๊ฐ ๋ฏธ๋ฆฌ ์ฑ์์ง ์ํ์์ ํธ๋ฆฌ๋ก ์ด๋ฏธ ๋ ๋น ๋ฆ).
ํ์ฌ ์ํ:
ํ์:
์๋นํ ๊ฐ๋จํ ์ต์ ํ ์ค ํ๋๋ ๋ฐฐ์ด ๋ฐฐ์ด์ ๋จ์ผ ๋ฐฐ์ด๋ก ๋ณํฉํ๋ ๊ฒ์
๋๋ค. ์ฆ, BufferLine
of _N_ ์ด ๋์ _data
_N_ CharData
์
์ ๋ฐฐ์ด์ด ์๊ณ ์ฌ๊ธฐ์ ๊ฐ CharData
๋ 4๊ฐ์ ๋ฐฐ์ด์
๋๋ค. _4*N_ ์์์ ๋ฐฐ์ด์
๋๋ค. ์ด๊ฒ์ _N_ ๋ฐฐ์ด์ ๊ฐ์ฒด ์ค๋ฒํค๋๋ฅผ ์ ๊ฑฐํฉ๋๋ค. ๋ํ ์บ์ ์ง์ญ์ฑ์ ํฅ์์ํค๋ฏ๋ก ๋ ๋นจ๋ผ์ผ ํฉ๋๋ค. ๋จ์ ์ ์ฝ๊ฐ ๋ ๋ณต์กํ๊ณ ๋ชป์๊ธด ์ฝ๋์ด์ง๋ง ๊ทธ๋งํ ๊ฐ์น๊ฐ ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
์ด์ ์๊ฒฌ์ ๋ํ ํ์ ์กฐ์น๋ก ๊ฐ ์
์ ๋ํด _data
๋ฐฐ์ด์์ ๋ค์ํ ์์ ์์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๊ณ ๋ คํด ๋ณผ ๊ฐ์น๊ฐ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ฆ, ์ํ ์ ์ฅ ํํ์
๋๋ค. ์์์ ์์น ๋ณ๊ฒฝ์ ๋น์ฉ์ด ๋ ๋ง์ด ๋ค์ง๋ง, ํนํ ๊ฐ๋จํ ์ด๋ ์ด๊ฐ ์บ์ ์ง์ญ์ฑ์ ์ต์ ํ๋์ด ์๊ธฐ ๋๋ฌธ์ ๋ผ์ธ ์์๋ถํฐ ์ ํ ์ค์บ๋์ด ๋งค์ฐ ๋น ๋ฅผ ์ ์์ต๋๋ค. ์ผ๋ฐ์ ์ธ ์์ฐจ ์ถ๋ ฅ์ ๋ ๋๋ง๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ๋น ๋ฆ
๋๋ค.
๊ณต๊ฐ์ ์ค์ด๋ ๊ฒ ์ธ์๋ ์
๋น ๋ค์ํ ์์ ์์ ์ด์ ์ ์ ์ฐ์ฑ์ด ์ฆ๊ฐํ๋ค๋ ๊ฒ์
๋๋ค. ์ถ๊ฐ ์์ฑ(์: 24๋นํธ ์์), ํน์ ์
๋๋ ๋ฒ์์ ๋ํ ์ฃผ์, ๊ธ๋ฆฌํ ๋๋
์ค์ฒฉ๋ DOM ์์
@PerBothner ๋น์ ์ ์์ด๋์ด์ ๋ํ Thx! ์, ์ด๋ฏธ ํฌ์ธํฐ ์ฐ์ ๋ก ๋จ์ผ ๋ฐ์ง ๋ฐฐ์ด ๋ ์ด์์์ ํ ์คํธํ์ผ๋ฉฐ ์ต๊ณ ์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฅ ์ ๋ณด์ฌ์ค๋๋ค. ํฌ๊ธฐ ์กฐ์ ๊ณผ ๊ด๋ จํ์ฌ ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ์ ์ฒด ๋ฉ๋ชจ๋ฆฌ ์ฒญํฌ๋ฅผ ๋ค์ ์์ฑ(๋ณต์ฌ)ํ๊ฑฐ๋ ๋ ํฐ ์ฒญํฌ๋ก ๋น ๋ฅด๊ฒ ๋ณต์ฌํ๊ณ ๋ถ๋ถ์ ์ฌ์ ๋ ฌํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ์ด๊ฒ์ ๊ฝค ํน๊ธ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ imho๋ mem ์ ์ฝ์ ์ํด ์ ๋นํ๋์ง ์์ต๋๋ค(์์ ๋์ด๋ ์ผ๋ถ ํ๋ ์ด๊ทธ๋ผ์ด๋ PR์์ ํ ์คํธ, ์ ์ฝ์ ์๋ก์ด ๋ฒํผ ๋ผ์ธ ๊ตฌํ๊ณผ ๋น๊ตํ์ฌ ์ฝ 10% ์ ๋์์ต๋๋ค).
๋ ๋ฒ์งธ ์๊ฒฌ์ ๋ํด - ๋ํ๋ ์ค์ ๋ ์ฝ๊ฒ ์ฒ๋ฆฌํ ์ ์๋๋ก ์ด๋ฏธ ๋ ผ์ํ์ต๋๋ค. ์ง๊ธ์ ์๋ก์ด ๋ฒํผ ๋ ์ด์์์ ๋ํด ํ X ์ด ์ ๊ทผ ๋ฐฉ์์ ์ฌ์ฉํ๊ณ ๋จผ์ ์๋ฃํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค. ๋ฆฌํ๋ก์ฐ ํฌ๊ธฐ ์กฐ์ ๊ตฌํ์ ์ํํ๋ฉด ์ด ๋ฌธ์ ๋ฅผ ๋ค์ ํด๊ฒฐํด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋ฒํผ์ ์ถ๊ฐ ํญ๋ชฉ ์ถ๊ฐ: ํ์ฌ ๋๋ถ๋ถ์ ๋ค๋ฅธ ํฐ๋ฏธ๋์ด ์ํํ๋ ์์
์ ์ํํฉ๋๋ค. ์ปค์ ์งํ์ ๋ฐ์ดํฐ๊ฐ ์ด๋ป๊ฒ ๋ฐฐ์น๋์ด์ผ ํ๋์ง pty/termios์ ์์ด๋์ด์ ํธํ๋๋๋ก ๋ณด์ฅํ๋ wcwidth
์ํด ๊ฒฐ์ ๋ฉ๋๋ค. ์ด๊ฒ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์๋ก๊ฒ์ดํธ ์ ๋ฐ ๋ฌธ์ ๊ฒฐํฉ๊ณผ ๊ฐ์ ๊ฒ๋ง ๋ฒํผ ์์ค์์ ์ฒ๋ฆฌํ๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ๋ค๋ฅธ "์์ ์์ค" ๊ฒฐํฉ ๊ท์น์ ๋ ๋๋ฌ์ ์บ๋ฆญํฐ ๊ฒฐํฉ์๊ฐ ์ ์ฉํ ์ ์์ต๋๋ค(ํ์ฌ ํฉ์์ ๋ํด https://github.com/xtermjs/xterm-addon-ligatures์์ ์ฌ์ฉ). ์ด๊ธฐ ๋ฒํผ ์์ค์์ ์ ๋์ฝ๋ ์์๋ฅผ ์ง์ํ๊ธฐ ์ํด PR์ ์ด์์ง๋ง ๋๋ถ๋ถ์ pty ๋ฐฑ์๋์๋ ์ด์ ๋ํ ๊ฐ๋
์ด ์๊ธฐ ๋๋ฌธ์(์ ํ ์กด์ฌํฉ๋๊น?) ์ด์ํ char ๋๊ธฐ์
์ผ๋ก ๋๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๊ทธ ๋จ๊ณ์์๋ ์ด ์์
์ ์ํํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. . ์ค์ BIDI ์ง์๋ ๋ง์ฐฌ๊ฐ์ง์
๋๋ค. ์ปค์/์
์์ง์์ ๊ทธ๋๋ก ์ ์งํ๋ ค๋ฉด ๋ ๋๋ฌ ๋จ๊ณ์์ grapheme๊ณผ BIDI๊ฐ ๋ ์ ์ํ๋๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ ์ ์ฐ๊ฒฐ๋ DOM ๋ ธ๋์ ๋ํ ์ง์์ ์ ๋ง ํฅ๋ฏธ๋กญ๊ฒ ๋ค๋ฆฝ๋๋ค. ์ ๋ ๊ทธ ์์ด๋์ด๊ฐ ์ข์ต๋๋ค. ํ์ฌ ๋ค๋ฅธ ๋ ๋๋ฌ ๋ฐฑ์๋(DOM, ์บ๋ฒ์ค 2D ๋ฐ ์๋ก์ด ๋น๋๋ webgl ๋ ๋๋ฌ)๊ฐ ์๊ธฐ ๋๋ฌธ์ ์ง์ ์ ์ธ ์ ๊ทผ ๋ฐฉ์์ผ๋ก๋ ๋ถ๊ฐ๋ฅํ์ง๋ง ๊ธฐ๋ณธ์ ์ผ๋ก ์ง์๋์ง ์๋ ์์น์ ์ค๋ฒ๋ ์ด๋ฅผ ๋ฐฐ์นํ์ฌ ๋ชจ๋ ๋ ๋๋ฌ์ ๋ํด ์ด๊ฒ์ด ์ฌ์ ํ ๋ฌ์ฑ๋ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค(DOM ๋ ๋๋ฌ๋ง ์ง์ ํ ์ ์์ต๋๋ค). ์ฐ๋ฆฌ๋ ๋ฌผ๊ฑด๊ณผ ๊ทธ ํฌ๊ธฐ์ ๋ ๋๋ฌ๊ฐ ๋๋ฌ์ด ์์ ์ ํ ์ ์์์ ์๋ฆฌ๊ธฐ ์ํด ๋ฒํผ ์์ค์์ ์ผ์ข ์ API๊ฐ ํ์ํฉ๋๋ค. ๋๋ ์ด๊ฒ์ ๋ณ๋์ ๋ฌธ์ ๋ก ๋ ผ์/์ถ์ ํด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
์์ธํ ๋ต๋ณ ๊ฐ์ฌํฉ๋๋ค.
_"ํฌ๊ธฐ ์กฐ์ ๊ณผ ๊ด๋ จํ์ฌ ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ์ ์ฒด ๋ฉ๋ชจ๋ฆฌ ์ฒญํฌ๋ฅผ ๋ค์ ์์ฑ(๋ณต์ฌ)ํ๊ฑฐ๋ ๋ ํฐ ์ฒญํฌ๋ก ๋น ๋ฅด๊ฒ ๋ณต์ฌํ๊ณ ๋ถ๋ถ์ ์ฌ์ ๋ ฌํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค."_
ํฌ๊ธฐ ์กฐ์ ์ _N_ ์์๊ฐ ์๋ _4*N_ ์์๋ฅผ ๋ณต์ฌํด์ผ ํ๋ค๋ ๋ป์ ๋๊น?
๋ฐฐ์ด์ด ๋
ผ๋ฆฌ์ (๋ํ๋์ง ์์) ํ์ ๋ํ ๋ชจ๋ ์
์ ํฌํจํ๋ ๊ฒ์ด ํฉ๋ฆฌ์ ์ผ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด 180์ ํ๊ณผ 80์ด ๋๋น์ ํฐ๋ฏธ๋์ ๊ฐ์ ํฉ๋๋ค. ์ด ๊ฒฝ์ฐ 3๊ฐ์ BufferLine
์ธ์คํด์ค๊ฐ ๋ชจ๋ ๋์ผํ _4*180_-element _data
๋ฒํผ๋ฅผ ๊ณต์ ํ ์ ์์ง๋ง ๊ฐ BufferLine
์๋ ์์ ์คํ์
๋ ํฌํจ๋ฉ๋๋ค.
๊ธ์, ๋๋ [cols] x [rows] x [needed single cell space]
์ํด ๊ตฌ์ถ๋ ํ๋์ ํฐ ๋ฐฐ์ด์ ๋ชจ๋ ๊ฒ์ ๊ฐ์ง๊ณ ์์๋ค. ๋ฐ๋ผ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฌ์ ํ ์ฃผ์ด์ง ๋์ด์ ๋๋น๋ก "์บ๋ฒ์ค"๋ก ์๋ํ์ต๋๋ค. ์ด๊ฒ์ ์ ์์ ์ธ ์
๋ ฅ ํ๋ฆ์ ๋ํด ์ค์ ๋ก ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ ์ด๊ณ ๋น ๋ฅด์ง๋ง insertCell
/ deleteCell
๊ฐ ํธ์ถ๋์๋ง์(ํฌ๊ธฐ ์กฐ์ ์ผ๋ก ์ํ๋จ) ์์
์ด ๋ฐ์ํ๋ ์์น ๋ค์ ์๋ ์ ์ฒด ๋ฉ๋ชจ๋ฆฌ ์ฎ๊ฒจ์ผ ํ ๊ฒ์
๋๋ค. ์์ ์คํฌ๋กค๋ฐฑ(<10k)์ ๊ฒฝ์ฐ ์ด๊ฒ๋ ๋ฌธ์ ๊ฐ ๋์ง ์์ต๋๋ค. ์ค์ ๋ก >100k ๋ผ์ธ์ ๋ํ ์ผ์คํ ํผ์
๋๋ค.
ํ์ฌ ํ์ํ๋ ๋ฐฐ์ด impl์ ์ฌ์ ํ โโ์ด๋ฌํ ์ด๋์ ์ํํด์ผ ํ์ง๋ง ๋ฉ๋ชจ๋ฆฌ ๋ด์ฉ์ ์ค ๋๊น์ง ์ด๋ํ๊ธฐ๋ง ํ๋ฉด ๋๋ฏ๋ก ๋
์ฑ์ด ๋ํฉ๋๋ค.
๋น์ฉ์ด ๋ง์ด ๋๋ ์ด๋์ ํผํ๊ธฐ ์ํด ๋ค๋ฅธ ๋ ์ด์์์ ๋ํด ์๊ฐํ์ต๋๋ค. ๋ง๋ ์๋๋ ๋ฉ๋ชจ๋ฆฌ ์ด๋์ ์ ์ฅํ๊ธฐ ์ํ ๊ธฐ๋ณธ ํ๋๋ ์ค์ ๋ก ์คํฌ๋กค๋ฐฑ์ "ํซ ํฐ๋ฏธ๋ ํ"(๊ฐ์ฅ ์ต๊ทผ terminal.rows
)์์ ๋ถ๋ฆฌํ๋ ๊ฒ์
๋๋ค. ์ปค์ ์ ํ ๋ฐ ์ฝ์
/์ญ์ ์ ์ํด ๋ณ๊ฒฝ๋ฉ๋๋ค.
์ฌ๋ฌ ๋ฒํผ ๋ผ์ธ ๊ฐ์ฒด๊ฐ ๊ธฐ๋ณธ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ณต์ ํ๋ ๊ฒ์ ๋ํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ํฅ๋ฏธ๋ก์ด ์์ด๋์ด์ ๋๋ค. ๋ช ์์ ์ธ ์ฐธ์กฐ ์ฒ๋ฆฌ ๋ฑ์ ๋์ ํ์ง ์๊ณ ์ด๊ฒ์ด ์ด๋ป๊ฒ ์์ ์ ์ผ๋ก ์๋ํ ์ ์๋์ง ์์ง ํ์คํ์ง ์์ต๋๋ค. ๋ค๋ฅธ ๋ฒ์ ์์๋ ๋ช ์์ ๋ฉ๋ชจ๋ฆฌ ์ฒ๋ฆฌ๋ก ๋ชจ๋ ์์ ์ ์ํํ๋ ค๊ณ ํ์ง๋ง ref ์นด์ดํฐ๋ ์ค์ ์ผ์คํ ํผ์์ผ๋ฉฐ GC ๋๋์์ ์๋ชป๋์๋ค๊ณ ๋๊ผ์ต๋๋ค. (ํ๋ฆฌ๋ฏธํฐ๋ธ๋ #1633 ์ฐธ์กฐ)
ํธ์ง: Btw ๋ช ์์ ๋ฉ๋ชจ๋ฆฌ ์ฒ๋ฆฌ๋ ํ์ฌ์ "๋ผ์ธ๋น ๋ฉ๋ชจ๋ฆฌ" ์ ๊ทผ ๋ฐฉ์๊ณผ ๋๋ฑํ์ต๋๋ค. ๋ ๋์ ์บ์ ์ง์ญ์ฑ์ผ๋ก ์ธํด ๋ ๋์ ์ฑ๋ฅ์ ๊ธฐ๋ํ๋๋ฐ, ์ฝ๊ฐ ๋ ๋ง์ ๊ฒฝํ์น๊ฐ ๋จนํ ๊ฒ ๊ฐ์ต๋๋ค. JS ์ถ์ํ์์ mem ์ฒ๋ฆฌ.
์ ์ ์ฐ๊ฒฐ๋ DOM ๋ ธ๋์ ๋ํ ์ง์์ ์ ๋ง ํฅ๋ฏธ๋กญ๊ฒ ๋ค๋ฆฝ๋๋ค. ์ ๋ ๊ทธ ์์ด๋์ด๊ฐ ์ข์ต๋๋ค. ํ์ฌ ๋ค๋ฅธ ๋ ๋๋ฌ ๋ฐฑ์๋(DOM, ์บ๋ฒ์ค 2D ๋ฐ ์๋ก์ด ๋น๋๋ webgl ๋ ๋๋ฌ)๊ฐ ์๊ธฐ ๋๋ฌธ์ ์ง์ ์ ์ธ ์ ๊ทผ ๋ฐฉ์์ผ๋ก๋ ๋ถ๊ฐ๋ฅํ์ง๋ง ๊ธฐ๋ณธ์ ์ผ๋ก ์ง์๋์ง ์๋ ์์น์ ์ค๋ฒ๋ ์ด๋ฅผ ๋ฐฐ์นํ์ฌ ๋ชจ๋ ๋ ๋๋ฌ์ ๋ํด ์ด๊ฒ์ด ์ฌ์ ํ ๋ฌ์ฑ๋ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค(DOM ๋ ๋๋ฌ๋ง ์ง์ ํ ์ ์์ต๋๋ค).
์ฃผ์ ์์ ์กฐ๊ธ ๋ฒ์ด๋์ง๋ง ๊ฒฐ๊ตญ ์บ๋ฒ์ค ๋ ๋ ๋ ์ด์ด์ ์ ์ฌํ๊ฒ ์๋ํ๋ ๋ทฐํฌํธ ๋ด์ ์ ๊ณผ ์ฐ๊ฒฐ๋ DOM ๋ ธ๋๋ฅผ ๊ฐ๊ฒ ๋ฉ๋๋ค. ๊ทธ๋ ๊ฒ ํ๋ฉด ์๋น์๋ HTML๊ณผ CSS๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ "์ฅ์"ํ ์ ์๊ณ ์บ๋ฒ์ค API์ ๋ค์ด๊ฐ ํ์๊ฐ ์์ต๋๋ค.
๋ฐฐ์ด์ด ๋ ผ๋ฆฌ์ (๋ํ๋์ง ์์) ํ์ ๋ํ ๋ชจ๋ ์ ์ ํฌํจํ๋ ๊ฒ์ด ํฉ๋ฆฌ์ ์ผ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด 180์ ํ๊ณผ 80์ด ๋๋น์ ํฐ๋ฏธ๋์ ๊ฐ์ ํฉ๋๋ค. ์ด ๊ฒฝ์ฐ 3๊ฐ์ BufferLine ์ธ์คํด์ค๊ฐ ๋ชจ๋ ๋์ผํ 4*180 ์์ _data ๋ฒํผ๋ฅผ ๊ณต์ ํ ์ ์์ง๋ง ๊ฐ BufferLine์๋ ์์ ์คํ์ ๋ ํฌํจ๋ฉ๋๋ค.
์์์ ์ธ๊ธํ ๋ฆฌํ๋ก์ฐ์ ๋ํ ๊ณํ์ https://github.com/xtermjs/xterm.js/issues/622#issuecomment -375403572์ ์บก์ฒ๋์ด
์กฐ๋ฐํ ๋ฐฐ์ด ์ ๊ทผ ๋ฐฉ์์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ฐ๋ฆฌ๊ฐ ๋ณผ ์ ์๋ ๊ฒ์ผ ์ ์์ง๋ง ์ด๋ฌํ ๋ฐฐ์ด์์ ์ค ๋ฐ๊ฟ๋์ง ์์ ์ค ๋ฐ๊ฟ์ ๊ด๋ฆฌํ๋ ๋ฐ ์ถ๊ฐ ์ค๋ฒํค๋์ ํ์ด ์คํฌ๋กค๋ฐฑ ๋ฒํผ ๊ทธ๋ผ์๋ ๋ถ๊ตฌํ๊ณ #791์ด ์๋ฃ๋๊ณ #622๋ฅผ ๋ณผ ๋๊น์ง ์ด๋ฌํ ๋ณ๊ฒฝ ์ฌํญ์ ์กฐ์ฌํด์๋ ์ ๋๋ค๊ณ ์๊ฐํฉ๋๋ค.
PR #1796์ ์ฌ์ฉํ๋ฉด ํ์๋ ๋ค๋ฅธ ์ ๋ ฅ ์ธ์ฝ๋ฉ์ ๋ํ ์๋ฒ์ ์ถ๊ฐ ์ต์ ํ๋ฅผ ์ํ ๋ฌธ์ ์ฌ๋ ํ์ํ๋ ๋ฐฐ์ด ์ง์์ ๋ฐ์ต๋๋ค.
์ง๊ธ์ JS ๋ฌธ์์ด๋ก ์๋ค๋ก ์ฝ๊ฒ ๋ณํํ ์ ์๊ธฐ ๋๋ฌธ์ Uint16Array
์ฌ์ฉํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค. ์ด๊ฒ์ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ฒ์์ UCS2/UTF16์ผ๋ก ์ ํํ๋ ๋ฐ๋ฉด ํ์ฌ ๋ฒ์ ์ ํ์๋ UTF32๋ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค(UTF8์ ์ง์๋์ง ์์). ์ ํ์ด ์ง์ ๋ ๋ฐฐ์ด ๊ธฐ๋ฐ ํฐ๋ฏธ๋ ๋ฒํผ๋ ํ์ฌ UTF32์ฉ์ผ๋ก ๋ ์ด์์๋์ด ์์ผ๋ฉฐ UTF16 --> UTF32 ๋ณํ์ InputHandler.print
์์ ์ํ๋ฉ๋๋ค. ์ฌ๊ธฐ์์ ๋ช ๊ฐ์ง ๋ฐฉํฅ์ด ๊ฐ๋ฅํฉ๋๋ค.
wcwidth
UTF16 ํธํ ๊ฐ๋ฅUTF8 ์ ๋ณด: ํ์๋ ํ์ฌ ๊ธฐ๋ณธ UTF8 ์ํ์ค๋ฅผ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ์ฃผ๋ก ์ค๊ฐ ๋ฌธ์๊ฐ C1 ์ ์ด ๋ฌธ์์ ์ถฉ๋ํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋ํ UTF8์ ์ถ๊ฐ ์ค๊ฐ ์ํ์ ํจ๊ป ์ ์ ํ ์คํธ๋ฆผ ์ฒ๋ฆฌ๊ฐ ํ์ํฉ๋๋ค. ๋ถ์พํ๊ณ imho๊ฐ ํ์์ ์ถ๊ฐ๋์ด์๋ ์ ๋ฉ๋๋ค. UTF8์ ์ฌ์ ์ ๋ ์ ์ฒ๋ฆฌ๋ ๊ฒ์ด๋ฉฐ ์๋ง๋ ๋ชจ๋ ๊ณณ์์ ๋ณด๋ค ์ฌ์ด ์ฝ๋ ํฌ์ธํธ ์ฒ๋ฆฌ๋ฅผ ์ํด UTF32๋ก์ ๋ณํ ๊ถํ์ด ์์ ๊ฒ์ ๋๋ค.
๊ฐ๋ฅํ UTF8 ์
๋ ฅ ์ธ์ฝ๋ฉ ๋ฐ ๋ด๋ถ ๋ฒํผ ๋ ์ด์์๊ณผ ๊ด๋ จํ์ฌ ๋๋ต์ ์ธ ํ
์คํธ๋ฅผ ์ํํ์ต๋๋ค. ์ ์ฒด ๋ฐํ์์ ๋ํ ์บ๋ฒ์ค ๋ ๋๋ฌ์ ํจ์ฌ ๋ ๋์ ์ํฅ์ ๋ฐฐ์ ํ๊ธฐ ์ํด ๊ณง ์ถ์๋ webgl ๋ ๋๋ฌ๋ก ์ด๋ฅผ ์ํํ์ต๋๋ค. ๋ด ls -lR /usr/lib
๋ฒค์น๋งํฌ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์ต๋๋ค.
ํ์ฌ ๋ง์คํฐ + webgl ๋ ๋๋ฌ:
๋์ดํฐ ๋ถ๊ธฐ๋ #1796, #1811 ๋ฐ webgl ๋ ๋๋ฌ์ ์ผ๋ถ๋ฅผ ์ ์ฉํฉ๋๋ค.
ํ๋ ์ด๊ทธ๋ผ์ด๋ ๋ธ๋์น๋ ๊ตฌ๋ฌธ ๋ถ์ ๋ฐ ์ ์ฅ์ ์ํํ๊ธฐ ์ ์ UTF8์์ UTF32๋ก ์ด๊ธฐ ๋ณํ์ ์ํํฉ๋๋ค(๋ณํ ์ถ๊ฐ ~ 30ms). ์๋ ํฅ์์ ์ฃผ๋ก ์
๋ ฅ ํ๋ฆ ์ค 2๊ฐ์ง ํซ ๊ธฐ๋ฅ์ธ EscapeSequenceParser.parse
(120ms ๋ 35ms) ๋ฐ InputHandler.print
(350ms ๋ 75ms)์ ์ํด ์ป์ต๋๋ค. ๋ ๋ค .charCodeAt
ํธ์ถ์ ์ ์ฅํ์ฌ ํ์ํ๋ ๋ฐฐ์ด ์ค์์น์์ ๋ง์ ์ด์ ์ ์ป์ต๋๋ค.
๋ํ ์ด ๊ฒฐ๊ณผ๋ฅผ UTF16 ์ค๊ฐ ์ ํ ๋ฐฐ์ด๊ณผ ๋น๊ตํ์ต๋๋ค. EscapeSequenceParser.parse
๋ ์ฝ๊ฐ ๋ ๋น ๋ฅด์ง๋ง(~ 25ms) InputHandler.print
๋ wcwidth
์์ ํ์ํ ๋๋ฆฌ ์ ๋ฐ ์ฝ๋ ํฌ์ธํธ ์กฐํ๋ก ์ธํด ๋ค์ณ์ง๋๋ค
๋ํ ๋๋ ์ด๋ฏธ ์์คํ
์ด ls
๋ฐ์ดํฐ๋ฅผ ์ ๊ณตํ ์ ์๋ ํ๊ณ์ ์ด๋ฅด๋ ์ต๋๋ค(SSD๊ฐ ์๋ i7) - ํ๋ํ ์๋ ํฅ์์ ์คํ์ ๋ ๋น ๋ฅด๊ฒ ๋ง๋๋ ๋์ ์ ํด ์๊ฐ์ ์ถ๊ฐํฉ๋๋ค.
์์ฝ:
Imho ์ฐ๋ฆฌ๊ฐ ์ป์ ์ ์๋ ๊ฐ์ฅ ๋น ๋ฅธ ์
๋ ฅ ์ฒ๋ฆฌ๋ ๋ฒํผ ํํ์ ์ํ UTF8 ์ ์ก + UTF32์ ํผํฉ์
๋๋ค. UTF8 ์ ์ก์ ์ผ๋ฐ์ ์ธ ํฐ๋ฏธ๋ ์
๋ ฅ์ ๋ํด ์ต๊ณ ์ ๋ฐ์ดํธ ํฉ๋ฅ ์ ๊ฐ์ง๋ฉฐ ์ต๋ Terminal.write
๋ฒํผ์ ์ฌ๋ฌ ๋ ์ด์ด๋ฅผ ํตํด pty์์ ๋ง๋ ์๋๋ ๋ณํ์ ์ ๊ฑฐํ์ง๋ง UTF32 ๊ธฐ๋ฐ ๋ฒํผ๋ ๋ฐ์ดํฐ๋ฅผ ๋งค์ฐ ๋น ๋ฅด๊ฒ ์ ์ฅํ ์ ์์ต๋๋ค. ํ์๋ UTF16๋ณด๋ค ์ฝ๊ฐ ๋ ๋์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์ ๊ณตํ๋ ๋ฐ๋ฉด UTF16์ ๋ ๋ง์ ๊ฐ์ ์ฐธ์กฐ๊ฐ ํฌํจ๋ ๋ ๋ณต์กํ ๋ฌธ์ ์ฒ๋ฆฌ๋ก ์ธํด ์ฝ๊ฐ ๋๋ฆฝ๋๋ค.
๊ฒฐ๋ก :
์ง๊ธ์ UTF32 ๊ธฐ๋ฐ ๋ฒํผ ๋ ์ด์์์ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ๋ํ UTF8 ์
๋ ฅ ์ธ์ฝ๋ฉ์ผ๋ก ์ ํํ๋ ๊ฒ์ ๊ณ ๋ คํด์ผ ํ์ง๋ง ํตํฉ์์ ๋ํ API ๋ณ๊ฒฝ ๋ฐ ์๋ฏธ์ ๋ํด ์ข ๋ ์๊ฐํด์ผ ํฉ๋๋ค(electron์ ipc ๋ฉ์ปค๋์ฆ์ด BASE64 ์ธ์ฝ๋ฉ ๋ฐ JSON ๋ํ ์์ด ๋ฐ์ด๋๋ฆฌ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ ๊ฒ์ฒ๋ผ ๋ณด์).
ํฅํ ํธ๋ฃจ ์ปฌ๋ฌ ์ง์์ ์ํ ๋ฒํผ ๋ ์ด์์:
ํ์ฌ ํ์ํ๋ ๋ฐฐ์ด ๊ธฐ๋ฐ ๋ฒํผ ๋ ์ด์์์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค(ํ๋์ ์ ).
| uint32_t | uint32_t | uint32_t |
| attrs | codepoint | wcwidth |
์ฌ๊ธฐ์ attrs
์๋ ํ์ํ ๋ชจ๋ ํ๋๊ทธ + 9๋นํธ ๊ธฐ๋ฐ FG ๋ฐ BG ์์์ด ํฌํจ๋ฉ๋๋ค. codepoint
๋ 21๋นํธ(UTF32์ ๊ฒฝ์ฐ ์ต๋ 0x10FFFF) + 1๋นํธ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฌธ์๋ฅผ ๊ฒฐํฉํ๊ณ wcwidth
2๋นํธ(0-2 ๋ฒ์)๋ฅผ ๋ํ๋
๋๋ค.
์์ด๋์ด๋ ์ถ๊ฐ RGB ๊ฐ์ ์ํ ๊ณต๊ฐ์ ๋ง๋ค๊ธฐ ์ํด ๋นํธ๋ฅผ ๋ ๋์ ํฉ๋ฅ ๋ก ์ฌ๋ฐฐ์ดํ๋ ๊ฒ์ ๋๋ค.
wcwidth
๋ฅผ codepoint
์ ์ฌ์ฉ๋์ง ์์ ์์ โโ๋นํธ์ ๋ฃ์ต๋๋ค.| uint32_t | uint32_t | uint32_t |
| content | FG | BG |
| comb(1) wcwidth(2) codepoint(21) | flags(8) R(8) G(8) B(8) | flags(8) R(8) G(8) B(8) |
์ด ์ ๊ทผ ๋ฐฉ์์ ์ฅ์ ์ ํ๋์ ์ธ๋ฑ์ค ์ก์ธ์ค ๋ฐ ์ต๋๊ฐ์ผ๋ก ๋ชจ๋ ๊ฐ์ ๋น๊ต์ ์ ๋ ดํ๊ฒ ์ก์ธ์คํ ์ ์๋ค๋ ๊ฒ์ ๋๋ค. 2๋นํธ ์ฐ์ฐ(๋ฐ/๋๋ + ์ํํธ).
๋ฉ๋ชจ๋ฆฌ ํํ๋ฆฐํธ๋ ํ์ฌ ๋ณํ์ ๋ํด ์์ ์ ์ด์ง๋ง ์ฌ์ ํ ์
๋น 12๋ฐ์ดํธ๋ก ์๋นํ ๋์ต๋๋ค. ์ด๊ฒ์ UTF16 ๋ฐ attr
๊ฐ์ ์ผ๋ก ์ ํํ์ฌ ์ผ๋ถ ๋ฐํ์์ ํฌ์ํ์ฌ ์ถ๊ฐ๋ก ์ต์ ํํ ์ ์์ต๋๋ค.
| uint16_t | uint16_t |
| BMP codepoint(16) | comb(1) wcwidth(2) attr pointer(13) |
์ด์ ์ฐ๋ฆฌ๋ ์ ๋น 4๋ฐ์ดํธ + ์์ฑ์ ์ํ ์ฝ๊ฐ์ ๊ณต๊ฐ์ผ๋ก ์ค์์ต๋๋ค. ์ด์ ์์ฑ์ ๋ค๋ฅธ ์ ์๋ ์ฌํ์ฉ๋ ์ ์์ต๋๋ค. ์ผ ๋ฏธ์ ์์! - ์, ์ ์๋ง...
๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ๋น๊ตํ๋ฉด ๋ ๋ฒ์งธ ์ ๊ทผ ๋ฐฉ์์ด ํ์คํ ์ ๋ฆฌํฉ๋๋ค. ๋ฐํ์์ ๊ฒฝ์ฐ ๋ฐํ์์ ํฌ๊ฒ ์ฆ๊ฐ์ํค๋ ์ธ ๊ฐ์ง ์ฃผ์ ์์ธ์ด ์์ต๋๋ค.
๋ ๋ฒ์งธ ์ ๊ทผ ๋ฐฉ์์ ์น์ํจ์ ์ถ๊ฐ ๋ฉ๋ชจ๋ฆฌ ์ ์ฝ์
๋๋ค. ๋ฐ๋ผ์ ์์ ๋ BufferLine
๊ตฌํ์ ์ฌ์ฉํ์ฌ ๋์ดํฐ ๋ถ๊ธฐ(์ ์ฃผ์ ์ฐธ์กฐ)๋ก ํ
์คํธํ์ต๋๋ค.
์, ํ์์์ UTF8 + ํ์ํ๋ ๋ฐฐ์ด๋ก ๋ณ๊ฒฝํ๊ธฐ ์ ์ ์์ํ ์์น๋ก ๋์๊ฐ๋๋ค. ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ~ 1.5MB์์ ~ 0.7MB๋ก ๋จ์ด์ก์ต๋๋ค(87์ ๋ฐ 1000์ค ์คํฌ๋กค๋ฐฑ์ด ์๋ ๋ฐ๋ชจ ์ฑ).
์ฌ๊ธฐ์๋ถํฐ๋ ๋ฉ๋ชจ๋ฆฌ ์ ์ฝ๊ณผ ์๋์ ๋ฌธ์ ์ ๋๋ค. ์ฐ๋ฆฌ๋ ์ด๋ฏธ js ๋ฐฐ์ด์์ ์ ํ์ด ์ง์ ๋ ๋ฐฐ์ด๋ก ์ ํํ์ฌ ๋ง์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ฝํ์ผ๋ฏ๋ก(C++ ํ์ ๊ฒฝ์ฐ ~ 5.6MB์์ ~ 1.5MB๋ก ๊ฐ์ํ๊ณ ์ ๋ ํ JS ํ ๋์ ๋ฐ GC๋ฅผ ์ฐจ๋จํจ) ๋ ๋น ๋ฅธ ๋ณํ์ผ๋ก ์ฌ๊ธฐ์ ๊ฐ์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ์ด ๋ค์ ์๊ธํ ๋ฌธ์ ๊ฐ ๋๋๋ผ๋ ์ฌ๊ธฐ์ ๋ ๋ฒ์งธ ์ ๊ทผ ๋ฐฉ์์์ ์ค๋ช ํ ๋๋ก ๋ ์ปดํฉํธํ ๋ฒํผ ๋ ์ด์์์ผ๋ก ์ ํํ ์ ์์ต๋๋ค.
๋์ํฉ๋๋ค. ๋ฉ๋ชจ๋ฆฌ ์๋น๊ฐ ๋ฌธ์ ๊ฐ ๋์ง ์๋ ํ ์๋๋ฅผ ์ต์ ํํฉ์๋ค. ๋ํ ์ฝ๋๋ฅผ ์ฝ๊ณ ์ ์ง ๊ด๋ฆฌํ๊ธฐ ๋ ์ด๋ ต๊ฒ ๋ง๋ค๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฅํ ํ ๊ฐ์ ์ฐธ์กฐ๋ฅผ ํผํ๊ณ ์ถ์ต๋๋ค. ์ฐ๋ฆฌ๋ ์ด๋ฏธ ๋ง์ ์ฌ๋๋ค(์ ๋ฅผ ํฌํจํ์ฌ)์ด ์ฝ๋ ํ๋ฆ์ ๋ฐ๋ฅด๊ธฐ ์ด๋ ต๊ฒ ๋ง๋๋ ๋ง์ ๊ฐ๋ ๊ณผ ์กฐ์ ์ ์ฝ๋๋ฒ ์ด์ค์ ๊ฐ์ง๊ณ ์์ต๋๋ค. ์ด๋ฌํ ๊ฒ๋ค์ ๋ ๋ง์ด ๋์ ํ๋ ๊ฒ์ ํญ์ ์ ๋นํ ์ด์ ๊ฐ ์์ด์ผ ํฉ๋๋ค. IMO๊ฐ ๋ ๋ค๋ฅธ ๋ฉ๊ฐ๋ฐ์ดํธ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ฝํ๋ ๊ฒ์ ์ ๋นํ๋์ง ์์ต๋๋ค.
๊ทธ๋ผ์๋ ๋ถ๊ตฌํ๊ณ , ๋๋ ๋น์ ์ ์ฐ์ต์์ ์ฝ๊ณ ๋ฐฐ์ฐ๋ ๊ฒ์ ์ ๋ง๋ก ์ฆ๊ธฐ๊ณ ์์ต๋๋ค. ์์ฃผ ์์ธํ๊ฒ ๊ณต์ ํด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค!
@mofux ์
๊ทธ๋ฆฌ๊ณ 32๋นํธ ๋ ์ด์์์ ๋๋ถ๋ถ ํ๋ซ ๋ฉ๋ชจ๋ฆฌ(๋ฌธ์ ๊ฒฐํฉ์๋ง ๊ฐ์ ์ฐธ์กฐ๊ฐ ํ์ํจ)์ด๊ธฐ ๋๋ฌธ์ ๋ ๋ง์ ์ต์ ํ๊ฐ ๊ฐ๋ฅํฉ๋๋ค(๋ํ #1811์ ์ผ๋ถ, ๋ ๋๋ฌ์ ๋ํด ์์ง ํ
์คํธ๋์ง ์์).
attr ๊ฐ์ฒด์ ๋ํ ๊ฐ์ ์ง์ ์ ํ ๊ฐ์ง ํฐ ์ด์ ์ด ์์ต๋๋ค. ํจ์ฌ ๋ ํ์ฅ ๊ฐ๋ฅํ๋ค๋ ๊ฒ์
๋๋ค. ์ฃผ์, ๊ธ๋ฆฌํ ๋๋ ์ฌ์ฉ์ ์ ์ ํ์ธํ
๊ท์น์ ์ถ๊ฐํ ์ ์์ต๋๋ค. ๋งํฌ ์ ๋ณด๋ฅผ ๋ ๊น๋ํ๊ณ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ผ๋ก ์ ์ฅํ ์ ์์ต๋๋ค. ์๋ง๋ ์
์ ๋ ๋๋งํ๋ ๋ฐฉ๋ฒ์ ์๊ณ ์ฌ์ฉ์ ์ ์ ์์ฑ์ ๊ฑธ ์ ์๋ ICellPainter
์ธํฐํ์ด์ค๋ฅผ ์ ์ํ ์ ์์ต๋๋ค.
ํ ๊ฐ์ง ์์ด๋์ด๋ BufferLine๋น ๋ ๊ฐ์ ๋ฐฐ์ด(Uint32Array ๋ฐ ICellPainter ๋ฐฐ์ด)์ ์ฌ์ฉํ๊ณ ๊ฐ ์ ์ ๋ํด ๊ฐ๊ฐ ํ๋์ ์์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค. ํ์ฌ ICellPainter๋ ํ์ ์ํ์ ์์ฑ์ด๋ฏ๋ก ์์/์์ฑ ์ํ๊ฐ ๋ณ๊ฒฝ๋์ง ์๋ ํ ๋์ผํ ICellPainter๋ฅผ ์ฌ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค. ์ ์ ํน์ ์์ฑ์ ์ถ๊ฐํด์ผ ํ๋ ๊ฒฝ์ฐ ๋จผ์ ICellPainter๋ฅผ ๋ณต์ ํฉ๋๋ค(๊ณต์ ๋ ์ ์๋ ๊ฒฝ์ฐ).
๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ์์/์์ฑ ์กฐํฉ์ ๋ํด ICellPainter๋ฅผ ๋ฏธ๋ฆฌ ํ ๋นํ ์ ์์ต๋๋ค. ์ต์ํ ๊ธฐ๋ณธ ์์/์์ฑ์ ํด๋นํ๋ ๊ณ ์ ํ ๊ฐ์ฒด๊ฐ ์์ด์ผ ํฉ๋๋ค.
์คํ์ผ ๋ณ๊ฒฝ(์: ๊ธฐ๋ณธ ์ ๊ฒฝ/๋ฐฐ๊ฒฝ ์์ ๋ณ๊ฒฝ)์ ๊ฐ ์ ์ ์ ๋ฐ์ดํธํ ํ์ ์์ด ํด๋น ICellPainter ์ธ์คํด์ค๋ฅผ ์ ๋ฐ์ดํธํ๊ธฐ๋ง ํ๋ฉด ๊ตฌํํ ์ ์์ต๋๋ค.
๊ฐ๋ฅํ ์ต์ ํ๊ฐ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ๋จ์ผ ๋๋น ๋ฐ ์ด์ค ๋๋น ๋ฌธ์(๋๋ ๋๋น๊ฐ 0์ธ ๋ฌธ์)์ ๋ํด ๋ค๋ฅธ ICellPainter ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํฉ๋๋ค. (์ด๋ ๊ฐ Uint32Array ์์์ 2๋นํธ๋ฅผ ์ ์ฅํฉ๋๋ค.) Uint32Array์๋ 11๊ฐ์ ์ฌ์ฉ ๊ฐ๋ฅํ ์์ฑ ๋นํธ๊ฐ ์์ต๋๋ค(BMP ๋ฌธ์์ ๋ํด ์ต์ ํํ๋ฉด ๋ ๋ง์ด). ์ด๋ค์ ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ICellPainter ์ธ์คํด์ค๋ฅผ ์ธ๋ฑ์ฑํ๋ ๋ฐ ์ฌ์ฉํ ์ ์๋ ๊ฐ์ฅ ์ผ๋ฐ์ /์ ์ฉํ ์์/์์ฑ ์กฐํฉ์ ์ธ์ฝ๋ฉํ๋ ๋ฐ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๊ทธ๋ ๋ค๋ฉด ICellPainter ๋ฐฐ์ด์ ๋๋ฆฌ๊ฒ ํ ๋น๋ ์ ์์ต๋๋ค. ์ฆ, ๋ผ์ธ์ ์ผ๋ถ ์ ์ "๋ ์ผ๋ฐ์ ์ธ" ICellPainter๊ฐ ํ์ํ ๊ฒฝ์ฐ์๋ง ๊ฐ๋ฅํฉ๋๋ค.
BMP๊ฐ ์๋ ๋ฌธ์์ ๋ํ _combined ๋ฐฐ์ด์ ์ ๊ฑฐํ๊ณ ICellPainter์ ์ ์ฅํ ์๋ ์์ต๋๋ค. (์ด๋ฅผ ์ํด์๋ BMP๊ฐ ์๋ ๊ฐ ์บ๋ฆญํฐ์ ๋ํด ๊ณ ์ ํ ICellPainter๊ฐ ํ์ํ๋ฏ๋ก ์ฌ๊ธฐ์๋ ์ ์ถฉ์ ์ด ์์ต๋๋ค.)
@PerBothner ์ ๊ฐ์ ์ฐธ์กฐ๋ ๋ ๋ค์ฌ๋ค๋ฅํ๋ฏ๋ก ๋๋ฌธ ์ถ๊ฐ ๊ธฐ๋ฅ์ ๋ ์ ํฉํฉ๋๋ค. ํ์ง๋ง ์ด๋๋ค์ ํํ์ง ์๊ธฐ ๋๋ฌธ์ ์ ์ด์ ์ต์ ํ๋ฅผ ํ์ง ์์ผ๋ ค๊ณ ํฉ๋๋ค.
๋ด๊ฐ ์ฌ๋ฌ ํ ์คํธ๋ฒ ๋์์ ์๋ํ ๊ฒ์ ๋ํ ๋ช ๊ฐ์ง ๋ฉ๋ชจ:
codepoint
์ ๊ฒฐํฉ๋ ๋นํธ ์ธํธ๊ฐ ์์ ๋ ์ธ๋ฑ์ฑํ ๋ฉ๋ชจ๋ฆฌ ๋ฉ์ด๋ฆฌ์ธ ์
์ฝํ
์ธ ๊ฒฐํฉ์ ๋ํ ํด๊ฒฐ ๋ฐฉ๋ฒ์ผ๋ก ๋ช
ํํด์ก์ต๋๋ค(valgrind๋ก ํ
์คํธํ ๋ ๋์ ์บ์ ์ง์ญ์ฑ์ผ๋ก ์ธํด ์ก์ธ์ค๊ฐ ๋ ๋น ๋ฆ). JS๋ก ์ด์๋ ์๋ ํฅ์์ ํ์ํ ๋ฌธ์์ด์์ ์ซ์๋ก์ ๋ณํ(์ฌ์ ํ ๋ ๋น ๋ฆ)์ผ๋ก ์ธํด ๊ทธ๋ค์ง ํฌ์ง ์์์ง๋ง ๋ฉ๋ชจ๋ฆฌ ์ ์ฝ์ ํจ์ฌ ๋ ์ปธ์ต๋๋ค(JS ์ ํ์ ๋ํ ์ผ๋ถ ์ถ๊ฐ ๊ด๋ฆฌ ๊ณต๊ฐ์ผ๋ก ์ธํด). ๋ฌธ์ ๋ JS์ ํฐ ๋ฐํจํด์ธ ๋ช
์์ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ์ ๊ฒฐํฉ๋ ์ ์ฒด StringStorage
์์ต๋๋ค. ์ด์ ๋ํ ๋น ๋ฅธ ์์ ์ ์ ๋ฆฌ๋ฅผ GC์ ์์ํ๋ _combined
๊ฐ์ฒด์์ต๋๋ค. ์ฌ์ ํ ๋ณ๊ฒฝ๋ ์ ์์ผ๋ฉฐ btw๋ ์์์ ์
๊ด๋ จ ๋ฌธ์์ด ๋ด์ฉ์ ์ ์ฅํ๊ธฐ ์ํ ๊ฒ์
๋๋ค(์์์๋ฅผ ์ผ๋์ ๋๊ณ ์ด ์์
์ ์ํํ์ง๋ง ๋ฐฑ์๋์์ ์ง์ํ์ง ์์ผ๋ฏ๋ก ๊ณง ๋ณผ ์ ์์ ๊ฒ์
๋๋ค). ๋ฐ๋ผ์ ์
๋จ์๋ก ์ถ๊ฐ ๋ฌธ์์ด ๋ด์ฉ์ ์ ์ฅํ๋ ๊ณณ์
๋๋ค.AttributeStorage
๋ฅผ ์ฌ์ฉํ์ฌ "ํฌ๊ฒ ์๊ฐ"ํ๊ธฐ ์์ํ์ต๋๋ค(https://github.com/jerch/xterm.js/tree/AttributeStorage ์ฐธ์กฐ). ๋ฉ๋ชจ๋ฆฌ ์ธก๋ฉด์์ ์ด๊ฒ์ ๊ฝค ์ข์ ๊ฒฐ๊ณผ๋ฅผ ์ป์์ต๋๋ค. ์ฃผ๋ก ppl์ด ํธ๋ฃจ ์ปฌ๋ฌ ์ง์์ด ์๋ ๊ฒฝ์ฐ์๋ ์์ ์์ฑ ์ธํธ๋ง ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์
๋๋ค. ์ฑ๋ฅ์ ๊ทธ๋ค์ง ์ข์ง ์์์ต๋๋ค. ์ฃผ๋ก ref ์นด์ดํ
(๋ชจ๋ ์
์ด ์ด ์ธ๋ถ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ ๋ฒ ์ฟ๋ด์ผ ํจ) ๋ฐ attr ์ผ์น ๋๋ฌธ์
๋๋ค. ๊ทธ๋ฆฌ๊ณ ref๋ฅผ JS์ ์ ์ฉํ๋ ค๊ณ ํ์ ๋ ์๋ชป๋ ๋๋์ด ๋ค์์ต๋๋ค. ๋ฐ๋ก "STOP" ๋ฒํผ์ ๋๋ ๋ค๋ ์ ์
๋๋ค. ๊ทธ ์ฌ์ด์ ์ด๋ฏธ ํ์ํ๋ ๋ฐฐ์ด๋ก ์ ํํ์ฌ ์๋ง์ ๋ฉ๋ชจ๋ฆฌ ๋ฐ GC ํธ์ถ์ ์ ์ฝํ์ผ๋ฉฐ ๋ฐ๋ผ์ ์ฝ๊ฐ ๋ ๋น์ผ ํ๋ซ ๋ฉ๋ชจ๋ฆฌ ๋ ์ด์์์ด ์๋ ์ด์ ์ ๋ณด์ํ ์ ์์ต๋๋ค.์ด์ ์ด ํํํ 32๋นํธ ๋ ์ด์์์ ์ผ๋ฐ์ ์ธ ๊ฒ๋ค์ ์ต์ ํ๋ ๊ฒ์ผ๋ก ๋ฐํ์ก์ผ๋ฉฐ ์ผ๋ฐ์ ์ด์ง ์์ ์ถ๊ฐ ๊ธฐ๋ฅ์ ๋ถ๊ฐ๋ฅํฉ๋๋ค. ์ง์ค. ๊ธ์, ์ฐ๋ฆฌ๋ ์ฌ์ ํ ๋ง์ปค๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค(์ด๋ค์ ์ต์ํ์ง ์์์ ๊ทธ๋ค์ด ๋ฌด์์ ํ ์ ์๋์ง ์ง๊ธ ๋น์ฅ์ ๋งํ ์ ์์ต๋๋ค). ๊ทธ๋ฆฌ๊ณ yepp - ๋ฒํผ์ ์ฌ์ ํ ์ฌ์ ๋นํธ๊ฐ ์์ต๋๋ค(์ด๋ ๋ฏธ๋์ ํ์๋ฅผ ์ํด ์ข์ ๊ฒ์ ๋๋ค. ์๋ฅผ ๋ค์ด ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์์ต๋๋ค. ํน๋ณ ๋์ฐ๋ฅผ ์ํ ๊น๋ฐ ๋ฑ).
์ ์๊ฒ๋ attrs ์คํ ๋ฆฌ์ง๊ฐ ์๋ 16๋นํธ ๋ ์ด์์์ด ๊ทธ๋ ๊ฒ ๋์ ์ฑ๋ฅ์ ๋ฐํํ๋ ๊ฒ์ด ์ ๊ฐ์ ๋๋ค. ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ์ ๋ฐ์ผ๋ก ์ค์ด๋ ๊ฒ์ ์ฌ์ ํ โโํฐ ๋ฌธ์ ์ ๋๋ค(ํนํ ppl์ด ์คํฌ๋กค ๋ผ์ธ >10k๋ฅผ ์ฌ์ฉํ๊ธฐ ์์ํ ๋). ๊ทธ๋ฌ๋ ๋ฐํ์ ํจ๋ํฐ์ ์ฝ๋ ๋ณต์ก์ฑ์ด ๋ ์ค์ํฉ๋๋ค. ์์ mem์ atm imho๊ฐ ํ์ํฉ๋๋ค.
ICellPainter ์์ด๋์ด์ ๋ํด ์์ธํ ์ค๋ช ํด ์ฃผ์๊ฒ ์ต๋๊น? ์ง๊ธ๊น์ง ์ค์ํ ๊ธฐ๋ฅ์ ๋์ณค์ ์๋ ์์ต๋๋ค.
DomTerm์ ๋ํ ์ ๋ชฉํ๋ ๊ธฐ์กด ํฐ๋ฏธ๋ ์๋ฎฌ๋ ์ดํฐ์์ ํ์ฑํ๋ ๊ฒ๋ณด๋ค ๋ ํ๋ถํ ์ํธ ์์ฉ์ ํ์ฑํํ๊ณ ์ฅ๋ คํ๋ ๊ฒ์ด์์ต๋๋ค. ์น ๊ธฐ์ ์ ์ฌ์ฉํ๋ฉด ๋ง์ ํฅ๋ฏธ๋ก์ด ์ผ์ ํ ์ ์์ผ๋ฏ๋ก ๋น ๋ฅธ ๊ธฐ์กด ํฐ๋ฏธ๋ ์๋ฎฌ๋ ์ดํฐ์๋ง ์ง์คํ๋ ๊ฒ์ ๋ถ๋๋ฌ์ด ์ผ์ ๋๋ค. ํนํ xterm.js์ ๋ง์ ์ฌ์ฉ ์ฌ๋ก(์: IDE์ฉ REPL)๋ ๋จ์ํ ํ ์คํธ ์ด์์ ์ด์ ์ ์ป์ ์ ์๊ธฐ ๋๋ฌธ์ ํนํ ๊ทธ๋ ์ต๋๋ค. Xterm.js๋ ์๋ ์ธก๋ฉด์์ ์ ์๋ํ์ง๋ง(์๋์ ๋ํด ๋ถํํ๋ ์ฌ๋์ด ์์ต๋๊น?), ๊ธฐ๋ฅ์์๋ ๊ทธ๋ ์ง ์์ต๋๋ค(์๋ฅผ ๋ค์ด ์ฌ๋๋ค ์ด ํธ๋ฃจ์ปฌ๋ฌ ๋ฐ ๋ด์ฅ ๊ทธ๋ํฝ ๋๋ฝ์ ๋ํด ๋ถํํ๊ณ ์์ต๋๋ค). ์ ์ฐ์ฑ์ ์กฐ๊ธ ๋ ์ง์คํ๊ณ ์ฑ๋ฅ์๋ ์ฝ๊ฐ ๋ ์ง์คํ๋ ๊ฒ์ด ๊ฐ์น๊ฐ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
_"ICellPainter ์์ด๋์ด์ ๋ํด ์์ธํ ์ค๋ช ํด ์ฃผ์๊ฒ ์ต๋๊น?"_
์ผ๋ฐ์ ์ผ๋ก ICellPainter๋ Uint32Array์์ ๊ฐ์ ธ์จ ๋ฌธ์ ์ฝ๋/๊ฐ์ ์ ์ธํ ๋ชจ๋ ์ ๋ณ ๋ฐ์ดํฐ๋ฅผ ์บก์ํํฉ๋๋ค. ์ด๋ "์ผ๋ฐ" ๋ฌธ์ ์ ์ ๊ฒฝ์ฐ์ ๋๋ค. ํฌํจ๋ ์ด๋ฏธ์ง ๋ฐ ๊ธฐํ "์์"์ ๊ฒฝ์ฐ ๋ฌธ์ ์ฝ๋/๊ฐ์ด ์๋ฏธ๊ฐ ์์ ์ ์์ต๋๋ค.
interface ICellPainter {
drawOnCanvas(ctx: CanvasRenderingContext2D, code: number, x: number, y: number);
// transitional - to avoid allocating IGlyphIdentifier we should replace
// uses by pair of ICellPainter and code. Also, a painter may do custom rendering,
// such that there is no 'code' or IGlyphIdentifier.
asGlyph(code: number): IGlyphIdentifier;
width(): number; // in pixels for flexibility?
height(): number;
clone(): ICellPainter;
}
์ ์ ICellPainter์ ๋งคํํ๋ ๊ฒ์ ๋ค์ํ ๋ฐฉ๋ฒ์ผ๋ก ์ํํ ์ ์์ต๋๋ค. ๋ถ๋ช ํ ๊ฒ์ ๊ฐ BufferLine์ ICellPainter ๋ฐฐ์ด์ด ์์ง๋ง ์ ๋น 8๋ฐ์ดํธ ํฌ์ธํฐ(์ต์ํ)๊ฐ ํ์ํ๋ค๋ ๊ฒ์ ๋๋ค. ํ ๊ฐ์ง ๊ฐ๋ฅ์ฑ์ _combined ๋ฐฐ์ด์ ICellPainter ๋ฐฐ์ด๊ณผ ๊ฒฐํฉํ๋ ๊ฒ์ ๋๋ค. IS_COMBINED_BIT_MASK๊ฐ ์ค์ ๋๋ฉด ICellPainter๋ ๊ฒฐํฉ๋ ๋ฌธ์์ด์ ํฌํจํฉ๋๋ค. ๋ ๋ค๋ฅธ ๊ฐ๋ฅํ ์ต์ ํ๋ Uint32Array์์ ์ฌ์ฉ ๊ฐ๋ฅํ ๋นํธ๋ฅผ ๋ฐฐ์ด์ ๋ํ ์ธ๋ฑ์ค๋ก ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ฝ๊ฐ์ ๋ณต์ก์ฑ๊ณผ ๊ฐ์ ์ฐธ์กฐ๊ฐ ์ถ๊ฐ๋์ง๋ง ๊ณต๊ฐ์ด ์ ์ฝ๋ฉ๋๋ค.
๋๋ ์ฐ๋ฆฌ๊ฐ monaco-editor๊ฐ ํ๋ ๋ฐฉ์๋๋ก ํ ์ ์๋์ง ํ์ธํ๋๋ก ๊ถ์ฅํ๊ณ ์ถ์ต๋๋ค. ์ด๋ฌํ ์ ๋ณด๋ฅผ ๋ฒํผ์ ์ ์ฅํ๋ ๋์ decorations
๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ํ / ์ด ๋ฒ์์ ๋ํ ์ฅ์์ ๋ง๋ค๊ณ ํด๋น ๋ฒ์์ ๊ณ ์ ๋ฉ๋๋ค.
// decorations are buffer-dependant (we need to know which buffer to decorate)
const decoration = buffer.createDecoration({
type: 'link',
data: 'https://www.google.com',
range: { startRow: 2, startColumn: 5, endRow: 2, endColumn: 25 }
});
๋์ค์ ๋ ๋๋ฌ๋ ์ด๋ฌํ ์ฅ์์ ์ ํํ์ฌ ๊ทธ๋ฆด ์ ์์ต๋๋ค.
monaco-editor API๊ฐ ์ด๋ป๊ฒ ๋ณด์ด๋์ง ๋ณด์ฌ์ฃผ๋ ์ด ์์ ์๋ฅผ ํ์ธํ์ญ์์ค.
https://microsoft.github.io/monaco-editor/playground.html#interacting -with-the-editor-line-and-inline-decorations
ํฐ๋ฏธ๋ ๋ด๋ถ์์ ๊ทธ๋ฆผ์ ๋ ๋๋งํ๋ ๊ฒ๊ณผ ๊ฐ์ ๊ฒฝ์ฐ monaco๋ ๋ค์ ์์์ ๋ณผ ์ ์๋ ๋ณด๊ธฐ ์์ญ ๊ฐ๋
์ ์ฌ์ฉํฉ๋๋ค(๋ค๋ฅธ ๊ฐ๋
์ค์์).
https://microsoft.github.io/monaco-editor/playground.html#interacting -with-the-editor-listening-to-mouse-events
์ค๋ช ๊ณผ ์ค์ผ์น์ ์ ์ํด
์ฐ๋ฆฌ๋ ๊ฒฐ๊ตญ ๋ฏธ๋์ ์
๋ ฅ ์ฒด์ธ + ๋ฒํผ๋ฅผ ์น ์์
์๋ก ์ด๋ํ ๊ณํ์
๋๋ค. ๋ฐ๋ผ์ ๋ฒํผ๋ ์ถ์ ์์ค์์ ์๋ํ๋๋ก ๋์ด ์์ผ๋ฉฐ ํฝ์
๋ฉํธ๋ฆญ์ด๋ DOM ๋
ธ๋์ ๊ฐ์ ๋ ๋๋ง/ํํ ๊ด๋ จ ํญ๋ชฉ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. DomTerm์ ๊ณ ๋๋ก ์ฌ์ฉ์ ์ ์ํ ์ ์๊ธฐ ๋๋ฌธ์ ์ด์ ๋ํ ์๊ตฌ ์ฌํญ์ด ์๋ค๊ณ ์๊ฐํ์ง๋ง ํฅ์๋ ๋ด๋ถ ๋ง์ปค API๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฅผ ์ํํด์ผ ํ๋ฉฐ ์ฌ๊ธฐ์์ monaco/vscode(thx for th ํฌ์ธํฐ @mofux)์์ ๋ฐฐ์ธ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ ๋ ์ฝ์ด ๋ฒํผ๋ฅผ ๋น์ผ์์ ์ธ ๊ฒ์ผ๋ก ์ ์งํ๊ณ ์ถ์ต๋๋ค. ์๋ก์ด ๋ฌธ์ ๋ก ๊ฐ๋ฅํ ๋ง์ปค ์ ๋ต์ ๋ํด ๋
ผ์ํด์ผ ํ ๊น์?
16๋นํธ ๋ ์ด์์ ํ ์คํธ ๊ฒฐ๊ณผ๊ฐ ์ฌ์ ํ ๋ง์กฑ์ค๋ฝ์ง ์์ต๋๋ค. ์ต์ข ๊ฒฐ์ ์ด ์์ง ์๊ธํ์ง ์๊ธฐ ๋๋ฌธ์(3.11 ์ด์ ์๋ ์ด ์ค ์ด๋ ๊ฒ๋ ๋ณผ ์ ์์) ๋ช ๊ฐ์ง ๋ณ๊ฒฝ ์ฌํญ์ผ๋ก ๊ณ์ ํ ์คํธํ ๊ฒ์ ๋๋ค(32๋นํธ ๋ณํ๋ณด๋ค ์ฌ์ ํ ๋ ํฅ๋ฏธ๋ก์ด ์๋ฃจ์ ์ ๋๋ค).
| uint32_t | uint32_t | uint32_t | | content | FG | BG | | comb(1) wcwidth(2) codepoint(21) | flags(8) R(8) G(8) B(8) | flags(8) R(8) G(8) B(8) |
๋๋ ๋ํ ์์ํ๊ธฐ ์ํด ์ด๊ฒ์ ๊ฐ๊น์ด ๊ฒ์ผ๋ก ๊ฐ์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋์ค์ ๋ค๋ฅธ ์ต์ ์ ํ์ํ ์ ์์ง๋ง ์ด๊ฒ์ด ์๋ง๋ ์์ํ๊ณ ์คํํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ฌ์ธ ๊ฒ์ ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ํฐ๋ฏธ๋ ์ธ์ ์๋ ๊ณ ์ ํ ์์ฑ์ด ๋ง์ง ์๊ธฐ ๋๋ฌธ์ ์์ฑ ๊ฐ์ ์ฐธ์กฐ๋ ํ์คํ IMO๋ฅผ ์ฝ์ํฉ๋๋ค.
๋๋ ์ฐ๋ฆฌ๊ฐ monaco-editor๊ฐ ํ๋ ๋ฐฉ์๋๋ก ํ ์ ์๋์ง ํ์ธํ๋๋ก ๊ถ์ฅํ๊ณ ์ถ์ต๋๋ค. ์ด๋ฌํ ์ ๋ณด๋ฅผ ๋ฒํผ์ ์ ์ฅํ๋ ๋์ ์ฅ์์ ๋ง๋ค ์ ์์ต๋๋ค. ํ / ์ด ๋ฒ์์ ๋ํ ์ฅ์์ ๋ง๋ค๊ณ ํด๋น ๋ฒ์์ ๊ณ ์ ๋ฉ๋๋ค.
์ด๋ฐ ์ผ์ด ์ผ์ด๋๋ ๊ฒ์ ๋ณด๊ณ ์ถ์ ๊ณณ์ ๋๋ค. ์ด๋ฌํ ๋ผ์ธ์ ๋ฐ๋ผ ๋ด๊ฐ ๊ฐ์ง ํ ๊ฐ์ง ์์ด๋์ด๋ ์๋ฒ ๋๊ฐ DOM ์์๋ฅผ ๋ฒ์์ ์ฒจ๋ถํ์ฌ ์ฌ์ฉ์ ์ ์ ํญ๋ชฉ์ ๊ทธ๋ฆด ์ ์๋๋ก ํ๋ ๊ฒ์ด์์ต๋๋ค. ์ด ์์ ์ผ๋ก ๋ฌ์ฑํ๊ณ ์ถ์ ์๊ฐ์ ์๊ฐํ ์ ์๋ 3๊ฐ์ง๊ฐ ์์ต๋๋ค.
์ด ๋ชจ๋ ๊ฒ์ ์ค๋ฒ๋ ์ด๋ก ๋ฌ์ฑํ ์ ์์ผ๋ฉฐ ์ด๋ ๋งค์ฐ ์ ๊ทผํ๊ธฐ ์ฌ์ด API ์ ํ(DOM ๋ ธ๋ ๋ ธ์ถ)์ด๋ฉฐ ๋ ๋๋ฌ ์ ํ์ ๊ด๊ณ์์ด ์๋ํ ์ ์์ต๋๋ค.
์๋ฒ ๋๊ฐ ๋ฐฐ๊ฒฝ์๊ณผ ์ ๊ฒฝ์์ ๊ทธ๋ฆฌ๋ ๋ฐฉ์์ ๋ณ๊ฒฝํ ์ ์๋๋ก ํ๋ ์ฌ์ ์ ๋ฐ์ด๋ค๊ณ ์ถ์์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.
@jerch ๋๋ ์ด๊ฒ์ 3.11.0 ์ด์ ํ์ ๋ฃ์ ๊ฒ์ ๋๋ค. ๊ทธ๋์ ๊ณํ๋ JS ๋ฐฐ์ด ๊ตฌํ์ ์ ๊ฑฐํ ๋ ์ด ๋ฌธ์ ๊ฐ ์๋ฃ๋ ๊ฒ์ผ๋ก ๊ฐ์ฃผํ๊ธฐ ๋๋ฌธ์ ๋๋ค. https://github.com/xtermjs/xterm.js/pull/1796 ๋ ๊ทธ๋ ๋ณํฉ๋ ์์ ์ด์ง๋ง, ์ด ๋ฌธ์ ๋ ํญ์ ๋ฒํผ์ ๋ฉ๋ชจ๋ฆฌ ๋ ์ด์์์ ๊ฐ์ ํ๊ธฐ ์ํ ๊ฒ์ด์์ต๋๋ค.
๋ํ, ์ด ๋์ค ๋ ผ์์ ๋๋ถ๋ถ์ https://github.com/xtermjs/xterm.js/issues/484 ๋ฐ https://github.com/xtermjs/xterm.js/issues/1852 ์์ ๋ ๋์ ๊ฒ์ ๋๋ค. (์ฅ์ ๋ฌธ์ ๊ฐ ์์๊ธฐ ๋๋ฌธ์ ์์ฑ๋จ).
@Tyriar Woot - ๋ง์นจ๋ด ๋ซํ์ต๋๋ค :sweat_smile:
๐ ๐บ ๐พ
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
ํ์ฌ ์ํ:
ํ์: