svghmi/svghmi.js
author Edouard Tisserant
Fri, 03 Apr 2020 14:37:41 +0200
branchsvghmi
changeset 2917 c8d923dd707f
parent 2916 4f3b130fd197
child 2920 3ee337c8c769
permissions -rw-r--r--
SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
2783
5ee6967f721d SVGHMI: Starting to define JS side more in details.
Edouard Tisserant
parents: 2780
diff changeset
     1
// svghmi.js
5ee6967f721d SVGHMI: Starting to define JS side more in details.
Edouard Tisserant
parents: 2780
diff changeset
     2
2803
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
     3
var cache = hmitree_types.map(_ignored => undefined);
2859
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
     4
var updates = {};
2897
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
     5
var need_cache_apply = []; 
2903
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
     6
var jumps_need_update = false;
2902
1fcb50af0335 SVGHMI: added Back widget.
Edouard Tisserant
parents: 2899
diff changeset
     7
var jump_history = [[default_page, undefined]];
2803
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
     8
2811
4a81cec5f786 SVGHMI - prepare page with cached data when switching. This prevents values that do not change and that was already subscribed in previous page from keeping undefined.
Edouard Tisserant
parents: 2810
diff changeset
     9
function dispatch_value_to_widget(widget, index, value, oldval) {
2834
6ac6a9dff594 SVGHMI: be a bit more tolerant with missing HMI paths or missing elements in widgets : continue build (with warning) and fail silently at runtime.
Edouard Tisserant
parents: 2829
diff changeset
    10
    try {
2870
634b43d69897 SVGHMI: relative pages and page jumps
Edouard Tisserant
parents: 2869
diff changeset
    11
        let idx = widget.offset ? index - widget.offset : index;
634b43d69897 SVGHMI: relative pages and page jumps
Edouard Tisserant
parents: 2869
diff changeset
    12
        let idxidx = widget.indexes.indexOf(idx);
2834
6ac6a9dff594 SVGHMI: be a bit more tolerant with missing HMI paths or missing elements in widgets : continue build (with warning) and fail silently at runtime.
Edouard Tisserant
parents: 2829
diff changeset
    13
        let d = widget.dispatch;
6ac6a9dff594 SVGHMI: be a bit more tolerant with missing HMI paths or missing elements in widgets : continue build (with warning) and fail silently at runtime.
Edouard Tisserant
parents: 2829
diff changeset
    14
        if(typeof(d) == "function" && idxidx == 0){
6ac6a9dff594 SVGHMI: be a bit more tolerant with missing HMI paths or missing elements in widgets : continue build (with warning) and fail silently at runtime.
Edouard Tisserant
parents: 2829
diff changeset
    15
            d.call(widget, value, oldval);
2870
634b43d69897 SVGHMI: relative pages and page jumps
Edouard Tisserant
parents: 2869
diff changeset
    16
        }
2871
ed9b16b33628 SVGHMI: Re-enable dispatch to arrays of functions in case of multiple suscription per widget. Still unused, but disabled for reasons not any more true.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2870
diff changeset
    17
        else if(typeof(d) == "object" && d.length >= idxidx){
2834
6ac6a9dff594 SVGHMI: be a bit more tolerant with missing HMI paths or missing elements in widgets : continue build (with warning) and fail silently at runtime.
Edouard Tisserant
parents: 2829
diff changeset
    18
            d[idxidx].call(widget, value, oldval);
2871
ed9b16b33628 SVGHMI: Re-enable dispatch to arrays of functions in case of multiple suscription per widget. Still unused, but disabled for reasons not any more true.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2870
diff changeset
    19
        }
2870
634b43d69897 SVGHMI: relative pages and page jumps
Edouard Tisserant
parents: 2869
diff changeset
    20
        /* else dispatch_0, ..., dispatch_n ? */
2834
6ac6a9dff594 SVGHMI: be a bit more tolerant with missing HMI paths or missing elements in widgets : continue build (with warning) and fail silently at runtime.
Edouard Tisserant
parents: 2829
diff changeset
    21
        /*else {
6ac6a9dff594 SVGHMI: be a bit more tolerant with missing HMI paths or missing elements in widgets : continue build (with warning) and fail silently at runtime.
Edouard Tisserant
parents: 2829
diff changeset
    22
            throw new Error("Dunno how to dispatch to widget at index = " + index);
6ac6a9dff594 SVGHMI: be a bit more tolerant with missing HMI paths or missing elements in widgets : continue build (with warning) and fail silently at runtime.
Edouard Tisserant
parents: 2829
diff changeset
    23
        }*/
2836
ce6cecdb7320 SVGHMI : still behave, even if important things are missing in SVG widget definitions (ex: needle missing for Meter widget)
Edouard Tisserant
parents: 2834
diff changeset
    24
    } catch(err) {
ce6cecdb7320 SVGHMI : still behave, even if important things are missing in SVG widget definitions (ex: needle missing for Meter widget)
Edouard Tisserant
parents: 2834
diff changeset
    25
        console.log(err);
2834
6ac6a9dff594 SVGHMI: be a bit more tolerant with missing HMI paths or missing elements in widgets : continue build (with warning) and fail silently at runtime.
Edouard Tisserant
parents: 2829
diff changeset
    26
    }
2811
4a81cec5f786 SVGHMI - prepare page with cached data when switching. This prevents values that do not change and that was already subscribed in previous page from keeping undefined.
Edouard Tisserant
parents: 2810
diff changeset
    27
}
4a81cec5f786 SVGHMI - prepare page with cached data when switching. This prevents values that do not change and that was already subscribed in previous page from keeping undefined.
Edouard Tisserant
parents: 2810
diff changeset
    28
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    29
function dispatch_value(index, value) {
2800
68cee1366b9c SVGHMI: dispatching data to minimalist "Display" text widget.
Edouard Tisserant
parents: 2799
diff changeset
    30
    let widgets = subscribers[index];
68cee1366b9c SVGHMI: dispatching data to minimalist "Display" text widget.
Edouard Tisserant
parents: 2799
diff changeset
    31
2805
e521e0d133d5 SVGHMI: fixed HMI->PLC dataflow : not updates as expected, and not initialized properly after subscribe.
Edouard Tisserant
parents: 2803
diff changeset
    32
    let oldval = cache[index];
e521e0d133d5 SVGHMI: fixed HMI->PLC dataflow : not updates as expected, and not initialized properly after subscribe.
Edouard Tisserant
parents: 2803
diff changeset
    33
    cache[index] = value;
e521e0d133d5 SVGHMI: fixed HMI->PLC dataflow : not updates as expected, and not initialized properly after subscribe.
Edouard Tisserant
parents: 2803
diff changeset
    34
2800
68cee1366b9c SVGHMI: dispatching data to minimalist "Display" text widget.
Edouard Tisserant
parents: 2799
diff changeset
    35
    if(widgets.size > 0) {
68cee1366b9c SVGHMI: dispatching data to minimalist "Display" text widget.
Edouard Tisserant
parents: 2799
diff changeset
    36
        for(let widget of widgets){
2811
4a81cec5f786 SVGHMI - prepare page with cached data when switching. This prevents values that do not change and that was already subscribed in previous page from keeping undefined.
Edouard Tisserant
parents: 2810
diff changeset
    37
            dispatch_value_to_widget(widget, index, value, oldval);
2800
68cee1366b9c SVGHMI: dispatching data to minimalist "Display" text widget.
Edouard Tisserant
parents: 2799
diff changeset
    38
        }
68cee1366b9c SVGHMI: dispatching data to minimalist "Display" text widget.
Edouard Tisserant
parents: 2799
diff changeset
    39
    }
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    40
};
2783
5ee6967f721d SVGHMI: Starting to define JS side more in details.
Edouard Tisserant
parents: 2780
diff changeset
    41
