sculpt_manager: use Rom_handler

This patch replaces the dynamic use of Attached_rom_dataspace by a
new Rom_handler utility, which implicitly covers the initial import of
content (safely using 'local_submit'), the registration of the signal
handler, passes the Xml_node to the handler function (no need to
manually call 'update'), and provides scoped access to the content via a
'with_xml' method. The latter reinforces a programming style that does
not need to copy Xml_node objects.

Issue #5150
This commit is contained in:
Norman Feske 2024-03-27 16:29:08 +01:00 committed by Christian Helmuth
parent f96cea8151
commit b78b2c7ac9
22 changed files with 512 additions and 671 deletions

View File

@ -182,7 +182,7 @@ struct Sculpt::Main : Input_event_handler,
_system_config.generate([&] (Xml_generator &xml) {
_system.generate(xml, _screensaver); }); }
void _handle_system_config(Xml_node node)
void _handle_system_config(Xml_node const &node)
{
_system = System::from_xml(node);
_update_managed_system_config();
@ -251,17 +251,10 @@ struct Sculpt::Main : Input_event_handler,
bool _verbose_modem = false;
Attached_rom_dataspace _config { _env, "config" };
Rom_handler<Main> _config { _env, "config", *this, &Main::_handle_config };
Signal_handler<Main> _config_handler {
_env.ep(), *this, &Main::_handle_config };
void _handle_config()
void _handle_config(Xml_node const &config)
{
_config.update();
Xml_node const config = _config.xml();
_verbose_modem = config.attribute_value("verbose_modem", false);
}
@ -277,21 +270,17 @@ struct Sculpt::Main : Input_event_handler,
generate_runtime_config();
}
Attached_rom_dataspace _leitzentrale_rom { _env, "leitzentrale" };
Rom_handler<Main> _leitzentrale_rom {
_env, "leitzentrale", *this, &Main::_handle_leitzentrale };
Signal_handler<Main> _leitzentrale_handler {
_env.ep(), *this, &Main::_handle_leitzentrale };
void _handle_leitzentrale()
void _handle_leitzentrale(Xml_node const &leitzentrale)
{
_leitzentrale_rom.update();
_leitzentrale_visible = _leitzentrale_rom.xml().attribute_value("enabled", false);
_leitzentrale_visible = leitzentrale.attribute_value("enabled", false);
/* disable automatic blanking while the application runtime is visible */
_screensaver.blank_after_some_time(_leitzentrale_visible);
_handle_window_layout();
_update_window_layout();
}
@ -411,13 +400,10 @@ struct Sculpt::Main : Input_event_handler,
** Update **
************/
Attached_rom_dataspace _update_state_rom {
_env, "report -> runtime/update/state" };
Rom_handler<Main> _update_state_rom {
_env, "report -> runtime/update/state", *this, &Main::_handle_update_state };
void _handle_update_state();
Signal_handler<Main> _update_state_handler {
_env.ep(), *this, &Main::_handle_update_state };
void _handle_update_state(Xml_node const &);
/**
* Condition for spawning the update subsystem
@ -482,18 +468,18 @@ struct Sculpt::Main : Input_event_handler,
xml.attribute("arch", _deploy._arch);
xml.attribute("version", _query_version.value);
if (_software_tab_watches_depot() || _scan_rom.xml().has_type("empty"))
if (_software_tab_watches_depot() || !_scan_rom.valid())
xml.node("scan", [&] {
xml.attribute("users", "yes"); });
if (_software_tab_watches_depot() || _image_index_rom.xml().has_type("empty"))
if (_software_tab_watches_depot() || !_image_index_rom.valid())
xml.node("index", [&] {
xml.attribute("user", _index_user);
xml.attribute("version", _sculpt_version);
xml.attribute("content", "yes");
});
if (_software_tab_watches_depot() || _image_index_rom.xml().has_type("empty"))
if (_software_tab_watches_depot() || !_image_index_rom.valid())
xml.node("image_index", [&] {
xml.attribute("os", "sculpt");
xml.attribute("board", _build_info.board);
@ -530,15 +516,11 @@ struct Sculpt::Main : Input_event_handler,
** Browse index **
******************/
Attached_rom_dataspace _index_rom { _env, "report -> runtime/depot_query/index" };
Rom_handler<Main> _index_rom {
_env, "report -> runtime/depot_query/index", *this, &Main::_handle_index };
Signal_handler<Main> _index_handler {
_env.ep(), *this, &Main::_handle_index };
void _handle_index()
void _handle_index(Xml_node const &)
{
_index_rom.update();
bool const software_add_widget_shown = _software_title_bar.selected()
&& _software_tabs_widget.hosted.add_selected();
if (software_add_widget_shown)
@ -559,17 +541,11 @@ struct Sculpt::Main : Input_event_handler,
** Blueprint query **
*********************/
Attached_rom_dataspace _blueprint_rom { _env, "report -> runtime/depot_query/blueprint" };
Rom_handler<Main> _blueprint_rom {
_env, "report -> runtime/depot_query/blueprint", *this, &Main::_handle_blueprint };
Signal_handler<Main> _blueprint_handler {
_env.ep(), *this, &Main::_handle_blueprint };
void _handle_blueprint()
void _handle_blueprint(Xml_node const &blueprint)
{
_blueprint_rom.update();
Xml_node const blueprint = _blueprint_rom.xml();
/*
* Drop intermediate results that will be superseded by a newer query.
* This is important because an outdated blueprint would be disregarded
@ -594,42 +570,30 @@ struct Sculpt::Main : Input_event_handler,
Deploy::Prio_levels const _prio_levels { 4 };
Attached_rom_dataspace _scan_rom { _env, "report -> runtime/depot_query/scan" };
Rom_handler<Main> _scan_rom {
_env, "report -> runtime/depot_query/scan", *this, &Main::_handle_scan };
Signal_handler<Main> _scan_handler { _env.ep(), *this, &Main::_handle_scan };
void _handle_scan()
void _handle_scan(Xml_node const &)
{
_scan_rom.update();
_generate_dialog();
_software_update_widget.hosted.sanitize_user_selection();
_software_add_widget.hosted.sanitize_user_selection();
}
Attached_rom_dataspace _image_index_rom { _env, "report -> runtime/depot_query/image_index" };
Rom_handler<Main> _image_index_rom {
_env, "report -> runtime/depot_query/image_index", *this, &Main::_handle_image_index };
Signal_handler<Main> _image_index_handler { _env.ep(), *this, &Main::_handle_image_index };
void _handle_image_index()
{
_image_index_rom.update();
_generate_dialog();
}
Attached_rom_dataspace _launcher_listing_rom {
_env, "report -> /runtime/launcher_query/listing" };
void _handle_image_index(Xml_node const &) { _generate_dialog(); }
Launchers _launchers { _heap };
Presets _presets { _heap };
Signal_handler<Main> _launcher_and_preset_listing_handler {
_env.ep(), *this, &Main::_handle_launcher_and_preset_listing };
Rom_handler<Main> _launcher_listing_rom {
_env, "report -> /runtime/launcher_query/listing", *this,
&Main::_handle_launcher_and_preset_listing };
void _handle_launcher_and_preset_listing()
void _handle_launcher_and_preset_listing(Xml_node const &listing)
{
_launcher_listing_rom.update();
Xml_node const listing = _launcher_listing_rom.xml();
listing.for_each_sub_node("dir", [&] (Xml_node const &dir) {
Path const dir_path = dir.attribute_value("path", Path());
@ -642,7 +606,7 @@ struct Sculpt::Main : Input_event_handler,
});
_generate_dialog();
_deploy._handle_managed_deploy();
_deploy.handle_deploy();
}
Deploy _deploy { _env, _heap, _child_states, _runtime_state, *this, *this, *this,
@ -653,19 +617,16 @@ struct Sculpt::Main : Input_event_handler,
*/
void refresh_deploy_dialog() override { _generate_dialog(); }
Attached_rom_dataspace _manual_deploy_rom { _env, "config -> deploy" };
Rom_handler<Main> _manual_deploy_rom {
_env, "config -> deploy", *this, &Main::_handle_manual_deploy };
void _handle_manual_deploy()
void _handle_manual_deploy(Xml_node const &manual_deploy)
{
_runtime_state.reset_abandoned_and_launched_children();
_manual_deploy_rom.update();
_deploy.use_as_deploy_template(_manual_deploy_rom.xml());
_deploy.use_as_deploy_template(manual_deploy);
_deploy.update_managed_deploy_config();
}
Signal_handler<Main> _manual_deploy_handler {
_env.ep(), *this, &Main::_handle_manual_deploy };
/************
** Global **
@ -716,15 +677,16 @@ struct Sculpt::Main : Input_event_handler,
});
}
Xml_node const state = main._update_state_rom.xml();
main._update_state_rom.with_xml([&] (Xml_node const &state) {
bool const download_in_progress =
main._update_running() && state.attribute_value("progress", false);
bool const download_in_progress =
main._update_running() && state.attribute_value("progress", false);
if (download_in_progress || main._download_queue.any_failed_download()) {
Hosted<Float, Vbox, Download_status_widget> download_status { Id { "Download" } };
s.widget(download_status, state, main._download_queue);
}
if (download_in_progress || main._download_queue.any_failed_download()) {
Hosted<Float, Vbox, Download_status_widget> download_status { Id { "Download" } };
s.widget(download_status, state, main._download_queue);
}
});
});
}
};
@ -824,7 +786,7 @@ struct Sculpt::Main : Input_event_handler,
_software_update_widget { Id { "software_update" }, _build_info,
_network._nic_state, _download_queue,
_index_update_queue, _file_operation_queue,
_scan_rom, _image_index_rom };
_scan_rom };
Conditional_widget<Software_version_widget>
_software_version_widget { Id { "software_version" } };
@ -953,10 +915,12 @@ struct Sculpt::Main : Input_event_handler,
&& _software_tabs_widget.hosted.add_selected()
&& _storage._sculpt_partition.valid());
s.widget(_software_update_widget, _software_title_bar.selected()
&& _software_tabs_widget.hosted.update_selected()
&& _storage._sculpt_partition.valid(),
_image_index_rom.xml());
_image_index_rom.with_xml([&] (Xml_node const &image_index) {
s.widget(_software_update_widget, _software_title_bar.selected()
&& _software_tabs_widget.hosted.update_selected()
&& _storage._sculpt_partition.valid(),
image_index);
});
s.widget(_software_version_widget, _software_title_bar.selected()
&& _software_tabs_widget.hosted.update_selected()
@ -987,7 +951,7 @@ struct Sculpt::Main : Input_event_handler,
_touch_keyboard.visible = touch_keyboard_needed();
if (orig_touch_keyboard_visible != _touch_keyboard.visible)
_handle_window_layout();
_update_window_layout();
}
void _generate_dialog()
@ -997,7 +961,10 @@ struct Sculpt::Main : Input_event_handler,
_main_view.refresh();
}
Attached_rom_dataspace _runtime_state_rom { _env, "report -> runtime/state" };
Rom_handler<Main> _runtime_state_rom {
_env, "report -> runtime/state", *this, &Main::_handle_runtime_state };
void _handle_runtime_state(Xml_node const &);
Runtime_state _runtime_state { _heap, _storage._sculpt_partition };
@ -1059,7 +1026,7 @@ struct Sculpt::Main : Input_event_handler,
bool _manually_managed_runtime = false;
void _handle_runtime(Xml_node config)
void _handle_runtime(Xml_node const &config)
{
_manually_managed_runtime = !config.has_type("empty");
generate_runtime_config();
@ -1078,11 +1045,6 @@ struct Sculpt::Main : Input_event_handler,
_generate_runtime_config(xml); });
}
Signal_handler<Main> _runtime_state_handler {
_env.ep(), *this, &Main::_handle_runtime_state };
void _handle_runtime_state();
/********************
** Touch keyboard **
@ -1167,17 +1129,14 @@ struct Sculpt::Main : Input_event_handler,
* manager, we still obtain it as a separate ROM session to keep the GUI
* part decoupled from the lower-level runtime configuration generator.
*/
Attached_rom_dataspace _runtime_config_rom { _env, "config -> managed/runtime" };
Signal_handler<Main> _runtime_config_handler {
_env.ep(), *this, &Main::_handle_runtime_config };
Rom_handler<Main> _runtime_config_rom {
_env, "config -> managed/runtime", *this, &Main::_handle_runtime_config };
Runtime_config _cached_runtime_config { _heap };
void _handle_runtime_config()
void _handle_runtime_config(Xml_node const &runtime_config)
{
_runtime_config_rom.update();
_cached_runtime_config.update_from_xml(_runtime_config_rom.xml());
_cached_runtime_config.update_from_xml(runtime_config);
_generate_dialog(); /* update graph */
}
@ -1311,7 +1270,25 @@ struct Sculpt::Main : Input_event_handler,
_generate_dialog();
}
void _handle_window_layout();
void _update_window_layout(Xml_node const &, Xml_node const &);
void _update_window_layout()
{
_decorator_margins.with_xml([&] (Xml_node const &decorator_margins) {
_window_list.with_xml([&] (Xml_node const &window_list) {
_update_window_layout(decorator_margins, window_list); }); });
}
void _handle_window_layout_or_decorator_margins(Xml_node const &)
{
_update_window_layout();
}
Rom_handler<Main> _window_list {
_env, "window_list", *this, &Main::_handle_window_layout_or_decorator_margins };
Rom_handler<Main> _decorator_margins {
_env, "decorator_margins", *this, &Main::_handle_window_layout_or_decorator_margins };
template <size_t N>
void _with_window(Xml_node window_list, String<N> const &match, auto const &fn)
@ -1321,18 +1298,7 @@ struct Sculpt::Main : Input_event_handler,
fn(win); });
}
Attached_rom_dataspace _window_list { _env, "window_list" };
Signal_handler<Main> _window_list_handler {
_env.ep(), *this, &Main::_handle_window_layout };
Expanding_reporter _wm_focus { _env, "focus", "wm_focus" };
Attached_rom_dataspace _decorator_margins { _env, "decorator_margins" };
Signal_handler<Main> _decorator_margins_handler {
_env.ep(), *this, &Main::_handle_window_layout };
Expanding_reporter _wm_focus { _env, "focus", "wm_focus" };
Expanding_reporter _window_layout { _env, "window_layout", "window_layout" };
void _reset_storage_widget_operation()
@ -1470,16 +1436,17 @@ struct Sculpt::Main : Input_event_handler,
*/
void load_deploy_preset(Presets::Info::Name const &name) override
{
Xml_node const listing = _launcher_listing_rom.xml();
_download_queue.remove_inactive_downloads();
listing.for_each_sub_node("dir", [&] (Xml_node const &dir) {
if (dir.attribute_value("path", Path()) == "/presets") {
dir.for_each_sub_node("file", [&] (Xml_node const &file) {
if (file.attribute_value("name", Presets::Info::Name()) == name) {
file.with_optional_sub_node("config", [&] (Xml_node const &config) {
_runtime_state.reset_abandoned_and_launched_children();
_deploy.use_as_deploy_template(config);
_deploy.update_managed_deploy_config(); }); } }); } });
_launcher_listing_rom.with_xml([&] (Xml_node const &listing) {
listing.for_each_sub_node("dir", [&] (Xml_node const &dir) {
if (dir.attribute_value("path", Path()) == "/presets") {
dir.for_each_sub_node("file", [&] (Xml_node const &file) {
if (file.attribute_value("name", Presets::Info::Name()) == name) {
file.with_optional_sub_node("config", [&] (Xml_node const &config) {
_runtime_state.reset_abandoned_and_launched_children();
_deploy.use_as_deploy_template(config);
_deploy.update_managed_deploy_config(); }); } }); } }); });
}
/**
@ -1678,10 +1645,8 @@ struct Sculpt::Main : Input_event_handler,
** Device functions **
**********************/
Attached_rom_dataspace _power_rom { _env, "report -> drivers/power" };
Signal_handler<Main> _power_handler {
_env.ep(), *this, &Main::_handle_power };
Rom_handler<Main> _power_rom {
_env, "report -> drivers/power", *this, &Main::_handle_power };
bool _update_soc_feature_selection()
{
@ -1702,12 +1667,10 @@ struct Sculpt::Main : Input_event_handler,
return changed;
}
void _handle_power()
void _handle_power(Xml_node const &power)
{
_power_rom.update();
Power_state const orig_power_state = _power_state;
_power_state = Power_state::from_xml(_power_rom.xml());
_power_state = Power_state::from_xml(power);
bool regenerate_dialog = false;
@ -1822,23 +1785,19 @@ struct Sculpt::Main : Input_event_handler,
Modem_config _curr_modem_config { };
Attached_rom_dataspace _modem_state_rom { _env, "report -> drivers/modem/state" };
Rom_handler<Main> _modem_state_rom {
_env, "report -> drivers/modem/state", *this, &Main::_handle_modem_state };
Signal_handler<Main> _modem_state_handler {
_env.ep(), *this, &Main::_handle_modem_state };
void _handle_modem_state()
void _handle_modem_state(Xml_node const &modem_state)
{
_modem_state_rom.update();
if (_verbose_modem)
log("modem state: ", _modem_state_rom.xml());
log("modem state: ", modem_state);
Modem_state const orig_modem_state = _modem_state;
bool regenerate_dialog = false;
_modem_state = Modem_state::from_xml(_modem_state_rom.xml());
_modem_state = Modem_state::from_xml(modem_state);
/* update condition of "Mobile data" network option */
if (orig_modem_state.ready() != _modem_state.ready())
@ -2023,36 +1982,9 @@ struct Sculpt::Main : Input_event_handler,
_drivers.update_options(_driver_options);
_drivers.update_soc(_soc);
_config.sigh(_config_handler);
_leitzentrale_rom.sigh(_leitzentrale_handler);
_manual_deploy_rom.sigh(_manual_deploy_handler);
_runtime_state_rom.sigh(_runtime_state_handler);
_runtime_config_rom.sigh(_runtime_config_handler);
_gui.input()->sigh(_input_handler);
_gui.mode_sigh(_gui_mode_handler);
/*
* Subscribe to reports
*/
_update_state_rom .sigh(_update_state_handler);
_window_list .sigh(_window_list_handler);
_decorator_margins .sigh(_decorator_margins_handler);
_scan_rom .sigh(_scan_handler);
_launcher_listing_rom.sigh(_launcher_and_preset_listing_handler);
_blueprint_rom .sigh(_blueprint_handler);
_image_index_rom .sigh(_image_index_handler);
_power_rom .sigh(_power_handler);
_modem_state_rom .sigh(_modem_state_handler);
_index_rom .sigh(_index_handler);
/*
* Import initial report content
*/
_handle_config();
_handle_leitzentrale();
_handle_gui_mode();
_handle_runtime_config();
_handle_modem_state();
_system_config.with_manual_config([&] (Xml_node const &system) {
_system = System::from_xml(system); });
@ -2070,8 +2002,6 @@ struct Sculpt::Main : Input_event_handler,
/*
* Generate initial config/managed/deploy configuration
*/
_handle_manual_deploy();
_generate_modem_config();
generate_runtime_config();
_generate_dialog();
@ -2079,7 +2009,8 @@ struct Sculpt::Main : Input_event_handler,
};
void Sculpt::Main::_handle_window_layout()
void Sculpt::Main::_update_window_layout(Xml_node const &decorator_margins,
Xml_node const &window_list)
{
/* skip window-layout handling (and decorator activity) while booting */
if (!_gui_mode_ready)
@ -2089,31 +2020,23 @@ void Sculpt::Main::_handle_window_layout()
{
unsigned top = 0, bottom = 0, left = 0, right = 0;
Decorator_margins(Xml_node node)
Decorator_margins(Xml_node const &node)
{
if (!node.has_sub_node("floating"))
return;
Xml_node const floating = node.sub_node("floating");
top = floating.attribute_value("top", 0U);
bottom = floating.attribute_value("bottom", 0U);
left = floating.attribute_value("left", 0U);
right = floating.attribute_value("right", 0U);
node.with_optional_sub_node("floating", [&] (Xml_node const &floating) {
top = floating.attribute_value("top", 0U);
bottom = floating.attribute_value("bottom", 0U);
left = floating.attribute_value("left", 0U);
right = floating.attribute_value("right", 0U);
});
}
};
/* read decorator margins from the decorator's report */
_decorator_margins.update();
Decorator_margins const margins(_decorator_margins.xml());
Decorator_margins const margins { decorator_margins };
typedef String<128> Label;
using Label = String<128>;
Label const main_view_label ("runtime -> leitzentrale -> main_view");
Label const touch_keyboard_label("runtime -> leitzentrale -> touch_keyboard");
_window_list.update();
Xml_node const window_list = _window_list.xml();
/*
* Take presence of main view as trigger for second driver stage.
*
@ -2182,7 +2105,7 @@ void Sculpt::Main::_handle_gui_mode()
if (mode.area.count() > 1)
_gui_mode_ready = true;
_handle_window_layout();
_update_window_layout();
_screen_size = mode.area;
_main_view.min_width = _screen_size.w();
@ -2192,12 +2115,8 @@ void Sculpt::Main::_handle_gui_mode()
}
void Sculpt::Main::_handle_update_state()
void Sculpt::Main::_handle_update_state(Xml_node const &update_state)
{
_update_state_rom.update();
Xml_node const update_state = _update_state_rom.xml();
_download_queue.apply_update_state(update_state);
bool const any_completed_download = _download_queue.any_completed_download();
_download_queue.remove_completed_downloads();
@ -2209,12 +2128,13 @@ void Sculpt::Main::_handle_update_state()
if (installation_complete) {
Xml_node const blueprint = _blueprint_rom.xml();
bool const new_depot_query_needed = blueprint_any_missing(blueprint)
|| blueprint_any_rom_missing(blueprint)
|| any_completed_download;
if (new_depot_query_needed)
trigger_depot_query();
_blueprint_rom.with_xml([&] (Xml_node const &blueprint) {
bool const new_depot_query_needed = blueprint_any_missing(blueprint)
|| blueprint_any_rom_missing(blueprint)
|| any_completed_download;
if (new_depot_query_needed)
trigger_depot_query();
});
_deploy.reattempt_after_installation();
}
@ -2223,12 +2143,8 @@ void Sculpt::Main::_handle_update_state()
}
void Sculpt::Main::_handle_runtime_state()
void Sculpt::Main::_handle_runtime_state(Xml_node const &state)
{
_runtime_state_rom.update();
Xml_node state = _runtime_state_rom.xml();
_runtime_state.update_from_state_report(state);
bool reconfigure_runtime = false;

View File

@ -25,7 +25,7 @@ struct Sculpt::Index_menu_widget : Widget<Vbox>
public:
using User = Depot::Archive::User;
using Index = Attached_rom_dataspace;
using Index = Rom_data;
using Name = Start_name;
struct Sub_menu_title : Widget<Left_floating_hbox>
@ -61,6 +61,12 @@ struct Sculpt::Index_menu_widget : Widget<Vbox>
void _reset_selection() { _pkg_selected = false; }
void _for_each_menu_item(User const &user, auto const &fn) const
{
_index.with_xml([&] (Xml_node const &index) {
_menu.for_each_item(index, user, fn); });
}
public:
Index_menu_widget(Index const &index) : _index(index) { }
@ -71,7 +77,7 @@ struct Sculpt::Index_menu_widget : Widget<Vbox>
s.widget(_back, Name { _menu });
unsigned count = 0;
_menu.for_each_item(_index.xml(), user, [&] (Xml_node const &item) {
_for_each_menu_item(user, [&] (Xml_node const &item) {
Id const id { { count } };
@ -110,7 +116,7 @@ struct Sculpt::Index_menu_widget : Widget<Vbox>
Id const clicked = at.matching_id<Vbox, Menu_entry>();
unsigned count = 0;
_menu.for_each_item(_index.xml(), user, [&] (Xml_node const &item) {
_for_each_menu_item(user, [&] (Xml_node const &item) {
if (clicked == Id { { count } }) {
@ -168,7 +174,7 @@ struct Sculpt::Index_menu_widget : Widget<Vbox>
return true;
bool at_least_one_item_exists = false;
_menu.for_each_item(_index.xml(), user, [&] (Xml_node const &) {
_for_each_menu_item(user, [&] (Xml_node const &) {
at_least_one_item_exists = true; });
return at_least_one_item_exists;

View File

@ -74,10 +74,8 @@ void Sculpt::Deploy::view_diag(Scope<> &s) const
}
void Sculpt::Deploy::handle_deploy()
void Sculpt::Deploy::_handle_managed_deploy(Xml_node const &managed_deploy)
{
Xml_node const managed_deploy = _managed_deploy_rom.xml();
/* determine CPU architecture of deployment */
Arch const orig_arch = _arch;
_arch = managed_deploy.attribute_value("arch", Arch());
@ -100,26 +98,27 @@ void Sculpt::Deploy::handle_deploy()
{
bool any_child_affected = false;
Xml_node const launcher_listing = _launcher_listing_rom.xml();
launcher_listing.for_each_sub_node("dir", [&] (Xml_node dir) {
_launcher_listing_rom.with_xml([&] (Xml_node const &listing) {
listing.for_each_sub_node("dir", [&] (Xml_node const &dir) {
typedef String<20> Path;
Path const path = dir.attribute_value("path", Path());
using Path = String<20>;
Path const path = dir.attribute_value("path", Path());
if (path != "/launcher")
return;
dir.for_each_sub_node("file", [&] (Xml_node file) {
if (file.attribute_value("xml", false) == false)
if (path != "/launcher")
return;
typedef Depot_deploy::Child::Launcher_name Name;
Name const name = file.attribute_value("name", Name());
dir.for_each_sub_node("file", [&] (Xml_node const &file) {
file.for_each_sub_node("launcher", [&] (Xml_node launcher) {
if (_children.apply_launcher(name, launcher))
any_child_affected = true; });
if (file.attribute_value("xml", false) == false)
return;
typedef Depot_deploy::Child::Launcher_name Name;
Name const name = file.attribute_value("name", Name());
file.for_each_sub_node("launcher", [&] (Xml_node const &launcher) {
if (_children.apply_launcher(name, launcher))
any_child_affected = true; });
});
});
});
return any_child_affected;
@ -129,18 +128,20 @@ void Sculpt::Deploy::handle_deploy()
auto apply_blueprint = [&]
{
bool progress = false;
try {
Xml_node const blueprint = _blueprint_rom.xml();
_blueprint_rom.with_xml([&] (Xml_node const &blueprint) {
/* apply blueprint, except when stale */
typedef String<32> Version;
Version const version = blueprint.attribute_value("version", Version());
if (version == Version(_depot_query.depot_query_version().value))
return _children.apply_blueprint(_blueprint_rom.xml());
using Version = String<32>;
Version const version = blueprint.attribute_value("version", Version());
if (version == Version(_depot_query.depot_query_version().value))
progress = _children.apply_blueprint(blueprint);
});
}
catch (...) {
error("spurious exception during deploy update (apply_blueprint)"); }
return false;
return progress;
};
bool const blueprint_affected_child = apply_blueprint();
@ -184,21 +185,22 @@ void Sculpt::Deploy::gen_runtime_start_nodes(Xml_generator &xml,
xml.node("start", [&] {
gen_depot_query_start_content(xml); });
Xml_node const managed_deploy = _managed_deploy_rom.xml();
_managed_deploy_rom.with_xml([&] (Xml_node const &managed_deploy) {
/* insert content of '<static>' node as is */
if (managed_deploy.has_sub_node("static")) {
Xml_node static_config = managed_deploy.sub_node("static");
static_config.with_raw_content([&] (char const *start, size_t length) {
xml.append(start, length); });
}
/* insert content of '<static>' node as is */
if (managed_deploy.has_sub_node("static")) {
Xml_node static_config = managed_deploy.sub_node("static");
static_config.with_raw_content([&] (char const *start, size_t length) {
xml.append(start, length); });
}
/* generate start nodes for deployed packages */
if (managed_deploy.has_sub_node("common_routes")) {
_children.gen_start_nodes(xml, managed_deploy.sub_node("common_routes"),
prio_levels, affinity_space,
"depot_rom", "dynamic_depot_rom");
xml.node("monitor", [&] {
_children.gen_monitor_policy_nodes(xml);});
}
/* generate start nodes for deployed packages */
if (managed_deploy.has_sub_node("common_routes")) {
_children.gen_start_nodes(xml, managed_deploy.sub_node("common_routes"),
prio_levels, affinity_space,
"depot_rom", "dynamic_depot_rom");
xml.node("monitor", [&] {
_children.gen_monitor_policy_nodes(xml);});
}
});
}

View File

@ -53,8 +53,8 @@ struct Sculpt::Deploy
Depot_query &_depot_query;
Attached_rom_dataspace const &_launcher_listing_rom;
Attached_rom_dataspace const &_blueprint_rom;
Rom_data const &_launcher_listing_rom;
Rom_data const &_blueprint_rom;
Download_queue &_download_queue;
@ -78,7 +78,8 @@ struct Sculpt::Deploy
Expanding_reporter _managed_deploy_config { _env, "config", "deploy_config" };
/* config obtained from '/config/managed/deploy' */
Attached_rom_dataspace _managed_deploy_rom { _env, "config -> managed/deploy" };
Rom_handler<Deploy> _managed_deploy_rom {
_env, "config -> managed/deploy", *this, &Deploy::_handle_managed_deploy };
Constructible<Buffered_xml> _template { };
@ -187,7 +188,7 @@ struct Sculpt::Deploy
Managed_config<Deploy> _installation {
_env, "installation", "installation", *this, &Deploy::_handle_installation };
void _handle_installation(Xml_node manual_config)
void _handle_installation(Xml_node const &manual_config)
{
_manual_installation_scheduled = manual_config.has_sub_node("archive");
handle_deploy();
@ -201,12 +202,12 @@ struct Sculpt::Deploy
|| _download_queue.any_active_download();
}
void handle_deploy();
void _handle_managed_deploy(Xml_node const &);
void _handle_managed_deploy()
void handle_deploy()
{
_managed_deploy_rom.update();
handle_deploy();
_managed_deploy_rom.with_xml([&] (Xml_node const &managed_deploy) {
_handle_managed_deploy(managed_deploy); });
}
/**
@ -254,9 +255,6 @@ struct Sculpt::Deploy
void gen_runtime_start_nodes(Xml_generator &, Prio_levels, Affinity::Space) const;
Signal_handler<Deploy> _managed_deploy_handler {
_env.ep(), *this, &Deploy::_handle_managed_deploy };
void restart()
{
/* ignore stale query results */
@ -296,8 +294,8 @@ struct Sculpt::Deploy
Action &action,
Runtime_config_generator &runtime_config_generator,
Depot_query &depot_query,
Attached_rom_dataspace const &launcher_listing_rom,
Attached_rom_dataspace const &blueprint_rom,
Rom_data const &launcher_listing_rom,
Rom_data const &blueprint_rom,
Download_queue &download_queue)
:
_env(env), _alloc(alloc), _child_states(child_states),
@ -308,9 +306,7 @@ struct Sculpt::Deploy
_launcher_listing_rom(launcher_listing_rom),
_blueprint_rom(blueprint_rom),
_download_queue(download_queue)
{
_managed_deploy_rom.sigh(_managed_deploy_handler);
}
{ }
};
#endif /* _DEPLOY_H_ */

View File

@ -20,6 +20,9 @@
#include <util/color.h>
#include <dialog/types.h>
/* local includes */
#include <xml.h>
namespace Dialog { struct Distant_runtime; }
@ -116,10 +119,9 @@ class Dialog::Distant_runtime::View : private Views::Element
Expanding_reporter _dialog_reporter {
_env, "dialog", { _dialog.name, "_dialog" } };
Attached_rom_dataspace _hover_rom {
_env, Session_label::String(_dialog.name, "_view_hover").string() };
Signal_handler<View> _hover_handler { _env.ep(), *this, &View::_handle_hover };
Sculpt::Rom_handler<View> _hover_rom {
_env, Session_label::String(_dialog.name, "_view_hover").string(),
*this, &View::_handle_hover };
bool _dialog_hovered = false; /* used to cut hover feedback loop */
@ -129,20 +131,17 @@ class Dialog::Distant_runtime::View : private Views::Element
{
bool done = false;
_hover_rom.xml().with_optional_sub_node("dialog", [&] (Xml_node const &dialog) {
fn(dialog);
done = true; });
_hover_rom.with_xml([&] (Xml_node const &hover) {
hover.with_optional_sub_node("dialog", [&] (Xml_node const &dialog) {
fn(dialog);
done = true; }); });
if (!done)
fn(Xml_node("<empty/>"));
}
void _handle_hover()
void _handle_hover(Xml_node const &hover)
{
_hover_rom.update();
Xml_node const hover = _hover_rom.xml();
bool const orig_dialog_hovered = _dialog_hovered;
_hover_seq_number = { hover.attribute_value("seq_number", 0U) };
@ -241,7 +240,6 @@ class Dialog::Distant_runtime::View : private Views::Element
_initial_ram(attr.initial_ram), _opaque(attr.opaque),
_background(attr.background)
{
_hover_rom.sigh(_hover_handler);
_refresh_handler.local_submit();
}

View File

@ -29,22 +29,12 @@ struct Sculpt::Ahci_driver : private Noncopyable
Constructible<Child_state> _ahci { };
Attached_rom_dataspace _ports { _env, "report -> runtime/ahci/ports" };
Rom_handler<Ahci_driver> _ports {
_env, "report -> runtime/ahci/ports", *this, &Ahci_driver::_handle_ports };
Signal_handler<Ahci_driver> _ports_handler {
_env.ep(), *this, &Ahci_driver::_handle_ports };
void _handle_ports(Xml_node const &) { _action.handle_ahci_discovered(); }
void _handle_ports()
{
_ports.update();
_action.handle_ahci_discovered();
}
Ahci_driver(Env &env, Action &action) : _env(env), _action(action)
{
_ports.sigh(_ports_handler);
_ports_handler.local_submit();
}
Ahci_driver(Env &env, Action &action) : _env(env), _action(action) { }
void gen_start_node(Xml_generator &xml) const
{
@ -81,7 +71,8 @@ struct Sculpt::Ahci_driver : private Noncopyable
void with_ports(auto const &fn) const
{
fn(_ahci.constructed() ? _ports.xml() : Xml_node("<none/>"));
_ports.with_xml([&] (Xml_node const &ports) {
fn(_ahci.constructed() ? ports : Xml_node("<none/>")); });
}
};

View File

@ -29,22 +29,12 @@ struct Sculpt::Mmc_driver : private Noncopyable
Constructible<Child_state> _mmc { };
Attached_rom_dataspace _devices { _env, "report -> runtime/mmc/block_devices" };
Rom_handler<Mmc_driver> _devices {
_env, "report -> runtime/mmc/block_devices", *this, &Mmc_driver::_handle_devices };
Signal_handler<Mmc_driver> _devices_handler {
_env.ep(), *this, &Mmc_driver::_handle_devices };
void _handle_devices(Xml_node const &) { _action.handle_mmc_discovered(); }
void _handle_devices()
{
_devices.update();
_action.handle_mmc_discovered();
}
Mmc_driver(Env &env, Action &action) : _env(env), _action(action)
{
_devices.sigh(_devices_handler);
_devices_handler.local_submit();
}
Mmc_driver(Env &env, Action &action) : _env(env), _action(action) { }
void gen_start_node(Xml_generator &xml) const
{
@ -79,7 +69,8 @@ struct Sculpt::Mmc_driver : private Noncopyable
void with_devices(auto const &fn) const
{
fn(_mmc.constructed() ? _devices.xml() : Xml_node("<none/>"));
_devices.with_xml([&] (Xml_node const &devices) {
fn(_mmc.constructed() ? devices : Xml_node("<none/>")); });
}
};

View File

@ -29,22 +29,12 @@ struct Sculpt::Nvme_driver : private Noncopyable
Constructible<Child_state> _nvme { };
Attached_rom_dataspace _namespaces { _env, "report -> runtime/nvme/controller" };
Rom_handler<Nvme_driver> _namespaces {
_env, "report -> runtime/nvme/controller", *this, &Nvme_driver::_handle_namespaces };
Signal_handler<Nvme_driver> _namespaces_handler {
_env.ep(), *this, &Nvme_driver::_handle_namespaces };
void _handle_namespaces(Xml_node const &) { _action.handle_nvme_discovered(); }
void _handle_namespaces()
{
_namespaces.update();
_action.handle_nvme_discovered();
}
Nvme_driver(Env &env, Action &action) : _env(env), _action(action)
{
_namespaces.sigh(_namespaces_handler);
_namespaces_handler.local_submit();
}
Nvme_driver(Env &env, Action &action) : _env(env), _action(action) { }
void gen_start_node(Xml_generator &xml) const
{
@ -80,7 +70,8 @@ struct Sculpt::Nvme_driver : private Noncopyable
void with_namespaces(auto const &fn) const
{
fn(_nvme.constructed() ? _namespaces.xml() : Xml_node("<none/>"));
_namespaces.with_xml([&] (Xml_node const &namespaces) {
fn(_nvme.constructed() ? namespaces : Xml_node("<none/>")); });
}
};

View File

@ -57,22 +57,19 @@ struct Sculpt::Usb_driver : private Noncopyable
} _detected { };
Attached_rom_dataspace _devices { _env, "report -> runtime/usb/devices" };
Rom_handler<Usb_driver> _devices {
_env, "report -> runtime/usb/devices", *this, &Usb_driver::_handle_devices };
Signal_handler<Usb_driver> _devices_handler {
_env.ep(), *this, &Usb_driver::_handle_devices };
void _handle_devices()
void _handle_devices(Xml_node const &devices)
{
_devices.update();
_detected = Detected::from_xml(_devices.xml());
_detected = Detected::from_xml(devices);
_action.handle_usb_plug_unplug();
}
Managed_config<Usb_driver> _usb_config {
_env, "config", "usb", *this, &Usb_driver::_handle_usb_config };
void _handle_usb_config(Xml_node config)
void _handle_usb_config(Xml_node const &config)
{
_usb_config.generate([&] (Xml_generator &xml) {
copy_attributes(xml, config);
@ -97,9 +94,7 @@ struct Sculpt::Usb_driver : private Noncopyable
:
_env(env), _info(info), _action(action)
{
_devices.sigh(_devices_handler);
_usb_config.trigger_update();
_devices_handler.local_submit();
}
void gen_start_nodes(Xml_generator &xml) const
@ -180,7 +175,8 @@ struct Sculpt::Usb_driver : private Noncopyable
void with_devices(auto const &fn) const
{
fn(_hcd.constructed() ? _devices.xml() : Xml_node("<none/>"));
_devices.with_xml([&] (Xml_node const &devices) {
fn(_hcd.constructed() ? devices : Xml_node("<none/>")); });
}
};

View File

@ -55,16 +55,12 @@ class Sculpt::Drivers::Instance : Noncopyable,
Attached_rom_dataspace const _platform { _env, "platform_info" };
Attached_rom_dataspace _devices { _env, "report -> drivers/devices" };
Rom_handler<Instance> _devices {
_env, "report -> drivers/devices", *this, &Instance::_handle_devices };
Signal_handler<Instance> _devices_handler {
_env.ep(), *this, &Instance::_handle_devices };
void _handle_devices()
void _handle_devices(Xml_node const &devices)
{
_devices.update();
_board_info.detected = Board_info::Detected::from_xml(_devices.xml(),
_board_info.detected = Board_info::Detected::from_xml(devices,
_platform.xml());
_fb_driver .update(_children, _board_info, _platform.xml());
@ -79,6 +75,12 @@ class Sculpt::Drivers::Instance : Noncopyable,
_action.handle_device_plug_unplug();
}
void _handle_devices()
{
_devices.with_xml([&] (Xml_node const &devices) {
_handle_devices(devices); });
}
Ps2_driver _ps2_driver { };
Touch_driver _touch_driver { };
Fb_driver _fb_driver { };
@ -104,10 +106,7 @@ class Sculpt::Drivers::Instance : Noncopyable,
Instance(Env &env, Children &children, Info const &info, Action &action)
:
_env(env), _children(children), _info(info), _action(action)
{
_devices.sigh(_devices_handler);
_devices_handler.local_submit();
}
{ }
void update_usb() { _usb_driver.update(_children, _board_info); }

View File

@ -109,7 +109,7 @@ struct Sculpt::Main : Input_event_handler,
Managed_config<Main> _system_config {
_env, "system", "system", *this, &Main::_handle_system_config };
void _handle_system_config(Xml_node)
void _handle_system_config(Xml_node const &)
{
_system_config.try_generate_manually_managed();
}
@ -132,7 +132,7 @@ struct Sculpt::Main : Input_event_handler,
Managed_config<Main> _fonts_config {
_env, "config", "fonts", *this, &Main::_handle_fonts_config };
void _handle_fonts_config(Xml_node config)
void _handle_fonts_config(Xml_node const &config)
{
/*
* Obtain font size from manually maintained fonts configuration
@ -164,7 +164,7 @@ struct Sculpt::Main : Input_event_handler,
void _generate_event_filter_config(Xml_generator &);
void _handle_event_filter_config(Xml_node)
void _handle_event_filter_config(Xml_node const &)
{
_update_event_filter_config();
}
@ -371,13 +371,10 @@ struct Sculpt::Main : Input_event_handler,
** Update **
************/
Attached_rom_dataspace _update_state_rom {
_env, "report -> runtime/update/state" };
Rom_handler<Main> _update_state_rom {
_env, "report -> runtime/update/state", *this, &Main::_handle_update_state };
void _handle_update_state();
Signal_handler<Main> _update_state_handler {
_env.ep(), *this, &Main::_handle_update_state };
void _handle_update_state(Xml_node const &);
/**
* Condition for spawning the update subsystem
@ -440,18 +437,19 @@ struct Sculpt::Main : Input_event_handler,
xml.node("scan", [&] {
xml.attribute("users", "yes"); });
if (_system_dialog_watches_depot() || _scan_rom.xml().has_type("empty"))
if (_system_dialog_watches_depot() || !_scan_rom.valid())
xml.node("scan", [&] {
xml.attribute("users", "yes"); });
if (_system_dialog_watches_depot() || _image_index_rom.xml().has_type("empty"))
if (_system_dialog_watches_depot() || !_image_index_rom.valid())
xml.node("image_index", [&] {
xml.attribute("os", "sculpt");
xml.attribute("board", _build_info.board);
xml.attribute("user", _image_index_user);
});
_popup_dialog.gen_depot_query(xml, _scan_rom.xml());
_scan_rom.with_xml([&] (Xml_node const &scan) {
_popup_dialog.gen_depot_query(xml, scan); });
/* update query for blueprints of all unconfigured start nodes */
_deploy.gen_depot_query(xml);
@ -479,17 +477,11 @@ struct Sculpt::Main : Input_event_handler,
** Blueprint query **
*********************/
Attached_rom_dataspace _blueprint_rom { _env, "report -> runtime/depot_query/blueprint" };
Rom_handler<Main> _blueprint_rom {
_env, "report -> runtime/depot_query/blueprint", *this, &Main::_handle_blueprint };
Signal_handler<Main> _blueprint_handler {
_env.ep(), *this, &Main::_handle_blueprint };
void _handle_blueprint()
void _handle_blueprint(Xml_node const &blueprint)
{
_blueprint_rom.update();
Xml_node const blueprint = _blueprint_rom.xml();
/*
* Drop intermediate results that will be superseded by a newer query.
* This is important because an outdated blueprint would be disregarded
@ -513,41 +505,29 @@ struct Sculpt::Main : Input_event_handler,
Deploy::Prio_levels const _prio_levels { 4 };
Attached_rom_dataspace _scan_rom { _env, "report -> runtime/depot_query/scan" };
Rom_handler<Main> _scan_rom {
_env, "report -> runtime/depot_query/scan", *this, &Main::_handle_scan };
Signal_handler<Main> _scan_handler { _env.ep(), *this, &Main::_handle_scan };
void _handle_scan()
void _handle_scan(Xml_node const &)
{
_scan_rom.update();
_popup_dialog.depot_users_scan_updated();
_system_dialog.sanitize_user_selection();
}
Attached_rom_dataspace _image_index_rom { _env, "report -> runtime/depot_query/image_index" };
Rom_handler<Main> _image_index_rom {
_env, "report -> runtime/depot_query/image_index", *this, &Main::_handle_image_index };
Signal_handler<Main> _image_index_handler { _env.ep(), *this, &Main::_handle_image_index };
void _handle_image_index()
{
_image_index_rom.update();
_system_dialog.refresh();
}
Attached_rom_dataspace _launcher_listing_rom {
_env, "report -> /runtime/launcher_query/listing" };
void _handle_image_index(Xml_node const &) { _system_dialog.refresh(); }
Launchers _launchers { _heap };
Presets _presets { _heap };
Signal_handler<Main> _launcher_and_preset_listing_handler {
_env.ep(), *this, &Main::_handle_launcher_and_preset_listing };
Rom_handler<Main> _launcher_listing_rom {
_env, "report -> /runtime/launcher_query/listing", *this,
&Main::_handle_launcher_and_preset_listing };
void _handle_launcher_and_preset_listing()
void _handle_launcher_and_preset_listing(Xml_node const &listing)
{
_launcher_listing_rom.update();
Xml_node const listing = _launcher_listing_rom.xml();
listing.for_each_sub_node("dir", [&] (Xml_node const &dir) {
Path const dir_path = dir.attribute_value("path", Path());
@ -560,7 +540,7 @@ struct Sculpt::Main : Input_event_handler,
});
_popup_dialog.refresh();
_deploy._handle_managed_deploy();
_deploy.handle_deploy();
}
Deploy _deploy { _env, _heap, _child_states, _runtime_state, *this, *this, *this,
@ -571,19 +551,16 @@ struct Sculpt::Main : Input_event_handler,
*/
void refresh_deploy_dialog() override { _generate_dialog(); }
Attached_rom_dataspace _manual_deploy_rom { _env, "config -> deploy" };
Rom_handler<Main> _manual_deploy_rom {
_env, "config -> deploy", *this, &Main::_handle_manual_deploy };
void _handle_manual_deploy()
void _handle_manual_deploy(Xml_node const &manual_deploy)
{
_runtime_state.reset_abandoned_and_launched_children();
_manual_deploy_rom.update();
_deploy.use_as_deploy_template(_manual_deploy_rom.xml());
_deploy.use_as_deploy_template(manual_deploy);
_deploy.update_managed_deploy_config();
}
Signal_handler<Main> _manual_deploy_handler {
_env.ep(), *this, &Main::_handle_manual_deploy };
/************
** Global **
@ -606,7 +583,8 @@ struct Sculpt::Main : Input_event_handler,
File_browser_state _file_browser_state { };
Attached_rom_dataspace _editor_saved_rom { _env, "report -> runtime/editor/saved" };
Rom_handler<Main> _editor_saved_rom {
_env, "report -> runtime/editor/saved", *this, &Main::_handle_editor_saved };
Affinity::Space _affinity_space { 1, 1 };
@ -661,17 +639,18 @@ struct Sculpt::Main : Input_event_handler,
});
}
Xml_node const state = _main._update_state_rom.xml();
_main._update_state_rom.with_xml([&] (Xml_node const &state) {
bool const download_in_progress =
_main._update_running() && state.attribute_value("progress", false);
bool const download_in_progress =
_main._update_running() && state.attribute_value("progress", false);
if (download_in_progress || _main._download_queue.any_failed_download()) {
if (download_in_progress || _main._download_queue.any_failed_download()) {
Hosted<Vbox, Download_status_widget> download_status { Id { "Download" } };
Hosted<Vbox, Download_status_widget> download_status { Id { "Download" } };
s.widget(download_status, state, _main._download_queue);
}
s.widget(download_status, state, _main._download_queue);
}
});
});
}
};
@ -685,7 +664,10 @@ struct Sculpt::Main : Input_event_handler,
_system_dialog.refresh();
}
Attached_rom_dataspace _runtime_state_rom { _env, "report -> runtime/state" };
Rom_handler<Main> _runtime_state_rom {
_env, "report -> runtime/state", *this, &Main::_handle_runtime_state };
void _handle_runtime_state(Xml_node const &);
Runtime_state _runtime_state { _heap, _storage._sculpt_partition };
@ -694,7 +676,7 @@ struct Sculpt::Main : Input_event_handler,
bool _manually_managed_runtime = false;
void _handle_runtime(Xml_node config)
void _handle_runtime(Xml_node const &config)
{
_manually_managed_runtime = !config.has_type("empty");
generate_runtime_config();
@ -713,11 +695,6 @@ struct Sculpt::Main : Input_event_handler,
_generate_runtime_config(xml); });
}
Signal_handler<Main> _runtime_state_handler {
_env.ep(), *this, &Main::_handle_runtime_state };
void _handle_runtime_state();
/****************************************
** Cached model of the runtime config **
@ -728,17 +705,14 @@ struct Sculpt::Main : Input_event_handler,
* manager, we still obtain it as a separate ROM session to keep the GUI
* part decoupled from the lower-level runtime configuration generator.
*/
Attached_rom_dataspace _runtime_config_rom { _env, "config -> managed/runtime" };
Signal_handler<Main> _runtime_config_handler {
_env.ep(), *this, &Main::_handle_runtime_config };
Rom_handler<Main> _runtime_config_rom {
_env, "config -> managed/runtime", *this, &Main::_handle_runtime_config };
Runtime_config _cached_runtime_config { _heap };
void _handle_runtime_config()
void _handle_runtime_config(Xml_node const &runtime_config)
{
_runtime_config_rom.update();
_cached_runtime_config.update_from_xml(_runtime_config_rom.xml());
_cached_runtime_config.update_from_xml(runtime_config);
_graph_view.refresh();
if (_selected_tab == Panel_dialog::Tab::FILES)
@ -834,7 +808,7 @@ struct Sculpt::Main : Input_event_handler,
/* hide system panel button and system dialog when "un-using" */
_panel_dialog.refresh();
_system_dialog.refresh();
_handle_window_layout();
_update_window_layout();
generate_runtime_config();
}
@ -939,13 +913,13 @@ struct Sculpt::Main : Input_event_handler,
_popup.anchor = anchor;
_popup.state = Popup::VISIBLE;
_graph_view.refresh();
_handle_window_layout();
_update_window_layout();
}
void _refresh_panel_and_window_layout()
{
_panel_dialog.refresh();
_handle_window_layout();
_update_window_layout();
}
/**
@ -1062,18 +1036,17 @@ struct Sculpt::Main : Input_event_handler,
*/
void load_deploy_preset(Presets::Info::Name const &name) override
{
Xml_node const listing = _launcher_listing_rom.xml();
_download_queue.remove_inactive_downloads();
listing.for_each_sub_node("dir", [&] (Xml_node const &dir) {
if (dir.attribute_value("path", Path()) == "/presets") {
dir.for_each_sub_node("file", [&] (Xml_node const &file) {
if (file.attribute_value("name", Presets::Info::Name()) == name) {
file.with_optional_sub_node("config", [&] (Xml_node const &config) {
_runtime_state.reset_abandoned_and_launched_children();
_deploy.use_as_deploy_template(config);
_deploy.update_managed_deploy_config(); }); } }); } });
_launcher_listing_rom.with_xml([&] (Xml_node const &listing) {
listing.for_each_sub_node("dir", [&] (Xml_node const &dir) {
if (dir.attribute_value("path", Path()) == "/presets") {
dir.for_each_sub_node("file", [&] (Xml_node const &file) {
if (file.attribute_value("name", Presets::Info::Name()) == name) {
file.with_optional_sub_node("config", [&] (Xml_node const &config) {
_runtime_state.reset_abandoned_and_launched_children();
_deploy.use_as_deploy_template(config);
_deploy.update_managed_deploy_config(); }); } }); } }); });
}
struct Settings_top_level_dialog : Top_level_dialog
@ -1131,15 +1104,8 @@ struct Sculpt::Main : Input_event_handler,
_file_browser_dialog.refresh();
}
Signal_handler<Main> _editor_saved_handler {
_env.ep(), *this, &Main::_handle_editor_saved };
void _handle_editor_saved()
void _handle_editor_saved(Xml_node const &saved)
{
_editor_saved_rom.update();
Xml_node const saved = _editor_saved_rom.xml();
bool const orig_modified = _file_browser_state.modified;
_file_browser_state.modified = saved.attribute_value("modified", false);
@ -1278,7 +1244,7 @@ struct Sculpt::Main : Input_event_handler,
_popup_dialog.refresh();
/* remove popup window from window layout */
_handle_window_layout();
_update_window_layout();
/* reset state of the '+' button */
_graph_view.refresh();
@ -1384,12 +1350,33 @@ struct Sculpt::Main : Input_event_handler,
Managed_config<Main> _fb_drv_config {
_env, "config", "fb_drv", *this, &Main::_handle_fb_drv_config };
void _handle_fb_drv_config(Xml_node)
void _handle_fb_drv_config(Xml_node const &)
{
_fb_drv_config.try_generate_manually_managed();
}
void _handle_window_layout();
void _update_window_layout(Xml_node const &, Xml_node const &);
void _update_window_layout()
{
_decorator_margins.with_xml([&] (Xml_node const &decorator_margins) {
_window_list.with_xml([&] (Xml_node const &window_list) {
_update_window_layout(decorator_margins, window_list); }); });
}
void _handle_window_layout_or_decorator_margins(Xml_node const &)
{
_update_window_layout();
}
Rom_handler<Main> _window_list {
_env, "window_list", *this, &Main::_handle_window_layout_or_decorator_margins };
Rom_handler<Main> _decorator_margins {
_env, "decorator_margins", *this, &Main::_handle_window_layout_or_decorator_margins };
Expanding_reporter _wm_focus { _env, "focus", "wm_focus" };
Expanding_reporter _window_layout { _env, "window_layout", "window_layout" };
template <size_t N>
void _with_window(Xml_node window_list, String<N> const &match, auto const &fn)
@ -1399,20 +1386,6 @@ struct Sculpt::Main : Input_event_handler,
fn(win); });
}
Attached_rom_dataspace _window_list { _env, "window_list" };
Signal_handler<Main> _window_list_handler {
_env.ep(), *this, &Main::_handle_window_layout };
Expanding_reporter _wm_focus { _env, "focus", "wm_focus" };
Attached_rom_dataspace _decorator_margins { _env, "decorator_margins" };
Signal_handler<Main> _decorator_margins_handler {
_env.ep(), *this, &Main::_handle_window_layout };
Expanding_reporter _window_layout { _env, "window_layout", "window_layout" };
/*******************
** Runtime graph **
@ -1450,23 +1423,9 @@ struct Sculpt::Main : Input_event_handler,
Main(Env &env) : _env(env)
{
_manual_deploy_rom.sigh(_manual_deploy_handler);
_runtime_state_rom.sigh(_runtime_state_handler);
_runtime_config_rom.sigh(_runtime_config_handler);
_gui.input()->sigh(_input_handler);
_gui.mode_sigh(_gui_mode_handler);
/*
* Subscribe to reports
*/
_update_state_rom .sigh(_update_state_handler);
_window_list .sigh(_window_list_handler);
_decorator_margins .sigh(_decorator_margins_handler);
_scan_rom .sigh(_scan_handler);
_launcher_listing_rom.sigh(_launcher_and_preset_listing_handler);
_blueprint_rom .sigh(_blueprint_handler);
_image_index_rom .sigh(_image_index_handler);
_editor_saved_rom .sigh(_editor_saved_handler);
_handle_gui_mode();
/*
* Generate initial configurations
@ -1474,12 +1433,7 @@ struct Sculpt::Main : Input_event_handler,
_network.wifi_disconnect();
_update_event_filter_config();
/*
* Import initial report content
*/
_handle_gui_mode();
_handle_storage_devices();
_handle_runtime_config();
/*
* Read static platform information
@ -1492,15 +1446,14 @@ struct Sculpt::Main : Input_event_handler,
/*
* Generate initial config/managed/deploy configuration
*/
_handle_manual_deploy();
generate_runtime_config();
_generate_dialog();
}
};
void Sculpt::Main::_handle_window_layout()
void Sculpt::Main::_update_window_layout(Xml_node const &decorator_margins,
Xml_node const &window_list)
{
/* skip window-layout handling (and decorator activity) while booting */
if (!_gui_mode_ready)
@ -1510,23 +1463,18 @@ void Sculpt::Main::_handle_window_layout()
{
unsigned top = 0, bottom = 0, left = 0, right = 0;
Decorator_margins(Xml_node node)
Decorator_margins(Xml_node const &node)
{
if (!node.has_sub_node("floating"))
return;
Xml_node const floating = node.sub_node("floating");
top = floating.attribute_value("top", 0U);
bottom = floating.attribute_value("bottom", 0U);
left = floating.attribute_value("left", 0U);
right = floating.attribute_value("right", 0U);
node.with_optional_sub_node("floating", [&] (Xml_node const &floating) {
top = floating.attribute_value("top", 0U);
bottom = floating.attribute_value("bottom", 0U);
left = floating.attribute_value("left", 0U);
right = floating.attribute_value("right", 0U);
});
}
};
/* read decorator margins from the decorator's report */
_decorator_margins.update();
Decorator_margins const margins(_decorator_margins.xml());
Decorator_margins const margins { decorator_margins };
unsigned const log_min_w = 400;
@ -1544,9 +1492,6 @@ void Sculpt::Main::_handle_window_layout()
editor_view_label ("runtime -> leitzentrale -> editor"),
logo_label ("logo");
_window_list.update();
Xml_node const window_list = _window_list.xml();
auto win_size = [&] (Xml_node win) { return Area::from_xml(win); };
unsigned panel_height = 0;
@ -1586,7 +1531,7 @@ void Sculpt::Main::_handle_window_layout()
_window_layout.generate([&] (Xml_generator &xml) {
auto gen_window = [&] (Xml_node win, Rect rect) {
auto gen_window = [&] (Xml_node const &win, Rect rect) {
if (rect.valid()) {
xml.node("window", [&] {
xml.attribute("id", win.attribute_value("id", 0UL));
@ -1600,7 +1545,7 @@ void Sculpt::Main::_handle_window_layout()
};
/* window size limited to space unobstructed by the menu and log */
auto constrained_win_size = [&] (Xml_node win) {
auto constrained_win_size = [&] (Xml_node const &win) {
unsigned const inspect_w = inspect_p2.x() - inspect_p1.x(),
inspect_h = inspect_p2.y() - inspect_p1.y();
@ -1609,15 +1554,15 @@ void Sculpt::Main::_handle_window_layout()
return Area(min(inspect_w, size.w()), min(inspect_h, size.h()));
};
_with_window(window_list, panel_view_label, [&] (Xml_node win) {
_with_window(window_list, panel_view_label, [&] (Xml_node const &win) {
gen_window(win, panel); });
_with_window(window_list, Label("log"), [&] (Xml_node win) {
_with_window(window_list, Label("log"), [&] (Xml_node const &win) {
gen_window(win, Rect(log_p1, log_p2)); });
int system_right_xpos = 0;
if (system_available()) {
_with_window(window_list, system_view_label, [&] (Xml_node win) {
_with_window(window_list, system_view_label, [&] (Xml_node const &win) {
Area const size = win_size(win);
Point const pos = _system_visible
? Point(0, avail.y1())
@ -1629,7 +1574,7 @@ void Sculpt::Main::_handle_window_layout()
});
}
_with_window(window_list, settings_view_label, [&] (Xml_node win) {
_with_window(window_list, settings_view_label, [&] (Xml_node const &win) {
Area const size = win_size(win);
Point const pos = _settings_visible
? Point(system_right_xpos, avail.y1())
@ -1639,7 +1584,7 @@ void Sculpt::Main::_handle_window_layout()
gen_window(win, Rect(pos, size));
});
_with_window(window_list, network_view_label, [&] (Xml_node win) {
_with_window(window_list, network_view_label, [&] (Xml_node const &win) {
Area const size = win_size(win);
Point const pos = _network_visible
? Point(log_p1.x() - size.w(), avail.y1())
@ -1647,7 +1592,7 @@ void Sculpt::Main::_handle_window_layout()
gen_window(win, Rect(pos, size));
});
_with_window(window_list, file_browser_view_label, [&] (Xml_node win) {
_with_window(window_list, file_browser_view_label, [&] (Xml_node const &win) {
if (_selected_tab == Panel_dialog::Tab::FILES) {
Area const size = constrained_win_size(win);
@ -1661,7 +1606,7 @@ void Sculpt::Main::_handle_window_layout()
}
});
_with_window(window_list, editor_view_label, [&] (Xml_node win) {
_with_window(window_list, editor_view_label, [&] (Xml_node const &win) {
if (_selected_tab == Panel_dialog::Tab::FILES) {
Area const size = constrained_win_size(win);
Point const pos = Rect(inspect_p1 + Point(400, 0), inspect_p2).center(size);
@ -1674,7 +1619,7 @@ void Sculpt::Main::_handle_window_layout()
}
});
_with_window(window_list, diag_view_label, [&] (Xml_node win) {
_with_window(window_list, diag_view_label, [&] (Xml_node const &win) {
if (_selected_tab == Panel_dialog::Tab::COMPONENTS) {
Area const size = win_size(win);
Point const pos(0, avail.y2() - size.h());
@ -1687,13 +1632,13 @@ void Sculpt::Main::_handle_window_layout()
* area.
*/
Point runtime_view_pos { };
_with_window(window_list, runtime_view_label, [&] (Xml_node win) {
_with_window(window_list, runtime_view_label, [&] (Xml_node const &win) {
Area const size = constrained_win_size(win);
runtime_view_pos = Rect(inspect_p1, inspect_p2).center(size);
});
if (_popup.state == Popup::VISIBLE) {
_with_window(window_list, popup_view_label, [&] (Xml_node win) {
_with_window(window_list, popup_view_label, [&] (Xml_node const &win) {
Area const size = win_size(win);
int const anchor_y_center = (_popup.anchor.y1() + _popup.anchor.y2())/2;
@ -1705,7 +1650,7 @@ void Sculpt::Main::_handle_window_layout()
});
}
_with_window(window_list, inspect_label, [&] (Xml_node win) {
_with_window(window_list, inspect_label, [&] (Xml_node const &win) {
if (_selected_tab == Panel_dialog::Tab::INSPECT)
gen_window(win, Rect(inspect_p1, inspect_p2)); });
@ -1713,11 +1658,11 @@ void Sculpt::Main::_handle_window_layout()
* Position runtime view centered within the inspect area, but allow
* the overlapping of the log area. (use the menu view's 'win_size').
*/
_with_window(window_list, runtime_view_label, [&] (Xml_node win) {
_with_window(window_list, runtime_view_label, [&] (Xml_node const &win) {
if (_selected_tab == Panel_dialog::Tab::COMPONENTS)
gen_window(win, Rect(runtime_view_pos, win_size(win))); });
_with_window(window_list, logo_label, [&] (Xml_node win) {
_with_window(window_list, logo_label, [&] (Xml_node const &win) {
Area const size = win_size(win);
Point const pos(mode.area.w() - size.w(), mode.area.h() - size.h());
gen_window(win, Rect(pos, size));
@ -1727,16 +1672,18 @@ void Sculpt::Main::_handle_window_layout()
/* define window-manager focus */
_wm_focus.generate([&] (Xml_generator &xml) {
_window_list.xml().for_each_sub_node("window", [&] (Xml_node win) {
Label const label = win.attribute_value("label", Label());
_window_list.with_xml([&] (Xml_node const &list) {
list.for_each_sub_node("window", [&] (Xml_node const &win) {
Label const label = win.attribute_value("label", Label());
if (label == inspect_label && _selected_tab == Panel_dialog::Tab::INSPECT)
xml.node("window", [&] {
xml.attribute("id", win.attribute_value("id", 0UL)); });
if (label == inspect_label && _selected_tab == Panel_dialog::Tab::INSPECT)
xml.node("window", [&] {
xml.attribute("id", win.attribute_value("id", 0UL)); });
if (label == editor_view_label && _selected_tab == Panel_dialog::Tab::FILES)
xml.node("window", [&] {
xml.attribute("id", win.attribute_value("id", 0UL)); });
if (label == editor_view_label && _selected_tab == Panel_dialog::Tab::FILES)
xml.node("window", [&] {
xml.attribute("id", win.attribute_value("id", 0UL)); });
});
});
});
}
@ -1749,7 +1696,7 @@ void Sculpt::Main::_handle_gui_mode()
if (mode.area.count() > 1)
_gui_mode_ready = true;
_handle_window_layout();
_update_window_layout();
_settings.manual_fonts_config = _fonts_config.try_generate_manually_managed();
@ -1821,13 +1768,8 @@ void Sculpt::Main::_handle_gui_mode()
}
void Sculpt::Main::_handle_update_state()
void Sculpt::Main::_handle_update_state(Xml_node const &update_state)
{
_update_state_rom.update();
_generate_dialog();
Xml_node const update_state = _update_state_rom.xml();
_download_queue.apply_update_state(update_state);
bool const any_completed_download = _download_queue.any_completed_download();
_download_queue.remove_completed_downloads();
@ -1839,12 +1781,13 @@ void Sculpt::Main::_handle_update_state()
if (installation_complete) {
Xml_node const blueprint = _blueprint_rom.xml();
bool const new_depot_query_needed = blueprint_any_missing(blueprint)
|| blueprint_any_rom_missing(blueprint)
|| any_completed_download;
if (new_depot_query_needed)
trigger_depot_query();
_blueprint_rom.with_xml([&] (Xml_node const &blueprint) {
bool const new_depot_query_needed = blueprint_any_missing(blueprint)
|| blueprint_any_rom_missing(blueprint)
|| any_completed_download;
if (new_depot_query_needed)
trigger_depot_query();
});
_deploy.reattempt_after_installation();
}
@ -1853,12 +1796,8 @@ void Sculpt::Main::_handle_update_state()
}
void Sculpt::Main::_handle_runtime_state()
void Sculpt::Main::_handle_runtime_state(Xml_node const &state)
{
_runtime_state_rom.update();
Xml_node state = _runtime_state_rom.xml();
_runtime_state.update_from_state_report(state);
bool reconfigure_runtime = false;

View File

@ -37,7 +37,7 @@ struct Sculpt::Managed_config
HANDLER &_obj;
void (HANDLER::*_handle) (Xml_node);
void (HANDLER::*_handle) (Xml_node const &);
/*
* Configuration supplied by the user
@ -97,7 +97,7 @@ struct Sculpt::Managed_config
Managed_config(Env &env, Xml_node_name const &xml_node_name,
Rom_name const &rom_name,
HANDLER &obj, void (HANDLER::*handle) (Xml_node))
HANDLER &obj, void (HANDLER::*handle) (Xml_node const &))
:
_env(env), _obj(obj), _handle(handle),
_manual_config_rom(_env, Label("config -> ", rom_name).string()),

View File

@ -66,11 +66,9 @@ struct Sculpt::Storage_device
Partitions partitions { };
Attached_rom_dataspace _partitions {
_env, String<80>("report -> runtime/", part_block_start_name(), "/partitions").string() };
Signal_handler<Storage_device> _partitions_handler {
_env.ep(), *this, &Storage_device::_handle_partitions };
Rom_handler<Storage_device> _partitions {
_env, String<80>("report -> runtime/", part_block_start_name(), "/partitions").string(),
*this, &Storage_device::_handle_partitions };
unsigned _part_block_version = 0;
@ -102,39 +100,37 @@ struct Sculpt::Storage_device
_update_partitions_from_xml(Xml_node("<partitions/>"));
}
void _handle_partitions()
{
_partitions.update();
_action.storage_device_discovered();
}
void _handle_partitions(Xml_node const &) { _action.storage_device_discovered(); }
void process_partitions()
{
Xml_node const report = _partitions.xml();
if (!report.has_type("partitions"))
return;
_partitions.with_xml([&] (Xml_node const &report) {
whole_device = (report.attribute_value("type", String<16>()) == "disk");
if (!report.has_type("partitions"))
return;
_update_partitions_from_xml(report);
whole_device = (report.attribute_value("type", String<16>()) == "disk");
/*
* Import whole-device partition information.
*
* Ignore reports that come in while the device is in use. Otherwise,
* the reconstruction of 'whole_device_partition' would wrongly reset
* the partition state such as the 'file_system.inspected' flag.
*/
if (!whole_device_partition.constructed() || whole_device_partition->idle()) {
whole_device_partition.construct(Partition::Args::whole_device(capacity));
report.for_each_sub_node("partition", [&] (Xml_node partition) {
if (partition.attribute_value("number", Partition::Number()) == "0")
whole_device_partition.construct(Partition::Args::from_xml(partition)); });
}
_update_partitions_from_xml(report);
/* finish initial discovery phase */
if (state == UNKNOWN)
state = RELEASED;
/*
* Import whole-device partition information.
*
* Ignore reports that come in while the device is in use. Otherwise,
* the reconstruction of 'whole_device_partition' would wrongly reset
* the partition state such as the 'file_system.inspected' flag.
*/
if (!whole_device_partition.constructed() || whole_device_partition->idle()) {
whole_device_partition.construct(Partition::Args::whole_device(capacity));
report.for_each_sub_node("partition", [&] (Xml_node partition) {
if (partition.attribute_value("number", Partition::Number()) == "0")
whole_device_partition.construct(Partition::Args::from_xml(partition)); });
}
/* finish initial discovery phase */
if (state == UNKNOWN)
state = RELEASED;
});
}
Storage_device(Env &env, Allocator &alloc, Driver const &driver,
@ -142,10 +138,7 @@ struct Sculpt::Storage_device
:
_env(env), _alloc(alloc), _action(action),
driver(driver), port(port), capacity(capacity)
{
_partitions.sigh(_partitions_handler);
_partitions_handler.local_submit();
}
{ }
~Storage_device()
{

View File

@ -51,31 +51,23 @@ struct Sculpt::Usb_storage_device : List_model<Usb_storage_device>::Element,
/* information provided asynchronously by usb_block_drv */
Constructible<Driver_info> driver_info { };
Attached_rom_dataspace _report {
_env, String<80>("report -> runtime/", driver, "/devices").string() };
Rom_handler<Usb_storage_device> _report {
_env, String<80>("report -> runtime/", driver, "/devices").string(),
*this, &Usb_storage_device::_handle_report };
Signal_handler<Usb_storage_device> _report_handler {
_env.ep(), *this, &Usb_storage_device::_handle_report };
void _handle_report()
{
_report.update();
_action.storage_device_discovered();
}
void _handle_report(Xml_node const &) { _action.storage_device_discovered(); }
void process_report()
{
Xml_node report = _report.xml();
_report.with_xml([&] (Xml_node const &report) {
report.with_optional_sub_node("device", [&] (Xml_node const &device) {
if (!report.has_sub_node("device"))
return;
capacity = Capacity { device.attribute_value("block_count", 0ULL)
* device.attribute_value("block_size", 0ULL) };
Xml_node const device = report.sub_node("device");
capacity = Capacity { device.attribute_value("block_count", 0ULL)
* device.attribute_value("block_size", 0ULL) };
driver_info.construct(device);
driver_info.construct(device);
});
});
}
bool usb_block_drv_needed() const
@ -122,10 +114,7 @@ struct Sculpt::Usb_storage_device : List_model<Usb_storage_device>::Element,
:
Storage_device(env, alloc, _driver(node), Port { }, Capacity{0}, action),
_env(env)
{
_report.sigh(_report_handler);
_report_handler.local_submit();
}
{ }
inline void gen_usb_block_drv_start_content(Xml_generator &xml) const;

View File

@ -152,17 +152,15 @@ void Sculpt::Network::_generate_nic_router_config()
}
void Sculpt::Network::_handle_wlan_accesspoints()
void Sculpt::Network::_handle_wlan_accesspoints(Xml_node const &accesspoints)
{
bool const initial_scan = !_wlan_accesspoints_rom.xml().has_sub_node("accesspoint");
_wlan_accesspoints_rom.update();
bool const initial_scan = !accesspoints.has_sub_node("accesspoint");
/* suppress updating the list while the access-point list is hovered */
if (!initial_scan && _info.ap_list_hovered())
return;
_access_points.update_from_xml(_wlan_accesspoints_rom.xml(),
_access_points.update_from_xml(accesspoints,
/* create */
[&] (Xml_node const &node) -> Access_point &
@ -193,20 +191,17 @@ void Sculpt::Network::_handle_wlan_accesspoints()
}
void Sculpt::Network::_handle_wlan_state()
void Sculpt::Network::_handle_wlan_state(Xml_node const &state)
{
_wlan_state_rom.update();
_wifi_connection = Wifi_connection::from_xml(_wlan_state_rom.xml());
_wifi_connection = Wifi_connection::from_xml(state);
_action.network_config_changed();
}
void Sculpt::Network::_handle_nic_router_state()
void Sculpt::Network::_handle_nic_router_state(Xml_node const &state)
{
_nic_router_state_rom.update();
Nic_state const old_nic_state = _nic_state;
_nic_state = Nic_state::from_xml(_nic_router_state_rom.xml());
_nic_state = Nic_state::from_xml(state);
if (_nic_state.ipv4 != old_nic_state.ipv4)
_action.network_config_changed();
@ -254,7 +249,7 @@ void Sculpt::Network::_update_nic_target_from_config(Xml_node const &config)
void Sculpt::Network::_handle_nic_router_config(Xml_node config)
void Sculpt::Network::_handle_nic_router_config(Xml_node const &config)
{
_update_nic_target_from_config(config);
_generate_nic_router_config();

View File

@ -64,14 +64,14 @@ struct Sculpt::Network : Noncopyable
unsigned _nic_drv_version = 0;
unsigned _wifi_drv_version = 0;
Attached_rom_dataspace _wlan_accesspoints_rom {
_env, "report -> runtime/wifi/accesspoints" };
Rom_handler<Network> _wlan_accesspoints_rom {
_env, "report -> runtime/wifi/accesspoints", *this, &Network::_handle_wlan_accesspoints };
Attached_rom_dataspace _wlan_state_rom {
_env, "report -> runtime/wifi/state" };
Rom_handler<Network> _wlan_state_rom {
_env, "report -> runtime/wifi/state", *this, &Network::_handle_wlan_state };
Attached_rom_dataspace _nic_router_state_rom {
_env, "report -> runtime/nic_router/state" };
Rom_handler<Network> _nic_router_state_rom {
_env, "report -> runtime/nic_router/state", *this, &Network::_handle_nic_router_state };
void _generate_nic_router_config();
@ -87,23 +87,14 @@ struct Sculpt::Network : Noncopyable
void handle_key_press(Codepoint);
void _handle_wlan_accesspoints();
void _handle_wlan_state();
void _handle_nic_router_state();
void _handle_nic_router_config(Xml_node);
void _handle_wlan_accesspoints(Xml_node const &);
void _handle_wlan_state(Xml_node const &);
void _handle_nic_router_state(Xml_node const &);
void _handle_nic_router_config(Xml_node const &);
Managed_config<Network> _nic_router_config {
_env, "config", "nic_router", *this, &Network::_handle_nic_router_config };
Signal_handler<Network> _wlan_accesspoints_handler {
_env.ep(), *this, &Network::_handle_wlan_accesspoints };
Signal_handler<Network> _wlan_state_handler {
_env.ep(), *this, &Network::_handle_wlan_state };
Signal_handler<Network> _nic_router_state_handler {
_env.ep(), *this, &Network::_handle_nic_router_state };
Wlan_config_policy _wlan_config_policy = Wlan_config_policy::MANAGED;
Network_widget dialog {
@ -113,7 +104,7 @@ struct Sculpt::Network : Noncopyable
Managed_config<Network> _wlan_config {
_env, "config", "wifi", *this, &Network::_handle_wlan_config };
void _handle_wlan_config(Xml_node)
void _handle_wlan_config(Xml_node const &)
{
if (_wlan_config.try_generate_manually_managed()) {
_wlan_config_policy = Wlan_config_policy::MANUAL;
@ -213,13 +204,6 @@ struct Sculpt::Network : Noncopyable
_child_states(child_states),
_runtime_config_generator(runtime_config_generator)
{
/*
* Subscribe to reports
*/
_wlan_accesspoints_rom.sigh(_wlan_accesspoints_handler);
_wlan_state_rom .sigh(_wlan_state_handler);
_nic_router_state_rom .sigh(_nic_router_state_handler);
/*
* Evaluate and forward initial manually managed config
*/

View File

@ -25,7 +25,7 @@ struct Sculpt::Depot_users_widget : Widget<Vbox>
{
public:
using Depot_users = Attached_rom_dataspace;
using Depot_users = Rom_data;
using User = Depot::Archive::User;
using Url = Depot_url::Url;
@ -215,10 +215,8 @@ struct Sculpt::Depot_users_widget : Widget<Vbox>
return (_selected == _add_id()) ? User() : _selected;
}
void view(Scope<Vbox> &s) const
void _view(Scope<Vbox> &s, Xml_node const &depot_users) const
{
Xml_node const depot_users = _depot_users.xml();
bool known_pubkey = false;
s.sub_scope<Frame>([&] (Scope<Vbox, Frame> &s) {
@ -255,6 +253,12 @@ struct Sculpt::Depot_users_widget : Widget<Vbox>
}
}
void view(Scope<Vbox> &s) const
{
_depot_users.with_xml([&] (Xml_node const &depot_users) {
_view(s, depot_users); });
}
bool unfolded() const { return _unfolded || !_selected_user_exists; }
struct User_properties
@ -267,14 +271,16 @@ struct Sculpt::Depot_users_widget : Widget<Vbox>
User_properties selected_user_properties() const
{
User_properties result { };
_depot_users.xml().for_each_sub_node([&] (Xml_node const &user) {
if (_selected == user.attribute_value("name", User())) {
result = {
.exists = true,
.download_url = Depot_url::from_string(_url(user)).valid(),
.public_key = user.attribute_value("known_pubkey", false)
};
}
_depot_users.with_xml([&] (Xml_node const &users) {
users.for_each_sub_node([&] (Xml_node const &user) {
if (_selected == user.attribute_value("name", User())) {
result = {
.exists = true,
.download_url = Depot_url::from_string(_url(user)).valid(),
.public_key = user.attribute_value("known_pubkey", false)
};
}
});
});
return result;
}
@ -289,11 +295,13 @@ struct Sculpt::Depot_users_widget : Widget<Vbox>
void _add_and_select_new_depot_user(Action &action)
{
Depot_url const depot_url = _edit_item.depot_url(_depot_users.xml());
if (depot_url.valid()) {
action.add_depot_url(depot_url);
_select_depot_user(depot_url.user);
}
_depot_users.with_xml([&] (Xml_node const &users) {
Depot_url const depot_url = _edit_item.depot_url(users);
if (depot_url.valid()) {
action.add_depot_url(depot_url);
_select_depot_user(depot_url.user);
}
});
}
void click(Clicked_at const &at, Action &action, auto const &select_fn)
@ -314,8 +322,9 @@ struct Sculpt::Depot_users_widget : Widget<Vbox>
}
}
_edit_item.propagate(at, _depot_users.xml(), [&] {
_add_and_select_new_depot_user(action); });
_depot_users.with_xml([&] (Xml_node const &users) {
_edit_item.propagate(at, users, [&] {
_add_and_select_new_depot_user(action); }); });
}
bool keyboard_needed() const { return _selected == _add_id(); }
@ -337,9 +346,10 @@ struct Sculpt::Depot_users_widget : Widget<Vbox>
*/
_selected_user_exists = false;
_depot_users.xml().for_each_sub_node([&] (Xml_node const &user) {
if (_selected == user.attribute_value("name", User()))
_selected_user_exists = true; });
_depot_users.with_xml([&] (Xml_node const &users) {
users.for_each_sub_node([&] (Xml_node const &user) {
if (_selected == user.attribute_value("name", User()))
_selected_user_exists = true; }); });
}
};

View File

@ -357,9 +357,10 @@ void Popup_dialog::click(Clicked_at const &at)
auto with_matching_user = [&] (Id const &id, auto const &fn)
{
unsigned count = 0;
_depot_users.xml().for_each_sub_node("user", [&] (Xml_node const &user) {
if (id == user_id(count++))
fn(user.attribute_value("name", User())); });
_depot_users.with_xml([&] (Xml_node const &users) {
users.for_each_sub_node("user", [&] (Xml_node const &user) {
if (id == user_id(count++))
fn(user.attribute_value("name", User())); }); });
};
State const orig_state = _state;

View File

@ -34,7 +34,7 @@ namespace Sculpt { struct Popup_dialog; }
struct Sculpt::Popup_dialog : Dialog::Top_level_dialog
{
using Depot_users = Attached_rom_dataspace;
using Depot_users = Rom_data;
using Blueprint_info = Component::Blueprint_info;
Env &_env;
@ -234,7 +234,8 @@ struct Sculpt::Popup_dialog : Dialog::Top_level_dialog
{
s.sub_scope<Frame>([&] (Scope<Frame> &s) {
s.sub_scope<Vbox>([&] (Scope<Frame, Vbox> &s) {
_view_menu_elements(s, _depot_users.xml()); }); });
_depot_users.with_xml([&] (Xml_node const &users) {
_view_menu_elements(s, users); }); }); });
}
void click(Clicked_at const &) override;

View File

@ -27,7 +27,6 @@ struct Sculpt::Software_update_widget : Widget<Vbox>
{
using Depot_users = Depot_users_widget::Depot_users;
using User = Depot_users_widget::User;
using Image_index = Attached_rom_dataspace;
using Version = String<16>;
Build_info const _build_info;
@ -36,7 +35,6 @@ struct Sculpt::Software_update_widget : Widget<Vbox>
Download_queue const &_download_queue;
Index_update_queue const &_index_update_queue;
File_operation_queue const &_file_operation_queue;
Image_index const &_image_index;
Path _last_installed { };
Path _last_selected { };
@ -209,14 +207,12 @@ struct Sculpt::Software_update_widget : Widget<Vbox>
Download_queue const &download_queue,
Index_update_queue const &index_update_queue,
File_operation_queue const &file_operation_queue,
Depot_users const &depot_users,
Image_index const &image_index)
Depot_users const &depot_users)
:
_build_info(build_info), _nic_state(nic_state),
_download_queue(download_queue),
_index_update_queue(index_update_queue),
_file_operation_queue(file_operation_queue),
_image_index(image_index),
_users(Id { "users" }, depot_users, _build_info.depot_user)
{ }

View File

@ -26,7 +26,7 @@ namespace Sculpt { struct System_dialog; }
struct Sculpt::System_dialog : Top_level_dialog
{
using Depot_users = Depot_users_widget::Depot_users;
using Image_index = Attached_rom_dataspace;
using Image_index = Rom_data;
Presets const &_presets;
Image_index const &_image_index;
@ -65,7 +65,8 @@ struct Sculpt::System_dialog : Top_level_dialog
s.widget(_presets_widget, _presets);
break;
case Tab::UPDATE:
s.widget(_update_widget, _image_index.xml());
_image_index.with_xml([&] (Xml_node const &index) {
s.widget(_update_widget, index); });
s.widget(_version_widget, _build_info);
break;
};
@ -107,8 +108,7 @@ struct Sculpt::System_dialog : Top_level_dialog
_presets_action(presets_action), _update_action(update_action),
_update_widget(Id { "update" },
build_info, nic_state, download_queue,
index_update_queue, file_operation_queue, depot_users,
image_index)
index_update_queue, file_operation_queue, depot_users)
{ }
bool update_tab_selected() const { return _selected_tab == Tab::UPDATE; }

View File

@ -16,6 +16,7 @@
/* Genode includes */
#include <util/xml_generator.h>
#include <base/attached_rom_dataspace.h>
#include <base/log.h>
/* local includes */
@ -162,6 +163,52 @@ namespace Sculpt {
from.for_each_sub_node([&] (Xml_node const &sub_node) {
copy_node(xml, sub_node, { max_depth.value - 1 }); }); });
}
struct Rom_data : Noncopyable
{
protected:
Xml_node _node { "<empty/>" };
public:
void with_xml(auto const &fn) const { fn(_node); }
bool valid() const { return !_node.has_type("empty"); }
};
template <typename T>
class Rom_handler : public Rom_data
{
private:
Attached_rom_dataspace _rom;
T &_obj;
void (T::*_member) (Xml_node const &);
Signal_handler<Rom_handler> _handler;
void _handle()
{
_rom.update();
_node = _rom.xml();
(_obj.*_member)(_node);
}
public:
Rom_handler(Env &env, Session_label const &label,
T &obj, void (T::*member)(Xml_node const &))
:
_rom(env, label.string()), _obj(obj), _member(member),
_handler(env.ep(), *this, &Rom_handler::_handle)
{
_rom.sigh(_handler);
_handler.local_submit();
}
};
}
#endif /* _XML_H_ */