Skip to content

Commit 47af810

Browse files
committed
Standardize naming to FastTerminalRenderer/FastTerminalScene, add Ansi helper, and update TODO.md
1 parent f608518 commit 47af810

18 files changed

Lines changed: 286 additions & 280 deletions

File tree

Data.txt

Lines changed: 114 additions & 59 deletions
Large diffs are not rendered by default.

TODO.md

Lines changed: 17 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -1,139 +1,17 @@
1-
# FastTerminal — Technical Roadmap & TODO List
2-
3-
This document acts as our development roadmap and architectural design system for building a zero-dependency, ultra-fast, true-color, and emoji-enabled terminal rendering engine for Java.
4-
5-
---
6-
7-
## 🛠️ Part 1: Current Bugs & Architectural Fixes
8-
Below are the analyzed flaws of the initial implementation and how we will resolve them.
9-
10-
### 1. `TerminalScene` — Dirty-Flag Semantics
11-
* **❌ The Bug**: `update()` sets `dirty = true`, but `render()` immediately clears it to `false`. This causes scenes to render only when external log events fire, while any background animations (like a title spinner or real-time ticker) freeze.
12-
* **✔ The Fix**: `update()` must *not* set `dirty = true`. The `dirty` state indicates whether the renderer needs to pull changes, not that the scene has just re-calculated itself.
13-
```java
14-
public void update() {
15-
if (this.updater != null) {
16-
this.clear();
17-
this.updater.run();
18-
// REMOVE: this.dirty = true;
19-
}
20-
}
21-
```
22-
Dirty propagation will be triggered externally via timers, keypresses, or callbacks.
23-
24-
### 2. CLILogger / RenderersBuffer Overwrite
25-
* **The Bug**: When updating a line of text in the character buffer, if the new line is shorter than the old one, the trailing characters from the old line remain visible.
26-
* **✔ The Fix**: Prior to drawing new content to a line in a text buffer, fill the line range with empty space characters:
27-
```java
28-
Arrays.fill(buffer, bufferStart, bufferStart + this.getWidth(), ' ');
29-
```
30-
31-
### 3. `TerminalRenderer` — Composite Buffer Lifecycle
32-
* **The Bug**: `TerminalRenderer` does a `System.arraycopy(...)` but never clears the `compositeBuffer` between frames, resulting in ghost characters and rendering artifacts.
33-
* **The Fix**: Clear the entire `compositeBuffer` with spaces at the beginning of each `render()` pass.
34-
```java
35-
public void render() {
36-
this.clear(); // Clear before painting
37-
System.out.print("\033[1;1H");
38-
...
39-
}
40-
```
41-
42-
### 4. `TerminalRenderer` — Alternate Screen & Cursor Resets
43-
* **The Bug**: Cursor reset via `\033[1;1H` works, but without clearing the screen or using an alternate buffer, artifacts persist in unused space.
44-
* **The Fix**: Use alternate screen buffer ANSI sequences (`\033[?1049h`) to take over the terminal in full-screen mode, hide the cursor (`\033[?25l`), and properly clear the viewport.
45-
46-
### 5. `CLIScene` — Resize-Handling & Listener Leaks
47-
* **The Bug**: Re-adding scenes and listeners on resize causes potential race-conditions and memory leaks if listeners are not cleanly detached beforehand.
48-
* **The Fix**: Securely detach and clean up listeners before any recreation occurs:
49-
```java
50-
Log.removeListener(logListener);
51-
```
52-
53-
### 6. `TerminalScene.dispose()` Null-Safety
54-
* **The Bug**: Setting `charBuffer = null` inside `dispose()` results in a immediate `NullPointerException` if `insertScene()` is invoked right after.
55-
* **The Fix**: Establish rigorous state checks and ensure scenes are removed from the active renderer list during cleanup.
56-
57-
---
58-
59-
## 🚀 Part 2: The Path to Independence, Speed, & True Color
60-
We are focusing on direct OS native hooks to achieve zero latency, full UTF-8 capabilities, alternate screen buffers, and high-performance JNI integration.
61-
62-
### 📋 1. Zero-Dependency Dimension Queries
63-
* **Terminal Dimensions**: Retrieve screen buffer info natively using `GetConsoleScreenBufferInfo` on Windows (via JNI) and `ioctl(TIOCGWINSZ)` on Linux/macOS.
64-
* **Keyboard Input**: Integrate directly with `FastKeyboard` to handle asynchronous raw mode input.
65-
* **Console Raw Mode**: Toggle echo and raw modes directly using native JNI calls:
66-
* **Windows**: `SetConsoleMode(hIn, ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT)`
67-
* **Linux**: `tcsetattr`
68-
69-
### 🎨 2. True Color (24-bit RGB) Support
70-
Instead of being limited to 16 basic colors, we will support full 24-bit True Color using standard ANSI escape codes:
71-
* **Foreground Color**: `\033[38;2;R;G;Bm`
72-
* **Background Color**: `\033[48;2;R;G;Bm`
73-
* *Example*: `System.out.print("\033[38;2;255;120;0mHello 24-bit Orange!\033[0m");`
74-
75-
### 🌐 3. Full Emoji & Unicode Support (Codepoints)
76-
Standard Java `char` values are UTF-16, meaning emojis occupy 2 or 4 chars. If we do standard character-by-character length checking, emojis break and warp lines.
77-
* **Solution**: Transition our internal text representation and buffer arrays from `char[]` to **Codepoint-based arrays (`int[]`)** or UTF-8 byte streams.
78-
79-
### ⚡ 4. Alternate Screen Buffer & WriteConsoleOutputW
80-
To achieve game-like performance (60120 FPS):
81-
* **ANSI Fullscreen (Alternate Screen Buffer)**:
82-
* `\033[?1049h` — Enter alternate screen buffer (hides existing terminal prompt history).
83-
* `\033[?25l` — Hide cursor.
84-
* `\033[?1049l` — Exit alternate screen buffer (restores prompt context).
85-
* **Windows JNI Fast-Path (`WriteConsoleOutputW`)**:
86-
* Instead of converting buffers to Java strings and printing to `System.out`, we will use the native Windows console API `WriteConsoleOutputW`. This allows copying our entire double-buffered grid directly to the console hardware buffer in a single native call, yielding 10x-20x higher throughput.
87-
88-
### 📥 5. Dynamic Progress Bars (apt / curl style)
89-
For downloads, installers, and live pipelines, we will implement dynamic bottom-anchored multiline progress indicators using ANSI cursor preservation:
90-
* `\033[s` — Save cursor position.
91-
* `\033[row;colH` — Move to progress bar row.
92-
* `\033[2K` — Clear current line.
93-
* Update live progress (True Color + Emojis).
94-
* `\033[u` — Restore cursor to original position for seamless logging.
95-
96-
---
97-
98-
## 🏗️ Part 3: Architecture & Class Structure
99-
100-
Our unified `FastTerminal` module will have a streamlined, modular layout:
101-
102-
```
103-
FastTerminal
104-
├── FastTerminalNative (JNI wrapper)
105-
│ ├── getTerminalSize() --> returns [cols, rows]
106-
│ ├── setRawMode(boolean active) --> configures terminal flags
107-
│ └── writeConsoleOutput(...) --> Windows Console API direct blit
108-
├── FastTerminalRenderer
109-
│ ├── frontBuffer (int[] codepoints)
110-
│ ├── backBuffer (int[] codepoints)
111-
│ ├── diff() --> compares buffers for minimum writes
112-
│ └── render() --> outputs changes
113-
└── FastTerminalScene
114-
├── update()
115-
└── draw()
116-
```
117-
118-
---
119-
120-
## 📝 TODO Checklist
121-
122-
### Phase 1: Cleanup & Restructuring
123-
* [ ] Remove legacy demo files (`CLILogger.java`, `CLITitle.java`).
124-
* [ ] Move core terminal classes (`TerminalRenderer.java`, `TerminalScene.java`, `CLIScene.java`) into the new Mavenized project package (`fastterminal`).
125-
* [ ] Refactor Maven `pom.xml` to include `FastCore` dependency and target Java 17+.
126-
127-
### Phase 2: Native JNI Core
128-
* [ ] Implement native C++ functions in `native/` for `GetConsoleScreenBufferInfo` and console mode setup.
129-
* [ ] Integrate JNI bindings in `FastTerminalNative.java` to allow querying terminal dimensions dynamically.
130-
* [ ] Build compilation script (`compile.bat`) aligned with Java 17+ and MSVC compiler.
131-
132-
### Phase 3: Codepoints & True Color
133-
* [ ] Refactor `TerminalScene` buffer representation to use `int[]` for safe UTF-32/Unicode Codepoint handling.
134-
* [ ] Build high-level True Color formatting builders for foreground and background.
135-
* [ ] Implement Double Buffering logic in `TerminalRenderer` to support diff-based ANSI rendering.
136-
137-
### Phase 4: Dynamic Views & Demos
138-
* [ ] Create a standalone demo displaying high-refresh rate live widgets, true-color patterns, and emojis.
139-
* [ ] Create a curl/npm-like progress bar demonstration that updates the bottom of the screen dynamically while terminal logs print above.
1+
# FastTerminal TODO
2+
3+
Hier ist die trockene, tabellarische Übersicht — ohne Deko, ohne Ausschweifen:
4+
5+
| Bereich | Was man machen könnte |
6+
| :--- | :--- |
7+
| **Rendering** | Diff-Rendering, Dirty-Rectangles, Double-Buffering, Partial Flush |
8+
| **Input** | Maus-Events, Key-Events, Modifier-Keys, Drag‑Tracking |
9+
| **Layout** | Flex-Layout, Grid-Layout, Anchors, Auto-Resize |
10+
| **Widgets** | Buttons, Panels, Textbox, Scrollview, Progressbar |
11+
| **Text** | UTF‑8 Parser, Emoji Width Fixes, Word-Wrap, Text-Shaping |
12+
| **Color** | 24‑bit Gradients, Paletten, Themes, Alpha‑Compositing |
13+
| **Performance** | SIMD‑Blitting, Native Line‑Drawing, GPU‑Terminal‑Mode (optional) |
14+
| **Scenes** | Z‑Index, Layer-Masking, Offscreen Buffers, Transitions |
15+
| **Animation** | Timelines, Easing, Keyframes, Sprite‑Sheets |
16+
| **System** | Resize‑Events, Raw‑Mode‑Manager, Cross‑Platform Backend |
17+
| **Debug** | FPS‑Overlay, Memory‑Overlay, Scene‑Inspector |