2801
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    42
function init_widgets() {
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    43
    Object.keys(hmi_widgets).forEach(function(id) {
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    44
        let widget = hmi_widgets[id];
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    45
        let init = widget.init;
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    46
        if(typeof(init) == "function"){
2834
6ac6a9dff594 SVGHMI: be a bit more tolerant with missing HMI paths or missing elements in widgets : continue build (with warning) and fail silently at runtime.
Edouard Tisserant
parents: 2829
diff changeset
    47
            try {
6ac6a9dff594 SVGHMI: be a bit more tolerant with missing HMI paths or missing elements in widgets : continue build (with warning) and fail silently at runtime.
Edouard Tisserant
parents: 2829
diff changeset
    48
                init.call(widget);
6ac6a9dff594 SVGHMI: be a bit more tolerant with missing HMI paths or missing elements in widgets : continue build (with warning) and fail silently at runtime.
Edouard Tisserant
parents: 2829
diff changeset
    49
            } catch(err) {
2836
ce6cecdb7320 SVGHMI : still behave, even if important things are missing in SVG widget definitions (ex: needle missing for Meter widget)
Edouard Tisserant
parents: 2834
diff changeset
    50
                console.log(err);
2834
6ac6a9dff594 SVGHMI: be a bit more tolerant with missing HMI paths or missing elements in widgets : continue build (with warning) and fail silently at runtime.
Edouard Tisserant
parents: 2829
diff changeset
    51
            }
2801
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    52
        }
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    53
    });
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    54
};
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
    55
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    56
// Open WebSocket to relative "/ws" address
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    57
var ws = new WebSocket(window.location.href.replace(/^http(s?:\/\/[^\/]*)\/.*$/, 'ws$1/ws'));
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    58
ws.binaryType = 'arraybuffer';
2783
5ee6967f721d SVGHMI: Starting to define JS side more in details.
Edouard Tisserant
parents: 2780
diff changeset
    59
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    60
const dvgetters = {
2826
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    61
    INT: (dv,offset) => [dv.getInt16(offset, true), 2],
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    62
    BOOL: (dv,offset) => [dv.getInt8(offset, true), 1],
2890
ae8063127e95 SVGHMI: make root HMI tree node a HMI_NODE, droped HMI_ROOT node type
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2889
diff changeset
    63
    NODE: (dv,offset) => [dv.getInt8(offset, true), 1],
2826
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    64
    STRING: (dv, offset) => {
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    65
        size = dv.getInt8(offset);
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    66
        return [
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    67
            String.fromCharCode.apply(null, new Uint8Array(
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    68
                dv.buffer, /* original buffer */
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    69
                offset + 1, /* string starts after size*/
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    70
                size /* size of string */
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    71
            )), size + 1]; /* total increment */
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
    72
    }
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    73
};
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
    74
