63 template "svg:*", mode="hmi_widgets" { |
63 template "svg:*", mode="hmi_widgets" { |
64 const "widget", "func:widget(@id)"; |
64 const "widget", "func:widget(@id)"; |
65 const "eltid","@id"; |
65 const "eltid","@id"; |
66 const "args" foreach "$widget/arg" > "«func:escape_quotes(@value)»"`if "position()!=last()" > ,` |
66 const "args" foreach "$widget/arg" > "«func:escape_quotes(@value)»"`if "position()!=last()" > ,` |
67 const "indexes" foreach "$widget/path" { |
67 const "indexes" foreach "$widget/path" { |
|
68 if "position()!=last()" > , |
|
69 } |
|
70 |
|
71 const "variables" foreach "$widget/path" { |
|
72 > [ |
68 choose { |
73 choose { |
69 when "not(@index)" { |
74 when "not(@index)" { |
70 choose { |
75 choose { |
71 when "not(@type)" { |
76 when "not(@type)" { |
72 warning > Widget «$widget/@type» id="«$eltid»" : No match for path "«@value»" in HMI tree |
77 warning > Widget «$widget/@type» id="«$eltid»" : No match for path "«@value»" in HMI tree |
82 } |
87 } |
83 otherwise { |
88 otherwise { |
84 > «@index» |
89 > «@index» |
85 } |
90 } |
86 } |
91 } |
87 if "position()!=last()" > , |
92 > , { |
88 } |
93 if "@min and @max"{ |
89 |
94 > minmax:[«@min», «@max»] |
90 const "minmaxes" foreach "$widget/path" { |
95 if "@assign" |
91 choose { |
96 > , |
92 when "@min and @max" |
97 } |
93 > [«@min»,«@max»] |
98 if "@assign" |
94 otherwise |
99 > assign:"«@assign»" |
95 > undefined |
100 > }] |
96 } |
|
97 if "position()!=last()" > , |
101 if "position()!=last()" > , |
98 } |
102 } |
99 |
103 |
100 const "freq" choose { |
104 const "freq" choose { |
101 when "$widget/@freq" |
105 when "$widget/@freq" |
102 > "«$widget/@freq»" |
106 > "«$widget/@freq»" |
103 otherwise |
107 otherwise |
104 > undefined |
108 > undefined |
105 } |
109 } |
106 |
110 |
107 const "has_enable" choose { |
111 const "enable_expr" choose{ |
108 when "$widget/@has_enable = 'yes'" |
112 when "$widget/@enable_expr" |
109 > true |
113 > true |
110 otherwise |
114 otherwise |
111 > false |
115 > false |
112 } |
116 } |
113 |
117 |
114 | "«@id»": new «$widget/@type»Widget ("«@id»",«$freq»,[«$args»],[«$indexes»],[«$minmaxes»],«$has_enable»,{ |
118 | "«@id»": new «$widget/@type»Widget ("«@id»",«$freq»,[«$args»],[«$variables»],«$enable_expr»,{ |
|
119 if "$widget/@enable_expr" { |
|
120 |
|
121 | assignments: [], |
|
122 | compute_enable: function(value, oldval, varnum) { |
|
123 | let result = false; |
|
124 | do { |
|
125 foreach "$widget/path" { |
|
126 const "varid","generate-id()"; |
|
127 const "varnum","position()-1"; |
|
128 if "@assign" foreach "$widget/path[@assign]" if "$varid = generate-id()" { |
|
129 | if(varnum == «$varnum») this.assignments[«position()-1»] = value; |
|
130 | let «@assign» = this.assignments[«position()-1»]; |
|
131 | if(«@assign» == undefined) break; |
|
132 } |
|
133 } |
|
134 | result = «$widget/@enable_expr»; |
|
135 | } while(0); |
|
136 | this.enable(result); |
|
137 | }, |
|
138 } |
115 apply "$widget", mode="widget_defs" with "hmi_element","."; |
139 apply "$widget", mode="widget_defs" with "hmi_element","."; |
116 | })`if "position()!=last()" > ,` |
140 | })`if "position()!=last()" > ,` |
117 } |
141 } |
118 |
142 |
119 emit "preamble:local-variable-indexes" { |
143 emit "preamble:local-variable-indexes" { |
223 offset = 0; |
247 offset = 0; |
224 frequency = 10; /* FIXME arbitrary default max freq. Obtain from config ? */ |
248 frequency = 10; /* FIXME arbitrary default max freq. Obtain from config ? */ |
225 unsubscribable = false; |
249 unsubscribable = false; |
226 pending_animate = false; |
250 pending_animate = false; |
227 |
251 |
228 constructor(elt_id, freq, args, indexes, minmaxes, has_enable, members){ |
252 constructor(elt_id, freq, args, variables, enable_expr, members){ |
229 this.element_id = elt_id; |
253 this.element_id = elt_id; |
230 this.element = id(elt_id); |
254 this.element = id(elt_id); |
231 this.args = args; |
255 this.args = args; |
232 this.indexes = indexes; |
256 [this.indexes, this.variables_options] = (variables.length>0) ? zip(...variables) : [[],[]]; |
233 this.indexes_length = indexes.length; |
257 this.indexes_length = this.indexes.length; |
234 this.minmaxes = minmaxes; |
258 this.enable_expr = enable_expr; |
235 this.has_enable = has_enable; |
|
236 Object.keys(members).forEach(prop => this[prop]=members[prop]); |
259 Object.keys(members).forEach(prop => this[prop]=members[prop]); |
237 this.lastapply = indexes.map(() => undefined); |
260 this.lastapply = this.indexes.map(() => undefined); |
238 this.inhibit = indexes.map(() => undefined); |
261 this.inhibit = this.indexes.map(() => undefined); |
239 this.pending = indexes.map(() => undefined); |
262 this.pending = this.indexes.map(() => undefined); |
240 this.bound_uninhibit = this.uninhibit.bind(this); |
263 this.bound_uninhibit = this.uninhibit.bind(this); |
241 |
264 |
242 this.lastdispatch = indexes.map(() => undefined); |
265 this.lastdispatch = this.indexes.map(() => undefined); |
243 this.deafen = indexes.map(() => undefined); |
266 this.deafen = this.indexes.map(() => undefined); |
244 this.incoming = indexes.map(() => undefined); |
267 this.incoming = this.indexes.map(() => undefined); |
245 this.bound_undeafen = this.undeafen.bind(this); |
268 this.bound_undeafen = this.undeafen.bind(this); |
246 |
269 |
247 this.forced_frequency = freq; |
270 this.forced_frequency = freq; |
248 this.clip = true; |
271 this.clip = true; |
249 } |
272 } |
275 } catch(err) { |
298 } catch(err) { |
276 console.log(err); |
299 console.log(err); |
277 } |
300 } |
278 } |
301 } |
279 |
302 |
280 if(this.has_enable){ |
303 if(this.enable_expr){ |
281 this.disabled_elt = null; |
304 this.disabled_elt = null; |
282 this.enabled_elts = []; |
305 this.enabled_elts = []; |
283 this.enable_state = false; |
306 this.enable_state = false; |
284 this.enable_displayed_state = false; |
307 this.enable_displayed_state = false; |
285 for(let child of Array.from(this.element.children)){ |
308 for(let child of Array.from(this.element.children)){ |
361 |
384 |
362 undershot(new_val, min) { |
385 undershot(new_val, min) { |
363 } |
386 } |
364 |
387 |
365 clip_min_max(index, new_val) { |
388 clip_min_max(index, new_val) { |
366 let minmax = this.minmaxes[index]; |
389 let minmax = this.variables_options[index].minmax; |
367 if(minmax !== undefined && typeof new_val == "number") { |
390 if(minmax !== undefined && typeof new_val == "number") { |
368 let [min,max] = minmax; |
391 let [min,max] = minmax; |
369 if(new_val < min){ |
392 if(new_val < min){ |
370 this.undershot(new_val, min); |
393 this.undershot(new_val, min); |
371 return min; |
394 return min; |
481 } |
504 } |
482 |
505 |
483 _dispatch(value, oldval, varnum) { |
506 _dispatch(value, oldval, varnum) { |
484 let dispatch = this.dispatch; |
507 let dispatch = this.dispatch; |
485 let has_dispatch = dispatch != undefined; |
508 let has_dispatch = dispatch != undefined; |
486 let is_enable_var = this.has_enable && (varnum == (this.indexes_length - 1)); |
509 if(has_dispatch || this.enable_expr){ |
487 if(has_dispatch || is_enable_var){ |
|
488 if(this.deafen[varnum] == undefined){ |
510 if(this.deafen[varnum] == undefined){ |
489 let now = Date.now(); |
511 let now = Date.now(); |
490 let min_interval = 1000/this.frequency; |
512 let min_interval = 1000/this.frequency; |
491 let lastdispatch = this.lastdispatch[varnum]; |
513 let lastdispatch = this.lastdispatch[varnum]; |
492 if(lastdispatch == undefined || now > lastdispatch + min_interval){ |
514 if(lastdispatch == undefined || now > lastdispatch + min_interval){ |
494 if(has_dispatch) try { |
516 if(has_dispatch) try { |
495 dispatch.call(this, value, oldval, varnum); |
517 dispatch.call(this, value, oldval, varnum); |
496 } catch(err) { |
518 } catch(err) { |
497 console.log(err); |
519 console.log(err); |
498 } |
520 } |
499 if(is_enable_var) try { |
521 if(this.enable_expr) try { |
500 this.enable(Boolean(value)); |
522 this.compute_enable(value, oldval, varnum); |
501 } catch(err) { |
523 } catch(err) { |
502 console.log(err); |
524 console.log(err); |
503 } |
525 } |
504 } |
526 } |
505 else { |
527 else { |