From: Ingo Ruhnke Date: Mon, 18 Aug 2014 21:21:39 +0000 (+0200) Subject: First round of cleanup up the AddonManager a bit X-Git-Url: https://git.octo.it/?a=commitdiff_plain;h=9216f1fcdf1b42ad67f794c383d252b35c885df7;p=supertux.git First round of cleanup up the AddonManager a bit --- diff --git a/src/addon/addon.cpp b/src/addon/addon.cpp index 2ab094eb1..44764ee05 100644 --- a/src/addon/addon.cpp +++ b/src/addon/addon.cpp @@ -29,40 +29,51 @@ std::string Addon::get_md5() const { - if (!installed) { - if (stored_md5 == "") { log_warning << "Add-on not installed and no stored MD5 available" << std::endl; } + if (!installed) + { + if (stored_md5.empty()) + { + log_warning << "Add-on not installed and no stored MD5 available" << std::endl; + } return stored_md5; } - - if (calculated_md5 != "") return calculated_md5; - - if (installed_physfs_filename == "") throw std::runtime_error("Tried to calculate MD5 of Add-on with unknown filename"); - - // TODO: this does not work as expected for some files -- IFileStream seems to not always behave like an ifstream. - //IFileStream ifs(installed_physfs_filename); - //std::string md5 = MD5(ifs).hex_digest(); - - MD5 md5; - PHYSFS_file* file; - file = PHYSFS_openRead(installed_physfs_filename.c_str()); - unsigned char buffer[1024]; - while (true) { - PHYSFS_sint64 len = PHYSFS_read(file, buffer, 1, sizeof(buffer)); - if (len <= 0) break; - md5.update(buffer, len); + else if (!calculated_md5.empty()) + { + return calculated_md5; + } + else if (installed_physfs_filename.empty()) + { + throw std::runtime_error("Tried to calculate MD5 of Add-on with unknown filename"); + } + else + { + // TODO: this does not work as expected for some files -- IFileStream seems to not always behave like an ifstream. + //IFileStream ifs(installed_physfs_filename); + //std::string md5 = MD5(ifs).hex_digest(); + + MD5 md5; + PHYSFS_file* file; + file = PHYSFS_openRead(installed_physfs_filename.c_str()); + unsigned char buffer[1024]; + while (true) { + PHYSFS_sint64 len = PHYSFS_read(file, buffer, 1, sizeof(buffer)); + if (len <= 0) break; + md5.update(buffer, len); + } + PHYSFS_close(file); + + calculated_md5 = md5.hex_digest(); + log_debug << "MD5 of " << title << ": " << calculated_md5 << std::endl; + + return calculated_md5; } - PHYSFS_close(file); - - calculated_md5 = md5.hex_digest(); - log_debug << "MD5 of " << title << ": " << calculated_md5 << std::endl; - - return calculated_md5; } void Addon::parse(const Reader& lisp) { - try { + try + { lisp.get("kind", kind); lisp.get("title", title); lisp.get("author", author); @@ -70,52 +81,36 @@ Addon::parse(const Reader& lisp) lisp.get("http-url", http_url); lisp.get("file", suggested_filename); lisp.get("md5", stored_md5); - } catch(std::exception& e) { + } + catch(const std::exception& err) + { std::stringstream msg; - msg << "Problem when parsing addoninfo: " << e.what(); + msg << "Problem when parsing addoninfo: " << err.what(); throw std::runtime_error(msg.str()); } } void -Addon::parse(std::string fname) +Addon::parse(const std::string& fname) { - try { + try + { lisp::Parser parser; const lisp::Lisp* root = parser.parse(fname); const lisp::Lisp* addon = root->get_lisp("supertux-addoninfo"); if(!addon) throw std::runtime_error("file is not a supertux-addoninfo file."); parse(*addon); - } catch(std::exception& e) { + } + catch(const std::exception& err) + { std::stringstream msg; - msg << "Problem when reading addoninfo '" << fname << "': " << e.what(); + msg << "Problem when reading addoninfo '" << fname << "': " << err.what(); throw std::runtime_error(msg.str()); } } -void -Addon::write(lisp::Writer& writer) const -{ - writer.start_list("supertux-addoninfo"); - if (kind != "") writer.write("kind", kind); - if (title != "") writer.write("title", title); - if (author != "") writer.write("author", author); - if (license != "") writer.write("license", license); - if (http_url != "") writer.write("http-url", http_url); - if (suggested_filename != "") writer.write("file", suggested_filename); - if (stored_md5 != "") writer.write("md5", stored_md5); - writer.end_list("supertux-addoninfo"); -} - -void -Addon::write(std::string fname) const -{ - lisp::Writer writer(fname); - write(writer); -} - bool -Addon::operator==(Addon addon2) const +Addon::operator==(const Addon& addon2) const { std::string s1 = this->get_md5(); std::string s2 = addon2.get_md5(); diff --git a/src/addon/addon.hpp b/src/addon/addon.hpp index 69b0bd9fc..e78990a0e 100644 --- a/src/addon/addon.hpp +++ b/src/addon/addon.hpp @@ -20,66 +20,51 @@ #include #include "util/reader_fwd.hpp" -#include "util/writer_fwd.hpp" -/** - * Represents an (available or installed) Add-on, e.g. a level set - */ +/** Represents an (available or installed) Add-on, e.g. a level set */ class Addon { public: + int id; std::string kind; std::string title; std::string author; std::string license; std::string http_url; + /** filename suggested by addon author, e.g. "pak0.zip" */ std::string suggested_filename; + /** PhysFS filename on disk, e.g. "pak0.zip" */ std::string installed_physfs_filename; + /** complete path and filename on disk, e.g. "/home/sommer/.supertux2/pak0.zip" */ std::string installed_absolute_filename; + std::string stored_md5; bool installed; bool loaded; - /** - * Get MD5, based either on installed file's contents or stored value - */ + /** Get MD5, based either on installed file's contents or stored value */ std::string get_md5() const; - /** - * Read additional information from given contents of a (supertux-addoninfo ...) block - */ + /** Read additional information from given contents of a (supertux-addoninfo ...) block */ void parse(const Reader& lisp); - /** - * Read additional information from given file - */ - void parse(std::string fname); + /** Read additional information from given file */ + void parse(const std::string& fname); - /** - * Writes out Add-on metainformation to a Lisp Writer - */ - void write(Writer& writer) const; - - /** - * Writes out Add-on metainformation to a file - */ - void write(std::string fname) const; - - /** - * Checks if Add-on is the same as given one. - * If available, checks MD5 sum, else relies on kind, author and title alone. - */ - bool operator==(Addon addon2) const; + /** Checks if Add-on is the same as given one. If available, checks + MD5 sum, else relies on kind, author and title alone. */ + bool operator==(const Addon& addon2) const; protected: friend class AddonManager; mutable std::string calculated_md5; - Addon() : + Addon(int id_) : + id(id_), kind(), title(), author(), @@ -93,6 +78,10 @@ protected: loaded(), calculated_md5() {}; + +private: + Addon(const Addon&) = delete; + Addon& operator=(const Addon&) = delete; }; #endif diff --git a/src/addon/addon_manager.cpp b/src/addon/addon_manager.cpp index 5ae64dfa7..e752ff20e 100644 --- a/src/addon/addon_manager.cpp +++ b/src/addon/addon_manager.cpp @@ -61,9 +61,9 @@ size_t my_curl_physfs_write(void *ptr, size_t size, size_t nmemb, void *f_p) } #endif -AddonManager::AddonManager(std::vector& ignored_addon_filenames_) : - addons(), - ignored_addon_filenames(ignored_addon_filenames_) +AddonManager::AddonManager(std::vector& ignored_addon_filenames) : + m_addons(), + m_ignored_addon_filenames(ignored_addon_filenames) { #ifdef HAVE_LIBCURL curl_global_init(CURL_GLOBAL_ALL); @@ -75,12 +75,23 @@ AddonManager::~AddonManager() #ifdef HAVE_LIBCURL curl_global_cleanup(); #endif +} - for (std::vector::iterator i = addons.begin(); i != addons.end(); i++) delete *i; +Addon& +AddonManager::get_addon(int id) +{ + if (0 <= id && id < static_cast(m_addons.size())) + { + return *m_addons[id]; + } + else + { + throw std::runtime_error("AddonManager::get_addon(): id out of range: " + std::to_string(id)); + } } -std::vector -AddonManager::get_addons() +const std::vector >& +AddonManager::get_addons() const { /* for (std::vector::iterator it = installed_addons.begin(); it != installed_addons.end(); ++it) { @@ -88,7 +99,17 @@ AddonManager::get_addons() if (addon.md5 == "") addon.md5 = calculate_md5(addon); } */ - return addons; + return m_addons; +} + +bool +AddonManager::has_online_support() const +{ +#ifdef HAVE_LIBCURL + return true; +#else + return false; +#endif } void @@ -136,14 +157,14 @@ AddonManager::check_online() log_warning << "Unknown token '" << token << "' in Add-on list" << std::endl; continue; } - std::unique_ptr addon(new Addon()); + std::unique_ptr addon(new Addon(m_addons.size())); addon->parse(*(iter.lisp())); addon->installed = false; addon->loaded = false; // make sure the list of known Add-ons does not already contain this one bool exists = false; - for (std::vector::const_iterator i = addons.begin(); i != addons.end(); i++) { + for (auto i = m_addons.begin(); i != m_addons.end(); ++i) { if (**i == *addon) { exists = true; break; @@ -161,7 +182,7 @@ AddonManager::check_online() } else { - addons.push_back(addon.release()); + m_addons.push_back(std::move(addon)); } } } catch(std::exception& e) { @@ -174,31 +195,31 @@ AddonManager::check_online() } void -AddonManager::install(Addon* addon) +AddonManager::install(Addon& addon) { #ifdef HAVE_LIBCURL - if (addon->installed) throw std::runtime_error("Tried installing installed Add-on"); + if (addon.installed) throw std::runtime_error("Tried installing installed Add-on"); // make sure the Add-on's file name does not contain weird characters - if (addon->suggested_filename.find_first_not_of("match.quiz-proxy_gwenblvdjfks0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != std::string::npos) { - throw std::runtime_error("Add-on has unsafe file name (\""+addon->suggested_filename+"\")"); + if (addon.suggested_filename.find_first_not_of("match.quiz-proxy_gwenblvdjfks0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != std::string::npos) { + throw std::runtime_error("Add-on has unsafe file name (\""+addon.suggested_filename+"\")"); } - std::string fileName = addon->suggested_filename; + std::string fileName = addon.suggested_filename; // make sure its file doesn't already exist if (PHYSFS_exists(fileName.c_str())) { - fileName = addon->stored_md5 + "_" + addon->suggested_filename; + fileName = addon.stored_md5 + "_" + addon.suggested_filename; if (PHYSFS_exists(fileName.c_str())) { - throw std::runtime_error("Add-on of suggested filename already exists (\""+addon->suggested_filename+"\", \""+fileName+"\")"); + throw std::runtime_error("Add-on of suggested filename already exists (\""+addon.suggested_filename+"\", \""+fileName+"\")"); } } char error_buffer[CURL_ERROR_SIZE+1]; - char* url = (char*)malloc(addon->http_url.length() + 1); - strncpy(url, addon->http_url.c_str(), addon->http_url.length() + 1); + char* url = (char*)malloc(addon.http_url.length() + 1); + strncpy(url, addon.http_url.c_str(), addon.http_url.length() + 1); PHYSFS_file* f = PHYSFS_openWrite(fileName.c_str()); @@ -227,21 +248,21 @@ AddonManager::install(Addon* addon) throw std::runtime_error("Downloading Add-on failed: " + why); } - addon->installed = true; - addon->installed_physfs_filename = fileName; + addon.installed = true; + addon.installed_physfs_filename = fileName; static const std::string writeDir = PHYSFS_getWriteDir(); static const std::string dirSep = PHYSFS_getDirSeparator(); - addon->installed_absolute_filename = writeDir + dirSep + fileName; - addon->loaded = false; + addon.installed_absolute_filename = writeDir + dirSep + fileName; + addon.loaded = false; - if (addon->get_md5() != addon->stored_md5) { - addon->installed = false; + if (addon.get_md5() != addon.stored_md5) { + addon.installed = false; PHYSFS_delete(fileName.c_str()); std::string why = "MD5 checksums differ"; throw std::runtime_error("Downloading Add-on failed: " + why); } - log_debug << "Finished downloading \"" << addon->installed_absolute_filename << "\". Enabling Add-on." << std::endl; + log_debug << "Finished downloading \"" << addon.installed_absolute_filename << "\". Enabling Add-on." << std::endl; enable(addon); @@ -252,88 +273,91 @@ AddonManager::install(Addon* addon) } void -AddonManager::remove(Addon* addon) +AddonManager::remove(Addon& addon) { - if (!addon->installed) throw std::runtime_error("Tried removing non-installed Add-on"); + if (!addon.installed) throw std::runtime_error("Tried removing non-installed Add-on"); //FIXME: more checks // make sure the Add-on's file name does not contain weird characters - if (addon->installed_physfs_filename.find_first_not_of("match.quiz-proxy_gwenblvdjfks0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != std::string::npos) { - throw std::runtime_error("Add-on has unsafe file name (\""+addon->installed_physfs_filename+"\")"); + if (addon.installed_physfs_filename.find_first_not_of("match.quiz-proxy_gwenblvdjfks0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != std::string::npos) { + throw std::runtime_error("Add-on has unsafe file name (\""+addon.installed_physfs_filename+"\")"); } unload(addon); - log_debug << "deleting file \"" << addon->installed_absolute_filename << "\"" << std::endl; - PHYSFS_delete(addon->installed_absolute_filename.c_str()); - addon->installed = false; + log_debug << "deleting file \"" << addon.installed_absolute_filename << "\"" << std::endl; + PHYSFS_delete(addon.installed_absolute_filename.c_str()); + addon.installed = false; // FIXME: As we don't know anything more about it (e.g. where to get it), remove it from list of known Add-ons } void -AddonManager::disable(Addon* addon) +AddonManager::disable(Addon& addon) { unload(addon); - std::string fileName = addon->installed_physfs_filename; - if (std::find(ignored_addon_filenames.begin(), ignored_addon_filenames.end(), fileName) == ignored_addon_filenames.end()) { - ignored_addon_filenames.push_back(fileName); + std::string fileName = addon.installed_physfs_filename; + if (std::find(m_ignored_addon_filenames.begin(), m_ignored_addon_filenames.end(), fileName) == m_ignored_addon_filenames.end()) { + m_ignored_addon_filenames.push_back(fileName); } } void -AddonManager::enable(Addon* addon) +AddonManager::enable(Addon& addon) { load(addon); - std::string fileName = addon->installed_physfs_filename; - std::vector::iterator i = std::find(ignored_addon_filenames.begin(), ignored_addon_filenames.end(), fileName); - if (i != ignored_addon_filenames.end()) { - ignored_addon_filenames.erase(i); + std::string fileName = addon.installed_physfs_filename; + std::vector::iterator i = std::find(m_ignored_addon_filenames.begin(), m_ignored_addon_filenames.end(), fileName); + if (i != m_ignored_addon_filenames.end()) { + m_ignored_addon_filenames.erase(i); } } void -AddonManager::unload(Addon* addon) +AddonManager::unload(Addon& addon) { - if (!addon->installed) throw std::runtime_error("Tried unloading non-installed Add-on"); - if (!addon->loaded) return; + if (!addon.installed) throw std::runtime_error("Tried unloading non-installed Add-on"); + if (!addon.loaded) return; - log_debug << "Removing archive \"" << addon->installed_absolute_filename << "\" from search path" << std::endl; - if (PHYSFS_removeFromSearchPath(addon->installed_absolute_filename.c_str()) == 0) { - log_warning << "Could not remove " << addon->installed_absolute_filename << " from search path. Ignoring." << std::endl; + log_debug << "Removing archive \"" << addon.installed_absolute_filename << "\" from search path" << std::endl; + if (PHYSFS_removeFromSearchPath(addon.installed_absolute_filename.c_str()) == 0) { + log_warning << "Could not remove " << addon.installed_absolute_filename << " from search path. Ignoring." << std::endl; return; } - addon->loaded = false; + addon.loaded = false; } void -AddonManager::load(Addon* addon) +AddonManager::load(Addon& addon) { - if (!addon->installed) throw std::runtime_error("Tried loading non-installed Add-on"); - if (addon->loaded) return; + if (!addon.installed) throw std::runtime_error("Tried loading non-installed Add-on"); + if (addon.loaded) return; - log_debug << "Adding archive \"" << addon->installed_absolute_filename << "\" to search path" << std::endl; - if (PHYSFS_addToSearchPath(addon->installed_absolute_filename.c_str(), 0) == 0) { - log_warning << "Could not add " << addon->installed_absolute_filename << " to search path. Ignoring." << std::endl; + log_debug << "Adding archive \"" << addon.installed_absolute_filename << "\" to search path" << std::endl; + if (PHYSFS_addToSearchPath(addon.installed_absolute_filename.c_str(), 0) == 0) { + log_warning << "Could not add " << addon.installed_absolute_filename << " to search path. Ignoring." << std::endl; return; } - addon->loaded = true; + addon.loaded = true; } void AddonManager::load_addons() { // unload all Addons and forget about them - for (std::vector::iterator i = addons.begin(); i != addons.end(); i++) { - if ((*i)->installed && (*i)->loaded) unload(*i); - delete *i; + for (auto i = m_addons.begin(); i != m_addons.end(); ++i) + { + if ((*i)->installed && (*i)->loaded) + { + unload(**i); + } } - addons.clear(); + m_addons.clear(); // Search for archives and add them to the search path char** rc = PHYSFS_enumerateFiles("/"); @@ -396,27 +420,30 @@ AddonManager::load_addons() PHYSFS_freeList(rc2); // if we have an infoFile, it's an Addon - if (infoFileName != "") { - try { - Addon* addon = new Addon(); + if (infoFileName != "") + { + try + { + std::unique_ptr addon(new Addon(m_addons.size())); addon->parse(infoFileName); addon->installed = true; addon->installed_physfs_filename = fileName; addon->installed_absolute_filename = fullFilename; addon->loaded = true; - addons.push_back(addon); // check if the Addon is disabled - if (std::find(ignored_addon_filenames.begin(), ignored_addon_filenames.end(), fileName) != ignored_addon_filenames.end()) + if (std::find(m_ignored_addon_filenames.begin(), m_ignored_addon_filenames.end(), fileName) != m_ignored_addon_filenames.end()) { - unload(addon); + unload(*addon); } - } catch (const std::runtime_error& e) { + m_addons.push_back(std::move(addon)); + } + catch (const std::runtime_error& e) + { log_warning << "Could not load add-on info for " << fullFilename << ", loading as unmanaged:" << e.what() << std::endl; } } - } PHYSFS_freeList(rc); diff --git a/src/addon/addon_manager.hpp b/src/addon/addon_manager.hpp index 9387f4e54..50a1fffc7 100644 --- a/src/addon/addon_manager.hpp +++ b/src/addon/addon_manager.hpp @@ -17,6 +17,7 @@ #ifndef HEADER_SUPERTUX_ADDON_ADDON_MANAGER_HPP #define HEADER_SUPERTUX_ADDON_ADDON_MANAGER_HPP +#include #include #include @@ -26,63 +27,55 @@ class Addon; -/** - * Checks for, installs and removes Add-ons - */ +typedef int AddonId; + +/** Checks for, installs and removes Add-ons */ class AddonManager : public Currenton { public: AddonManager(std::vector& ignored_addon_filenames_); ~AddonManager(); - /** - * returns a list of installed Add-ons - */ - std::vector get_addons(); + /** returns a list of installed Add-ons */ + const std::vector >& get_addons() const; + + /** Returns true if online support is available */ + bool has_online_support() const; - /** - * downloads list of available Add-ons - */ + /** downloads list of available Add-ons */ void check_online(); - /** - * Download and install Add-on - */ - void install(Addon* addon); - - /** - * Physically delete Add-on - */ - void remove(Addon* addon); - - /** - * Unload Add-on and mark as not to be loaded automatically - */ - void disable(Addon* addon); - - /** - * Load Add-on and mark as to be loaded automatically - */ - void enable(Addon* addon); - - /** - * Remove Add-on from search path - */ - void unload(Addon* addon); - - /** - * Add Add-on to search path - */ - void load(Addon* addon); - - /** - * Loads all enabled Add-ons, i.e. adds them to the search path - */ + /** Download and install Add-on */ + void install(Addon& addon); + + /** Physically delete Add-on */ + void remove(Addon& addon); + + /** Unload Add-on and mark as not to be loaded automatically */ + void disable(Addon& addon); + + /** Load Add-on and mark as to be loaded automatically */ + void enable(Addon& addon); + + /** Remove Add-on from search path */ + void unload(Addon& addon); + + /** Add Add-on to search path */ + void load(Addon& addon); + + /** Loads all enabled Add-ons, i.e. adds them to the search path */ void load_addons(); + Addon& get_addon(int id); + int get_num_addons() const { return static_cast(m_addons.size()); } + +private: + std::vector > m_addons; + std::vector& m_ignored_addon_filenames; + private: - std::vector addons; - std::vector& ignored_addon_filenames; + AddonManager(const AddonManager&) = delete; + AddonManager& operator=(const AddonManager&) = delete; }; #endif diff --git a/src/supertux/menu/addon_menu.cpp b/src/supertux/menu/addon_menu.cpp index a658a9670..43ed81c97 100644 --- a/src/supertux/menu/addon_menu.cpp +++ b/src/supertux/menu/addon_menu.cpp @@ -26,17 +26,8 @@ #include "gui/menu_item.hpp" #include "util/gettext.hpp" -namespace { - -bool generate_addons_menu_sorter(const Addon* a1, const Addon* a2) -{ - return a1->title < a2->title; -} - -} // namespace - AddonMenu::AddonMenu() : - m_addons() + m_addon_manager(*AddonManager::current()) { refresh(); } @@ -46,29 +37,38 @@ AddonMenu::refresh() { clear(); - AddonManager& adm = *AddonManager::current(); - // refresh list of addons - m_addons = adm.get_addons(); + const auto& addons_ref = m_addon_manager.get_addons(); + std::vector > addons; + std::transform(addons_ref.begin(), addons_ref.end(), std::back_inserter(addons), + [](const std::unique_ptr& addon) -> Addon& { + return *addon.get(); + }); // sort list - std::sort(m_addons.begin(), m_addons.end(), generate_addons_menu_sorter); + std::sort(addons.begin(), addons.end(), + [](const Addon& lhs, const Addon& rhs) + { + return lhs.title < lhs.title; + }); add_label(_("Add-ons")); add_hl(); - // FIXME: don't use macro, use AddonManager::online_available() or so -#ifdef HAVE_LIBCURL - add_entry(0, std::string(_("Check Online"))); -#else - add_inactive(0, std::string(_("Check Online (disabled)"))); -#endif + if (!m_addon_manager.has_online_support()) + { + add_inactive(MNID_CHECK_ONLINE, std::string(_("Check Online (disabled)"))); + } + else + { + add_entry(MNID_CHECK_ONLINE, std::string(_("Check Online"))); + } //add_hl(); - for (unsigned int i = 0; i < m_addons.size(); i++) + for (auto& addon_ : addons) { - const Addon& addon = *m_addons[i]; + Addon& addon = addon_.get(); std::string text = ""; if (!addon.kind.empty()) @@ -112,7 +112,7 @@ AddonMenu::refresh() % addon.title); } } - add_toggle(ADDON_LIST_START_ID + i, text, addon.loaded); + add_toggle(MNID_ADDON_LIST_START + addon.id, text, addon.loaded); } add_hl(); @@ -122,67 +122,58 @@ AddonMenu::refresh() void AddonMenu::menu_action(MenuItem* item) { - int index = item->id; - - if (index == -1) - { - // do nothing - } - else if (index == 0) // check if "Check Online" was chosen + if (item->id == MNID_CHECK_ONLINE) // check if "Check Online" was chosen { try { - AddonManager::current()->check_online(); + m_addon_manager.check_online(); refresh(); - set_active_item(index); + set_active_item(item->id); } catch (std::exception& e) { log_warning << "Check for available Add-ons failed: " << e.what() << std::endl; } } - else + else if ((MNID_ADDON_LIST_START <= item->id) && (item->id < MNID_ADDON_LIST_START + m_addon_manager.get_num_addons())) { - // if one of the Addons listed was chosen, take appropriate action - if ((index >= ADDON_LIST_START_ID) && (index < ADDON_LIST_START_ID) + m_addons.size()) + int addon_id = item->id - MNID_ADDON_LIST_START; + Addon& addon = m_addon_manager.get_addon(addon_id); + if (!addon.installed) { - Addon& addon = *m_addons[index - ADDON_LIST_START_ID]; - if (!addon.installed) + try { - try - { - AddonManager::current()->install(&addon); - } - catch (std::exception& e) - { - log_warning << "Installing Add-on failed: " << e.what() << std::endl; - } - set_toggled(index, addon.loaded); + m_addon_manager.install(addon); } - else if (!addon.loaded) + catch (std::exception& e) { - try - { - AddonManager::current()->enable(&addon); - } - catch (std::exception& e) - { - log_warning << "Enabling Add-on failed: " << e.what() << std::endl; - } - set_toggled(index, addon.loaded); + log_warning << "Installing Add-on failed: " << e.what() << std::endl; } - else + set_toggled(item->id, addon.loaded); + } + else if (!addon.loaded) + { + try + { + m_addon_manager.enable(addon); + } + catch (std::exception& e) + { + log_warning << "Enabling Add-on failed: " << e.what() << std::endl; + } + set_toggled(item->id, addon.loaded); + } + else + { + try + { + m_addon_manager.disable(addon); + } + catch (std::exception& e) { - try - { - AddonManager::current()->disable(&addon); - } - catch (std::exception& e) - { - log_warning << "Disabling Add-on failed: " << e.what() << std::endl; - } - set_toggled(index, addon.loaded); + log_warning << "Disabling Add-on failed: " << e.what() << std::endl; } + set_toggled(item->id, addon.loaded); } } } diff --git a/src/supertux/menu/addon_menu.hpp b/src/supertux/menu/addon_menu.hpp index 640c5bc3f..3d81aefdd 100644 --- a/src/supertux/menu/addon_menu.hpp +++ b/src/supertux/menu/addon_menu.hpp @@ -19,16 +19,19 @@ #include "gui/menu.hpp" -enum { - ADDON_LIST_START_ID = 10 -}; - class Addon; +class AddonManager; class AddonMenu : public Menu { private: - std::vector m_addons; + enum { + MNID_CHECK_ONLINE, + MNID_ADDON_LIST_START = 10 + }; + +private: + AddonManager& m_addon_manager; public: AddonMenu();