From 9b61b4086df98ac2df506035875e86b8ad63efb9 Mon Sep 17 00:00:00 2001 From: pot <196140351+pot@users.noreply.github.com> Date: Mon, 27 Oct 2025 11:42:43 -0500 Subject: [PATCH 1/4] fix: duplicate message handling in primary eventloop with renderer --- .../main/java/dev/weisz/boba/StandardRenderer.java | 4 ++++ core/src/main/java/dev/weisz/boba/tea/Program.java | 11 +++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/dev/weisz/boba/StandardRenderer.java b/core/src/main/java/dev/weisz/boba/StandardRenderer.java index 2a611d7..073992b 100644 --- a/core/src/main/java/dev/weisz/boba/StandardRenderer.java +++ b/core/src/main/java/dev/weisz/boba/StandardRenderer.java @@ -371,6 +371,10 @@ public void handleMessages(Msg msg) { case Msg.PrintLineMsg(String line) -> write(line); + case Msg.ClearScreenMsg ignored -> clearScreen(); + + case Msg.SetTitleMsg(String title) -> setWindowTitle(title); + default -> {} } } diff --git a/core/src/main/java/dev/weisz/boba/tea/Program.java b/core/src/main/java/dev/weisz/boba/tea/Program.java index 9c460af..42633c8 100644 --- a/core/src/main/java/dev/weisz/boba/tea/Program.java +++ b/core/src/main/java/dev/weisz/boba/tea/Program.java @@ -141,11 +141,6 @@ private void eventLoop() throws InterruptedException { case Msg.QuitMsg _ -> { return; } - case Msg.ClearScreenMsg _ -> - renderer.clearScreen(); - - case Msg.SetTitleMsg(String title) -> - renderer.setWindowTitle(title); case BatchCmd.BatchMsg(List cmds) -> cmds.forEach(this::processCmd); @@ -153,6 +148,7 @@ private void eventLoop() throws InterruptedException { default -> { /* ignore */ } } + // handle all internal handling of messages renderer.handleMessages(msg); var updateCmd = update(msg); @@ -161,7 +157,10 @@ private void eventLoop() throws InterruptedException { processCmd(updateCmd); } - renderer.write(view()); + // don't force renderer to render because it already runs on a timer + // todo: maybe this should be toggable incase the user wants a low fps or + // todo: possibly only re-render on an event/command + //renderer.write(view()); } } From c4b6a28c04fe30937c9643d414cb885898caf181 Mon Sep 17 00:00:00 2001 From: pot <196140351+pot@users.noreply.github.com> Date: Mon, 27 Oct 2025 15:33:10 -0500 Subject: [PATCH 2/4] boba frame render event --- .../java/dev/weisz/boba/RenderCallback.java | 6 ++++++ .../java/dev/weisz/boba/StandardRenderer.java | 14 +++++++++++-- .../weisz/boba/jfr/BobaFrameRenderEvent.java | 21 +++++++++++++++++++ .../boba/jfr/BobaRenderSettingsEvent.java | 11 ++++++++++ .../main/java/dev/weisz/boba/tea/Program.java | 3 +-- core/src/main/java/module-info.java | 1 + 6 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 core/src/main/java/dev/weisz/boba/RenderCallback.java create mode 100644 core/src/main/java/dev/weisz/boba/jfr/BobaFrameRenderEvent.java create mode 100644 core/src/main/java/dev/weisz/boba/jfr/BobaRenderSettingsEvent.java diff --git a/core/src/main/java/dev/weisz/boba/RenderCallback.java b/core/src/main/java/dev/weisz/boba/RenderCallback.java new file mode 100644 index 0000000..076d5dc --- /dev/null +++ b/core/src/main/java/dev/weisz/boba/RenderCallback.java @@ -0,0 +1,6 @@ +package dev.weisz.boba; + +@FunctionalInterface +public interface RenderCallback { + String render(); +} diff --git a/core/src/main/java/dev/weisz/boba/StandardRenderer.java b/core/src/main/java/dev/weisz/boba/StandardRenderer.java index 073992b..fc8c352 100644 --- a/core/src/main/java/dev/weisz/boba/StandardRenderer.java +++ b/core/src/main/java/dev/weisz/boba/StandardRenderer.java @@ -2,6 +2,7 @@ import dev.weisz.ansi.*; import dev.weisz.ansi.parser.Width; +import dev.weisz.boba.jfr.BobaFrameRenderEvent; import dev.weisz.boba.tea.Msg; import dev.weisz.boba.terminal.WinSize; import org.jspecify.annotations.Nullable; @@ -19,6 +20,7 @@ public class StandardRenderer implements Renderer { private static final Logger LOGGER = LoggerFactory.getLogger(StandardRenderer.class); private final OutputStream out; + private final RenderCallback frameRenderer; private final int fps; private @Nullable Timer timer; // timer that calls the flush function (started based on fps) @@ -40,8 +42,9 @@ public class StandardRenderer implements Renderer { private String lastRender = ""; // used to check for any differences in the render private List lastRenderedLines = new ArrayList<>(); - public StandardRenderer(OutputStream out, int fps) { + public StandardRenderer(OutputStream out, RenderCallback frameRenderer, int fps) { this.out = out; + this.frameRenderer = frameRenderer; this.fps = fps; } @@ -132,7 +135,6 @@ public void start() { } running.set(true); - timer.scheduleAtFixedRate( new TimerTask() { @Override @@ -142,7 +144,15 @@ public void run() { return; } + // frame render will include the flush too, + var renderEvent = new BobaFrameRenderEvent(); + renderEvent.begin(); + renderEvent.activeRenderer = "Standard Renderer"; // TODO: replace with static key + + write(frameRenderer.render()); flush(); + + renderEvent.commit(); } }, 0, diff --git a/core/src/main/java/dev/weisz/boba/jfr/BobaFrameRenderEvent.java b/core/src/main/java/dev/weisz/boba/jfr/BobaFrameRenderEvent.java new file mode 100644 index 0000000..9818c8e --- /dev/null +++ b/core/src/main/java/dev/weisz/boba/jfr/BobaFrameRenderEvent.java @@ -0,0 +1,21 @@ +package dev.weisz.boba.jfr; + +import jdk.jfr.*; + +@Name(BobaFrameRenderEvent.NAME) +@Label("Boba Frame Render") +@Category({"Boba", "Boba Renderer"}) +public class BobaFrameRenderEvent extends Event { + static final String NAME = "dev.weisz.boba.jfr.BobaFrameRender"; + + @Label("Active Renderer") + public String activeRenderer; + + @Label("Frame") + public String frameContent; // TODO: do we really want to do all this? + + @Label("Frame Render Duration") + @Description("The time that Program#view took to render the current frame") + @Timespan(Timespan.MICROSECONDS) + public long frameRenderDuration; +} diff --git a/core/src/main/java/dev/weisz/boba/jfr/BobaRenderSettingsEvent.java b/core/src/main/java/dev/weisz/boba/jfr/BobaRenderSettingsEvent.java new file mode 100644 index 0000000..f550330 --- /dev/null +++ b/core/src/main/java/dev/weisz/boba/jfr/BobaRenderSettingsEvent.java @@ -0,0 +1,11 @@ +package dev.weisz.boba.jfr; + +import jdk.jfr.*; + +@Name(BobaRenderSettingsEvent.NAME) +@Label("Boba Render Settings") +@Description("Triggered whenever the settings of the renderer are updated") +@Category({"Boba", "Boba Renderer"}) +public class BobaRenderSettingsEvent extends Event { + static final String NAME = "dev.weisz.boba.jfr.BobaRenderSettings"; +} diff --git a/core/src/main/java/dev/weisz/boba/tea/Program.java b/core/src/main/java/dev/weisz/boba/tea/Program.java index 42633c8..4628d51 100644 --- a/core/src/main/java/dev/weisz/boba/tea/Program.java +++ b/core/src/main/java/dev/weisz/boba/tea/Program.java @@ -71,7 +71,7 @@ public void run(ProgramOpts opts) { }); // TODO: allow configurable renderer - renderer = new StandardRenderer(opts.output(), opts.fps()); + renderer = new StandardRenderer(opts.output(), this::view, opts.fps()); renderer.hideCursor(); if (!opts.startupTitle().isEmpty()) { @@ -102,7 +102,6 @@ public void run(ProgramOpts opts) { }); renderer.start(); - renderer.write(view()); LOGGER.debug("Program started with initial frame printed."); diff --git a/core/src/main/java/module-info.java b/core/src/main/java/module-info.java index 8f50634..cce6066 100644 --- a/core/src/main/java/module-info.java +++ b/core/src/main/java/module-info.java @@ -10,4 +10,5 @@ requires dev.mccue.color.terminal; requires org.apache.commons.lang3; requires org.slf4j; + requires jdk.jfr; } \ No newline at end of file From 9680336648ce5325fbdc35b1f897ff749e8ff679 Mon Sep 17 00:00:00 2001 From: pot <196140351+pot@users.noreply.github.com> Date: Mon, 27 Oct 2025 15:34:24 -0500 Subject: [PATCH 3/4] add frame content to frames --- core/src/main/java/dev/weisz/boba/StandardRenderer.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/dev/weisz/boba/StandardRenderer.java b/core/src/main/java/dev/weisz/boba/StandardRenderer.java index fc8c352..424f88e 100644 --- a/core/src/main/java/dev/weisz/boba/StandardRenderer.java +++ b/core/src/main/java/dev/weisz/boba/StandardRenderer.java @@ -149,7 +149,10 @@ public void run() { renderEvent.begin(); renderEvent.activeRenderer = "Standard Renderer"; // TODO: replace with static key - write(frameRenderer.render()); + var frameContent = frameRenderer.render(); + renderEvent.frameContent = frameContent; + + write(frameContent); flush(); renderEvent.commit(); From 615eb972131b76d266d05ea6b8946ef270ae702a Mon Sep 17 00:00:00 2001 From: pot <196140351+pot@users.noreply.github.com> Date: Tue, 28 Oct 2025 14:21:03 -0500 Subject: [PATCH 4/4] remove extra data from frame render --- .../java/dev/weisz/boba/StandardRenderer.java | 1 - .../java/dev/weisz/boba/jfr/BobaErrorEvent.java | 17 +++++++++++++++++ .../weisz/boba/jfr/BobaFrameRenderEvent.java | 3 --- .../weisz/boba/jfr/BobaRenderSettingsEvent.java | 11 ----------- .../main/java/dev/weisz/boba/tea/Program.java | 3 +++ 5 files changed, 20 insertions(+), 15 deletions(-) create mode 100644 core/src/main/java/dev/weisz/boba/jfr/BobaErrorEvent.java delete mode 100644 core/src/main/java/dev/weisz/boba/jfr/BobaRenderSettingsEvent.java diff --git a/core/src/main/java/dev/weisz/boba/StandardRenderer.java b/core/src/main/java/dev/weisz/boba/StandardRenderer.java index 424f88e..8fcc1ff 100644 --- a/core/src/main/java/dev/weisz/boba/StandardRenderer.java +++ b/core/src/main/java/dev/weisz/boba/StandardRenderer.java @@ -150,7 +150,6 @@ public void run() { renderEvent.activeRenderer = "Standard Renderer"; // TODO: replace with static key var frameContent = frameRenderer.render(); - renderEvent.frameContent = frameContent; write(frameContent); flush(); diff --git a/core/src/main/java/dev/weisz/boba/jfr/BobaErrorEvent.java b/core/src/main/java/dev/weisz/boba/jfr/BobaErrorEvent.java new file mode 100644 index 0000000..459c4ef --- /dev/null +++ b/core/src/main/java/dev/weisz/boba/jfr/BobaErrorEvent.java @@ -0,0 +1,17 @@ +package dev.weisz.boba.jfr; + +import jdk.jfr.*; + +@Name(BobaErrorEvent.NAME) +@Label("Boba Error") +@Category("Boba") +public class BobaErrorEvent extends Event { + static final String NAME = "dev.weisz.boba.jfr.BobaError"; + + @Label("Message") + public String message; + + @Label("Stacktrace") + @DataAmount("kB") + public String stackTrace; +} diff --git a/core/src/main/java/dev/weisz/boba/jfr/BobaFrameRenderEvent.java b/core/src/main/java/dev/weisz/boba/jfr/BobaFrameRenderEvent.java index 9818c8e..fe89033 100644 --- a/core/src/main/java/dev/weisz/boba/jfr/BobaFrameRenderEvent.java +++ b/core/src/main/java/dev/weisz/boba/jfr/BobaFrameRenderEvent.java @@ -11,9 +11,6 @@ public class BobaFrameRenderEvent extends Event { @Label("Active Renderer") public String activeRenderer; - @Label("Frame") - public String frameContent; // TODO: do we really want to do all this? - @Label("Frame Render Duration") @Description("The time that Program#view took to render the current frame") @Timespan(Timespan.MICROSECONDS) diff --git a/core/src/main/java/dev/weisz/boba/jfr/BobaRenderSettingsEvent.java b/core/src/main/java/dev/weisz/boba/jfr/BobaRenderSettingsEvent.java deleted file mode 100644 index f550330..0000000 --- a/core/src/main/java/dev/weisz/boba/jfr/BobaRenderSettingsEvent.java +++ /dev/null @@ -1,11 +0,0 @@ -package dev.weisz.boba.jfr; - -import jdk.jfr.*; - -@Name(BobaRenderSettingsEvent.NAME) -@Label("Boba Render Settings") -@Description("Triggered whenever the settings of the renderer are updated") -@Category({"Boba", "Boba Renderer"}) -public class BobaRenderSettingsEvent extends Event { - static final String NAME = "dev.weisz.boba.jfr.BobaRenderSettings"; -} diff --git a/core/src/main/java/dev/weisz/boba/tea/Program.java b/core/src/main/java/dev/weisz/boba/tea/Program.java index 4628d51..51eb91e 100644 --- a/core/src/main/java/dev/weisz/boba/tea/Program.java +++ b/core/src/main/java/dev/weisz/boba/tea/Program.java @@ -118,6 +118,9 @@ public void run(ProgramOpts opts) { eventLoop(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); + + + throw new RuntimeException(e); }