2859
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
    75
// Apply updates recieved through ws.onmessage to subscribed widgets
2865
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    76
function apply_updates() {
2859
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
    77
    for(let index in updates){
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
    78
        // serving as a key, index becomes a string
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
    79
        // -> pass Number(index) instead
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
    80
        dispatch_value(Number(index), updates[index]);
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
    81
        delete updates[index];
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
    82
    }
2865
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    83
}
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    84
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    85
// Called on requestAnimationFrame, modifies DOM
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    86
var requestAnimationFrameID = null;
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    87
function animate() {
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    88
    // Do the page swith if any one pending
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    89
    if(current_subscribed_page != current_visible_page){
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    90
        switch_visible_page(current_subscribed_page);
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    91
    }
2895
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
    92
2897
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
    93
    while(widget = need_cache_apply.pop()){
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
    94
        widget.apply_cache();
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
    95
    }
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
    96
2903
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
    97
    if(jumps_need_update) update_jumps();
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
    98
2865
545902730141 SVGHMI: cosmetic code moving
Edouard Tisserant
parents: 2864
diff changeset
    99
    apply_updates();
2864
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   100
    requestAnimationFrameID = null;
2859
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
   101
}
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
   102
2860
b7650c6abeda SVGHMI: more decoupling in between UI related and the rest of JS code, still in the aim of enhancing robustness under heavy load.
Edouard Tisserant
parents: 2859
diff changeset
   103
function requestHMIAnimation() {
2864
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   104
    if(requestAnimationFrameID == null){
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   105
        requestAnimationFrameID = window.requestAnimationFrame(animate);
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   106
    }
2860
b7650c6abeda SVGHMI: more decoupling in between UI related and the rest of JS code, still in the aim of enhancing robustness under heavy load.
Edouard Tisserant
parents: 2859
diff changeset
   107
}
b7650c6abeda SVGHMI: more decoupling in between UI related and the rest of JS code, still in the aim of enhancing robustness under heavy load.
Edouard Tisserant
parents: 2859
diff changeset
   108
2859
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
   109
// Message reception handler
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
   110
// Hash is verified and HMI values updates resulting from binary parsing
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
   111
// are stored until browser can compute next frame, DOM is left untouched
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   112
ws.onmessage = function (evt) {
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   113
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   114
    let data = evt.data;
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   115
    let dv = new DataView(data);
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   116
    let i = 0;
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   117
    try {
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   118
        for(let hash_int of hmi_hash) {
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   119
            if(hash_int != dv.getUint8(i)){
2800
68cee1366b9c SVGHMI: dispatching data to minimalist "Display" text widget.
Edouard Tisserant
parents: 2799
diff changeset
   120
                throw new Error("Hash doesn't match");
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   121
            };
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   122
            i++;
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   123
        };
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   124
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   125
        while(i < data.byteLength){
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   126
            let index = dv.getUint32(i, true);
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   127
            i += 4;
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   128
            let iectype = hmitree_types[index];
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   129
            if(iectype != undefined){
2826
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
   130
                let dvgetter = dvgetters[iectype];
1e5abecc3cde SVGHMI : support for HMI_STRING and HMI_BOOL
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2822
diff changeset
   131
                let [value, bytesize] = dvgetter(dv,i);
2859
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
   132
                updates[index] = value;
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   133
                i += bytesize;
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   134
            } else {
2859
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
   135
                throw new Error("Unknown index "+index);
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   136
            }
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   137
        };
2859
517583e21bfd SVGHMI: use requestAnimationFrame to delegate rendering of updates from network. Should help prevent browser collapse leading to watchdog in case of overload.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2850
diff changeset
   138
        // register for rendering on next frame, since there are updates
2864
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   139
        requestHMIAnimation();
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   140
    } catch(err) {
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   141
        // 1003 is for "Unsupported Data"
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   142
        // ws.close(1003, err.message);
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   143
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   144
        // TODO : remove debug alert ?
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   145
        alert("Error : "+err.message+"\\\\nHMI will be reloaded.");
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   146
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   147
        // force reload ignoring cache
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   148
        location.reload(true);
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   149
    }
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   150
};
2783
5ee6967f721d SVGHMI: Starting to define JS side more in details.
Edouard Tisserant
parents: 2780
diff changeset
   151
