sculpt: display parent roles in graph

This commit is contained in:
Norman Feske 2019-02-23 16:57:38 +01:00 committed by Christian Helmuth
parent d0e1ddb8c2
commit 21968d35bb
2 changed files with 113 additions and 36 deletions

View File

@ -92,6 +92,13 @@ struct Sculpt::Graph
xml.attribute("text", caps); }); 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() void _gen_graph_dialog()
{ {
_graph_dialog_reporter.generate([&] (Xml_generator &xml) { _graph_dialog_reporter.generate([&] (Xml_generator &xml) {
@ -109,6 +116,12 @@ struct Sculpt::Graph
xml.attribute("text", "+"); }); }); 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; typedef Runtime_config::Component Component;
_runtime_config.for_each_component([&] (Component const &component) { _runtime_config.for_each_component([&] (Component const &component) {

View File

@ -29,27 +29,98 @@ class Sculpt::Runtime_config
Allocator &_alloc; Allocator &_alloc;
/**
* Return target name of route specified by <service> 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 * Return component name targeted by the first route of the start node
*/ */
static Start_name _primary_dependency(Xml_node const start) static Start_name _primary_dependency(Xml_node const start)
{ {
if (!start.has_sub_node("route")) Start_name result { };
return Start_name(); 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"); return result;
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();
} }
public: public:
@ -60,39 +131,31 @@ class Sculpt::Runtime_config
Start_name primary_dependency { }; Start_name primary_dependency { };
struct Child_dep : List_model<Child_dep>::Element struct Dep : List_model<Dep>::Element
{ {
Start_name const to_name; 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 struct Update_policy
{ {
typedef Child_dep Element; typedef Dep Element;
Allocator &_alloc; Allocator &_alloc;
Update_policy(Allocator &alloc) : _alloc(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 { }; log("to_name -> ", _to_name(node), " for ", node);
node.with_sub_node("child", [&] (Xml_node child) { return *new (_alloc) Dep(_to_name(node));
result = child.attribute_value("name", Start_name()); });
return result;
} }
Child_dep &create_element(Xml_node node) void update_element(Dep &, Xml_node) { }
{
return *new (_alloc) Child_dep(_to_name(node));
}
void update_element(Child_dep &, Xml_node) { } static bool element_matches_xml_node(Dep const &elem, Xml_node node)
static bool element_matches_xml_node(Child_dep const &elem, Xml_node node)
{ {
return _to_name(node) == elem.to_name; return _to_name(node) == elem.to_name;
} }
@ -105,12 +168,12 @@ class Sculpt::Runtime_config
}; };
/* dependencies on other child components */ /* dependencies on other child components */
List_model<Child_dep> child_deps { }; List_model<Dep> deps { };
template <typename FN> template <typename FN>
void for_each_secondary_dep(FN const &fn) const 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) if (dep.to_name != primary_dependency)
fn(dep.to_name); }); fn(dep.to_name); });
} }
@ -138,11 +201,12 @@ class Sculpt::Runtime_config
void update_element(Component &elem, Xml_node node) void update_element(Component &elem, Xml_node node)
{ {
log("update component ", elem.name);
elem.primary_dependency = _primary_dependency(node); 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) { 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) static bool element_matches_xml_node(Component const &elem, Xml_node node)