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); });
}
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) {

View File

@ -29,27 +29,98 @@ class Sculpt::Runtime_config
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
*/
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<Child_dep>::Element
struct Dep : List_model<Dep>::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_dep> child_deps { };
List_model<Dep> deps { };
template <typename FN>
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)