2788
2ed9ff826d03 SVGHMI: Work in progress. C side mostly implemented, neither built nor tested.
Edouard Tisserant
parents: 2783
diff changeset
   152
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   153
function send_blob(data) {
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   154
    if(data.length > 0) {
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   155
        ws.send(new Blob([new Uint8Array(hmi_hash)].concat(data)));
2780
e468f18df200 SVGHMI: moved static JS code to a separate file included at xhtml generation time
Edouard Tisserant
parents:
diff changeset
   156
    };
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   157
};
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   158
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   159
const typedarray_types = {
2829
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   160
    INT: (number) => new Int16Array([number]),
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   161
    BOOL: (truth) => new Int16Array([truth]),
2890
ae8063127e95 SVGHMI: make root HMI tree node a HMI_NODE, droped HMI_ROOT node type
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2889
diff changeset
   162
    NODE: (truth) => new Int16Array([truth]),
2829
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   163
    STRING: (str) => {
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   164
        // beremiz default string max size is 128
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   165
        str = str.slice(0,128);
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   166
        binary = new Uint8Array(str.length + 1);
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   167
        binary[0] = str.length;
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   168
        for(var i = 0; i < str.length; i++){
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   169
            binary[i+1] = str.charCodeAt(i);
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   170
        }
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   171
        return binary;
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   172
    }
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   173
    /* TODO */
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   174
};
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   175
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   176
function send_reset() {
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   177
    send_blob(new Uint8Array([1])); /* reset = 1 */
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   178
};
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   179
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   180
// subscription state, as it should be in hmi server
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   181
// hmitree indexed array of integers
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   182
var subscriptions =  hmitree_types.map(_ignored => 0);
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   183
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   184
// subscription state as needed by widget now
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   185
// hmitree indexed array of Sets of widgets objects
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   186
var subscribers = hmitree_types.map(_ignored => new Set());
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   187
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   188
// artificially subscribe the watchdog widget to "/heartbeat" hmi variable
2829
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   189
// Since dispatch directly calls change_hmi_value,
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   190
// PLC will periodically send variable at given frequency
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   191
subscribers[heartbeat_index].add({
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   192
    /* type: "Watchdog", */
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   193
    frequency: 1,
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   194
    indexes: [heartbeat_index],
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   195
    dispatch: function(value) {
2829
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   196
        change_hmi_value(heartbeat_index, "+1");
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   197
    }
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   198
});
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   199
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   200
function update_subscriptions() {
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   201
    let delta = [];
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   202
    for(let index = 0; index < subscribers.length; index++){
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   203
        let widgets = subscribers[index];
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   204
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   205
        // periods are in ms
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   206
        let previous_period = subscriptions[index];
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   207
2822
9101a72a1da0 SVGHMI: added a watchdog. To ensure that the whole chain is checked, watchdog use a periodic echo of a hearteat variable. JS client code systematically register /HEARTBEAT at 1s update freq, and reacts on updates of /HEARTBEAT by systematically incrementing it. C code catch /HEARTBEAT update and feeds python-implemented watchdog. For now, watchdog does nothing when tiggered
Edouard Tisserant
parents: 2811
diff changeset
   208
        // subscribing with a zero period is unsubscribing
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   209
        let new_period = 0;
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   210
        if(widgets.size > 0) {
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   211
            let maxfreq = 0;
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   212
            for(let widget of widgets)
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   213
                if(maxfreq < widget.frequency)
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   214
                    maxfreq = widget.frequency;
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   215
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   216
            if(maxfreq != 0)
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   217
                new_period = 1000/maxfreq;
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   218
        }
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   219
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   220
        if(previous_period != new_period) {
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   221
            subscriptions[index] = new_period;
2802
64e6f73b9859 SVGHMI - Fixed svghmi.{c,js} about HMI -> PLC data unpack.
Edouard Tisserant
parents: 2801
diff changeset
   222
            delta.push(
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   223
                new Uint8Array([2]), /* subscribe = 2 */
2806
7d0e81cdedb0 SVGHMI: Quicker update path for input widget when pressing on buttons, do not wait until data comes back, and simply update value text of the pressed widget. Updated PLC prog for more amimated value to display
Edouard Tisserant
parents: 2805
diff changeset
   224
                new Uint32Array([index]),
2802
64e6f73b9859 SVGHMI - Fixed svghmi.{c,js} about HMI -> PLC data unpack.
Edouard Tisserant
parents: 2801
diff changeset
   225
                new Uint16Array([new_period]));
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   226
        }
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   227
    }
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   228
    send_blob(delta);
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   229
};
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   230
2801
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
   231