examples/Demo/demo_mvn_stderr.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[DEBUG] JNI Sizing Failed: fastterminal/FastTerminal
2+
java.lang.NoClassDefFoundError: fastterminal/FastTerminal
3+
at fastterminal.Demo.main(Demo.java:19)
4+
at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:279)
5+
at java.base/java.lang.Thread.run(Thread.java:1474)
6+
Caused by: java.lang.ClassNotFoundException: fastterminal.FastTerminal
7+
at org.codehaus.mojo.exec.URLClassLoaderBuilder$ExecJavaClassLoader.loadClass(URLClassLoaderBuilder.java:198)
8+
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:490)
9+
... 3 more

examples/Demo/demo_mvn_stdout.txt

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
[INFO] Scanning for projects...
2+
[WARNING]
3+
[WARNING] Some problems were encountered while building the effective model for com.github.andrestubbe:fastterminal-demo:jar:0.1.0
4+
[WARNING] 'dependencies.dependency.systemPath' for com.github.andrestubbe:fastterminal:jar should not point at files within the project directory, ${project.basedir}/../../target/fastterminal-0.1.0.jar will be unresolvable by dependent projects @ line 36, column 25
5+
[WARNING]
6+
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
7+
[WARNING]
8+
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
9+
[WARNING]
10+
Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/mojo/maven-metadata.xml
11+
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-metadata.xml
12+
Progress (1): 3.1 kBProgress (2): 3.1 kB | 4.6 kBProgress (2): 7.7 kB | 4.6 kBProgress (2): 7.7 kB | 9.7 kBProgress (2): 7.7 kB | 14 kB Progress (2): 12 kB | 14 kB Progress (2): 17 kB | 14 kBProgress (2): 20 kB | 14 kBProgress (2): 21 kB | 14 kB Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-metadata.xml (14 kB at 24 kB/s)
13+
Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/mojo/maven-metadata.xml (21 kB at 32 kB/s)
14+
Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/mojo/exec-maven-plugin/3.1.0/exec-maven-plugin-3.1.0.pom
15+
Progress (1): 1.1 kBProgress (1): 3.0 kBProgress (1): 6.3 kBProgress (1): 9.6 kBProgress (1): 11 kB Progress (1): 14 kB Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/mojo/exec-maven-plugin/3.1.0/exec-maven-plugin-3.1.0.pom (14 kB at 227 kB/s)
16+
Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/mojo/mojo-parent/69/mojo-parent-69.pom
17+
Progress (1): 715 BProgress (1): 1.7 kBProgress (1): 5.2 kBProgress (1): 7.5 kBProgress (1): 9.0 kBProgress (1): 11 kB Progress (1): 16 kBProgress (1): 19 kBProgress (1): 23 kBProgress (1): 26 kBProgress (1): 28 kBProgress (1): 32 kBProgress (1): 35 kB Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/mojo/mojo-parent/69/mojo-parent-69.pom (35 kB at 631 kB/s)
18+
Downloading from central: https://repo.maven.apache.org/maven2/org/junit/junit-bom/5.8.2/junit-bom-5.8.2.pom
19+
Progress (1): 907 BProgress (1): 2.3 kBProgress (1): 5.6 kB Downloaded from central: https://repo.maven.apache.org/maven2/org/junit/junit-bom/5.8.2/junit-bom-5.8.2.pom (5.6 kB at 99 kB/s)
20+
Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/mojo/exec-maven-plugin/3.1.0/exec-maven-plugin-3.1.0.jar
21+
Progress (1): 0.9/73 kBProgress (1): 2.3/73 kBProgress (1): 3.6/73 kBProgress (1): 5.0/73 kBProgress (1): 6.4/73 kBProgress (1): 7.7/73 kBProgress (1): 9.1/73 kBProgress (1): 10/73 kB Progress (1): 12/73 kBProgress (1): 13/73 kBProgress (1): 15/73 kBProgress (1): 15/73 kBProgress (1): 17/73 kBProgress (1): 18/73 kBProgress (1): 20/73 kBProgress (1): 21/73 kBProgress (1): 22/73 kBProgress (1): 24/73 kBProgress (1): 25/73 kBProgress (1): 26/73 kBProgress (1): 28/73 kBProgress (1): 29/73 kBProgress (1): 31/73 kBProgress (1): 35/73 kBProgress (1): 39/73 kBProgress (1): 43/73 kBProgress (1): 47/73 kBProgress (1): 52/73 kBProgress (1): 56/73 kBProgress (1): 60/73 kBProgress (1): 64/73 kBProgress (1): 69/73 kBProgress (1): 73 kB Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/mojo/exec-maven-plugin/3.1.0/exec-maven-plugin-3.1.0.jar (73 kB at 1.2 MB/s)
22+
[INFO]
23+
[INFO] --------------< com.github.andrestubbe:fastterminal-demo >--------------
24+
[INFO] Building fastterminal-demo 0.1.0
25+
[INFO] from pom.xml
26+
[INFO] --------------------------------[ jar ]---------------------------------
27+
[INFO]
28+
[INFO] --- exec:3.1.0:java (default-cli) @ fastterminal-demo ---
29+
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-exec/1.3/commons-exec-1.3.pom
30+
Progress (1): 788 BProgress (1): 2.3 kBProgress (1): 5.3 kBProgress (1): 7.8 kBProgress (1): 10 kB Progress (1): 11 kB Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-exec/1.3/commons-exec-1.3.pom (11 kB at 220 kB/s)
31+
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/35/commons-parent-35.pom
32+
Progress (1): 714 BProgress (1): 2.0 kBProgress (1): 3.3 kBProgress (1): 4.8 kBProgress (1): 8.2 kBProgress (1): 11 kB Progress (1): 15 kBProgress (1): 16 kBProgress (1): 19 kBProgress (1): 22 kBProgress (1): 25 kBProgress (1): 27 kBProgress (1): 31 kBProgress (1): 34 kBProgress (1): 38 kBProgress (1): 44 kBProgress (1): 45 kBProgress (1): 47 kBProgress (1): 50 kBProgress (1): 52 kBProgress (1): 55 kBProgress (1): 57 kBProgress (1): 58 kB Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/35/commons-parent-35.pom (58 kB at 1.1 MB/s)
33+
Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-component-annotations/2.1.1/plexus-component-annotations-2.1.1.jar
34+
Progress (1): 3.8/4.1 kBProgress (1): 4.1 kB Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-component-annotations/2.1.1/plexus-component-annotations-2.1.1.jar (4.1 kB at 111 kB/s)
35+
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-exec/1.3/commons-exec-1.3.jar
36+
Progress (1): 3.8/54 kBProgress (1): 8.0/54 kBProgress (1): 12/54 kB Progress (1): 12/54 kBProgress (1): 17/54 kBProgress (1): 21/54 kBProgress (1): 25/54 kBProgress (1): 29/54 kBProgress (1): 33/54 kBProgress (1): 38/54 kBProgress (1): 42/54 kBProgress (1): 46/54 kBProgress (1): 50/54 kBProgress (1): 54 kB Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-exec/1.3/commons-exec-1.3.jar (54 kB at 1.1 MB/s)
37+
Initializing FastTerminal Live Fullscreen Demo...
38+
[WARNING]
39+
java.lang.NoClassDefFoundError: fastterminal/TerminalRenderer
40+
at fastterminal.Demo.main (Demo.java:60)
41+
at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:279)
42+
at java.lang.Thread.run (Thread.java:1474)
43+
Caused by: java.lang.ClassNotFoundException: fastterminal.TerminalRenderer
44+
at org.codehaus.mojo.exec.URLClassLoaderBuilder$ExecJavaClassLoader.loadClass (URLClassLoaderBuilder.java:198)
45+
at java.lang.ClassLoader.loadClass (ClassLoader.java:490)
46+
at fastterminal.Demo.main (Demo.java:60)
47+
at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:279)
48+
at java.lang.Thread.run (Thread.java:1474)
49+
[INFO] ------------------------------------------------------------------------
50+
[INFO] BUILD FAILURE
51+
[INFO] ------------------------------------------------------------------------
52+
[INFO] Total time: 1.946 s
53+
[INFO] Finished at: 2026-05-18T02:24:43+02:00
54+
[INFO] ------------------------------------------------------------------------
55+
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:3.1.0:java (default-cli) on project fastterminal-demo: An exception occurred while executing the Java class. fastterminal/TerminalRenderer: fastterminal.TerminalRenderer -> [Help 1]
56+
[ERROR]
57+
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
58+
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
59+
[ERROR]
60+
[ERROR] For more information about the errors and possible solutions, please read the following articles:
61+
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

