-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Try to support GUI v2 on MFD devices #467
Comments
Here is the original investigation done by @ReinvdZee: victronenergy/gui-v2#909 (comment). I will be adding my own later. |
Investigating Qt WASM build process and build artifactsI have examined QT WASM build process in order to better understand what are the possible failure modes of Qt based WASM app being used on a limited device like MFD. Qt itself declares requirement of WebAssembly and WebGL (https://doc.qt.io/qt-6/wasm.html#supported-browsers). These can be tested for relatively easily. When emscripten (a compiler used to transform C++ into WASM) compiles our app, it actually produces couple important artifacts.
The The Nothing special (yet) to say about DebuggingSince debugging on MFDs is nearly impossible, the only useful technique so far that proves to be working is to use One issue on MFDs seems to be Here is the strategy:
Early ResultsRaymarine Axiom 12 running Lighthouse 4 advertises support for all modern JS features as well as support for WebAssembly and WebGL. GUI v2 works, but renders very badly. Text is not very readable, especially compared to GUI v1. Garmin is missing WebAssembly support. Furuno is missing WebAssembly support, and Simard is missing nullish coalescing support. This may possibly be fixed by patching |
The
It's the super new JS operator to assign variable to a new value when its existing value is The The Plan
|
With the patch attached below, the However this still does not mean that GUI-v2 actually works on SIMRAD, more work needed. --- qtloader.js.orig 2025-01-28 10:17:40
+++ qtloader.js 2025-01-28 10:22:39
@@ -93,8 +93,12 @@
if (typeof config.qt.entryFunction !== 'function')
config.qt.entryFunction = window.createQtAppInstance;
- config.qt.qtdir ??= 'qt';
- config.qt.preload ??= [];
+ if (config.qt.qtdir === null || config.qt.qtdir === undefined) {
+ config.qt.qtdir = 'qt';
+ }
+ if (config.qt.preload === null || config.qt.preload === undefined) {
+ config.qt.preload = [];
+ }
config.qtContainerElements = config.qt.containerElements;
delete config.qt.containerElements;
@@ -124,7 +128,10 @@
const qtPreRun = (instance) => {
// Copy qt.environment to instance.ENV
throwIfEnvUsedButNotExported(instance, config);
- for (const [name, value] of Object.entries(config.qt.environment ?? {}))
+ const environment = config.qt.environment !== null && config.qt.environment !== undefined
+ ? config.qt.environment
+ : {}
+ for (const [name, value] of Object.entries(environment))
instance.ENV[name] = value;
// Copy self.preloadData to MEMFS
@@ -156,7 +163,11 @@
config.preRun = [];
config.preRun.push(qtPreRun);
- config.onRuntimeInitialized = () => config.qt.onLoaded?.();
+ config.onRuntimeInitialized = () => {
+ if (config.qt.onLoaded !== undefined && config.qt.onLoaded !== null) {
+ config.qt.onLoaded();
+ }
+ }
const originalLocateFile = config.locateFile;
config.locateFile = filename =>
@@ -169,23 +180,31 @@
const originalOnExit = config.onExit;
config.onExit = code => {
- originalOnExit?.();
- config.qt.onExit?.({
- code,
- crashed: false
- });
+ if (originalOnExit !== undefined && originalOnExit !== null) {
+ originalOnExit();
+ }
+ if (config.qt.onExit !== undefined && config.qt.onExit !== null) {
+ config.qt.onExit({
+ code,
+ crashed: false
+ });
+ }
}
const originalOnAbort = config.onAbort;
config.onAbort = text =>
{
- originalOnAbort?.();
+ if (originalOnAbort !== undefined && originalOnAbort !== null) {
+ originalOnAbort();
+ }
aborted = true;
- config.qt.onExit?.({
- text,
- crashed: true
- });
+ if (config.qt.onExit !== undefined && config.qt.onExit !== null) {
+ config.qt.onExit({
+ text,
+ crashed: true
+ });
+ }
};
const fetchPreloadFiles = async () => {
@@ -211,66 +230,14 @@
instance = await Promise.race(
[circuitBreaker, config.qt.entryFunction(config)]);
} catch (e) {
- config.qt.onExit?.({
- text: e.message,
- crashed: true
- });
- throw e;
+ if (config.qt.onExit !== undefined && config.qt.onExit !== null) {
+ config.qt.onExit({
+ text: e.message,
+ crashed: true
+ });
+ throw e;
+ }
}
return instance;
}
-
-// Compatibility API. This API is deprecated,
-// and will be removed in a future version of Qt.
-function QtLoader(qtConfig) {
-
- const warning = 'Warning: The QtLoader API is deprecated and will be removed in ' +
- 'a future version of Qt. Please port to the new qtLoad() API.';
- console.warn(warning);
-
- let emscriptenConfig = qtConfig.moduleConfig || {}
- qtConfig.moduleConfig = undefined;
- const showLoader = qtConfig.showLoader;
- qtConfig.showLoader = undefined;
- const showError = qtConfig.showError;
- qtConfig.showError = undefined;
- const showExit = qtConfig.showExit;
- qtConfig.showExit = undefined;
- const showCanvas = qtConfig.showCanvas;
- qtConfig.showCanvas = undefined;
- if (qtConfig.canvasElements) {
- qtConfig.containerElements = qtConfig.canvasElements
- qtConfig.canvasElements = undefined;
- } else {
- qtConfig.containerElements = qtConfig.containerElements;
- qtConfig.containerElements = undefined;
- }
- emscriptenConfig.qt = qtConfig;
-
- let qtloader = {
- exitCode: undefined,
- exitText: "",
- loadEmscriptenModule: _name => {
- try {
- qtLoad(emscriptenConfig);
- } catch (e) {
- showError?.(e.message);
- }
- }
- }
-
- qtConfig.onLoaded = () => {
- showCanvas?.();
- }
-
- qtConfig.onExit = exit => {
- qtloader.exitCode = exit.code
- qtloader.exitText = exit.text;
- showExit?.();
- }
-
- showLoader?.("Loading");
-
- return qtloader;
-}; |
After patching
More investigation needed... |
Examining the https://emscripten.org/docs/tools_reference/settings_reference.html#memory64 https://emscripten.org/docs/tools_reference/settings_reference.html#wasm-bigint |
The commit 5062fe9 introduces a robust and detailed check of the MFD to see what features we are currently missing to display GUI v2. Future development may be to investigate whether we can actually make the GUI v2 run on wider spectrum of devices by getting rid of new JS features in |
With the implementation of #389 - whenever GUI v2 is set as default, MFD is no longer able to access Venus Remote Console directly due to limited support of WebAssembly in older web browsers shipping with MFD displays from various manufacturers.
Identify devices that can support GUI v2 properly and selectively allow access to GUI v2 there, especially newer devices with latest software update would work just fine.
The text was updated successfully, but these errors were encountered: