summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Bridle <ben@derelict.engineering>2025-09-07 18:46:29 +1200
committerBen Bridle <ben@derelict.engineering>2025-09-07 18:47:51 +1200
commit53fa574c9af4095f07f4883547939a25522f81e6 (patch)
treebbfbbd3f6a325c5ed8bc330a9c332577a95d02d5
parente09013621b3c26945d16d7f2a621bd18f1e814e4 (diff)
downloadbedrock-js-53fa574c9af4095f07f4883547939a25522f81e6.zip
Improve transmission rendering performance
Previously, the DOM would be updated every time a complete character was pushed to the transmission parser by the stream device. This caused frequent re-renders of the transmission panel and massively slowed down the emulator. To fix this, the contents of the transmission parser are now only flushed to the transmission panel when the state panel updates, which is currently every 10_000 cycles.
-rw-r--r--bedrock.js33
1 files changed, 21 insertions, 12 deletions
diff --git a/bedrock.js b/bedrock.js
index 19d4c99..a0155e7 100644
--- a/bedrock.js
+++ b/bedrock.js
@@ -360,7 +360,7 @@ function EmulatorElement(options) {
emulator.canvas = canvas;
let br = new Bedrock(emulator);
br.reset();
- br.onUpdate = () => emulator.updateStatePanel();
+ br.onUpdate = () => emulator.updateDOM();
emulator.showStatePanel = function() {
statePanel.classList.remove('hidden'); }
@@ -397,14 +397,14 @@ function EmulatorElement(options) {
// Fires when the stop button is pressed.
emulator.stopProgram = function() {
br.stop();
- emulator.updateStatePanel();
+ emulator.updateDOM();
transmissions.innerHTML = '';
emulator.hideStreamPanel();
emulator.hideScreenPanel();
currentTransmission = null;
}
- emulator.updateStatePanel = function() {
+ emulator.updateDOM = function() {
function renderStack(stack) {
let string = '';
for (let i=0; i<stack.p && i<stack.mem.length; i++) {
@@ -428,6 +428,7 @@ function EmulatorElement(options) {
} else {
status.textContent = `running / ${br.cycle}`;
}
+ emulator.flushTransmission();
}
emulator.updateScreenSize = function() {
@@ -446,20 +447,28 @@ function EmulatorElement(options) {
// Receive an incoming byte from the local stream.
emulator.receiveTransmissionByte = function(byte) {
- if (!currentTransmission) {
- emulator.showStreamPanel();
- let element = document.createElement('li');
- element.addEventListener('click', function() {
- copyText(element.textContent); })
- currentTransmission = element;
- transmissions.appendChild(element); }
transmissionParser.push(byte);
- currentTransmission.textContent += transmissionParser.read();
- streamPanel.scrollTop = streamPanel.scrollHeight;
+ }
+
+ // Push all received bytes to the DOM.
+ emulator.flushTransmission = function() {
+ let string = transmissionParser.read();
+ if (string) {
+ if (!currentTransmission) {
+ emulator.showStreamPanel();
+ let element = document.createElement('li');
+ element.addEventListener('click', function() {
+ copyText(element.textContent); })
+ currentTransmission = element;
+ transmissions.appendChild(element); }
+ currentTransmission.textContent += string;
+ streamPanel.scrollTop = streamPanel.scrollHeight;
+ }
}
// End the current incoming transmission.
emulator.endTransmission = function() {
+ emulator.flushTransmission();
streamPanel.scrollTop = streamPanel.scrollHeight;
currentTransmission = null;