From 5112a56439421666c0ebe32ce25c7c7328d98382 Mon Sep 17 00:00:00 2001 From: Chris Beck Date: Sat, 13 Sep 2014 21:08:43 -0400 Subject: [PATCH] add try_fetch_addon_with_checks fcn, use when gui installs addons Extending the 'try_fetch_addon' fcn, this fcn also calls the dep check and the check for dev overwrite functions beforehand. Thus it does a fully 'smart' download of an add-on and tidies up many of the details. We plan to call this function also as part of the code path when we do addon auto-downloads from the mp lobby. --- src/addon/manager_ui.cpp | 70 ++++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 20 deletions(-) diff --git a/src/addon/manager_ui.cpp b/src/addon/manager_ui.cpp index 5f3b55f5a94f..59b68e5fa720 100644 --- a/src/addon/manager_ui.cpp +++ b/src/addon/manager_ui.cpp @@ -136,17 +136,23 @@ static bool try_fetch_addon(display & disp, addons_client & client, const addon_ } } +enum OUTCOME { SUCCESS, FAILURE, ABORT }; + // A structure which summarizes the outcome of one or more add-on install operations. struct ADDON_OP_RESULT { - bool continue_; + OUTCOME outcome_; bool wml_changed_; }; -/** Warns the user about unresolved dependencies and installs them if they choose to do so. */ +/** Warns the user about unresolved dependencies and installs them if they choose to do so. + * Returns: outcome: ABORT in case the user chose to abort because of an issue + * SUCCESS otherwise + * wml_change: indicates if new wml content was installed + */ ADDON_OP_RESULT do_resolve_addon_dependencies(display& disp, addons_client& client, const addons_list& addons, const addon_info& addon) { ADDON_OP_RESULT result; - result.continue_ = true; + result.outcome_ = SUCCESS; result.wml_changed_ = false; boost::scoped_ptr cursor_setter(new cursor::setter(cursor::WAIT)); @@ -185,7 +191,7 @@ ADDON_OP_RESULT do_resolve_addon_dependencies(display& disp, addons_client& clie } if(gui2::show_message(disp.video(), _("Broken Dependencies"), broken_deps_report, gui2::tmessage::yes_no_buttons) != gui2::twindow::OK) { - result.continue_ = false; + result.outcome_ = ABORT; return result; // canceled by user } } @@ -273,7 +279,7 @@ ADDON_OP_RESULT do_resolve_addon_dependencies(display& disp, addons_client& clie "The following dependencies could not be installed. Do you still wish to continue?", failed_titles.size()) + std::string("\n\n") + utils::bullet_list(failed_titles); - result.continue_ = gui2::show_message(disp.video(), _("Dependencies Installation Failed"), failed_deps_report, gui2::tmessage::yes_no_buttons) == gui2::twindow::OK; // Only continue if the user chooses to ignore the failures + result.outcome_ = gui2::show_message(disp.video(), _("Dependencies Installation Failed"), failed_deps_report, gui2::tmessage::yes_no_buttons) == gui2::twindow::OK ? SUCCESS : ABORT; // If the user cancels, return ABORT. Otherwise, return SUCCESS, since the user chose to ignore the failure. return result; } @@ -314,6 +320,38 @@ bool do_check_before_overwriting_addon(CVideo& video, const addon_info& addon) return gui2::show_message(video, _("Confirm"), text, gui2::tmessage::yes_no_buttons) == gui2::twindow::OK; } +/** Do a 'smart' fetch of an add-on, checking to avoid overwrites for devs and resolving dependencies, using gui interaction to handle issues that arise + * Returns: outcome: ABORT in case the user chose to abort because of an issue + * FAILURE in case we resolved checks and dependencies, but fetching this particular add-on failed + * SUCCESS otherwise + * wml_changed: indicates if new wml content was installed at any point + */ +static ADDON_OP_RESULT try_fetch_addon_with_checks(display & disp, addons_client& client, const addons_list& addons, const addon_info& addon) +{ + if(!(do_check_before_overwriting_addon(disp.video(), addon))) { + // Just do nothing and leave. + ADDON_OP_RESULT result; + result.outcome_ = ABORT; + result.wml_changed_ = false; + + return result; + } + + // Resolve any dependencies + ADDON_OP_RESULT res = do_resolve_addon_dependencies(disp, client, addons, addon); + if (res.outcome_ != SUCCESS) { // this function only returns SUCCESS and ABORT as outcomes + return res; // user aborted + } + + if(!try_fetch_addon(disp, client, addon)) { + res.outcome_ = FAILURE; + return res; //wml_changed should have whatever value was obtained in resolving dependencies + } else { + res.wml_changed_ = true; + return res; //we successfully installed something, so now the wml was definitely changed + } +} + /** Performs all backend and UI actions for taking down the specified add-on. */ void do_remote_addon_delete(CVideo& video, addons_client& client, const std::string& addon_id) { @@ -887,21 +925,13 @@ void show_addons_manager_dialog(display& disp, addons_client& client, addons_lis BOOST_FOREACH(const std::string& id, ids_to_install) { const addon_info& addon = addon_at(id, addons); - if(!(do_check_before_overwriting_addon(disp.video(), addon))) { - // Just do nothing and leave. - return; - } - - // Resolve any dependencies - ADDON_OP_RESULT res = do_resolve_addon_dependencies(disp, client, addons, addon); - wml_changed |= res.wml_changed_; // Take note if this op changed the wml. - if (!res.continue_) { - return; // abort - } - - if(!try_fetch_addon(disp, client, addon)) { - failed_titles.push_back(addon.title); - } else { + ADDON_OP_RESULT res = try_fetch_addon_with_checks(disp, client, addons, addon); + wml_changed |= res.wml_changed_; // take note if any wml_changes occurred + if (res.outcome_ == ABORT) { + return; // the user aborted because of some issue encountered + } else if (res.outcome_ == FAILURE) { + failed_titles.push_back(addon.title); // we resolved dependencies, but fetching this particular addon failed. + } else { // res.outcome == SUCCESS wml_changed = true; } }