# HG changeset patch
# User Edouard Tisserant
# Date 1582805664 -3600
# Node ID 94696b3f69fb6554df7946279babf36fff9d7441
# Parent 2f73f001955a248e6f1a7c5fb33b35f9f164e904
SVGHMI : still trying to optimize. Added xslt code to identitfy minimum set of elements needed by a particular page. Plan is to remove unseen/unused elements from the DOM, and re-appending them later when used, on page switch. Disabled previous optimization.
diff -r 2f73f001955a -r 94696b3f69fb svghmi/gen_index_xhtml.xslt
--- a/svghmi/gen_index_xhtml.xslt Fri Feb 21 16:22:44 2020 +0100
+++ b/svghmi/gen_index_xhtml.xslt Thu Feb 27 13:14:24 2020 +0100
@@ -126,40 +126,6 @@
All units must be set to "px" in Inkscape's document properties
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Made with SVGHMI. https://beremiz.org
@@ -238,17 +204,35 @@
-
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
//(function(){
@@ -359,10 +343,10 @@
-
-
-
-
+
+
+
+
"
": {
@@ -395,6 +379,16 @@
]
+ required_elements: [
+
+
+ "
+
+ ",
+
+
+ ]
+
}
,
@@ -852,6 +846,32 @@
+ function prepare_svg() {
+
+ /* set everybody hidden initially for better performance */
+
+ for(let widget in hmi_widgets){
+
+ if(widget.element != undefined)
+
+ widget.element.style.display = "none";
+
+ }
+
+ /*for(let name in page_desc){
+
+ if(name != new_desc){
+
+ page_desc[name].widget.element.style.display = "none";
+
+ }
+
+ }*/
+
+ };
+
+
+
function switch_page(page_name) {
let old_desc = page_desc[current_page];
@@ -862,18 +882,30 @@
if(new_desc == undefined){
+ /* TODO LOG ERROR */
+
return;
}
- /* remove subsribers of previous page if any */
-
if(old_desc){
for(let widget of old_desc.widgets){
+
+
+ /* hide widget */
+
+ if(widget.element != undefined)
+
+ widget.element.style.display = "none";
+
+
+
+ /* remove subsribers */
+
for(let index of widget.indexes){
subscribers[index].delete(widget);
@@ -884,17 +916,35 @@
old_desc.widget.element.style.display = "none";
- } else {
-
- /* initial page switch : set everybody hidden */
-
- for(let name in page_desc){
-
- if(name != new_desc){
-
- page_desc[name].widget.element.style.display = "none";
-
- }
+ }
+
+
+
+ for(let widget of new_desc.widgets){
+
+
+
+ /* unhide widget */
+
+ if(widget.element != undefined)
+
+ widget.element.style.display = "inline";
+
+
+
+ /* add widget's subsribers */
+
+ for(let index of widget.indexes){
+
+ subscribers[index].add(widget);
+
+ /* dispatch current cache in newly opened page widgets */
+
+ let cached_val = cache[index];
+
+ if(cached_val != undefined)
+
+ dispatch_value_to_widget(widget, index, cached_val, cached_val);
}
@@ -902,28 +952,6 @@
- /* add new subsribers if any */
-
- for(let widget of new_desc.widgets){
-
- for(let index of widget.indexes){
-
- subscribers[index].add(widget);
-
- /* dispatch current cache in newly opened page widgets */
-
- let cached_val = cache[index];
-
- if(cached_val != undefined)
-
- dispatch_value_to_widget(widget, index, cached_val, cached_val);
-
- }
-
- }
-
-
-
new_desc.widget.element.style.display = "inline";
@@ -952,6 +980,8 @@
// show main page
+ prepare_svg();
+
switch_page(default_page);
};
diff -r 2f73f001955a -r 94696b3f69fb svghmi/gen_index_xhtml.ysl2
--- a/svghmi/gen_index_xhtml.ysl2 Fri Feb 21 16:22:44 2020 +0100
+++ b/svghmi/gen_index_xhtml.ysl2 Thu Feb 27 13:14:24 2020 +0100
@@ -72,6 +72,10 @@
const "_indexed_hmitree" apply "$hmitree", mode="index";
const "indexed_hmitree", "exsl:node-set($_indexed_hmitree)";
+
+ // TODO globally discardable elements, not (used by | ancestor of) any page
+
+
template "*", mode="index" {
param "index", "0";
param "parentpath", "''";
@@ -113,6 +117,7 @@
template "@* | node()", mode="inline_svg" {
/* use real xsl:copy instead copy-of alias from yslt.yml2 */
xsl:copy apply "@* | node()", mode="inline_svg";
+ /* TODO filter out globally discardable elements */
}
/* replaces inkscape's height and width hints. forces fit */
@@ -133,32 +138,35 @@
error > All units must be set to "px" in Inkscape's document properties
}
- /* clone unlinkink until widget for better perf with webkit */
- svgtmpl "svg:use", mode="inline_svg"
- {
- g{
- attrib "style" > «@style»
- attrib "transform" > «@transform»
- /* keep same id and label in case it is a widget */
- //attrib "inkscape:label","@inkscape:label";
- attrib "id" > «@id»
- const "targetid","substring-after(@xlink:href,'#')";
- apply "//svg:*[@id = $targetid]", mode="unlink_clone";
- }
- }
- svgtmpl "@*", mode="unlink_clone" xsl:copy;
- svgtmpl "svg:*", mode="unlink_clone" {
- choose {
- when "@id = $hmi_elements/@id" {
- use{
- attrib "xlink:href" > «concat('#',@id)»
- }
- }
- otherwise {
- xsl:copy apply "@* | node()", mode="unlink_clone";
- }
- }
- }
+
+ //// Commented out before implementing runtime DOM remove/append on page switch - would have side effect
+ ////
+ //// /* clone unlinkink until widget for better perf with webkit */
+ //// svgtmpl "svg:use", mode="inline_svg"
+ //// {
+ //// g{
+ //// attrib "style" > «@style»
+ //// attrib "transform" > «@transform»
+ //// /* keep same id and label in case it is a widget */
+ //// //attrib "inkscape:label","@inkscape:label";
+ //// attrib "id" > «@id»
+ //// const "targetid","substring-after(@xlink:href,'#')";
+ //// apply "//svg:*[@id = $targetid]", mode="unlink_clone";
+ //// }
+ //// }
+ //// svgtmpl "@*", mode="unlink_clone" xsl:copy;
+ //// svgtmpl "svg:*", mode="unlink_clone" {
+ //// choose {
+ //// when "@id = $hmi_elements/@id" {
+ //// use{
+ //// attrib "xlink:href" > «concat('#',@id)»
+ //// }
+ //// }
+ //// otherwise {
+ //// xsl:copy apply "@* | node()", mode="unlink_clone";
+ //// }
+ //// }
+ //// }
// template "svg:use/@style", mode="inline_svg"{
// attrib "style" > all:initial;
@@ -212,7 +220,7 @@
}
*/
- func:function name="func:parselabel" {
+ def "func:parselabel" {
param "label";
const "description", "substring-after($label,'HMI:')";
@@ -243,22 +251,49 @@
}
}
- func:result select="exsl:node-set($ast)"
+ result "exsl:node-set($ast)";
}
// returns all directly or indirectly refered elements
- func:function name="func:refered_elements" {
+ def "func:refered_elements" {
param "elems";
const "descend", "$elems/descendant-or-self::svg:*";
const "clones", "$descend[self::svg:use]";
- const "reals", "$descend[not(self::svg:use)]";
const "originals", "//svg:*[concat('#',@id) = $clones/@xlink:href]";
choose {
when "$originals"
- func:result select="$reals | func:refered_elements($originals)";
+ result "$descend | func:refered_elements($originals)";
otherwise
- func:result select="$reals";
- }
+ result "$descend";
+ }
+ }
+
+ // return included geometry a given element
+ def "func:included_geometry" {
+ param "elt";
+ const "g", "$geometry[@Id = $elt/@id]";
+ result """$geometry[@Id != $elt/@id and
+ @x >= $g/@x and @y >= $g/@y and
+ @x+@w <= $g/@x+$g/@w and @y+@h <= $g/@y+$g/@h]""";
+
+ }
+
+ def "func:sumarized_elements" {
+ param "elements";
+ const "short_list", "$elements[not(ancestor::*/@id = $elements/@id)]";
+ /* TODO exclude globally discardable elements from group fulfillment check */
+ const "filled_groups", "$short_list/parent::svg:*[not(descendant::*[not(self::svg:g)][not(@id = $short_list/descendant-or-self::*[not(self::svg:g)]/@id)])]";
+ const "groups_to_add", "$filled_groups[not(ancestor::*/@id = $filled_groups/@id)]";
+ result "$groups_to_add | $short_list[not(ancestor::svg:g/@id = $filled_groups/@id)]";
+ }
+
+ def "func:all_related_elements" {
+ param "page";
+ const "page_included_geometry", "func:included_geometry($page)";
+ const "page_sub_elements", "func:refered_elements($page)";
+
+ const "page_included_elements", "//svg:*[@id = $page_included_geometry/@Id]";
+ result "$page_sub_elements | $page_included_elements";
}
function "scripts"
@@ -324,17 +359,20 @@
| ]
|
+
| var page_desc = {
foreach "$hmi_pages" {
const "desc", "func:parselabel(@inkscape:label)/widget";
- const "page", ".";
- const "p", "$hmi_geometry[@Id = $page/@id]";
- const "page_ids","""$hmi_geometry[@Id != $page/@id and
- @x >= $p/@x and @y >= $p/@y and
- @x+@w <= $p/@x+$p/@w and @y+@h <= $p/@y+$p/@h]/@Id""";
- const "page_sub_ids", "func:refered_elements($page)[@id = $hmi_elements/@id]/@id";
- const "all_page_ids","$page_ids | $page_sub_ids[not(. = $page_ids)]";
+ const "page", ".";
+ const "p", "$geometry[@Id = $page/@id]";
+
+ const "page_all_elements", "func:all_related_elements($page)";
+
+ const "all_page_ids","$page_all_elements[@id = $hmi_elements/@id and @id != $page/@id]/@id";
+
+ const "shorter_list", "func:sumarized_elements($page_all_elements)";
+
| "«$desc/arg[1]/@value»": {
| widget: hmi_widgets["«@id»"],
| bbox: [«$p/@x», «$p/@y», «$p/@w», «$p/@h»],
@@ -343,6 +381,11 @@
| hmi_widgets["«.»"]`if "position()!=last()" > ,`
}
| ]
+ | required_elements: [
+ foreach "$shorter_list" {
+ | "«@id»",
+ }
+ | ]
| }`if "position()!=last()" > ,`
}
| }
diff -r 2f73f001955a -r 94696b3f69fb svghmi/svghmi.js
--- a/svghmi/svghmi.js Fri Feb 21 16:22:44 2020 +0100
+++ b/svghmi/svghmi.js Thu Feb 27 13:14:24 2020 +0100
@@ -217,33 +217,50 @@
var current_page;
+function prepare_svg() {
+ /* set everybody hidden initially for better performance */
+ for(let widget in hmi_widgets){
+ if(widget.element != undefined)
+ widget.element.style.display = "none";
+ }
+ /*for(let name in page_desc){
+ if(name != new_desc){
+ page_desc[name].widget.element.style.display = "none";
+ }
+ }*/
+};
+
function switch_page(page_name) {
let old_desc = page_desc[current_page];
let new_desc = page_desc[page_name];
if(new_desc == undefined){
+ /* TODO LOG ERROR */
return;
}
- /* remove subsribers of previous page if any */
if(old_desc){
for(let widget of old_desc.widgets){
+
+ /* hide widget */
+ if(widget.element != undefined)
+ widget.element.style.display = "none";
+
+ /* remove subsribers */
for(let index of widget.indexes){
subscribers[index].delete(widget);
}
}
old_desc.widget.element.style.display = "none";
- } else {
- /* initial page switch : set everybody hidden */
- for(let name in page_desc){
- if(name != new_desc){
- page_desc[name].widget.element.style.display = "none";
- }
- }
- }
-
- /* add new subsribers if any */
+ }
+
for(let widget of new_desc.widgets){
+
+ /* unhide widget */
+ if(widget.element != undefined)
+ widget.element.style.display = "inline";
+
+ /* add widget's subsribers */
for(let index of widget.indexes){
subscribers[index].add(widget);
/* dispatch current cache in newly opened page widgets */
@@ -267,6 +284,7 @@
init_widgets();
send_reset();
// show main page
+ prepare_svg();
switch_page(default_page);
};