function send_hmi_value(index, value) {
2802
64e6f73b9859 SVGHMI - Fixed svghmi.{c,js} about HMI -> PLC data unpack.
Edouard Tisserant
parents: 2801
diff changeset
   232
    let iectype = hmitree_types[index];
2829
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   233
    let tobinary = typedarray_types[iectype];
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   234
    send_blob([
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   235
        new Uint8Array([0]),  /* setval = 0 */
2829
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   236
        new Uint32Array([index]),
4c2c50f60730 SVGHMI : HMI_STRING now also supported from HMI to PLC
Edouard Tisserant
parents: 2827
diff changeset
   237
        tobinary(value)]);
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   238
2803
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   239
    cache[index] = value;
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   240
};
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   241
2911
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   242
function apply_hmi_value(index, new_val) {
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   243
    let old_val = cache[index]
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   244
    if(new_val != undefined && old_val != new_val)
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   245
        send_hmi_value(index, new_val);
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   246
    return new_val;
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   247
}
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   248
2801
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
   249
function change_hmi_value(index, opstr) {
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
   250
    let op = opstr[0];
2803
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   251
    let given_val = opstr.slice(1);
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   252
    let old_val = cache[index]
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   253
    let new_val;
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   254
    switch(op){
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   255
      case "=":
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   256
        eval("new_val"+opstr);
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   257
        break;
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   258
      case "+":
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   259
      case "-":
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   260
      case "*":
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   261
      case "/":
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   262
        if(old_val != undefined)
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   263
            new_val = eval("old_val"+opstr);
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   264
        break;
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   265
    }
f48121cf31b6 SVGHMI: Added relative changes of HMI value from widgets.
Edouard Tisserant
parents: 2802
diff changeset
   266
    if(new_val != undefined && old_val != new_val)
2806
7d0e81cdedb0 SVGHMI: Quicker update path for input widget when pressing on buttons, do not wait until data comes back, and simply update value text of the pressed widget. Updated PLC prog for more amimated value to display
Edouard Tisserant
parents: 2805
diff changeset
   267
        send_hmi_value(index, new_val);
7d0e81cdedb0 SVGHMI: Quicker update path for input widget when pressing on buttons, do not wait until data comes back, and simply update value text of the pressed widget. Updated PLC prog for more amimated value to display
Edouard Tisserant
parents: 2805
diff changeset
   268
    return new_val;
2801
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
   269
}
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
   270
2864
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   271
var current_visible_page;
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   272
var current_subscribed_page;
2903
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   273
var current_page_index;
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   274
2843
94696b3f69fb SVGHMI : still trying to optimize. Added xslt code to identitfy minimum set of elements needed by a particular page. Plan is to remove unseen/unused elements from the DOM, and re-appending them later when used, on page switch. Disabled previous optimization.
Edouard Tisserant
parents: 2841
diff changeset
   275
function prepare_svg() {
2850
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   276
    for(let eltid in detachable_elements){
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   277
        let [element,parent] = detachable_elements[eltid];
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   278
        parent.removeChild(element);
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   279
    }
2843
94696b3f69fb SVGHMI : still trying to optimize. Added xslt code to identitfy minimum set of elements needed by a particular page. Plan is to remove unseen/unused elements from the DOM, and re-appending them later when used, on page switch. Disabled previous optimization.
Edouard Tisserant
parents: 2841
diff changeset
   280
};
94696b3f69fb SVGHMI : still trying to optimize. Added xslt code to identitfy minimum set of elements needed by a particular page. Plan is to remove unseen/unused elements from the DOM, and re-appending them later when used, on page switch. Disabled previous optimization.
Edouard Tisserant
parents: 2841
diff changeset
   281
2870
634b43d69897 SVGHMI: relative pages and page jumps
Edouard Tisserant
parents: 2869
diff changeset
   282
function switch_page(page_name, page_index) {
2864
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   283
    if(current_subscribed_page != current_visible_page){
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   284
        /* page switch already going */
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   285
        /* TODO LOG ERROR */
2902
1fcb50af0335 SVGHMI: added Back widget.
Edouard Tisserant
parents: 2899
diff changeset
   286
        return false;
2895
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   287
    }
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   288
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   289
    if(page_name == undefined)
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   290
        page_name = current_subscribed_page;
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   291
2903
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   292
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   293
    let old_desc = page_desc[current_subscribed_page];
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   294
    let new_desc = page_desc[page_name];
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   295
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   296
    if(new_desc == undefined){
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   297
        /* TODO LOG ERROR */
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   298
        return false;
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   299
    }
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   300
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   301
    if(page_index == undefined){
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   302
        page_index = new_desc.page_index;
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   303
    }
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   304
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   305
    if(old_desc){
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   306
        old_desc.absolute_widgets.map(w=>w.unsub());
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   307
        old_desc.relative_widgets.map(w=>w.unsub());
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   308
    }
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   309
    new_desc.absolute_widgets.map(w=>w.sub());
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   310
    var new_offset = page_index == undefined ? 0 : page_index - new_desc.page_index;
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   311
    new_desc.relative_widgets.map(w=>w.sub(new_offset));
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   312
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   313
    update_subscriptions();
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   314
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   315
    current_subscribed_page = page_name;
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   316
    current_page_index = page_index;
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   317
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   318
    jumps_need_update = true;
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   319
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   320
    requestHMIAnimation();
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   321
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   322
    jump_history.push([page_name, page_index]);
2905
3d7e3866cc51 SVGHMI: prevent man-made memory leak by limiting back button history items count to 42
Edouard Tisserant
parents: 2903
diff changeset
   323
    if(jump_history.length > 42)
3d7e3866cc51 SVGHMI: prevent man-made memory leak by limiting back button history items count to 42
Edouard Tisserant
parents: 2903
diff changeset
   324
        jump_history.shift();
2903
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   325
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   326
    return true;
2864
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   327
};
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   328
2869
d9eb50c015d1 SVGHMI: take care of path given in HMI:Page and HMI:Jump, but do not apply subscription offset for now. Intermediate commit in a "working" state.
Edouard Tisserant
parents: 2867
diff changeset
   329
