]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
fiddle: cleaned up and documented the status-loading progress mechanism in prep for...
authorstephan <stephan@noemail.net>
Mon, 23 May 2022 16:54:18 +0000 (16:54 +0000)
committerstephan <stephan@noemail.net>
Mon, 23 May 2022 16:54:18 +0000 (16:54 +0000)
FossilOrigin-Name: 107e3497869d757265f2a4235082bf324ba1220075d1096c2a82021a5d348a6c

ext/fiddle/fiddle-worker.js
ext/fiddle/fiddle.js
manifest
manifest.uuid

index e2297dbeb2b33153278246bb1eaf084b8218e236..16da63606efd8ec9304d8eda8b61aa6d9c54e0a9 100644 (file)
     layer. The data property is the string of the output, noting
     that the emscripten binding emits these one line at a time. Thus,
     if a C-side puts() emits multiple lines in a single call, the JS
-    side will see that as multiple calls.
+    side will see that as multiple calls. Example:
+
+    {type:'stdout', data: 'Hi, world.'}
 
   - module: Status text. This is intended to alert the main thread
     about module loading status so that, e.g., the main thread can
     update a progress widget and DTRT when the module is finished
-    loading and available for work. The status text is mostly in some
-    undocumented(?) format emited by the emscripten generated
-    module-loading code, encoding progress info within it.
+    loading and available for work. Status messages come in the form
+    
+    {type:'module', data:{
+        type:'status',
+        data: {text:string|null, step:1-based-integer}
+    }
+
+    with an incrementing step value for each subsequent message. When
+    the module loading is complete, a message with a text value of
+    null is posted.
 
   - working: data='start'|'end'. Indicates that work is about to be
     sent to the module or has just completed. This can be used, e.g.,
     to disable UI elements which should not be activated while work
-    is pending.
+    is pending. Example:
+
+    {type:'working', data:'start'}
 
   Main-to-Worker types:
 
@@ -60,7 +71,9 @@
     it starts and a 'working' event (data='end') when it finished. If
     called while work is currently being executed it emits stderr
     message instead of doing actual work, as the underlying db cannot
-    handle concurrent tasks.
+    handle concurrent tasks. Example:
+
+    {type:'shellExec', data: 'select * from sqlite_master'}
 
   - More TBD as the higher-level db layer develops.
 */
@@ -102,7 +115,40 @@ self.Module = {
     //onRuntimeInitialized: function(){},
     print: function(text){wMsg('stdout', Array.prototype.slice.call(arguments));},
     printErr: function(text){wMsg('stderr', Array.prototype.slice.call(arguments));},
-    setStatus: function f(text){wMsg('module',{type:'status',data:text});},
+    /**
+       Intercepts status updates from the Module object and fires
+       worker events with a type of 'status' and a payload of:
+
+       {
+         text: string | null, // null at end of load process
+         step: integer // starts at 1, increments 1 per call
+       }
+
+       We have no way of knowing in advance how many steps will
+       be processed/posted, so creating a "percentage done" view is
+       not really practical. One can be approximated by giving it a
+       current value of message.step and max value of message.step+1,
+       though.
+
+       When work is finished, a message with a text value of null is
+       submitted.
+
+       After a message with text==null is posted, the module may later
+       post messages about fatal problems, e.g. an exit() being
+       triggered, so it is recommended that UI elements for posting
+       status messages not be outright removed from the DOM when
+       text==null, and that they instead be hidden until/unless
+       text!=null.
+    */
+    setStatus: function f(text){
+        if(!f.last) f.last = { step: 0, text: '' };
+        else if(text === f.last.text) return;
+        f.last.text = text;
+        wMsg('module',{
+            type:'status',
+            data:{step: ++f.last.step, text: text||null}
+        });
+    },
     totalDependencies: 0,
     monitorRunDependencies: function(left) {
         this.totalDependencies = Math.max(this.totalDependencies, left);
@@ -147,6 +193,5 @@ importScripts('fiddle-module.js')
    is called _before_ the final call to Module.setStatus(). */;
 
 Module["onRuntimeInitialized"] = function onRuntimeInitialized() {
-    //console.log('onRuntimeInitialized');
-    //wMsg('module','done');
+    wMsg('fiddle-ready');
 };
index 30c20a81024d63fc6e81e20638efe3c40abab083..2353509da72f7729f37e2ac72532485676a07711 100644 (file)
@@ -17,6 +17,9 @@
 (function(){
     'use strict';
 
+    /* Recall that the 'self' symbol, except where locally
+       overwritten, refers to the global window or worker object. */
+
     /**
        The SqliteFiddle object is intended to be the primary
        app-level object for the main-thread side of the sqlite
 
     SF.addMsgHandler('module', function f(ev){
         ev = ev.data;
-        //console.log("Module status:",ev);
-        if('status'!==ev.type) return;
-        /* This weird handling of the ev.data is simply how
-           emscripten's auto-generated code notifies the client of
-           load progress. */
-        let text = ev.data;
-        if(!f.last) f.last = { time: Date.now(), text: '' };
-        if(text === f.last.text) return;
-        const m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
-        const now = Date.now();
-        if(m && now - f.last.time < 30) return; // if this is a progress update, skip it if too soon
-        f.last.time = now;
-        f.last.text = text;
-        if(m) {
-            text = m[1];
-            progressElement.value = parseInt(m[2])*100;
-            progressElement.max = parseInt(m[4])*100;
+        if('status'!==ev.type){
+            console.warn("Unexpected module-type message:",ev);
+            return;
+        }
+        const msg = ev.data;
+        progressElement.value = msg.step;
+        progressElement.max = msg.step + 1/*we don't know how many steps to expect*/;
+        if(1==msg.step){
             progressElement.hidden = false;
             spinnerElement.hidden = false;
-        } else {
-            progressElement.remove();
-            if(!text) spinnerElement.remove();
         }
-        if(text){
-            statusElement.innerText = text;
+        if(msg.text){
+            statusElement.classList.remove('hidden');
+            statusElement.innerText = msg.text;
         }else{
-            console.log("Finalizing status.");
-            statusElement.remove();
-            SF.clearMsgHandlers('module');
-            self.onSFLoaded();
+            progressElement.remove();
+            spinnerElement.remove();
+            statusElement.classList.add('hidden');
+            /* The module can post messages about fatal problems,
+               e.g. an exit() being triggered or assertion failure,
+               after the last "load" message has arrived, so
+               leave the statusElement and message listener intact. */
         }
     });
 
+    /**
+       The 'fiddle-ready' event is fired (with no payload) when the
+       wasm module has finished loading. Interestingly, that happens
+       _before_ the final module:status event */
+    SF.addMsgHandler('fiddle-ready', function(){
+        SF.clearMsgHandlers('fiddle-ready');
+        self.onSFLoaded();
+    });
+
     /**
        Performs all app initialization which must wait until after the
        worker module is loaded. This function removes itself when it's
index 4e15ac2067f7f7e5d203fdc324eb7b5ed2c6e3eb..3d192125d290cbc4af500a0f5ca5f1ff4aaa4a74 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C wasm:\sadded\smissing\s'use\sstrict'\sand\sfixed\san\sundeclared\svar\suse\scaught\sby\sthat.
-D 2022-05-23T13:55:39.347
+C fiddle:\scleaned\sup\sand\sdocumented\sthe\sstatus-loading\sprogress\smechanism\sin\sprep\sfor\sreusing\sit\sin\sthe\ssqlite3-api\sworker.
+D 2022-05-23T16:54:18.777
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -60,9 +60,9 @@ F ext/fiddle/EXPORTED_FUNCTIONS.sqlite3 5816adc4d4715b410a9df971c70f55fca610d3a2
 F ext/fiddle/EXPORTED_RUNTIME_METHODS 91d5dcb0168ee056fa1a340cb8ab3c23d922622f8dad39d28919dd8af2b3ade0
 F ext/fiddle/Makefile 9277c73e208b9c8093659256c9f07409c877e366480c7c22ec545ee345451d95
 F ext/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
-F ext/fiddle/fiddle-worker.js c22557b641b47fa1473d3465a4e69fe06b8b09b924955805a4202c8201ddc429
+F ext/fiddle/fiddle-worker.js e87c17070b979bd057a6849332f2a86660a4255ff7f1b6671e3e6026182ffd5a
 F ext/fiddle/fiddle.html 657c6c3f860c322fba3c69fa4f7a1209e2d2ce44b4bc65a3e154e3a97c047a7c
-F ext/fiddle/fiddle.js f9c79164428e96a5909532f18a8bc8f8c8ec4f738bfc09ad3d2a532c2400f9f0
+F ext/fiddle/fiddle.js 68f5bb45fc1ae7f8ae3f6b85f465257db514d12bf50ec492259685178c452a88
 F ext/fiddle/index.md d9c1c308d8074341bc3b11d1d39073cd77754cb3ca9aeb949f23fdd8323d81cf
 F ext/fiddle/sqlite3-api.js c684fc5ce6b6c3e70f33699de2fc4bf9eaf045a217a30125a9da31737a9ca9e7
 F ext/fiddle/testing-common.js 53284264504821314f052017b54fa75ab065dcd9cbb754cc8060930498faeee8
@@ -1967,8 +1967,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 7e2d2e807272e98e9a3c9c9ba492b796a603f36b7cc12b16923cd8a9e6579851
-R 775bb58b424cc12ca6c6f62d38938ce2
+P c16a7f4950d47c2f5177db7dc5d83f0f11eb0cafdce1ec688d6f1bd740d92733
+R d12da4267c62c5adab320ccc656c0131
 U stephan
-Z e5e8a91572b08fda7b97d6952202209e
+Z e5ea295f62c882bcf12e60eff235c6ea
 # Remove this line to create a well-formed Fossil manifest.
index bab01378f53f425e17296610bca10d7d211f04ff..6b5e057ea107985a671c32604d0e821b5c9293b6 100644 (file)
@@ -1 +1 @@
-c16a7f4950d47c2f5177db7dc5d83f0f11eb0cafdce1ec688d6f1bd740d92733
\ No newline at end of file
+107e3497869d757265f2a4235082bf324ba1220075d1096c2a82021a5d348a6c
\ No newline at end of file