mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-06 01:11:46 +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 <types.h>
|
||||||
#include <model/route.h>
|
#include <model/route.h>
|
||||||
#include <depot/archive.h>
|
#include <depot/archive.h>
|
||||||
|
#include <depot_query.h>
|
||||||
|
|
||||||
namespace Sculpt { struct Component; }
|
namespace Sculpt { struct Component; }
|
||||||
|
|
||||||
@ -44,7 +45,18 @@ struct Sculpt::Component : Noncopyable
|
|||||||
affinity_space.height() };
|
affinity_space.height() };
|
||||||
Priority priority = Priority::DEFAULT;
|
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 { };
|
List_model<Route> routes { };
|
||||||
Route pd_route { "<pd/>" };
|
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,
|
Component(Allocator &alloc, Path const &path, Info const &info,
|
||||||
Affinity::Space const space)
|
Affinity::Space const space)
|
||||||
:
|
:
|
||||||
@ -78,11 +133,18 @@ struct Sculpt::Component : Noncopyable
|
|||||||
|
|
||||||
void try_apply_blueprint(Xml_node blueprint)
|
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()))
|
if (path != pkg.attribute_value("path", Path()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (pkg.has_type("missing")) {
|
||||||
|
blueprint_info.known = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
pkg.with_optional_sub_node("runtime", [&] (Xml_node runtime) {
|
pkg.with_optional_sub_node("runtime", [&] (Xml_node runtime) {
|
||||||
|
|
||||||
ram = runtime.attribute_value("ram", Number_of_bytes());
|
ram = runtime.attribute_value("ram", Number_of_bytes());
|
||||||
@ -92,7 +154,11 @@ struct Sculpt::Component : Noncopyable
|
|||||||
_update_routes_from_xml(requires); });
|
_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
|
* inconsistent with the content contained in
|
||||||
* the pkg's archives.
|
* the pkg's archives.
|
||||||
*/
|
*/
|
||||||
if (!_pkg_missing && _pkg_rom_missing) {
|
if (_blueprint_info.incomplete()) {
|
||||||
_gen_info_label(xml, "pad2", "");
|
_gen_info_label(xml, "pad2", "");
|
||||||
_gen_info_label(xml, "path", component.path);
|
_gen_info_label(xml, "path", component.path);
|
||||||
_gen_info_label(xml, "pad3", "");
|
_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
|
* 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_pkg_info(xml, component);
|
||||||
_gen_info_label(xml, "pad2", "");
|
_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
|
* Package is missing and we cannot do anything
|
||||||
* about it
|
* about it
|
||||||
*/
|
*/
|
||||||
else if (_pkg_missing) {
|
else if (_blueprint_info.uninstalled()) {
|
||||||
_gen_info_label(xml, "pad2", "");
|
_gen_info_label(xml, "pad2", "");
|
||||||
_gen_info_label(xml, "path", component.path);
|
_gen_info_label(xml, "path", component.path);
|
||||||
_gen_info_label(xml, "pad3", "");
|
_gen_info_label(xml, "pad3", "");
|
||||||
@ -398,7 +398,6 @@ void Popup_dialog::click(Action &action)
|
|||||||
_construction_name = action.new_construction(path, info);
|
_construction_name = action.new_construction(path, info);
|
||||||
|
|
||||||
_state = PKG_REQUESTED;
|
_state = PKG_REQUESTED;
|
||||||
_pkg_missing = false;
|
|
||||||
_depot_query.trigger_depot_query();
|
_depot_query.trigger_depot_query();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@ namespace Sculpt { struct Popup_dialog; }
|
|||||||
struct Sculpt::Popup_dialog : 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;
|
Env &_env;
|
||||||
|
|
||||||
@ -132,8 +133,7 @@ struct Sculpt::Popup_dialog : Dialog
|
|||||||
typedef Depot::Archive::User User;
|
typedef Depot::Archive::User User;
|
||||||
User _selected_user { };
|
User _selected_user { };
|
||||||
|
|
||||||
bool _pkg_missing = false;
|
Blueprint_info _blueprint_info { };
|
||||||
bool _pkg_rom_missing = false;
|
|
||||||
|
|
||||||
Component::Name _construction_name { };
|
Component::Name _construction_name { };
|
||||||
|
|
||||||
@ -338,7 +338,7 @@ struct Sculpt::Popup_dialog : Dialog
|
|||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_pkg_missing && _install_item.activated("install")) {
|
if (!_blueprint_info.pkg_avail && _install_item.activated("install")) {
|
||||||
_construction_info.with_construction([&] (Component const &component) {
|
_construction_info.with_construction([&] (Component const &component) {
|
||||||
action.trigger_download(component.path);
|
action.trigger_download(component.path);
|
||||||
_install_item.reset();
|
_install_item.reset();
|
||||||
@ -412,11 +412,11 @@ struct Sculpt::Popup_dialog : Dialog
|
|||||||
construction.affinity_location,
|
construction.affinity_location,
|
||||||
construction.priority);
|
construction.priority);
|
||||||
|
|
||||||
_pkg_rom_missing = blueprint_rom_missing(blueprint, construction.path);
|
|
||||||
_pkg_missing = blueprint_missing (blueprint, construction.path);
|
|
||||||
|
|
||||||
construction.try_apply_blueprint(blueprint);
|
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;
|
_state = PKG_SHOWN;
|
||||||
|
|
||||||
_refresh.refresh_popup_dialog();
|
_refresh.refresh_popup_dialog();
|
||||||
@ -427,7 +427,7 @@ struct Sculpt::Popup_dialog : Dialog
|
|||||||
if (_state == DEPOT_SELECTION)
|
if (_state == DEPOT_SELECTION)
|
||||||
return true;
|
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
|
bool interested_in_file_operations() const
|
||||||
|
Loading…
x
Reference in New Issue
Block a user