function* chain(a,b){
d9eb50c015d1 SVGHMI: take care of path given in HMI:Page and HMI:Jump, but do not apply subscription offset for now. Intermediate commit in a "working" state.
Edouard Tisserant
parents: 2867
diff changeset
   330
    yield* a;
d9eb50c015d1 SVGHMI: take care of path given in HMI:Page and HMI:Jump, but do not apply subscription offset for now. Intermediate commit in a "working" state.
Edouard Tisserant
parents: 2867
diff changeset
   331
    yield* b;
d9eb50c015d1 SVGHMI: take care of path given in HMI:Page and HMI:Jump, but do not apply subscription offset for now. Intermediate commit in a "working" state.
Edouard Tisserant
parents: 2867
diff changeset
   332
};
d9eb50c015d1 SVGHMI: take care of path given in HMI:Page and HMI:Jump, but do not apply subscription offset for now. Intermediate commit in a "working" state.
Edouard Tisserant
parents: 2867
diff changeset
   333
2889
4eeed820fd3a SVGHMI: reworked widget (un)subscription now a method of widgect object, allowing special subscription methods
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2871
diff changeset
   334
function unsubscribe(){
4eeed820fd3a SVGHMI: reworked widget (un)subscription now a method of widgect object, allowing special subscription methods
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2871
diff changeset
   335
    /* remove subsribers */
2895
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   336
    for(let index of this.indexes){
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   337
        let idx = index + this.offset;
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   338
        subscribers[idx].delete(this);
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   339
    }
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   340
    this.offset = 0;
2889
4eeed820fd3a SVGHMI: reworked widget (un)subscription now a method of widgect object, allowing special subscription methods
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2871
diff changeset
   341
}
4eeed820fd3a SVGHMI: reworked widget (un)subscription now a method of widgect object, allowing special subscription methods
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2871
diff changeset
   342
4eeed820fd3a SVGHMI: reworked widget (un)subscription now a method of widgect object, allowing special subscription methods
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2871
diff changeset
   343
function subscribe(new_offset=0){
4eeed820fd3a SVGHMI: reworked widget (un)subscription now a method of widgect object, allowing special subscription methods
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2871
diff changeset
   344
    /* set the offset because relative */
2895
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   345
    this.offset = new_offset;
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   346
    /* add this's subsribers */
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   347
    for(let index of this.indexes){
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   348
        subscribers[index + new_offset].add(this);
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   349
    }
2897
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   350
    need_cache_apply.push(this); 
2895
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   351
}
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   352
2896
99c5335ed59f SVGHMI: Widget ForEach buttons now call corresponding methods.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2895
diff changeset
   353
