aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Stendahl <jakob.stendahl@outlook.com>2022-04-28 20:06:38 +0200
committerJakob Stendahl <jakob.stendahl@outlook.com>2022-04-28 20:08:55 +0200
commit916ab40d65c9c25f63256f2cd98be297c3da2208 (patch)
treedcf07544310fd34f79e72f34ef0e653f30a163f0
parent4ee57ab935718a269fe7ab65b26ff27837d49003 (diff)
downloadLuxcena-Neo-916ab40d65c9c25f63256f2cd98be297c3da2208.tar.gz
Luxcena-Neo-916ab40d65c9c25f63256f2cd98be297c3da2208.zip
:bug: Small bugfixes
-rw-r--r--NeoRuntime/Runtime/luxcena_neo/strip.py12
-rw-r--r--NeoRuntime/Runtime/neo_runtime.py2
-rw-r--r--src/NeoRuntimeManager/IPC.js16
-rw-r--r--src/NeoRuntimeManager/RuntimeProcess.js9
-rw-r--r--src/NeoRuntimeManager/index.js74
-rw-r--r--src/SocketIO/index.js42
-rw-r--r--src/UserData/index.js4
-rw-r--r--src_frontend/App.svelte12
-rw-r--r--src_frontend/Components/Editor/Editor.svelte75
-rw-r--r--src_frontend/Components/Editor/Output.svelte9
-rw-r--r--src_frontend/Components/Editor/Simulation.svelte27
11 files changed, 180 insertions, 102 deletions
diff --git a/NeoRuntime/Runtime/luxcena_neo/strip.py b/NeoRuntime/Runtime/luxcena_neo/strip.py
index d673e1b..0d23069 100644
--- a/NeoRuntime/Runtime/luxcena_neo/strip.py
+++ b/NeoRuntime/Runtime/luxcena_neo/strip.py
@@ -16,7 +16,7 @@ class Strip:
self.LED_PIN = int(strip_conf["led_pin"]) # 18 uses PWM, 10 uses SPI /dev/spidev0.0
self.LED_DMA = int(strip_conf["led_dma"]) # DMA channel for generating the signal, on the newer ones, try 10
self.LED_COUNT = sum(self.SEGMENTS) # Number of LEDs in strip
-
+
# Setup the color calibration array
if ("color_calibration" in strip_conf) and (strip_conf["color_calibration"] != ""):
self.COLOR_CALIBRATION = strip_conf["led_calibration"]
@@ -34,7 +34,7 @@ class Strip:
self.__set_brightness = 255
# Keeping what the brightness actually is
self.__actual_brightness = self.__set_brightness
-
+
# Setup the strip instance
self.strip = ws.Adafruit_NeoPixel(
self.LED_COUNT,
@@ -50,7 +50,7 @@ class Strip:
# Blank out all the LEDs
self.blank()
-
+
# Setup matrix
print(" * Generating matrix")
# try:
@@ -58,7 +58,7 @@ class Strip:
self.pixelMatrix.dump()
# except:
# print("Something went wrong while setting up your self-defined matrix.")
-
+
# Read in state file, so we can revoces the last state.
self.__globvars_path = path.join(path.split(path.dirname(path.abspath(__file__)))[0], "state.json")
if path.exists(self.__globvars_path):
@@ -100,7 +100,7 @@ class Strip:
self.save_globvars()
else:
raise Exception("Value ({}) outside allowed range (0-255)".format(value))
-
+
def _set_brightness(self, value):
self.__actual_brightness = value
self.strip.setBrightness(value)
@@ -145,7 +145,7 @@ class Strip:
def get_pixel_color(self, n):
"""Get the 24-bit RGB color value for the LED at position n."""
return self.strip.getPixelColor(n)
-
+
def blank(self):
"""Will turn off all pixels, this also calls show for you."""
for n in range(self.LED_COUNT):
diff --git a/NeoRuntime/Runtime/neo_runtime.py b/NeoRuntime/Runtime/neo_runtime.py
index 01e5a9e..7733a4b 100644
--- a/NeoRuntime/Runtime/neo_runtime.py
+++ b/NeoRuntime/Runtime/neo_runtime.py
@@ -119,7 +119,7 @@ class NeoRuntime:
ws.close()
last_send = time.perf_counter()
-
+
if self.__send_strip_buffer:
time.sleep(0.05)
buffer = [2]
diff --git a/src/NeoRuntimeManager/IPC.js b/src/NeoRuntimeManager/IPC.js
index 6428a13..56c8b5d 100644
--- a/src/NeoRuntimeManager/IPC.js
+++ b/src/NeoRuntimeManager/IPC.js
@@ -61,7 +61,7 @@ class IPC {
.on('connect', () => {
clearInterval(this.reconnectInterval);
this.reconnectInterval = false;
- // logger.info("IPC Connected.");
+ logger.info("IPC Connected.");
})
.on("ready", () => {
this.connected = true;
@@ -100,30 +100,30 @@ class IPC {
}
this.eventEmitter.emit("matrix", json_data);
break;
-
+
case DATATYPE.STRIP_BUF:
this.eventEmitter.emit("strip_buffer", Array.from(data.values()).slice(1));
break;
-
+
default:
logger.info(data);
}
-
+
})
.on("timeout", () => {
logger.info("IPC Timeout");
})
.on("close", (hadError) => {
- // logger.info("IPC Close, hadError: ", hadError);
+ logger.info("IPC Close, hadError: ", hadError);
this.connected = false;
this.reconnect();
})
.on("end", () => {
- // logger.info("IPC End");
+ logger.info("IPC End");
this.connected = false;
})
.on('error', (data) => {
- // logger.info('IPC Server not active.');
+ logger.info('IPC Server not active.');
this.connected = false;
this.reconnect();
})
@@ -137,7 +137,7 @@ class IPC {
sendCommand(commandType, name, value) {
if (this.connected) {
let buf;
-
+
switch (commandType) {
case (COMMAND.SET_GLOB):
buf = Buffer.allocUnsafe(3);
diff --git a/src/NeoRuntimeManager/RuntimeProcess.js b/src/NeoRuntimeManager/RuntimeProcess.js
index c5c4749..be78fa9 100644
--- a/src/NeoRuntimeManager/RuntimeProcess.js
+++ b/src/NeoRuntimeManager/RuntimeProcess.js
@@ -23,12 +23,12 @@ class RuntimeProcess {
start() {
if (this.isRunning) {
console.log("PROCESS ALREADY RUNNING");
- return;
+ return {success: false, reason: "already running"};
}
this.isRunning = true;
this.proc = spawn.spawn(
- `${__appdir}/NeoRuntime/Runtime/venv/bin/python`,
- //"python",
+ // `${__appdir}/NeoRuntime/Runtime/venv/bin/python`,
+ "python3",
[
"-u", // This makes us able to get real-time output
`${__appdir}/NeoRuntime/Runtime/neo_runtime.py`,
@@ -75,6 +75,7 @@ class RuntimeProcess {
this.exitCode = code;
});
+ return {success: true};
}
stop(restart=false) {
@@ -85,8 +86,10 @@ class RuntimeProcess {
});
}
this.proc.kill("SIGINT");
+ return {success: true}
} catch (err) {
console.log(err);
+ return {success:false, reason:err}
}
}
}
diff --git a/src/NeoRuntimeManager/index.js b/src/NeoRuntimeManager/index.js
index a178bf1..eb38632 100644
--- a/src/NeoRuntimeManager/index.js
+++ b/src/NeoRuntimeManager/index.js
@@ -39,9 +39,9 @@ eventEmitter.on("matrix", (_matrix) => matrix = _matrix);
/**
* Check if a path id actually a mode (if it is a folder with a script.py file)
- *
+ *
* @param {string} path - Path to check.
- *
+ *
* @return {boolean} wether the path points to a valid mode.
*/
function isMode(path) {
@@ -54,7 +54,7 @@ function isMode(path) {
/**
* Get all ids of modes that can be set.
- *
+ *
* @returns {array} All modeids
*/
function listModes() {
@@ -77,9 +77,9 @@ function listModes() {
/**
* Change mode, stop the old one and start the new one.
- *
+ *
* @param {string} _modeId - Id of the mode to change to.
- *
+ *
* @return {object} A standardform return object.
*/
function setMode(_modeId) {
@@ -93,7 +93,7 @@ function setMode(_modeId) {
logger.info(`Changing mode to "${_modeId}".`);
stopMode();
-
+
modeId = _modeId;
neoModules.userData.config.activeMode = modeId;
eventEmitter.emit("change", "mode", modeId);
@@ -106,7 +106,7 @@ function setMode(_modeId) {
/**
* Get current mode
- *
+ *
* @return {string} current modeId
*/
function currentMode() {
@@ -115,7 +115,7 @@ function currentMode() {
/**
* Will attempt to stop current mode
- *
+ *
* @return {object} A standardform return object.
*/
function stopMode(restart=false) {
@@ -127,18 +127,17 @@ function stopMode(restart=false) {
/**
* Will attempt to start current mode
- *
+ *
* @return {object} A standardform return object.
*/
function startMode() {
if (runtimeProcess === null) { return {success: false, reason: "no runtimeprocess", detail: "Runtimeprocess not set, did you mean to call setMode?"}; }
- runtimeProcess.start();
- return {success: true}
+ return runtimeProcess.start();
};
/**
* Will attempt to restart current mode
- *
+ *
* @return {object} A standardform return object.
*/
function restartMode() {
@@ -147,7 +146,7 @@ function restartMode() {
/**
* Checks if mode is running currently
- *
+ *
* @return {boolean} if mode is running
*/
function modeRunning() {
@@ -157,9 +156,9 @@ function modeRunning() {
/**
* Get the full system path to a mode
- *
+ *
* @param {string} modeId
- *
+ *
* @return {string} Full path of mode
*/
function getModePath(modeId) {
@@ -172,24 +171,9 @@ function getModePath(modeId) {
}
/**
- * This should be called by RuntimeProcess when a variable changes in the mode
- *
- * @param {string} location - This is globvars/variables
- * @param {string} name - Name of the variable
- * @param {any} newValue - The new value of the variable
- */
-function onVariableChange(location, name, newValue) {
- if (location == "variables") {
- eventEmitter.emit("change", `variable/${name}`, newValue)
- } else if (location == "globvars") {
- eventEmitter.emit("change", `${name}`, newValue)
- }
-}
-
-/**
* Function that returns all globvars (brightness, power_on) as the values they
* had last time we heard from the python script.
- *
+ *
* @return {object}
*/
function getGlobvars() {
@@ -199,15 +183,15 @@ function getGlobvars() {
/**
* Sets value of a globvar power_on/brightness.
- *
+ *
* @param {string} name - Name of the variable power_on/brightness
* @param {any} value - The value the variable should be set to
- *
+ *
* @return {object} Standardform return object
*/
function setGlobvar(name, value) {
if (!modeRunning()) { return; }
-
+
switch(name) {
case "power_on":
return ipc.sendCommand(IPC.COMMAND.SET_GLOB, IPC.GLOBVAR.POWER_ON, (value) ? 1 : 0);
@@ -220,7 +204,7 @@ function setGlobvar(name, value) {
/**
* Get all variables declared in mode
- *
+ *
* @return {object}
*/
function getVariables() {
@@ -230,10 +214,10 @@ function getVariables() {
/**
* Sets value of a variable
- *
+ *
* @param {string} name - Name of the variable
* @param {any} value - The value the variable should be set to
- *
+ *
* @return {object} Standardform return object
*/
function setVariable(name, value) {
@@ -243,9 +227,9 @@ function setVariable(name, value) {
/**
* Start debugger for a mode
- *
+ *
* @param {string} modeId - The mode to debug
- *
+ *
* @return {object} Standardform return object
*/
function startDebugger(debuggerModeId) {
@@ -258,17 +242,17 @@ function startDebugger(debuggerModeId) {
modeDebuggerProcStartHandler = eventEmitter.on("proc:start", () => {
setTimeout(() => {
ipc.sendCommand(IPC.COMMAND.SET_SEND_STRIP_BUF, true);
- }, 500);
+ }, 2000);
});
+ } else {
+ console.log(modeDebuggerProcStartHandler);
}
modeDebuggerActive = true;
modeDebuggerId = debuggerModeId;
- if (debuggerModeId != modeId) {
+ setTimeout(() => {
setMode(debuggerModeId);
- } else {
- restartMode();
- }
+ }, 300);
return {success: true, code: fs.readFileSync(getModePath(debuggerModeId) + "/script.py").toString()}
}
@@ -284,7 +268,7 @@ function saveModeCode(_modeId, code) {
/**
* Stop the active debugger
- *
+ *
* @return {object} Standardform return object
*/
function stopDebugger() {
diff --git a/src/SocketIO/index.js b/src/SocketIO/index.js
index 88b5459..ff8f378 100644
--- a/src/SocketIO/index.js
+++ b/src/SocketIO/index.js
@@ -12,6 +12,7 @@ let logger = require(__appdir + "/src/Logger");
var exec = require('child_process').exec;
var CryptoJS = require("crypto-js");
let fs = require("fs");
+const { performance } = require("perf_hooks");
let neoModules;
@@ -82,7 +83,7 @@ function createOpenSocketNamespace(io) {
}
session_tokens[token] = {
- expire: (~~Date.now())+(86400),
+ expire: (~~Date.now())+(2678400),
host: socket.handshake.headers.host,
user: {username: user.username}
};
@@ -139,7 +140,7 @@ function authorize_middleware(socket, next) {
const token = socket.handshake.auth.token;
if (session_tokens.hasOwnProperty(token) &&
- session_tokens[token].host === socket.handshake.headers.host &&
+ // session_tokens[token].host === socket.handshake.headers.host &&
session_tokens[token].expire > (~~(Date.now()))) {
socket.data.user = session_tokens[token].user;
next();
@@ -266,8 +267,8 @@ function createAuthorizedNamespace(io) {
/* Editor/debugger */
let onProcStart = () => socket.emit("editor:proc:start");
let onProcStop = (code) => socket.emit("editor:proc:exit", code);
- let onProcStdout = (stdout) => socket.emit("editor:proc:stdout", stdout);
- let onProcStderr = (stderr) => socket.emit("editor:proc:stderr", stderr);
+ let onProcStdout = (stdout) => socket.volatile.emit("editor:proc:stdout", stdout);
+ let onProcStderr = (stderr) => socket.volatile.emit("editor:proc:stderr", stderr);
let closeDebugger = () => {
debuggerOpen = false;
neoModules.neoRuntimeManager.event.removeListener("proc:start", onProcStart);
@@ -277,6 +278,10 @@ function createAuthorizedNamespace(io) {
return neoModules.neoRuntimeManager.stopDebugger();
};
socket.on("editor:open", (modeId, fn) => {
+ neoModules.neoRuntimeManager.event.on("proc:start", onProcStart);
+ neoModules.neoRuntimeManager.event.on("proc:exit", onProcStop);
+ neoModules.neoRuntimeManager.event.on("proc:stdout", onProcStdout);
+ neoModules.neoRuntimeManager.event.on("proc:stderr", onProcStderr);
let res = neoModules.neoRuntimeManager.startDebugger(modeId);
if (!res.success) { fn(res); return; }
logger.info(`Starting debugger for ${modeId}.`)
@@ -284,20 +289,21 @@ function createAuthorizedNamespace(io) {
fn({success: true})
socket.emit("editor:code", modeId, res.code);
- neoModules.neoRuntimeManager.event.on("proc:start", onProcStart);
- neoModules.neoRuntimeManager.event.on("proc:exit", onProcStop);
- neoModules.neoRuntimeManager.event.on("proc:stdout", onProcStdout);
- neoModules.neoRuntimeManager.event.on("proc:stderr", onProcStderr);
if (neoModules.neoRuntimeManager.modeRunning()) {
socket.emit("editor:proc:start");
}
});
socket.on("editor:save", (modeId, code, fn) => {
- if (!debuggerOpen) { fn({success: false, reason: "Debugger not open"}); return; };
+ if (!debuggerOpen) { fn({success: false, reason: "debugger not open"}); return; };
fn(neoModules.neoRuntimeManager.saveModeCode(modeId, code));
});
socket.on("editor:startmode", (fn) => {
- fn(neoModules.neoRuntimeManager.startMode());
+ if (neoModules.neoRuntimeManager.modeRunning()) {
+ fn({success: true});
+ socket.emit("editor:proc:start");
+ } else {
+ fn(neoModules.neoRuntimeManager.startMode());
+ }
});
socket.on("editor:stopmode", (fn) => {
fn(neoModules.neoRuntimeManager.stopMode());
@@ -327,8 +333,12 @@ function createAuthorizedNamespace(io) {
neoModules.neoRuntimeManager.event.on("matrix", (matrix) => {
authorizedNamespace.emit("matrix", matrix);
});
+ let lastStripBufferEmit = performance.now();
neoModules.neoRuntimeManager.event.on("strip_buffer", (strip_buffer) => {
- authorizedNamespace.emit("strip_buffer", strip_buffer);
+ if ((performance.now() - lastStripBufferEmit) > 50) {
+ authorizedNamespace.volatile.emit("strip_buffer", strip_buffer);
+ lastStripBufferEmit = performance.now();
+ } // We just drop packets
});
neoModules.selfUpdater.updater.event.on("step", (step) => {
authorizedNamespace.emit("updater:step", step);
@@ -342,6 +352,16 @@ function createAuthorizedNamespace(io) {
}
/**
+ * Protect
+ */
+function limitEmits(fn) {
+ let lastEmit = performance.now();
+
+ return {
+ }
+}
+
+/**
* Creates an access-token from the clients host-name and the current EPOCH.
*
* @param {client}
diff --git a/src/UserData/index.js b/src/UserData/index.js
index 5ac32f6..e442a79 100644
--- a/src/UserData/index.js
+++ b/src/UserData/index.js
@@ -57,8 +57,8 @@ function ensureStripConfig() {
if (config.DEFAULT.led_dma == null) { config.DEFAULT.led_dma = 10; }
if (config.DEFAULT.led_invert == null) { config.DEFAULT.led_invert = false; }
if (config.DEFAULT.led_channel == null) { config.DEFAULT.led_channel = 0 }
- if (config.DEFAULT.segments == null) { config.DEFAULT.segments = ""; }
- if (config.DEFAULT.matrix == null) { config.DEFAULT.matrix = ""; }
+ if (config.DEFAULT.segments == null) { config.DEFAULT.segments = "50 50"; }
+ if (config.DEFAULT.matrix == null) { config.DEFAULT.matrix = "[[[0,false]],[[1,false]]]"; }
fse.writeFileSync(__configdir + "/strip.ini", ini.encode(config))
}
diff --git a/src_frontend/App.svelte b/src_frontend/App.svelte
index d9f5f92..c5648ca 100644
--- a/src_frontend/App.svelte
+++ b/src_frontend/App.svelte
@@ -30,10 +30,10 @@
component: UnknownRoute
}));
- let updateInProgess = false;
- openSocket.on("updater", (state) => {
- if (state == "start") { updateInProgess = true; }
- });
+ //let updateInProgess = false;
+ //openSocket.on("updater", (state) => {
+ // if (state == "start") { updateInProgess = true; }
+ //});
</script>
<style>
@@ -104,7 +104,7 @@
</style>
-{#if $updateInProgess || $connected}
+{#if $connected}
<Router routes={main_router_routes} />
{:else if $reconnecting}
<div class="no-connection">
@@ -116,4 +116,4 @@
<div class="lds-ellipsis"><div></div><div></div><div></div><div></div></div>
<div>No server connection, attempting to connect...</div>
</div>
-{/if} \ No newline at end of file
+{/if}
diff --git a/src_frontend/Components/Editor/Editor.svelte b/src_frontend/Components/Editor/Editor.svelte
index fc5d589..d77b4f5 100644
--- a/src_frontend/Components/Editor/Editor.svelte
+++ b/src_frontend/Components/Editor/Editor.svelte
@@ -3,6 +3,7 @@
</script>
<script>
import { onDestroy } from "svelte";
+ import { get } from "svelte/store";
import { pop } from "svelte-spa-router";
import { EditorState, basicSetup } from "@codemirror/basic-setup"
import { EditorView, keymap } from "@codemirror/view"
@@ -17,7 +18,7 @@
import Output from "./Output.svelte";
import Simulation from "./Simulation.svelte";
- import { authorizedSocket, authorizedSocketNeeded } from "../../stores/socketStore";
+ import { authorizedSocket, authorizedSocketNeeded, openSocketConnected } from "../../stores/socketStore";
authorizedSocketNeeded.set(true);
export let modeId;
@@ -26,16 +27,50 @@
let codeEditorEl;
let codeEditorHasChanges = false;
let procIsRunning = false;
+ let failCount = 0;
+ let reconnecting = false;
function initDebugger() {
if (debuggerInitialised) { return; }
debuggerInitialised = true;
+ console.log("emitting editor:open");
authorizedSocket.emit("editor:open", `user/${modeId}`, (res) => {
- if (!res.success) { notif({title: res.reason, type: "danger"}); return; }
+ handleError(res);
});
}
+ function notifErr(err) {
+ if (err.hasOwnProperty("detail")) {
+ notif({title: err.reason, type: "danger"});
+ } else {
+ notif({title: err.reason, text: err.detail, type: "danger"});
+ }
+ }
+
+ function handleError(err) {
+ console.log(err);
+ if (err.success) { return; }
+ failCount++;
+ if (failCount < 10) {
+ if (err.reason == "debugger not open") {
+ if (!reconnecting) {
+ reconnecting = true;
+ console.log("emitting editor:open");
+ authorizedSocket.emit("editor:open", `user/${modeId}`, (res) => {
+ reconnecting = false;
+ handleError(res);
+ });
+ }
+ } else {
+ notifErr(err);
+ }
+ } else {
+ notifErr(err);
+ }
+ }
+
authorizedSocket.on("editor:code", (modeId, code) => {
+ console.log("received editor:code");
const chalky = "#e5c07b",
coral = "#e06c75",
cyan = "#56b6c2",
@@ -165,38 +200,47 @@
parent: codeEditorEl
})
});
- authorizedSocket.on("editor:proc:start", () => procIsRunning = true);
- authorizedSocket.on("editor:proc:exit", (code) => {
+ authorizedSocket.on("receivededitor:proc:start", () => {
+ console.log("received editor:proc:start");
+ procIsRunning = true
+ });
+ authorizedSocket.on("received editor:proc:exit", (code) => {
+ console.log("received editor:proc:exit");
procIsRunning = false;
});
function startProc() {
- saveCode(() => {
+ saveCode((res) => {
+ handleError(res);
+ console.log("emitting editor:startmode");
authorizedSocket.emit("editor:startmode", (res) => {
- if (!res.success) { notif({title: res.reason, type: "danger"}); }
+ handleError(res);
});
});
}
function stopProc() {
+ console.log("emitting editor:stopmode");
authorizedSocket.emit("editor:stopmode", (res) => {
- if (!res.success) { notif({title: res.reason, type: "danger"}); }
+ handleError(res);
});
}
function restartProc () {
saveCode((res) => {
- if (!res.success) { notif({title: res.reason, type: "danger"}); }
+ handleError(res);
+ console.log("emitting editor:restartmode");
authorizedSocket.emit("editor:restartmode", (res) => {
- if (!res.success) { notif({title: res.reason, type: "danger"}); }
+ handleError(res);
});
});
}
function saveCode(fn) {
if (codeEditorView == null) { return; }
+ console.log("emitting editor:save");
authorizedSocket.emit("editor:save", `user/${modeId}`, codeEditorView.state.doc.toString(), res => {
- if (!res.success) { notif({title: res.reason, type: "danger"}); }
+ handleError(res);
if (fn != null) { fn(res) }
});
codeEditorHasChanges = false;
@@ -204,16 +248,21 @@
function closeDebugger() {
saveCode((res) => {
- if (!res.success) { notif({title: res.reason, type: "danger"}); }
+ handleError(res);
+ console.log("emitting editor:close");
authorizedSocket.emit("editor:close", res => {
- if (!res.success) { notif({title: res.reason, type: "danger"}); }
+ handleError(res);
debuggerInitialised = false;
});
});
}
onDestroy(() => {
- closeDebugger();
+ if (get(openSocketConnected)) {
+ closeDebugger();
+ } else {
+ debuggerInitialised = false;
+ }
})
document.addEventListener("keydown", function(e) {
diff --git a/src_frontend/Components/Editor/Output.svelte b/src_frontend/Components/Editor/Output.svelte
index 9e4c953..52b7216 100644
--- a/src_frontend/Components/Editor/Output.svelte
+++ b/src_frontend/Components/Editor/Output.svelte
@@ -4,6 +4,7 @@
let scrollBox;
let htmlCode = "";
+ let buffer = "";
function addData(data, classname) {
// let styles = "white-space:pre-wrap;margin:0;";
@@ -17,11 +18,17 @@
styles += "color: red";
break;
}
- htmlCode += `<span style="${styles}">${data}</span>`;
+ buffer += `<span style="${styles}">${data}</span>`;
if (scrollBox != null) {
scrollBox.scrollTop = scrollBox.scrollHeight + 100;
}
}
+
+ function flushBuffer() {
+ htmlCode += buffer;
+ buffer = "";
+ };
+ setInterval(flushBuffer, 400);
authorizedSocket.on("editor:proc:start", () => htmlCode = "");
authorizedSocket.on("editor:proc:exit", (code) => addData(`\nMode exited with ${code}\n\n`, "exit"));
diff --git a/src_frontend/Components/Editor/Simulation.svelte b/src_frontend/Components/Editor/Simulation.svelte
index abe202c..86cc66c 100644
--- a/src_frontend/Components/Editor/Simulation.svelte
+++ b/src_frontend/Components/Editor/Simulation.svelte
@@ -5,6 +5,7 @@
let svg;
let pixels = [];
+ let pixelBuffer = [];
function updateMatrix(matrix) {
if (matrix == null) { return; }
@@ -24,12 +25,26 @@
}
async function updateColors(colors) {
- for (let i = 0; i+2 < colors.length; i+=3) {
- try {
- document.querySelector("#sim-pixel-"+(i/3)).style.setProperty("fill", `rgb(${colors[i]}, ${colors[i+1]}, ${colors[i+2]})`);
- } catch(e) {}
- }
+ pixelBuffer = colors;
+ }
+
+ async function flushPixelBuffer() {
+ //console.log(pixelBuffer);
+ window.requestAnimationFrame((ts) => {
+ for (let i = 0; i+2 < pixelBuffer.length; i+=3) {
+ try {
+ document.querySelector("#sim-pixel-"+(i/3))
+ .style
+ .setProperty(
+ "fill",
+ `rgb(${pixelBuffer[i]}, ${pixelBuffer[i+1]}, ${pixelBuffer[i+2]})`);
+ } catch(e) {
+ console.log(e);
+ }
+ }
+ });
}
+ setInterval(flushPixelBuffer, 50);
onMount(() => {
authorizedSocket.on("matrix", updateMatrix);
@@ -58,4 +73,4 @@
<rect id="sim-pixel-{pixel.n}" x="{pixel.x*2+1}" y="{pixel.y*2+1}" width="1" height="1" style="fill:rgb(0,0,0);filter:blur(0.2px);" />
{/each}
</svg>
-</div> \ No newline at end of file
+</div>