examples/Demo/src/main/java/fastterminal/CubeDemo.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,11 @@ public static void main(String[] args) {
5454

5555
// Register JVM Shutdown Hook to safely restore the console on exit
5656
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
57-
System.out.print("\033[?1049l\033[?25h\033[0m");
58-
System.out.flush();
57+
Ansi.print(Ansi.EXIT_ALT_BUFFER, Ansi.SHOW_CURSOR, Ansi.RESET);
5958
}));
6059

6160
// Enter Alternate Screen Buffer, Hide Cursor
62-
System.out.print("\033[?1049h\033[?25l");
63-
System.out.flush();
61+
Ansi.print(Ansi.ENTER_ALT_BUFFER, Ansi.HIDE_CURSOR);
6462

6563
int cols = 80;
6664
int rows = 30;
@@ -74,8 +72,8 @@ public static void main(String[] args) {
7472
}
7573
} catch (Throwable ignored) {}
7674

77-
TerminalRenderer renderer = null;
78-
TerminalScene canvas = null;
75+
FastTerminalRenderer renderer = null;
76+
FastTerminalScene canvas = null;
7977

8078
double angleX = 0.0;
8179
double angleY = 0.0;
@@ -101,8 +99,8 @@ public static void main(String[] args) {
10199
if (renderer == null || canvas == null || currentCols != cols || currentRows != rows) {
102100
cols = currentCols;
103101
rows = currentRows;
104-
renderer = new TerminalRenderer(cols, rows);
105-
canvas = new TerminalScene(0, 0, cols, rows);
102+
renderer = new FastTerminalRenderer(cols, rows);
103+
canvas = new FastTerminalScene(0, 0, cols, rows);
106104
renderer.addScene(canvas);
107105
}
108106

@@ -214,7 +212,7 @@ private static int getNeonColor(double huePhase) {
214212
}
215213

216214
// High-Performance Bresenham Line Drawing Algorithm
217-
private static void drawLine(TerminalScene canvas, int x0, int y0, int x1, int y1, int fgColor, int bgColor) {
215+
private static void drawLine(FastTerminalScene canvas, int x0, int y0, int x1, int y1, int fgColor, int bgColor) {
218216
int dx = Math.abs(x1 - x0);
219217
int dy = Math.abs(y1 - y0);
220218
int sx = x0 < x1 ? 1 : -1;

0 commit comments

Comments
 (0)