function foreach_unsubscribe(){
2895
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   354
    for(let item of this.items){
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   355
        for(let widget of item) {
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   356
            unsubscribe.call(widget);
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   357
        }
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   358
    }
2897
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   359
    this.offset = 0;
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   360
}
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   361
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   362
function foreach_widgets_do(new_offset, todo){
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   363
    this.offset = new_offset;
2895
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   364
    for(let i = 0; i < this.items.length; i++) {
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   365
        let item = this.items[i];
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   366
        let orig_item_index = this.index_pool[i];
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   367
        let item_index = this.index_pool[i+this.item_offset];
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   368
        let item_index_offset = item_index - orig_item_index;
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   369
        for(let widget of item) {
2897
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   370
            todo.call(widget, new_offset + item_index_offset);
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   371
        }
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   372
    }
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   373
}
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   374
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   375
function foreach_subscribe(new_offset=0){
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   376
    foreach_widgets_do.call(this, new_offset, subscribe);
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   377
}
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   378
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   379
function widget_apply_cache() {
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   380
    for(let index of this.indexes){
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   381
        /* dispatch current cache in newly opened page widgets */
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   382
        let realindex = index+this.offset;
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   383
        let cached_val = cache[realindex];
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   384
        if(cached_val != undefined)
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   385
            dispatch_value_to_widget(this, realindex, cached_val, cached_val);
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   386
    }
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   387
}
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   388
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   389
function foreach_apply_cache() {
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   390
    foreach_widgets_do.call(this, this.offset, widget_apply_cache);
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   391
}
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   392
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   393
function foreach_onclick(opstr, evt) {
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   394
    new_item_offset = eval(String(this.item_offset)+opstr)
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   395
    if(new_item_offset + this.items.length > this.index_pool.length) {
2899
f1baf2d0552c SVGHMI: ForEach Widget now has a better wrap-around when scrolling : hit the boundary systematically before wrapping
Edouard Tisserant
parents: 2897
diff changeset
   396
        if(this.item_offset + this.items.length == this.index_pool.length)
f1baf2d0552c SVGHMI: ForEach Widget now has a better wrap-around when scrolling : hit the boundary systematically before wrapping
Edouard Tisserant
parents: 2897
diff changeset
   397
            new_item_offset = 0;
f1baf2d0552c SVGHMI: ForEach Widget now has a better wrap-around when scrolling : hit the boundary systematically before wrapping
Edouard Tisserant
parents: 2897
diff changeset
   398
        else
f1baf2d0552c SVGHMI: ForEach Widget now has a better wrap-around when scrolling : hit the boundary systematically before wrapping
Edouard Tisserant
parents: 2897
diff changeset
   399
            new_item_offset = this.index_pool.length - this.items.length;
2897
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   400
    } else if(new_item_offset < 0) {
2899
f1baf2d0552c SVGHMI: ForEach Widget now has a better wrap-around when scrolling : hit the boundary systematically before wrapping
Edouard Tisserant
parents: 2897
diff changeset
   401
        if(this.item_offset == 0)
f1baf2d0552c SVGHMI: ForEach Widget now has a better wrap-around when scrolling : hit the boundary systematically before wrapping
Edouard Tisserant
parents: 2897
diff changeset
   402
            new_item_offset = this.index_pool.length - this.items.length;
f1baf2d0552c SVGHMI: ForEach Widget now has a better wrap-around when scrolling : hit the boundary systematically before wrapping
Edouard Tisserant
parents: 2897
diff changeset
   403
        else
f1baf2d0552c SVGHMI: ForEach Widget now has a better wrap-around when scrolling : hit the boundary systematically before wrapping
Edouard Tisserant
parents: 2897
diff changeset
   404
            new_item_offset = 0;
2897
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   405
    }
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   406
    this.item_offset = new_item_offset;
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   407
    off = this.offset;
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   408
    foreach_unsubscribe.call(this);
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   409
    foreach_subscribe.call(this,off);
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   410
    update_subscriptions();
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   411
    need_cache_apply.push(this);
2903
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   412
    jumps_need_update = true;
2897
bf8a39cc65e4 SVGHMI: Generalize applying cache to widgets, be it from page or ForEach widgets. Now ForEach widget buttons work as expected.
Edouard Tisserant
parents: 2896
diff changeset
   413
    requestHMIAnimation();
2889
4eeed820fd3a SVGHMI: reworked widget (un)subscription now a method of widgect object, allowing special subscription methods
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2871
diff changeset
   414
}
4eeed820fd3a SVGHMI: reworked widget (un)subscription now a method of widgect object, allowing special subscription methods
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2871
diff changeset
   415
