mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-30 08:03:59 +00:00
sculpt: reusable component-construction interfaces
This patch moves the interfaces needed for the interactive addition of runtime components from the 'Popup_dialog' to the 'model/component.h'. So those interfaces are no longer tied to one specific view implementation.
This commit is contained in:
parent
daf53df670
commit
3a99deef5a
@ -17,6 +17,7 @@
|
||||
#include <types.h>
|
||||
#include <model/route.h>
|
||||
#include <depot/archive.h>
|
||||
#include <depot_query.h>
|
||||
|
||||
namespace Sculpt { struct Component; }
|
||||
|
||||
@ -44,7 +45,18 @@ struct Sculpt::Component : Noncopyable
|
||||
affinity_space.height() };
|
||||
Priority priority = Priority::DEFAULT;
|
||||
|
||||
bool blueprint_known = false;
|
||||
struct Blueprint_info
|
||||
{
|
||||
bool known;
|
||||
bool pkg_avail;
|
||||
bool content_complete;
|
||||
|
||||
bool uninstalled() const { return known && !pkg_avail; }
|
||||
bool ready_to_deploy() const { return known && pkg_avail && content_complete; }
|
||||
bool incomplete() const { return known && pkg_avail && !content_complete; }
|
||||
};
|
||||
|
||||
Blueprint_info blueprint_info { };
|
||||
|
||||
List_model<Route> routes { };
|
||||
Route pd_route { "<pd/>" };
|
||||
@ -65,6 +77,49 @@ struct Sculpt::Component : Noncopyable
|
||||
);
|
||||
}
|
||||
|
||||
struct Construction_info : Interface
|
||||
{
|
||||
struct With : Interface { virtual void with(Component const &) const = 0; };
|
||||
|
||||
virtual void _with_construction(With const &) const = 0;
|
||||
|
||||
template <typename FN>
|
||||
void with_construction(FN const &fn) const
|
||||
{
|
||||
struct _With : With {
|
||||
FN const &_fn;
|
||||
_With(FN const &fn) : _fn(fn) { }
|
||||
void with(Component const &c) const override { _fn(c); }
|
||||
};
|
||||
_with_construction(_With(fn));
|
||||
}
|
||||
};
|
||||
|
||||
struct Construction_action : Interface
|
||||
{
|
||||
virtual void new_construction(Path const &pkg, Info const &info) = 0;
|
||||
|
||||
struct Apply_to : Interface { virtual void apply_to(Component &) = 0; };
|
||||
|
||||
virtual void _apply_to_construction(Apply_to &) = 0;
|
||||
|
||||
template <typename FN>
|
||||
void apply_to_construction(FN const &fn)
|
||||
{
|
||||
struct _Apply_to : Apply_to {
|
||||
FN const &_fn;
|
||||
_Apply_to(FN const &fn) : _fn(fn) { }
|
||||
void apply_to(Component &c) override { _fn(c); }
|
||||
} apply_fn(fn);
|
||||
|
||||
_apply_to_construction(apply_fn);
|
||||
}
|
||||
|
||||
virtual void discard_construction() = 0;
|
||||
virtual void launch_construction() = 0;
|
||||
virtual void trigger_pkg_download() = 0;
|
||||
};
|
||||
|
||||
Component(Allocator &alloc, Path const &path, Info const &info,
|
||||
Affinity::Space const space)
|
||||
:
|
||||
@ -78,11 +133,18 @@ struct Sculpt::Component : Noncopyable
|
||||
|
||||
void try_apply_blueprint(Xml_node blueprint)
|
||||
{
|
||||
blueprint.for_each_sub_node("pkg", [&] (Xml_node pkg) {
|
||||
blueprint_info = { };
|
||||
|
||||
blueprint.for_each_sub_node([&] (Xml_node pkg) {
|
||||
|
||||
if (path != pkg.attribute_value("path", Path()))
|
||||
return;
|
||||
|
||||
if (pkg.has_type("missing")) {
|
||||
blueprint_info.known = true;
|
||||
return;
|
||||
}
|
||||
|
||||
pkg.with_optional_sub_node("runtime", [&] (Xml_node runtime) {
|
||||
|
||||
ram = runtime.attribute_value("ram", Number_of_bytes());
|
||||
@ -92,7 +154,11 @@ struct Sculpt::Component : Noncopyable
|
||||
_update_routes_from_xml(requires); });
|
||||
});
|
||||
|
||||
blueprint_known = true;
|
||||
blueprint_info = {
|
||||
.known = true,
|
||||
.pkg_avail = !blueprint_missing(blueprint, path),
|
||||
.content_complete = !blueprint_rom_missing(blueprint, path)
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -243,7 +243,7 @@ void Popup_dialog::_gen_menu_elements(Xml_generator &xml, Xml_node const &depot_
|
||||
* inconsistent with the content contained in
|
||||
* the pkg's archives.
|
||||
*/
|
||||
if (!_pkg_missing && _pkg_rom_missing) {
|
||||
if (_blueprint_info.incomplete()) {
|
||||
_gen_info_label(xml, "pad2", "");
|
||||
_gen_info_label(xml, "path", component.path);
|
||||
_gen_info_label(xml, "pad3", "");
|
||||
@ -254,7 +254,7 @@ void Popup_dialog::_gen_menu_elements(Xml_generator &xml, Xml_node const &depot_
|
||||
/*
|
||||
* Package is missing but can be installed
|
||||
*/
|
||||
else if (_pkg_missing && _nic_ready()) {
|
||||
else if (_blueprint_info.uninstalled() && _nic_ready()) {
|
||||
|
||||
_gen_pkg_info(xml, component);
|
||||
_gen_info_label(xml, "pad2", "");
|
||||
@ -273,7 +273,7 @@ void Popup_dialog::_gen_menu_elements(Xml_generator &xml, Xml_node const &depot_
|
||||
* Package is missing and we cannot do anything
|
||||
* about it
|
||||
*/
|
||||
else if (_pkg_missing) {
|
||||
else if (_blueprint_info.uninstalled()) {
|
||||
_gen_info_label(xml, "pad2", "");
|
||||
_gen_info_label(xml, "path", component.path);
|
||||
_gen_info_label(xml, "pad3", "");
|
||||
@ -398,7 +398,6 @@ void Popup_dialog::click(Action &action)
|
||||
_construction_name = action.new_construction(path, info);
|
||||
|
||||
_state = PKG_REQUESTED;
|
||||
_pkg_missing = false;
|
||||
_depot_query.trigger_depot_query();
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,8 @@ namespace Sculpt { struct Popup_dialog; }
|
||||
|
||||
struct Sculpt::Popup_dialog : Dialog
|
||||
{
|
||||
using Depot_users = Attached_rom_dataspace;
|
||||
using Depot_users = Attached_rom_dataspace;
|
||||
using Blueprint_info = Component::Blueprint_info;
|
||||
|
||||
Env &_env;
|
||||
|
||||
@ -132,8 +133,7 @@ struct Sculpt::Popup_dialog : Dialog
|
||||
typedef Depot::Archive::User User;
|
||||
User _selected_user { };
|
||||
|
||||
bool _pkg_missing = false;
|
||||
bool _pkg_rom_missing = false;
|
||||
Blueprint_info _blueprint_info { };
|
||||
|
||||
Component::Name _construction_name { };
|
||||
|
||||
@ -338,7 +338,7 @@ struct Sculpt::Popup_dialog : Dialog
|
||||
reset();
|
||||
}
|
||||
|
||||
if (_pkg_missing && _install_item.activated("install")) {
|
||||
if (!_blueprint_info.pkg_avail && _install_item.activated("install")) {
|
||||
_construction_info.with_construction([&] (Component const &component) {
|
||||
action.trigger_download(component.path);
|
||||
_install_item.reset();
|
||||
@ -412,11 +412,11 @@ struct Sculpt::Popup_dialog : Dialog
|
||||
construction.affinity_location,
|
||||
construction.priority);
|
||||
|
||||
_pkg_rom_missing = blueprint_rom_missing(blueprint, construction.path);
|
||||
_pkg_missing = blueprint_missing (blueprint, construction.path);
|
||||
|
||||
construction.try_apply_blueprint(blueprint);
|
||||
if (construction.blueprint_known && !_pkg_missing && !_pkg_rom_missing)
|
||||
|
||||
_blueprint_info = construction.blueprint_info;
|
||||
|
||||
if (_blueprint_info.ready_to_deploy())
|
||||
_state = PKG_SHOWN;
|
||||
|
||||
_refresh.refresh_popup_dialog();
|
||||
@ -427,7 +427,7 @@ struct Sculpt::Popup_dialog : Dialog
|
||||
if (_state == DEPOT_SELECTION)
|
||||
return true;
|
||||
|
||||
return _state >= PKG_REQUESTED && (_pkg_missing || _pkg_rom_missing);
|
||||
return _state >= PKG_REQUESTED && !_blueprint_info.ready_to_deploy();
|
||||
}
|
||||
|
||||
bool interested_in_file_operations() const
|
||||
|
Loading…
x
Reference in New Issue
Block a user