# HG changeset patch # User Edouard Tisserant # Date 1583483708 -3600 # Node ID 517583e21bfdc25b8e6c599bec15ee0bf5319353 # Parent 39c8d6079f0f6fd4b7f5e99d2b096347c291a8a3 SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload. diff -r 39c8d6079f0f -r 517583e21bfd svghmi/gen_index_xhtml.xslt --- a/svghmi/gen_index_xhtml.xslt Thu Mar 05 13:54:29 2020 +0100 +++ b/svghmi/gen_index_xhtml.xslt Fri Mar 06 09:35:08 2020 +0100 @@ -623,6 +623,8 @@ var cache = hmitree_types.map(_ignored => undefined); + var updates = {}; + function dispatch_value_to_widget(widget, index, value, oldval) { @@ -749,7 +751,33 @@ - // Register message reception handler + // Apply updates recieved through ws.onmessage to subscribed widgets + + // Called on requestAnimationFram, modifies DOM + + function apply_pending_updates() { + + for(let index in updates){ + + // serving as a key, index becomes a string + + // -> pass Number(index) instead + + dispatch_value(Number(index), updates[index]); + + delete updates[index]; + + } + + } + + + + // Message reception handler + + // Hash is verified and HMI values updates resulting from binary parsing + + // are stored until browser can compute next frame, DOM is left untouched ws.onmessage = function (evt) { @@ -791,18 +819,22 @@ let [value, bytesize] = dvgetter(dv,i); - dispatch_value(index, value); + updates[index] = value; i += bytesize; } else { - throw new Error("Unknown index "+index) + throw new Error("Unknown index "+index); } }; + // register for rendering on next frame, since there are updates + + window.requestAnimationFrame(apply_pending_updates); + } catch(err) { // 1003 is for "Unsupported Data" diff -r 39c8d6079f0f -r 517583e21bfd svghmi/svghmi.js --- a/svghmi/svghmi.js Thu Mar 05 13:54:29 2020 +0100 +++ b/svghmi/svghmi.js Fri Mar 06 09:35:08 2020 +0100 @@ -1,6 +1,7 @@ // svghmi.js var cache = hmitree_types.map(_ignored => undefined); +var updates = {}; function dispatch_value_to_widget(widget, index, value, oldval) { try { @@ -64,7 +65,20 @@ } }; -// Register message reception handler +// Apply updates recieved through ws.onmessage to subscribed widgets +// Called on requestAnimationFrame, modifies DOM +function apply_pending_updates() { + for(let index in updates){ + // serving as a key, index becomes a string + // -> pass Number(index) instead + dispatch_value(Number(index), updates[index]); + delete updates[index]; + } +} + +// Message reception handler +// Hash is verified and HMI values updates resulting from binary parsing +// are stored until browser can compute next frame, DOM is left untouched ws.onmessage = function (evt) { let data = evt.data; @@ -85,12 +99,14 @@ if(iectype != undefined){ let dvgetter = dvgetters[iectype]; let [value, bytesize] = dvgetter(dv,i); - dispatch_value(index, value); + updates[index] = value; i += bytesize; } else { - throw new Error("Unknown index "+index) + throw new Error("Unknown index "+index); } }; + // register for rendering on next frame, since there are updates + window.requestAnimationFrame(apply_pending_updates); } catch(err) { // 1003 is for "Unsupported Data" // ws.close(1003, err.message);