Removed harmful assert in ProcessLogger.
ProcessLogger was having an assert in constructor when missing logger, leading to systematic exception when testing options accepted by compiler. This exception was silenced in ProjectController, and then MatIEC was always called without options.
// detachable_pages.ysl2
//
// compute what elements are required by pages
// and decide where to cut when removing/attaching
// pages elements on page switch
const "hmi_pages_descs", "$parsed_widgets/widget[@type = 'Page']";
const "hmi_pages", "$hmi_elements[@id = $hmi_pages_descs/@id]";
const "default_page" choose {
when "count($hmi_pages) > 1" {
choose {
when "$hmi_pages_descs/arg[1]/@value = 'Home'" > Home
otherwise {
error "No Home page defined!";
}
}
}
when "count($hmi_pages) = 0" {
error "No page defined!";
}
otherwise > «func:widget($hmi_pages/@id)/arg[1]/@value»
}
emit "preamble:default-page" {
|
| var default_page = "«$default_page»";
}
const "keypads_descs", "$parsed_widgets/widget[@type = 'Keypad']";
const "keypads", "$hmi_elements[@id = $keypads_descs/@id]";
// returns all directly or indirectly refered elements
def "func:refered_elements" {
param "elems";
const "descend", "$elems/descendant-or-self::svg:*";
const "clones", "$descend[self::svg:use]";
const "originals", "//svg:*[concat('#',@id) = $clones/@xlink:href]";
choose {
when "$originals"
result "$descend | func:refered_elements($originals)";
otherwise
result "$descend";
}
}
def "func:all_related_elements" {
param "page";
const "page_overlapping_geometry", "func:overlapping_geometry($page)";
const "page_overlapping_elements", "//svg:*[@id = $page_overlapping_geometry/@Id]";
const "page_sub_elements", "func:refered_elements($page | $page_overlapping_elements)";
result "$page_sub_elements";
}
def "func:required_elements" {
param "pages";
choose{
when "$pages"{
result """func:all_related_elements($pages[1])
| func:required_elements($pages[position()!=1])""";
}otherwise{
result "/..";
}
}
}
const "required_elements",
"""//svg:defs/descendant-or-self::svg:*
| func:required_elements($hmi_pages | $keypads)/ancestor-or-self::svg:*""";
const "discardable_elements", "//svg:*[not(@id = $required_elements/@id)]";
def "func:sumarized_elements" {
param "elements";
const "short_list", "$elements[not(ancestor::*/@id = $elements/@id)]";
const "filled_groups", """$short_list/parent::svg:*[
not(descendant::*[
not(self::svg:g) and
not(@id = $discardable_elements/@id) and
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:detachable_elements" {
param "pages";
choose{
when "$pages"{
result """func:sumarized_elements(func:all_related_elements($pages[1]))
| func:detachable_elements($pages[position()!=1])""";
}otherwise{
result "/..";
}
}
}
// Avoid nested detachables
const "_detachable_elements", "func:detachable_elements($hmi_pages | $keypads)";
const "detachable_elements", "$_detachable_elements[not(ancestor::*/@id = $_detachable_elements/@id)]";
emit "declarations:detachable-elements" {
|
| var detachable_elements = {
foreach "$detachable_elements"{
| "«@id»":[id("«@id»"), id("«../@id»")]`if "position()!=last()" > ,`
}
| }
}
const "forEach_widgets_ids", "$parsed_widgets/widget[@type = 'ForEach']/@id";
const "forEach_widgets", "$hmi_elements[@id = $forEach_widgets_ids]";
const "in_forEach_widget_ids", "func:refered_elements($forEach_widgets)[not(@id = $forEach_widgets_ids)]/@id";
template "svg:*", mode="page_desc" {
const "desc", "func:widget(@id)";
const "page", ".";
const "p", "$geometry[@Id = $page/@id]";
const "page_all_elements", "func:all_related_elements($page)";
const "all_page_widgets","$hmi_elements[@id = $page_all_elements/@id and @id != $page/@id]";
const "page_managed_widgets","$all_page_widgets[not(@id=$in_forEach_widget_ids)]";
const "page_relative_widgets",
"$page_managed_widgets[func:is_descendant_path(func:widget(@id)/path/@value, $desc/path/@value)]";
// Take closest ancestor in detachable_elements
// since nested detachable elements are filtered out
const "required_detachables",
"""func:sumarized_elements($page_all_elements)/
ancestor-or-self::*[@id = $detachable_elements/@id]""";
| "«$desc/arg[1]/@value»": {
//| widget: hmi_widgets["«@id»"],
| bbox: [«$p/@x», «$p/@y», «$p/@w», «$p/@h»],
if "$desc/path/@value" {
if "count($desc/path/@index)=0"
warning > Page id="«$page/@id»" : No match for path "«$desc/path/@value»" in HMI tree
| page_index: «$desc/path/@index»,
}
| widgets: [
foreach "$page_managed_widgets" {
const "widget_paths_relativeness"
foreach "func:widget(@id)/path" {
value "func:is_descendant_path(@value, $desc/path/@value)";
if "position()!=last()" > ,
}
| [hmi_widgets["«@id»"], [«$widget_paths_relativeness»]]`if "position()!=last()" > ,`
}
| ],
| jumps: [
foreach "$parsed_widgets/widget[@id = $all_page_widgets/@id and @type='Jump']" {
| hmi_widgets["«@id»"]`if "position()!=last()" > ,`
}
| ],
| required_detachables: {
foreach "$required_detachables" {
| "«@id»": detachable_elements["«@id»"]`if "position()!=last()" > ,`
}
| }
/* TODO generate some code for init() instead */
apply "$parsed_widgets/widget[@id = $all_page_widgets/@id]", mode="per_page_widget_template"{
with "page_desc", "$desc";
}
| }`if "position()!=last()" > ,`
}
emit "definitions:page-desc" {
|
| var page_desc = {
apply "$hmi_pages", mode="page_desc";
| }
}
template "*", mode="per_page_widget_template";
emit "debug:detachable-pages" {
|
| DETACHABLES:
foreach "$detachable_elements"{
| «@id»
}
| In Foreach:
foreach "$in_forEach_widget_ids"{
| «.»
}
}