diff --git a/repos/gems/src/app/sculpt_manager/graph.h b/repos/gems/src/app/sculpt_manager/graph.h index fd5eb7b1fb..04678cb7db 100644 --- a/repos/gems/src/app/sculpt_manager/graph.h +++ b/repos/gems/src/app/sculpt_manager/graph.h @@ -92,6 +92,13 @@ struct Sculpt::Graph xml.attribute("text", caps); }); } + void _gen_parent_node(Xml_generator &xml, Start_name const &name) const + { + gen_named_node(xml, "frame", name, [&] () { + xml.node("label", [&] () { + xml.attribute("text", name); }); }); + } + void _gen_graph_dialog() { _graph_dialog_reporter.generate([&] (Xml_generator &xml) { @@ -109,6 +116,12 @@ struct Sculpt::Graph xml.attribute("text", "+"); }); }); } + /* parent roles */ + _gen_parent_node(xml, "hardware"); + _gen_parent_node(xml, "config"); + _gen_parent_node(xml, "info"); + _gen_parent_node(xml, "GUI"); + typedef Runtime_config::Component Component; _runtime_config.for_each_component([&] (Component const &component) { diff --git a/repos/gems/src/app/sculpt_manager/model/runtime_config.h b/repos/gems/src/app/sculpt_manager/model/runtime_config.h index b445c7a14e..a99df159a1 100644 --- a/repos/gems/src/app/sculpt_manager/model/runtime_config.h +++ b/repos/gems/src/app/sculpt_manager/model/runtime_config.h @@ -29,27 +29,98 @@ class Sculpt::Runtime_config Allocator &_alloc; + /** + * Return target name of route specified by node + * + * For a route to another child, the target name is the child name. + * For a route to the parent, the target name expresses a role of + * the parent: + * + * - 'hardware' provides access to hardware + * - 'config' allows the change of the systems configuration + * - 'info' reveals system information + * - 'GUI' connects to the nitpicker GUI server + */ + static Start_name _to_name(Xml_node node) + { + Start_name result { }; + node.with_sub_node("child", [&] (Xml_node child) { + result = child.attribute_value("name", Start_name()); }); + + if (result.valid()) + return result; + + node.with_sub_node("parent", [&] (Xml_node parent) { + + typedef String<16> Service; + Service const service = + node.attribute_value("name", Service()); + + Label const dst_label = + parent.attribute_value("label", Label()); + + bool const ignored_service = (service == "CPU") + || (service == "PD") + || (service == "Report") + || (service == "Timer") + || (service == "LOG"); + if (ignored_service) + return; + + bool const hardware = (service == "Block") + || (service == "USB") + || (service == "Platform") + || (service == "IO_PORT") + || (service == "IO_MEM") + || (service == "Rtc") + || (service == "IRQ") + || (service == "TRACE"); + if (hardware) { + result = "hardware"; + return; + } + + if (service == "ROM") { + bool const interesting_rom = !dst_label.valid(); + if (interesting_rom) { + result = "info"; + return; + } + } + + if (service == "File_system") { + + if (dst_label == "config") { + result = "config"; + return; + } + + if (dst_label == "fonts" || dst_label == "report") { + result = "info"; + return; + } + } + + if (service == "Nitpicker") { + result = "GUI"; + return; + } + }); + + return result; + } + /** * Return component name targeted by the first route of the start node */ static Start_name _primary_dependency(Xml_node const start) { - if (!start.has_sub_node("route")) - return Start_name(); + Start_name result { }; + start.with_sub_node("route", [&] (Xml_node route) { + route.with_sub_node("service", [&] (Xml_node service) { + result = _to_name(service); }); }); - Xml_node const route = start.sub_node("route"); - - if (!route.has_sub_node("service")) - return Start_name(); - - Xml_node const service = route.sub_node("service"); - - if (service.has_sub_node("child")) { - Xml_node const child = service.sub_node("child"); - return child.attribute_value("name", Start_name()); - } - - return Start_name(); + return result; } public: @@ -60,39 +131,31 @@ class Sculpt::Runtime_config Start_name primary_dependency { }; - struct Child_dep : List_model::Element + struct Dep : List_model::Element { Start_name const to_name; - Child_dep(Start_name to_name) : to_name(to_name) { } + Dep(Start_name to_name) : to_name(to_name) { } struct Update_policy { - typedef Child_dep Element; + typedef Dep Element; Allocator &_alloc; Update_policy(Allocator &alloc) : _alloc(alloc) { } - void destroy_element(Child_dep &elem) { destroy(_alloc, &elem); } + void destroy_element(Dep &elem) { destroy(_alloc, &elem); } - static Start_name _to_name(Xml_node node) + Dep &create_element(Xml_node node) { - Start_name result { }; - node.with_sub_node("child", [&] (Xml_node child) { - result = child.attribute_value("name", Start_name()); }); - - return result; + log("to_name -> ", _to_name(node), " for ", node); + return *new (_alloc) Dep(_to_name(node)); } - Child_dep &create_element(Xml_node node) - { - return *new (_alloc) Child_dep(_to_name(node)); - } + void update_element(Dep &, Xml_node) { } - void update_element(Child_dep &, Xml_node) { } - - static bool element_matches_xml_node(Child_dep const &elem, Xml_node node) + static bool element_matches_xml_node(Dep const &elem, Xml_node node) { return _to_name(node) == elem.to_name; } @@ -105,12 +168,12 @@ class Sculpt::Runtime_config }; /* dependencies on other child components */ - List_model child_deps { }; + List_model deps { }; template void for_each_secondary_dep(FN const &fn) const { - child_deps.for_each([&] (Child_dep const &dep) { + deps.for_each([&] (Dep const &dep) { if (dep.to_name != primary_dependency) fn(dep.to_name); }); } @@ -138,11 +201,12 @@ class Sculpt::Runtime_config void update_element(Component &elem, Xml_node node) { + log("update component ", elem.name); elem.primary_dependency = _primary_dependency(node); - Child_dep::Update_policy policy(_alloc); + Dep::Update_policy policy(_alloc); node.with_sub_node("route", [&] (Xml_node route) { - elem.child_deps.update_from_xml(policy, route); }); + elem.deps.update_from_xml(policy, route); }); } static bool element_matches_xml_node(Component const &elem, Xml_node node)