# HG changeset patch # User Edouard Tisserant # Date 1596894808 -7200 # Node ID 15e2df3e5610e5c73245ae4c8f78530ffd4fc80c # Parent dabad70db1bfec5b4afdeef1ee821d974f1d0163 SVGHMI: Intermediate state while implementing local HMI variables. Now write to cache only (no send), still need to implement dispatch on change. diff -r dabad70db1bf -r 15e2df3e5610 svghmi/gen_index_xhtml.xslt --- a/svghmi/gen_index_xhtml.xslt Thu Aug 06 15:01:01 2020 +0200 +++ b/svghmi/gen_index_xhtml.xslt Sat Aug 08 15:53:28 2020 +0200 @@ -169,14 +169,30 @@ - - - - - - - - + + + + + + + + + + + + + + PAGE_LOCAL + + + + + HMI_LOCAL + + + + + @@ -845,15 +861,35 @@ - - Widget - - id=" - - " : No match for path " - - " in HMI tree - + + + + Widget + + id=" + + " : No match for path " + + " in HMI tree + + + + " + + " + + , + + + + hmi_local_index(" + + ") + + , + + + @@ -905,8 +941,8 @@ - - + + /* @@ -915,6 +951,67 @@ + let hmi_locals = {}; + + var last_remote_index = hmitree_types.length - 1; + + var next_available_index = hmitree_types.length; + + + + function page_local_index(varname, pagename){ + + let pagevars = hmi_locals[pagename]; + + if(pagevars == undefined){ + + let new_index = next_available_index++; + + hmi_locals[pagename] = {varname:new_index} + + return new_index; + + } else { + + let result = pagevars[varname]; + + if(result==undefined){ + + let new_index = next_available_index++; + + pagevars[varname] = new_index; + + return new_index; + + } + + return result; + + } + + } + + + + function hmi_local_index(varname){ + + return page_local_index(varname, "HMI_LOCAL"); + + } + + + + + + + + + /* + + */ + + + class Widget { offset = 0; @@ -965,23 +1062,23 @@ - sub(new_offset=0, relativeness){ + sub(new_offset=0, relativeness, container_id){ this.offset = new_offset; this.relativeness = relativeness; + this.container_id = container_id ; + /* add this's subsribers */ if(!this.unsubscribable) for(let i = 0; i < this.indexes.length; i++) { - let index = this.indexes[i]; - - if(relativeness[i]) - - index += new_offset; + let index = this.get_variable_index(i); + + if(index > last_remote_index) return; subscribers[index].add(this); @@ -995,11 +1092,11 @@ apply_cache() { - if(!this.unsubscribable) for(let index of this.indexes){ + if(!this.unsubscribable) for(let i = 0; i < this.indexes.length; i++) { /* dispatch current cache in newly opened page widgets */ - let realindex = index+this.offset; + let realindex = this.get_variable_index(i); let cached_val = cache[realindex]; @@ -1013,17 +1110,33 @@ - get_idx(index) { - - let orig = this.indexes[index]; - - return this.relativeness[index] ? orig + this.offset : orig; + get_variable_index(varnum) { + + let index = this.indexes[varnum]; + + if(typeof(index) == "string"){ + + let page = this.relativeness[varnum]; + + index = page_local_index(index, this.container_id); + + } else { + + if(this.relativeness[varnum]){ + + index += this.offset; + + } + + } + + return index; } change_hmi_value(index,opstr) { - return change_hmi_value(this.get_idx(index), opstr); + return change_hmi_value(this.get_variable_index(index), opstr); } @@ -1031,7 +1144,7 @@ apply_hmi_value(index, new_val) { - return apply_hmi_value(this.get_idx(0), new_val); + return apply_hmi_value(this.get_variable_index(0), new_val); } @@ -1045,11 +1158,7 @@ for(let i = 0; i < this.indexes.length; i++) { - let refindex = this.indexes[i]; - - if(this.relativeness[i]) - - refindex += this.offset; + let refindex = this.get_variable_index(i); @@ -4056,6 +4165,20 @@ function send_hmi_value(index, value) { + if(index > last_remote_index){ + + cache[index] = value; + + console.log("updated local variable ",index,value); + + /* TODO : dispatch value ASAP */ + + return; + + } + + + let iectype = hmitree_types[index]; let tobinary = typedarray_types[iectype]; @@ -4250,7 +4373,13 @@ var new_offset = page_index == undefined ? 0 : page_index - new_desc.page_index; - new_desc.widgets.map(([widget,relativeness])=>widget.sub(new_offset,relativeness)); + + + container_id = String([page_name, page_index]); + + + + new_desc.widgets.map(([widget,relativeness])=>widget.sub(new_offset,relativeness,container_id)); diff -r dabad70db1bf -r 15e2df3e5610 svghmi/hmi_tree.ysl2 --- a/svghmi/hmi_tree.ysl2 Thu Aug 06 15:01:01 2020 +0200 +++ b/svghmi/hmi_tree.ysl2 Sat Aug 08 15:53:28 2020 +0200 @@ -107,9 +107,21 @@ attrib "value" > «.» const "path", "."; const "item", "$indexed_hmitree/*[@hmipath = $path]"; - if "count($item) = 1" { - attrib "index" > «$item/@index» - attrib "type" > «local-name($item)» + choose { + when "count($item) = 1" { + attrib "index" > «$item/@index» + attrib "type" > «local-name($item)» + } + otherwise { + choose { + when "regexp:test($path,'^\.[a-zA-Z0-9_]+')" { + attrib "type" > PAGE_LOCAL + } + when "regexp:test($path,'^[a-zA-Z0-9_]+')" { + attrib "type" > HMI_LOCAL + } + } + } } } } diff -r dabad70db1bf -r 15e2df3e5610 svghmi/svghmi.js --- a/svghmi/svghmi.js Thu Aug 06 15:01:01 2020 +0200 +++ b/svghmi/svghmi.js Sat Aug 08 15:53:28 2020 +0200 @@ -210,6 +210,13 @@ }; function send_hmi_value(index, value) { + if(index > last_remote_index){ + cache[index] = value; + console.log("updated local variable ",index,value); + /* TODO : dispatch value ASAP */ + return; + } + let iectype = hmitree_types[index]; let tobinary = typedarray_types[iectype]; send_blob([ @@ -307,7 +314,10 @@ old_desc.widgets.map(([widget,relativeness])=>widget.unsub()); } var new_offset = page_index == undefined ? 0 : page_index - new_desc.page_index; - new_desc.widgets.map(([widget,relativeness])=>widget.sub(new_offset,relativeness)); + + container_id = String([page_name, page_index]); + + new_desc.widgets.map(([widget,relativeness])=>widget.sub(new_offset,relativeness,container_id)); update_subscriptions(); diff -r dabad70db1bf -r 15e2df3e5610 svghmi/widgets_common.ysl2 --- a/svghmi/widgets_common.ysl2 Thu Aug 06 15:01:01 2020 +0200 +++ b/svghmi/widgets_common.ysl2 Sat Aug 08 15:53:28 2020 +0200 @@ -28,7 +28,14 @@ const "indexes" foreach "$widget/path" { choose { when "not(@index)" { - warning > Widget «$widget/@type» id="«$eltid»" : No match for path "«@value»" in HMI tree + choose { + when "not(@type)" + error > Widget «$widget/@type» id="«$eltid»" : No match for path "«@value»" in HMI tree + when "@type = 'PAGE_LOCAL'" + > "«substring(1,@value)»"`if "position()!=last()" > ,` + when "@type = 'HMI_LOCAL'" + > hmi_local_index("«@value»")`if "position()!=last()" > ,` + } } otherwise { > «@index»`if "position()!=last()" > ,` @@ -62,8 +69,37 @@ } } +emit "preamble:local-variable-indexes" { + || + let hmi_locals = {}; + var last_remote_index = hmitree_types.length - 1; + var next_available_index = hmitree_types.length; + + function page_local_index(varname, pagename){ + let pagevars = hmi_locals[pagename]; + if(pagevars == undefined){ + let new_index = next_available_index++; + hmi_locals[pagename] = {varname:new_index} + return new_index; + } else { + let result = pagevars[varname]; + if(result==undefined){ + let new_index = next_available_index++; + pagevars[varname] = new_index; + return new_index; + } + return result; + } + } + + function hmi_local_index(varname){ + return page_local_index(varname, "HMI_LOCAL"); + } + || +} + emit "preamble:widget-base-class" { - || + || class Widget { offset = 0; frequency = 10; /* FIXME arbitrary default max freq. Obtain from config ? */ @@ -89,49 +125,55 @@ this.relativeness = undefined; } - sub(new_offset=0, relativeness){ + sub(new_offset=0, relativeness, container_id){ this.offset = new_offset; this.relativeness = relativeness; + this.container_id = container_id ; /* add this's subsribers */ if(!this.unsubscribable) for(let i = 0; i < this.indexes.length; i++) { - let index = this.indexes[i]; - if(relativeness[i]) - index += new_offset; + let index = this.get_variable_index(i); + if(index > last_remote_index) return; subscribers[index].add(this); } need_cache_apply.push(this); } apply_cache() { - if(!this.unsubscribable) for(let index of this.indexes){ + if(!this.unsubscribable) for(let i = 0; i < this.indexes.length; i++) { /* dispatch current cache in newly opened page widgets */ - let realindex = index+this.offset; + let realindex = this.get_variable_index(i); let cached_val = cache[realindex]; if(cached_val != undefined) this.new_hmi_value(realindex, cached_val, cached_val); } } - get_idx(index) { - let orig = this.indexes[index]; - return this.relativeness[index] ? orig + this.offset : orig; + get_variable_index(varnum) { + let index = this.indexes[varnum]; + if(typeof(index) == "string"){ + let page = this.relativeness[varnum]; + index = page_local_index(index, this.container_id); + } else { + if(this.relativeness[varnum]){ + index += this.offset; + } + } + return index; } change_hmi_value(index,opstr) { - return change_hmi_value(this.get_idx(index), opstr); + return change_hmi_value(this.get_variable_index(index), opstr); } apply_hmi_value(index, new_val) { - return apply_hmi_value(this.get_idx(0), new_val); + return apply_hmi_value(this.get_variable_index(0), new_val); } new_hmi_value(index, value, oldval) { try { // TODO avoid searching, store index at sub() for(let i = 0; i < this.indexes.length; i++) { - let refindex = this.indexes[i]; - if(this.relativeness[i]) - refindex += this.offset; + let refindex = this.get_variable_index(i); if(index == refindex) { let d = this.dispatch; diff -r dabad70db1bf -r 15e2df3e5610 tests/svghmi/svghmi_0@svghmi/svghmi.svg --- a/tests/svghmi/svghmi_0@svghmi/svghmi.svg Thu Aug 06 15:01:01 2020 +0200 +++ b/tests/svghmi/svghmi_0@svghmi/svghmi.svg Sat Aug 08 15:53:28 2020 +0200 @@ -170,13 +170,13 @@ inkscape:current-layer="hmi0" showgrid="false" units="px" - inkscape:zoom="0.7071068" - inkscape:cx="543.82641" - inkscape:cy="218.7845" - inkscape:window-width="2419" + inkscape:zoom="1" + inkscape:cx="864.70245" + inkscape:cy="281.30768" + inkscape:window-width="2693" inkscape:window-height="1266" - inkscape:window-x="1405" - inkscape:window-y="37" + inkscape:window-x="31" + inkscape:window-y="828" inkscape:window-maximized="0" showguides="true" inkscape:guide-bbox="true" /> @@ -266,7 +266,7 @@ + transform="matrix(0.35865594,0,0,0.35865594,22.072155,63.074421)"> 8888 SetPoint + x="114.11434" + y="90.742165" + style="stroke-width:0.35865593px">SetPoint Actual + style="stroke-width:0.35865593px">Actual - - - + inkscape:label="HMI:JsonTable:/alarms@/ALARMCOUNT" + transform="matrix(0.5,0,0,0.5,635.30409,71.500438)"> @@ -3147,7 +3124,7 @@ sodipodi:role="line">information Multiple variables + 8888 + + 8888 + + + + dhu + + + + plop + + + + mhoo + + + + yodl + + + + mhe + + + HMI_LOCAL variables + + + + + + 8888 + + 8888 + + + + dhu + + + + plop + + + + mhoo + + + + yodl + + + + mhe + + + PAGE_LOCAL variables