2864
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   416
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   417
function switch_visible_page(page_name) {
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   418
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   419
    let old_desc = page_desc[current_visible_page];
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   420
    let new_desc = page_desc[page_name];
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   421
36f78f6cfabd SVGHMI: split page switch into switching subscription and switching elements in the DOM, to ensure that subscriptions have been send before changing DOM, and avoid some flicker.
Edouard Tisserant
parents: 2860
diff changeset
   422
    if(old_desc){
2850
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   423
        for(let eltid in old_desc.required_detachables){
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   424
            if(!(eltid in new_desc.required_detachables)){
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   425
                let [element, parent] = old_desc.required_detachables[eltid];
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   426
                parent.removeChild(element);
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   427
            }
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   428
        }
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   429
        for(let eltid in new_desc.required_detachables){
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   430
            if(!(eltid in old_desc.required_detachables)){
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   431
                let [element, parent] = new_desc.required_detachables[eltid];
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   432
                parent.appendChild(element);
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   433
            }
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   434
        }
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   435
    }else{
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   436
        for(let eltid in new_desc.required_detachables){
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   437
            let [element, parent] = new_desc.required_detachables[eltid];
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   438
            parent.appendChild(element);
e38654ec6281 SVGHMI: detach/re-attach elements required by pages on page switch
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2843
diff changeset
   439
        }
2843
94696b3f69fb SVGHMI : still trying to optimize. Added xslt code to identitfy minimum set of elements needed by a particular page. Plan is to remove unseen/unused elements from the DOM, and re-appending them later when used, on page switch. Disabled previous optimization.
Edouard Tisserant
parents: 2841
diff changeset
   440
    }
94696b3f69fb SVGHMI : still trying to optimize. Added xslt code to identitfy minimum set of elements needed by a particular page. Plan is to remove unseen/unused elements from the DOM, and re-appending them later when used, on page switch. Disabled previous optimization.
Edouard Tisserant
parents: 2841
diff changeset
   441
2895
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   442
    svg_root.setAttribute('viewBox',new_desc.bbox.join(" "));
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   443
    current_visible_page = page_name;
89c02b452717 SVGHMI: ForEach now has working (un)subscribe. Fixed PageSwitch that wasn't behaving when jumping to current page with another path.
Edouard Tisserant
parents: 2890
diff changeset
   444
};
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   445
2903
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   446
function update_jumps() {
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   447
    page_desc[current_visible_page].jumps.map(w=>w.notify_page_change(current_visible_page,current_page_index));
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   448
    jumps_need_update = false;
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   449
};
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   450
881d0248b3ce SVGHMI: Jump widget can now display as active or inactive, if corresponfing "active" and "inactive labeled elements are provided.
Edouard Tisserant
parents: 2902
diff changeset
   451
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   452
// Once connection established
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   453
ws.onopen = function (evt) {
2801
390acff12755 SVGHMI: Added init call to all widgets at startup to bind events. More features in Input widget : Edit and Change buttons. WIP HMI->PLC value update, incoherent data detected in C part on update.
Edouard Tisserant
parents: 2800
diff changeset
   454
    init_widgets();
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   455
    send_reset();
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   456
    // show main page
2843
94696b3f69fb SVGHMI : still trying to optimize. Added xslt code to identitfy minimum set of elements needed by a particular page. Plan is to remove unseen/unused elements from the DOM, and re-appending them later when used, on page switch. Disabled previous optimization.
Edouard Tisserant
parents: 2841
diff changeset
   457
    prepare_svg();
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   458
    switch_page(default_page);
2799
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   459
};
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   460
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   461
ws.onclose = function (evt) {
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   462
    // TODO : add visible notification while waiting for reload
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   463
    console.log("Connection closed. code:"+evt.code+" reason:"+evt.reason+" wasClean:"+evt.wasClean+" Reload in 10s.");
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   464
    // TODO : re-enable auto reload when not in debug
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   465
    //window.setTimeout(() => location.reload(true), 10000);
f5da343b9b63 SVGHMI: Many fixes. Subscriptions to HMItree seems to be working, and dispatch function is called in JS with good data. Bidirectional communication now really working.
Edouard Tisserant
parents: 2798
diff changeset
   466
    alert("Connection closed. code:"+evt.code+" reason:"+evt.reason+" wasClean:"+evt.wasClean+".");
2798
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   467
ddb2c4668a6b SVGHMI : many details about communication implemented in JS, with side effects.
Edouard Tisserant
parents: 2788
diff changeset
   468
};
2911
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   469
2916
4f3b130fd197 SVGHMI: fix keyboard not showing
Edouard Tisserant
parents: 2913
diff changeset
   470
var xmlns = "http://www.w3.org/2000/svg";
2911
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   471
var edit_callback;
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   472
function edit_value(path, valuetype, callback, initial) {
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   473
2913
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   474
    let [keypadid, xcoord, ycoord] = keypads[valuetype];
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   475
    console.log('XXX TODO : Edit value', path, valuetype, callback, initial, keypadid);
2911
211d6a185e31 SVGHMI: More infrastructure for editing values with a keypad.
Edouard Tisserant
parents: 2905
diff changeset
   476
    edit_callback = callback;
2917
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   477
    let widget = hmi_widgets[keypadid];
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   478
    widget.start_edit(path, valuetype, callback, initial);
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   479
};
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   480
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   481
var current_modal; /* TODO stack ?*/
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   482
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   483
function show_modal() {
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   484
    let [element, parent] = detachable_elements[this.element.id];
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   485
2916
4f3b130fd197 SVGHMI: fix keyboard not showing
Edouard Tisserant
parents: 2913
diff changeset
   486
    tmpgrp = document.createElementNS(xmlns,"g");
2913
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   487
    tmpgrpattr = document.createAttribute("transform");
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   488
2917
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   489
    let [xcoord,ycoord] = this.coordinates;
2913
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   490
    let [xdest,ydest] = page_desc[current_visible_page].bbox;
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   491
    tmpgrpattr.value = "translate("+String(xdest-xcoord)+","+String(ydest-ycoord)+")";
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   492
    tmpgrp.setAttributeNode(tmpgrpattr);
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   493
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   494
    tmpgrp.appendChild(element);
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   495
    parent.appendChild(tmpgrp);
ac4328e69079 SVGHMI: Keypad: added code to re-attach keypad when starting edit.
Edouard Tisserant
parents: 2912
diff changeset
   496
2917
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   497
    current_modal = [this.element.id, tmpgrp];
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   498
};
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   499
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   500
function end_modal() {
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   501
    let [eltid, tmpgrp] = current_modal;
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   502
    let [element, parent] = detachable_elements[this.element.id];
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   503
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   504
    parent.removeChild(tmpgrp);
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   505
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   506
    current_modal = undefined;
c8d923dd707f SVGHMI: Keypad working for HMI_STRING, still Shift/CapsLock not finished.
Edouard Tisserant
parents: 2916
diff changeset
   507
};