SVGHMI: dispatching data to minimalist "Display" text widget. svghmi
authorEdouard Tisserant
Sat, 19 Oct 2019 01:23:30 +0200
branchsvghmi
changeset 2800 68cee1366b9c
parent 2799 f5da343b9b63
child 2801 390acff12755
SVGHMI: dispatching data to minimalist "Display" text widget.
svghmi/gen_index_xhtml.xslt
svghmi/gen_index_xhtml.ysl2
svghmi/svghmi.js
--- 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 &gt; 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" &amp;&amp; idxidx == 0){
+</xsl:text>
+    <xsl:text>                return d.call(widget,value);
+</xsl:text>
+    <xsl:text>            }else if(typeof(d) == "object" &amp;&amp; d.length &gt;= 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>
--- 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
+    */
 }
--- 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){