Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions core/src/main/java/dev/weisz/boba/RenderCallback.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package dev.weisz.boba;

@FunctionalInterface
public interface RenderCallback {
String render();
}
20 changes: 18 additions & 2 deletions core/src/main/java/dev/weisz/boba/StandardRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
Expand All @@ -40,8 +42,9 @@ public class StandardRenderer implements Renderer {
private String lastRender = ""; // used to check for any differences in the render
private List<String> 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;
}

Expand Down Expand Up @@ -132,7 +135,6 @@ public void start() {
}

running.set(true);

timer.scheduleAtFixedRate(
new TimerTask() {
@Override
Expand All @@ -142,7 +144,17 @@ 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

var frameContent = frameRenderer.render();

write(frameContent);
flush();

renderEvent.commit();
}
},
0,
Expand Down Expand Up @@ -371,6 +383,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 -> {}
}
}
Expand Down
17 changes: 17 additions & 0 deletions core/src/main/java/dev/weisz/boba/jfr/BobaErrorEvent.java
Original file line number Diff line number Diff line change
@@ -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;
}
18 changes: 18 additions & 0 deletions core/src/main/java/dev/weisz/boba/jfr/BobaFrameRenderEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
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 Render Duration")
@Description("The time that Program#view took to render the current frame")
@Timespan(Timespan.MICROSECONDS)
public long frameRenderDuration;
}
17 changes: 9 additions & 8 deletions core/src/main/java/dev/weisz/boba/tea/Program.java
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand Down Expand Up @@ -102,7 +102,6 @@ public void run(ProgramOpts opts) {
});

renderer.start();
renderer.write(view());

LOGGER.debug("Program started with initial frame printed.");

Expand All @@ -119,6 +118,9 @@ public void run(ProgramOpts opts) {
eventLoop();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();



throw new RuntimeException(e);
}

Expand All @@ -141,18 +143,14 @@ 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<Cmd> cmds) ->
cmds.forEach(this::processCmd);

default -> { /* ignore */ }
}

// handle all internal handling of messages
renderer.handleMessages(msg);

var updateCmd = update(msg);
Expand All @@ -161,7 +159,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());
}
}

Expand Down
1 change: 1 addition & 0 deletions core/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@
requires dev.mccue.color.terminal;
requires org.apache.commons.lang3;
requires org.slf4j;
requires jdk.jfr;
}