# HG changeset patch # User Edouard Tisserant # Date 1571441010 -7200 # Node ID 68cee1366b9c7b7c8365b007e279d57a48b75960 # Parent f5da343b9b63f27b2ea1f3898f01b185f8bfc2e4 SVGHMI: dispatching data to minimalist "Display" text widget. diff -r f5da343b9b63 -r 68cee1366b9c svghmi/gen_index_xhtml.xslt --- a/svghmi/gen_index_xhtml.xslt Thu Oct 17 15:48:09 2019 +0200 +++ b/svghmi/gen_index_xhtml.xslt Sat Oct 19 01:23:30 2019 +0200 @@ -198,10 +198,6 @@ <xsl:value-of select="$widget/@type"/> <xsl:text>", </xsl:text> - <xsl:text> frequency: </xsl:text> - <xsl:apply-templates mode="refresh_frequency" select="$widget"/> - <xsl:text>, -</xsl:text> <xsl:text> args: [ </xsl:text> <xsl:for-each select="$widget/arg"> @@ -236,8 +232,15 @@ <xsl:text> </xsl:text> </xsl:for-each> - <xsl:text> ] -</xsl:text> + <xsl:text> ], +</xsl:text> + <xsl:text> element: document.getElementById("</xsl:text> + <xsl:value-of select="@id"/> + <xsl:text>"), +</xsl:text> + <xsl:apply-templates mode="widget_defs" 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> @@ -319,7 +322,43 @@ </xsl:text> <xsl:text>function dispatch_value(index, value) { </xsl:text> - <xsl:text> console.log("dispatch_value("+index+", "+value+")"); + <xsl:text> let widgets = subscribers[index]; +</xsl:text> + <xsl:text> +</xsl:text> + <xsl:text> if(widgets.size > 0) { +</xsl:text> + <xsl:text> for(let widget of widgets){ +</xsl:text> + <xsl:text> let idxidx = widget.indexes.indexOf(index); +</xsl:text> + <xsl:text> if(idxidx == -1){ +</xsl:text> + <xsl:text> throw new Error("Dispatching to widget not interested, should not happen."); +</xsl:text> + <xsl:text> } +</xsl:text> + <xsl:text> let d = widget.dispatch; +</xsl:text> + <xsl:text> if(typeof(d) == "function" && idxidx == 0){ +</xsl:text> + <xsl:text> return d.call(widget,value); +</xsl:text> + <xsl:text> }else if(typeof(d) == "object" && d.length >= idxidx){ +</xsl:text> + <xsl:text> d[idxidx].call(widget,value); +</xsl:text> + <xsl:text> }/* else dispatch_0, ..., dispatch_n ? */ +</xsl:text> + <xsl:text> /*else { +</xsl:text> + <xsl:text> throw new Error("Dunno how to dispatch to widget at index = " + index); +</xsl:text> + <xsl:text> }*/ +</xsl:text> + <xsl:text> } +</xsl:text> + <xsl:text> } </xsl:text> <xsl:text>}; </xsl:text> @@ -357,7 +396,7 @@ </xsl:text> <xsl:text> let i = 0; </xsl:text> - <xsl:text> console.log("Recv something."); + <xsl:text> //console.log("Recv something."); </xsl:text> <xsl:text> try { </xsl:text> @@ -365,7 +404,7 @@ </xsl:text> <xsl:text> if(hash_int != dv.getUint8(i)){ </xsl:text> - <xsl:text> throw new Error("Hash doesn't match") + <xsl:text> throw new Error("Hash doesn't match"); </xsl:text> <xsl:text> }; </xsl:text> @@ -375,7 +414,7 @@ </xsl:text> <xsl:text> </xsl:text> - <xsl:text> console.log("Recv something GOOD."); + <xsl:text> //console.log("Recv something GOOD."); </xsl:text> <xsl:text> </xsl:text> @@ -383,7 +422,7 @@ </xsl:text> <xsl:text> let index = dv.getUint32(i, true); </xsl:text> - <xsl:text> console.log("Recv something index is "+index); + <xsl:text> //console.log("Recv something index is "+index); </xsl:text> <xsl:text> i += 4; </xsl:text> @@ -722,16 +761,30 @@ </xsl:with-param> </xsl:apply-templates> </xsl:template> - <xsl:template mode="refresh_frequency" match="widget"> - <xsl:text>10</xsl:text> - </xsl:template> - <xsl:template mode="refresh_frequency" match="widget[@type='Meter']"> - <xsl:text>10</xsl:text> - </xsl:template> - <xsl:template mode="refresh_frequency" match="widget[@type='Display']"> - <xsl:text>5</xsl:text> - </xsl:template> - <xsl:template mode="refresh_frequency" match="widget[@type='Input']"> - <xsl:text>5</xsl:text> + <xsl:template mode="widget_defs" match="widget[@type='Display']"> + <xsl:param name="hmi_element"/> + <xsl:text>frequency: 5, +</xsl:text> + <xsl:text>dispatch: function(value) { +</xsl:text> + <xsl:choose> + <xsl:when test="$hmi_element[self::svg:text]"> + <xsl:text> this.element.textContent = String(value); +</xsl:text> + </xsl:when> + <xsl:otherwise> + <xsl:message terminate="yes">Display widget as a group not implemented</xsl:message> + </xsl:otherwise> + </xsl:choose> + <xsl:text>}, +</xsl:text> + </xsl:template> + <xsl:template mode="widget_defs" match="widget[@type='Meter']"> + <xsl:text> frequency: 10, +</xsl:text> + </xsl:template> + <xsl:template mode="widget_defs" match="widget[@type='Input']"> + <xsl:text> frequency: 5, +</xsl:text> </xsl:template> </xsl:stylesheet> diff -r f5da343b9b63 -r 68cee1366b9c svghmi/gen_index_xhtml.ysl2 --- a/svghmi/gen_index_xhtml.ysl2 Thu Oct 17 15:48:09 2019 +0200 +++ b/svghmi/gen_index_xhtml.ysl2 Sat Oct 19 01:23:30 2019 +0200 @@ -191,7 +191,6 @@ const "widget", "func:parselabel(@inkscape:label)/widget"; | «@id»: { | type: "«$widget/@type»", - | frequency: `apply "$widget", mode="refresh_frequency"`, | args: [ foreach "$widget/arg" | "«@value»"`if "position()!=last()" > ,` @@ -204,7 +203,9 @@ error > No match for HMI «$hmipath»; | «$hmitree_match/@index»`if "position()!=last()" > ,` } - | ] + | ], + | element: document.getElementById("«@id»"), + apply "$widget", mode="widget_defs" with "hmi_element","."; | }`if "position()!=last()" > ,` } | } @@ -306,8 +307,33 @@ }; } - template "widget", mode="refresh_frequency" > 10 + template "widget[@type='Display']", mode="widget_defs" { + param "hmi_element"; + | frequency: 5, + | dispatch: function(value) { + choose { + when "$hmi_element[self::svg:text]"{ + // TODO : care about <tspan> ? + | this.element.textContent = String(value); + } + otherwise { + error "Display widget as a group not implemented"; + } + } + | }, + + } + template "widget[@type='Meter']", mode="widget_defs" { + | frequency: 10, + } + template "widget[@type='Input']", mode="widget_defs" { + | frequency: 5, + } + // | frequency: 10`apply ".", mode="refresh_frequency"`, + // template "widget", mode="refresh_frequency" > 10 + /* template "widget[@type='Meter']", mode="refresh_frequency" > 10 template "widget[@type='Display']", mode="refresh_frequency" > 5 template "widget[@type='Input']", mode="refresh_frequency" > 5 + */ } diff -r f5da343b9b63 -r 68cee1366b9c svghmi/svghmi.js --- a/svghmi/svghmi.js Thu Oct 17 15:48:09 2019 +0200 +++ b/svghmi/svghmi.js Sat Oct 19 01:23:30 2019 +0200 @@ -1,7 +1,25 @@ // svghmi.js function dispatch_value(index, value) { - console.log("dispatch_value("+index+", "+value+")"); + let widgets = subscribers[index]; + + if(widgets.size > 0) { + for(let widget of widgets){ + let idxidx = widget.indexes.indexOf(index); + if(idxidx == -1){ + throw new Error("Dispatching to widget not interested, should not happen."); + } + let d = widget.dispatch; + if(typeof(d) == "function" && idxidx == 0){ + return d.call(widget,value); + }else if(typeof(d) == "object" && d.length >= idxidx){ + d[idxidx].call(widget,value); + }/* else dispatch_0, ..., dispatch_n ? */ + /*else { + throw new Error("Dunno how to dispatch to widget at index = " + index); + }*/ + } + } }; // Open WebSocket to relative "/ws" address @@ -23,14 +41,13 @@ try { for(let hash_int of hmi_hash) { if(hash_int != dv.getUint8(i)){ - throw new Error("Hash doesn't match") + throw new Error("Hash doesn't match"); }; i++; }; while(i < data.byteLength){ let index = dv.getUint32(i, true); - console.log("Recv something index is "+index); i += 4; let iectype = hmitree_types[index]; if(iectype != undefined){