# HG changeset patch
# User Edouard Tisserant
# Date 1571904127 -7200
# Node ID f48121cf31b6c31172252fa79a0b39f3819748c3
# Parent 64e6f73b98594be47b2ca02be9b84858cf96a7ba
SVGHMI: Added relative changes of HMI value from widgets.
diff -r 64e6f73b9859 -r f48121cf31b6 svghmi/gen_index_xhtml.xslt
--- a/svghmi/gen_index_xhtml.xslt Tue Oct 22 22:58:55 2019 +0200
+++ b/svghmi/gen_index_xhtml.xslt Thu Oct 24 10:02:07 2019 +0200
@@ -320,323 +320,357 @@
+ var cache = hmitree_types.map(_ignored => undefined);
+
+
+
function dispatch_value(index, value) {
let widgets = subscribers[index];
- // TODO : value cache
+ if(widgets.size > 0) {
+
+ for(let widget of widgets){
+
+ let idxidx = widget.indexes.indexOf(index);
+
+ if(idxidx == -1){
+
+ throw new Error("Dispatching to widget not interested, should not happen.");
+
+ }
+
+ let d = widget.dispatch;
+
+ if(typeof(d) == "function" && idxidx == 0){
+
+ return d.call(widget,value);
+
+ }else if(typeof(d) == "object" && d.length >= idxidx){
+
+ d[idxidx].call(widget,value);
+
+ }/* else dispatch_0, ..., dispatch_n ? */
+
+ /*else {
+
+ throw new Error("Dunno how to dispatch to widget at index = " + index);
+
+ }*/
+
+ }
+
+ }
+
+
+
+ cache[index] = value;
- if(widgets.size > 0) {
-
- for(let widget of widgets){
-
- let idxidx = widget.indexes.indexOf(index);
-
- if(idxidx == -1){
-
- throw new Error("Dispatching to widget not interested, should not happen.");
+ };
+
+
+
+ function init_widgets() {
+
+ Object.keys(hmi_widgets).forEach(function(id) {
+
+ let widget = hmi_widgets[id];
+
+ let init = widget.init;
+
+ if(typeof(init) == "function"){
+
+ return init.call(widget);
+
+ }
+
+ });
+
+ };
+
+
+
+ // Open WebSocket to relative "/ws" address
+
+ var ws = new WebSocket(window.location.href.replace(/^http(s?:\/\/[^\/]*)\/.*$/, 'ws$1/ws'));
+
+ ws.binaryType = 'arraybuffer';
+
+
+
+ const dvgetters = {
+
+ INT: [DataView.prototype.getInt16, 2],
+
+ BOOL: [DataView.prototype.getInt8, 1]
+
+ /* TODO */
+
+ };
+
+
+
+ // Register message reception handler
+
+ ws.onmessage = function (evt) {
+
+
+
+ let data = evt.data;
+
+ let dv = new DataView(data);
+
+ let i = 0;
+
+ //console.log("Recv something.");
+
+ try {
+
+ for(let hash_int of hmi_hash) {
+
+ if(hash_int != dv.getUint8(i)){
+
+ throw new Error("Hash doesn't match");
+
+ };
+
+ i++;
+
+ };
+
+
+
+ //console.log("Recv something GOOD.");
+
+
+
+ while(i < data.byteLength){
+
+ let index = dv.getUint32(i, true);
+
+ //console.log("Recv something index is "+index);
+
+ i += 4;
+
+ let iectype = hmitree_types[index];
+
+ if(iectype != undefined){
+
+ let [dvgetter, bytesize] = dvgetters[iectype];
+
+ let value = dvgetter.call(dv,i,true);
+
+ dispatch_value(index, value);
+
+ i += bytesize;
+
+ } else {
+
+ throw new Error("Unknown index "+index)
}
- let d = widget.dispatch;
-
- if(typeof(d) == "function" && idxidx == 0){
-
- return d.call(widget,value);
-
- }else if(typeof(d) == "object" && d.length >= idxidx){
-
- d[idxidx].call(widget,value);
-
- }/* else dispatch_0, ..., dispatch_n ? */
-
- /*else {
-
- throw new Error("Dunno how to dispatch to widget at index = " + index);
-
- }*/
+ };
+
+ } catch(err) {
+
+ // 1003 is for "Unsupported Data"
+
+ // ws.close(1003, err.message);
+
+
+
+ // TODO : remove debug alert ?
+
+ alert("Error : "+err.message+"\nHMI will be reloaded.");
+
+
+
+ // force reload ignoring cache
+
+ location.reload(true);
+
+ }
+
+ };
+
+
+
+
+
+ function send_blob(data) {
+
+ if(data.length > 0) {
+
+ ws.send(new Blob([new Uint8Array(hmi_hash)].concat(data)));
+
+ };
+
+ };
+
+
+
+ const typedarray_types = {
+
+ INT: Int16Array,
+
+ BOOL: Uint8Array
+
+ /* TODO */
+
+ };
+
+
+
+ function send_reset() {
+
+ send_blob(new Uint8Array([1])); /* reset = 1 */
+
+ };
+
+
+
+ // subscription state, as it should be in hmi server
+
+ // hmitree indexed array of integers
+
+ var subscriptions = hmitree_types.map(_ignored => 0);
+
+
+
+ // subscription state as needed by widget now
+
+ // hmitree indexed array of Sets of widgets objects
+
+ var subscribers = hmitree_types.map(_ignored => new Set());
+
+
+
+ function update_subscriptions() {
+
+ let delta = [];
+
+ for(let index = 0; index < subscribers.length; index++){
+
+ let widgets = subscribers[index];
+
+
+
+ // periods are in ms
+
+ let previous_period = subscriptions[index];
+
+
+
+ let new_period = 0;
+
+ if(widgets.size > 0) {
+
+ let maxfreq = 0;
+
+ for(let widget of widgets)
+
+ if(maxfreq < widget.frequency)
+
+ maxfreq = widget.frequency;
+
+
+
+ if(maxfreq != 0)
+
+ new_period = 1000/maxfreq;
}
+
+
+ if(previous_period != new_period) {
+
+ subscriptions[index] = new_period;
+
+ delta.push(
+
+ new Uint8Array([2]), /* subscribe = 2 */
+
+ new Uint32Array([index]),
+
+ new Uint16Array([new_period]));
+
+ }
+
+
+
}
- };
-
-
-
- function init_widgets() {
-
- Object.keys(hmi_widgets).forEach(function(id) {
-
- let widget = hmi_widgets[id];
-
- let init = widget.init;
-
- if(typeof(init) == "function"){
-
- return init.call(widget);
-
- }
-
- });
-
- };
-
-
-
- // Open WebSocket to relative "/ws" address
-
- var ws = new WebSocket(window.location.href.replace(/^http(s?:\/\/[^\/]*)\/.*$/, 'ws$1/ws'));
-
- ws.binaryType = 'arraybuffer';
-
-
-
- const dvgetters = {
-
- INT: [DataView.prototype.getInt16, 2],
-
- BOOL: [DataView.prototype.getInt8, 1]
-
- /* TODO */
-
- };
-
-
-
- // Register message reception handler
-
- ws.onmessage = function (evt) {
-
-
-
- let data = evt.data;
-
- let dv = new DataView(data);
-
- let i = 0;
-
- //console.log("Recv something.");
-
- try {
-
- for(let hash_int of hmi_hash) {
-
- if(hash_int != dv.getUint8(i)){
-
- throw new Error("Hash doesn't match");
-
- };
-
- i++;
-
- };
-
-
-
- //console.log("Recv something GOOD.");
-
-
-
- while(i < data.byteLength){
-
- let index = dv.getUint32(i, true);
-
- //console.log("Recv something index is "+index);
-
- i += 4;
-
- let iectype = hmitree_types[index];
-
- if(iectype != undefined){
-
- let [dvgetter, bytesize] = dvgetters[iectype];
-
- let value = dvgetter.call(dv,i,true);
-
- dispatch_value(index, value);
-
- i += bytesize;
-
- } else {
-
- throw new Error("Unknown index "+index)
-
- }
-
- };
-
- } catch(err) {
-
- // 1003 is for "Unsupported Data"
-
- // ws.close(1003, err.message);
-
-
-
- // TODO : remove debug alert ?
-
- alert("Error : "+err.message+"\nHMI will be reloaded.");
-
-
-
- // force reload ignoring cache
-
- location.reload(true);
+ send_blob(delta);
+
+ };
+
+
+
+ function send_hmi_value(index, value) {
+
+ let iectype = hmitree_types[index];
+
+ let jstype = typedarray_types[iectype];
+
+ send_blob([
+
+ new Uint8Array([0]), /* setval = 0 */
+
+ new Uint32Array([index]),
+
+ new jstype([value])]);
+
+
+
+ cache[index] = value;
+
+ };
+
+
+
+ function change_hmi_value(index, opstr) {
+
+ let op = opstr[0];
+
+ let given_val = opstr.slice(1);
+
+ let old_val = cache[index]
+
+ let new_val;
+
+ switch(op){
+
+ case "=":
+
+ eval("new_val"+opstr);
+
+ break;
+
+ case "+":
+
+ case "-":
+
+ case "*":
+
+ case "/":
+
+ if(old_val != undefined)
+
+ new_val = eval("old_val"+opstr);
+
+ break;
}
- };
-
-
-
-
-
- function send_blob(data) {
-
- if(data.length > 0) {
-
- ws.send(new Blob([new Uint8Array(hmi_hash)].concat(data)));
-
- };
-
- };
-
-
-
- const typedarray_types = {
-
- INT: Int16Array,
-
- BOOL: Uint8Array
-
- /* TODO */
-
- };
-
-
-
- function send_reset() {
-
- send_blob(new Uint8Array([1])); /* reset = 1 */
-
- };
-
-
-
- // subscription state, as it should be in hmi server
-
- // hmitree indexed array of integers
-
- var subscriptions = hmitree_types.map(_ignored => 0);
-
-
-
- // subscription state as needed by widget now
-
- // hmitree indexed array of Sets of widgets objects
-
- var subscribers = hmitree_types.map(_ignored => new Set());
-
-
-
- function update_subscriptions() {
-
- let delta = [];
-
- for(let index = 0; index < subscribers.length; index++){
-
- let widgets = subscribers[index];
-
-
-
- // periods are in ms
-
- let previous_period = subscriptions[index];
-
-
-
- let new_period = 0;
-
- if(widgets.size > 0) {
-
- let maxfreq = 0;
-
- for(let widget of widgets)
-
- if(maxfreq < widget.frequency)
-
- maxfreq = widget.frequency;
-
-
-
- if(maxfreq != 0)
-
- new_period = 1000/maxfreq;
-
- }
-
-
-
- if(previous_period != new_period) {
-
- subscriptions[index] = new_period;
-
- delta.push(
-
- new Uint8Array([2]), /* subscribe = 2 */
-
- new Uint32Array([index]),
-
- new Uint16Array([new_period]));
-
- }
-
-
-
- }
-
- send_blob(delta);
-
- };
-
-
-
- function send_hmi_value(index, value) {
-
- let iectype = hmitree_types[index];
-
- let jstype = typedarray_types[iectype];
-
- send_blob([
-
- new Uint8Array([0]), /* setval = 0 */
-
- new Uint32Array([index]),
-
- new jstype([value])]);
-
-
-
- };
-
-
-
- function change_hmi_value(index, opstr) {
-
- let op = opstr[0];
-
- if(op == "=")
-
- return send_hmi_value(index, Number(opstr.slice(1)));
-
-
-
- alert('Change '+opstr+" TODO !!! (index :"+index+")");
+ if(new_val != undefined && old_val != new_val)
+
+ return send_hmi_value(index, new_val);
}
diff -r 64e6f73b9859 -r f48121cf31b6 svghmi/svghmi.js
--- a/svghmi/svghmi.js Tue Oct 22 22:58:55 2019 +0200
+++ b/svghmi/svghmi.js Thu Oct 24 10:02:07 2019 +0200
@@ -1,10 +1,10 @@
// svghmi.js
+var cache = hmitree_types.map(_ignored => undefined);
+
function dispatch_value(index, value) {
let widgets = subscribers[index];
- // TODO : value cache
-
if(widgets.size > 0) {
for(let widget of widgets){
let idxidx = widget.indexes.indexOf(index);
@@ -22,6 +22,9 @@
}*/
}
}
+
+ cache[index] = value;
+
};
function init_widgets() {
@@ -147,14 +150,28 @@
new Uint32Array([index]),
new jstype([value])]);
+ cache[index] = value;
};
function change_hmi_value(index, opstr) {
let op = opstr[0];
- if(op == "=")
- return send_hmi_value(index, Number(opstr.slice(1)));
-
- alert('Change '+opstr+" TODO !!! (index :"+index+")");
+ let given_val = opstr.slice(1);
+ let old_val = cache[index]
+ let new_val;
+ switch(op){
+ case "=":
+ eval("new_val"+opstr);
+ break;
+ case "+":
+ case "-":
+ case "*":
+ case "/":
+ if(old_val != undefined)
+ new_val = eval("old_val"+opstr);
+ break;
+ }
+ if(new_val != undefined && old_val != new_val)
+ return send_hmi_value(index, new_val);
}
var current_page;