# HG changeset patch # User Edouard Tisserant <edouard.tisserant@gmail.com> # Date 1584642236 -3600 # Node ID 4eeed820fd3a9f97c8f12f4e86399a877838820c # Parent 7beddc62a3889df782e45185bc55cd8e2298ba8a SVGHMI: reworked widget (un)subscription now a method of widgect object, allowing special subscription methods diff -r 7beddc62a388 -r 4eeed820fd3a svghmi/gen_index_xhtml.xslt --- a/svghmi/gen_index_xhtml.xslt Thu Mar 19 11:32:20 2020 +0100 +++ b/svghmi/gen_index_xhtml.xslt Thu Mar 19 19:23:56 2020 +0100 @@ -579,6 +579,8 @@ </xsl:for-each> <xsl:text> ], </xsl:text> + <xsl:text> offset: 0, +</xsl:text> <xsl:text> indexes: [ </xsl:text> <xsl:for-each select="$widget/path"> @@ -614,6 +616,9 @@ <xsl:apply-templates mode="widget_defs" select="$widget"> <xsl:with-param name="hmi_element" select="."/> </xsl:apply-templates> + <xsl:apply-templates mode="widget_subscribe" select="$widget"> + <xsl:with-param name="hmi_element" select="."/> + </xsl:apply-templates> <xsl:text> }</xsl:text> <xsl:if test="position()!=last()"> <xsl:text>,</xsl:text> @@ -621,6 +626,13 @@ <xsl:text> </xsl:text> </xsl:template> + <xsl:template mode="widget_subscribe" match="widget"> + <xsl:text> sub: subscribe, +</xsl:text> + <xsl:text> unsub: unsubscribe, +</xsl:text> + </xsl:template> + <xsl:template mode="widget_subscribe" match="widget[@type='Page']"/> <xsl:template name="defs_by_labels"> <xsl:param name="labels" select="''"/> <xsl:param name="mandatory" select="'yes'"/> @@ -1024,8 +1036,6 @@ </xsl:text> <xsl:text> let d = widget.dispatch; </xsl:text> - <xsl:text> console.log(index, idx, idxidx, value); -</xsl:text> <xsl:text> if(typeof(d) == "function" && idxidx == 0){ </xsl:text> <xsl:text> d.call(widget, value, oldval); @@ -1372,8 +1382,6 @@ </xsl:text> <xsl:text> dispatch: function(value) { </xsl:text> - <xsl:text> // console.log("Heartbeat" + value); -</xsl:text> <xsl:text> change_hmi_value(heartbeat_index, "+1"); </xsl:text> <xsl:text> } @@ -1566,6 +1574,46 @@ </xsl:text> <xsl:text> </xsl:text> + <xsl:text>function unsubscribe(){ +</xsl:text> + <xsl:text> widget = this; +</xsl:text> + <xsl:text> /* remove subsribers */ +</xsl:text> + <xsl:text> for(let index of widget.indexes){ +</xsl:text> + <xsl:text> let idx = index + widget.offset; +</xsl:text> + <xsl:text> subscribers[idx].delete(widget); +</xsl:text> + <xsl:text> } +</xsl:text> + <xsl:text> widget.offset = 0; +</xsl:text> + <xsl:text>} +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>function subscribe(new_offset=0){ +</xsl:text> + <xsl:text> widget = this; +</xsl:text> + <xsl:text> /* set the offset because relative */ +</xsl:text> + <xsl:text> widget.offset = new_offset; +</xsl:text> + <xsl:text> /* add widget's subsribers */ +</xsl:text> + <xsl:text> for(let index of widget.indexes){ +</xsl:text> + <xsl:text> subscribers[index + new_offset].add(widget); +</xsl:text> + <xsl:text> } +</xsl:text> + <xsl:text>} +</xsl:text> + <xsl:text> +</xsl:text> <xsl:text>function switch_subscribed_page(page_name, page_index) { </xsl:text> <xsl:text> let old_desc = page_desc[current_subscribed_page]; @@ -1594,150 +1642,100 @@ </xsl:text> <xsl:text> if(old_desc){ </xsl:text> - <xsl:text> for(let widget of old_desc.absolute_widgets){ -</xsl:text> - <xsl:text> /* remove subsribers */ -</xsl:text> - <xsl:text> for(let index of widget.indexes){ -</xsl:text> - <xsl:text> subscribers[index].delete(widget); + <xsl:text> old_desc.absolute_widgets.map(w=>w.unsub()); +</xsl:text> + <xsl:text> old_desc.relative_widgets.map(w=>w.unsub()); +</xsl:text> + <xsl:text> } +</xsl:text> + <xsl:text> new_desc.absolute_widgets.map(w=>w.sub()); +</xsl:text> + <xsl:text> var new_offset = page_index == undefined ? 0 : page_index - new_desc.page_index; +</xsl:text> + <xsl:text> new_desc.relative_widgets.map(w=>w.sub(new_offset)); +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text> update_subscriptions(); +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text> current_subscribed_page = page_name; +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text> requestHMIAnimation(); +</xsl:text> + <xsl:text>} +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text>function switch_visible_page(page_name) { +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text> let old_desc = page_desc[current_visible_page]; +</xsl:text> + <xsl:text> let new_desc = page_desc[page_name]; +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text> if(old_desc){ +</xsl:text> + <xsl:text> for(let eltid in old_desc.required_detachables){ +</xsl:text> + <xsl:text> if(!(eltid in new_desc.required_detachables)){ +</xsl:text> + <xsl:text> let [element, parent] = old_desc.required_detachables[eltid]; +</xsl:text> + <xsl:text> parent.removeChild(element); </xsl:text> <xsl:text> } </xsl:text> <xsl:text> } </xsl:text> - <xsl:text> for(let widget of old_desc.relative_widgets){ -</xsl:text> - <xsl:text> /* remove subsribers */ -</xsl:text> - <xsl:text> for(let index of widget.indexes){ -</xsl:text> - <xsl:text> let idx = widget.offset ? index + widget.offset : index; -</xsl:text> - <xsl:text> subscribers[idx].delete(widget); + <xsl:text> for(let eltid in new_desc.required_detachables){ +</xsl:text> + <xsl:text> if(!(eltid in old_desc.required_detachables)){ +</xsl:text> + <xsl:text> let [element, parent] = new_desc.required_detachables[eltid]; +</xsl:text> + <xsl:text> parent.appendChild(element); </xsl:text> <xsl:text> } </xsl:text> - <xsl:text> /* lose the offset */ -</xsl:text> - <xsl:text> delete widget.offset; -</xsl:text> <xsl:text> } </xsl:text> - <xsl:text> } -</xsl:text> - <xsl:text> for(let widget of new_desc.absolute_widgets){ -</xsl:text> - <xsl:text> /* add widget's subsribers */ + <xsl:text> }else{ +</xsl:text> + <xsl:text> for(let eltid in new_desc.required_detachables){ +</xsl:text> + <xsl:text> let [element, parent] = new_desc.required_detachables[eltid]; +</xsl:text> + <xsl:text> parent.appendChild(element); +</xsl:text> + <xsl:text> } +</xsl:text> + <xsl:text> } +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text> for(let widget of chain(new_desc.absolute_widgets,new_desc.relative_widgets)){ </xsl:text> <xsl:text> for(let index of widget.indexes){ </xsl:text> - <xsl:text> subscribers[index].add(widget); + <xsl:text> /* dispatch current cache in newly opened page widgets */ +</xsl:text> + <xsl:text> let cached_val = cache[index]; +</xsl:text> + <xsl:text> if(cached_val != undefined) +</xsl:text> + <xsl:text> dispatch_value_to_widget(widget, index, cached_val, cached_val); </xsl:text> <xsl:text> } </xsl:text> <xsl:text> } </xsl:text> - <xsl:text> var new_offset = page_index == undefined ? 0 : page_index - new_desc.page_index; -</xsl:text> - <xsl:text> for(let widget of new_desc.relative_widgets){ -</xsl:text> - <xsl:text> /* set the offset because relative */ -</xsl:text> - <xsl:text> widget.offset = new_offset; -</xsl:text> - <xsl:text> /* add widget's subsribers */ -</xsl:text> - <xsl:text> for(let index of widget.indexes){ -</xsl:text> - <xsl:text> subscribers[index + new_offset].add(widget); -</xsl:text> - <xsl:text> } -</xsl:text> - <xsl:text> } -</xsl:text> - <xsl:text> -</xsl:text> - <xsl:text> update_subscriptions(); -</xsl:text> - <xsl:text> -</xsl:text> - <xsl:text> current_subscribed_page = page_name; -</xsl:text> - <xsl:text> -</xsl:text> - <xsl:text> requestHMIAnimation(); -</xsl:text> - <xsl:text>} -</xsl:text> - <xsl:text> -</xsl:text> - <xsl:text>function switch_visible_page(page_name) { -</xsl:text> - <xsl:text> -</xsl:text> - <xsl:text> let old_desc = page_desc[current_visible_page]; -</xsl:text> - <xsl:text> let new_desc = page_desc[page_name]; -</xsl:text> - <xsl:text> -</xsl:text> - <xsl:text> if(old_desc){ -</xsl:text> - <xsl:text> for(let eltid in old_desc.required_detachables){ -</xsl:text> - <xsl:text> if(!(eltid in new_desc.required_detachables)){ -</xsl:text> - <xsl:text> let [element, parent] = old_desc.required_detachables[eltid]; -</xsl:text> - <xsl:text> parent.removeChild(element); -</xsl:text> - <xsl:text> } -</xsl:text> - <xsl:text> } -</xsl:text> - <xsl:text> for(let eltid in new_desc.required_detachables){ -</xsl:text> - <xsl:text> if(!(eltid in old_desc.required_detachables)){ -</xsl:text> - <xsl:text> let [element, parent] = new_desc.required_detachables[eltid]; -</xsl:text> - <xsl:text> parent.appendChild(element); -</xsl:text> - <xsl:text> } -</xsl:text> - <xsl:text> } -</xsl:text> - <xsl:text> }else{ -</xsl:text> - <xsl:text> for(let eltid in new_desc.required_detachables){ -</xsl:text> - <xsl:text> let [element, parent] = new_desc.required_detachables[eltid]; -</xsl:text> - <xsl:text> parent.appendChild(element); -</xsl:text> - <xsl:text> } -</xsl:text> - <xsl:text> } -</xsl:text> - <xsl:text> -</xsl:text> - <xsl:text> for(let widget of chain(new_desc.absolute_widgets,new_desc.relative_widgets)){ -</xsl:text> - <xsl:text> for(let index of widget.indexes){ -</xsl:text> - <xsl:text> /* dispatch current cache in newly opened page widgets */ -</xsl:text> - <xsl:text> let cached_val = cache[index]; -</xsl:text> - <xsl:text> if(cached_val != undefined) -</xsl:text> - <xsl:text> dispatch_value_to_widget(widget, index, cached_val, cached_val); -</xsl:text> - <xsl:text> } -</xsl:text> - <xsl:text> } -</xsl:text> <xsl:text> </xsl:text> <xsl:text> svg_root.setAttribute('viewBox',new_desc.bbox.join(" ")); diff -r 7beddc62a388 -r 4eeed820fd3a svghmi/svghmi.js --- a/svghmi/svghmi.js Thu Mar 19 11:32:20 2020 +0100 +++ b/svghmi/svghmi.js Thu Mar 19 19:23:56 2020 +0100 @@ -8,7 +8,6 @@ let idx = widget.offset ? index - widget.offset : index; let idxidx = widget.indexes.indexOf(idx); let d = widget.dispatch; - console.log(index, idx, idxidx, value); if(typeof(d) == "function" && idxidx == 0){ d.call(widget, value, oldval); } @@ -182,7 +181,6 @@ frequency: 1, indexes: [heartbeat_index], dispatch: function(value) { - // console.log("Heartbeat" + value); change_hmi_value(heartbeat_index, "+1"); } }); @@ -279,6 +277,26 @@ yield* b; }; +function unsubscribe(){ + widget = this; + /* remove subsribers */ + for(let index of widget.indexes){ + let idx = index + widget.offset; + subscribers[idx].delete(widget); + } + widget.offset = 0; +} + +function subscribe(new_offset=0){ + widget = this; + /* set the offset because relative */ + widget.offset = new_offset; + /* add widget's subsribers */ + for(let index of widget.indexes){ + subscribers[index + new_offset].add(widget); + } +} + function switch_subscribed_page(page_name, page_index) { let old_desc = page_desc[current_subscribed_page]; let new_desc = page_desc[page_name]; @@ -293,37 +311,12 @@ } if(old_desc){ - for(let widget of old_desc.absolute_widgets){ - /* remove subsribers */ - for(let index of widget.indexes){ - subscribers[index].delete(widget); - } - } - for(let widget of old_desc.relative_widgets){ - /* remove subsribers */ - for(let index of widget.indexes){ - let idx = widget.offset ? index + widget.offset : index; - subscribers[idx].delete(widget); - } - /* lose the offset */ - delete widget.offset; - } - } - for(let widget of new_desc.absolute_widgets){ - /* add widget's subsribers */ - for(let index of widget.indexes){ - subscribers[index].add(widget); - } - } + old_desc.absolute_widgets.map(w=>w.unsub()); + old_desc.relative_widgets.map(w=>w.unsub()); + } + new_desc.absolute_widgets.map(w=>w.sub()); var new_offset = page_index == undefined ? 0 : page_index - new_desc.page_index; - for(let widget of new_desc.relative_widgets){ - /* set the offset because relative */ - widget.offset = new_offset; - /* add widget's subsribers */ - for(let index of widget.indexes){ - subscribers[index + new_offset].add(widget); - } - } + new_desc.relative_widgets.map(w=>w.sub(new_offset)); update_subscriptions(); diff -r 7beddc62a388 -r 4eeed820fd3a svghmi/widgets_common.ysl2 --- a/svghmi/widgets_common.ysl2 Thu Mar 19 11:32:20 2020 +0100 +++ b/svghmi/widgets_common.ysl2 Thu Mar 19 19:23:56 2020 +0100 @@ -17,9 +17,10 @@ | "«@id»": { | type: "«$widget/@type»", | args: [ - foreach "$widget/arg" + foreach "$widget/arg" | "«@value»"`if "position()!=last()" > ,` | ], + | offset: 0, | indexes: [ foreach "$widget/path" { choose { @@ -34,9 +35,17 @@ | ], | element: id("«@id»"), apply "$widget", mode="widget_defs" with "hmi_element","."; + apply "$widget", mode="widget_subscribe" with "hmi_element","."; | }`if "position()!=last()" > ,` } +// default : normal subscribing +template "widget", mode="widget_subscribe" { + | sub: subscribe, + | unsub: unsubscribe, +} +// page aren't subscribers +template "widget[@type='Page']", mode="widget_subscribe"; function "defs_by_labels" { param "labels","''";