diff options
author | Ben Bridle <ben@derelict.engineering> | 2025-09-07 18:46:29 +1200 |
---|---|---|
committer | Ben Bridle <ben@derelict.engineering> | 2025-09-07 18:47:51 +1200 |
commit | 53fa574c9af4095f07f4883547939a25522f81e6 (patch) | |
tree | bbfbbd3f6a325c5ed8bc330a9c332577a95d02d5 | |
parent | e09013621b3c26945d16d7f2a621bd18f1e814e4 (diff) | |
download | bedrock-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.js | 33 |
1 files changed, 21 insertions, 12 deletions
@@ -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; |