Allow downloading addon icons on demand, fixed #2844

This commit is contained in:
Benau 2020-06-16 14:02:55 +08:00
parent 2171bd7bf3
commit 451bbd1a4a
5 changed files with 67 additions and 50 deletions

View File

@ -290,8 +290,16 @@ void AddonsManager::initAddons(const XMLNode *xml)
}
m_addons_list.unlock();
if (UserConfigParams::m_internet_status == RequestManager::IPERM_ALLOWED)
downloadIcons();
for (unsigned int i = 0; i < m_addons_list.getData().size(); i++)
{
Addon& addon = m_addons_list.getData()[i];
const std::string& icon = addon.getIconBasename();
const std::string& icon_full =
file_manager->getAddonsFile("icons/" + icon);
if (!addon.iconNeedsUpdate() && file_manager->fileExists(icon_full))
addon.setIconReady();
} // for i < m_addons_list.size()
m_state.setAtomic(STATE_READY);
} // initAddons
@ -362,57 +370,59 @@ void AddonsManager::checkInstalledAddons()
} // checkInstalledAddons
// ----------------------------------------------------------------------------
/** Download all necessary icons (i.e. icons that are either missing or have
* been updated since they were downloaded).
*/
void AddonsManager::downloadIcons()
/** Download icon for specific addon */
void AddonsManager::downloadIconForAddon(const std::string& addon_id,
std::weak_ptr<bool> result)
{
for(unsigned int i=0; i<m_addons_list.getData().size(); i++)
Addon* addon = getAddon(addon_id);
if (!addon)
return;
const std::string &icon = addon->getIconBasename();
const std::string &icon_full =
file_manager->getAddonsFile("icons/" + icon);
if (addon->iconNeedsUpdate() ||
!file_manager->fileExists(icon_full))
{
Addon &addon = m_addons_list.getData()[i];
const std::string &icon = addon.getIconBasename();
const std::string &icon_full
= file_manager->getAddonsFile("icons/"+icon);
if(addon.iconNeedsUpdate() ||
!file_manager->fileExists(icon_full))
const std::string& url = addon->getIconURL();
const std::string& icon = addon->getIconBasename();
if (icon.empty())
{
const std::string &url = addon.getIconURL();
const std::string &icon = addon.getIconBasename();
if(icon=="")
if (UserConfigParams::logAddons())
{
if(UserConfigParams::logAddons())
Log::error("addons", "No icon or image specified for '%s'.",
addon.getId().c_str());
continue;
Log::error("addons", "No icon or image specified for '%s'.",
addon->getId().c_str());
}
// A simple class that will notify the addon via a callback
class IconRequest : public Online::HTTPRequest
{
Addon *m_addon; // stores this addon object
void callback()
{
m_addon->setIconReady();
if (!hadDownloadError())
addons_manager->m_downloaded_icons = true;
} // callback
public:
IconRequest(const std::string &filename,
const std::string &url,
Addon *addon ) : HTTPRequest(filename,/*priority*/1)
{
m_addon = addon; setURL(url);
} // IconRequest
};
auto r = std::make_shared<IconRequest>("icons/"+icon, url, &addon);
r->queue();
return;
}
else
m_addons_list.getData()[i].setIconReady();
} // for i<m_addons_list.size()
return;
} // downloadIcons
// A simple class that will notify the addon via a callback
class IconRequest : public Online::HTTPRequest
{
std::weak_ptr<bool> m_result;
Addon* m_addon; // stores this addon object
void callback()
{
m_addon->setIconReady();
if (std::shared_ptr<bool> result = m_result.lock())
*result = true;
if (!hadDownloadError())
addons_manager->m_downloaded_icons = true;
} // callback
public:
IconRequest(const std::string& filename,
const std::string& url,
Addon* addon, std::weak_ptr<bool> result)
: HTTPRequest(filename,/*priority*/1)
{
m_addon = addon;
m_result = result;
setURL(url);
} // IconRequest
};
auto r =
std::make_shared<IconRequest>("icons/"+icon, url, addon, result);
r->queue();
}
} // downloadIconForAddon
// ----------------------------------------------------------------------------
/** Loads the installed addons from .../addons/addons_installed.xml.

View File

@ -23,6 +23,7 @@
#include <string>
#include <map>
#include <memory>
#include <vector>
#include "addons/addon.hpp"
@ -60,7 +61,6 @@ private:
bool m_downloaded_icons;
void loadInstalledAddons();
void downloadIcons();
public:
AddonsManager();
@ -74,6 +74,8 @@ public:
bool uninstall(const Addon &addon);
void reInit();
bool anyAddonsInstalled() const;
void downloadIconForAddon(const std::string& addon_id,
std::weak_ptr<bool> result);
// ------------------------------------------------------------------------
/** Returns true if the list of online addons has been downloaded. This is
* used to grey out the 'addons' entry till a network connections could be

View File

@ -291,8 +291,10 @@ void AddonsScreen::loadList()
core::stringw s;
if (addon->getDesigner().size()==0)
{
s = (addon->getName()+L"\t" +
core::stringc(addon->getDateAsString().c_str())).c_str();
}
//FIXME I'd like to move this to CGUISTKListBox.cpp

View File

@ -55,7 +55,9 @@ AddonsLoading::AddonsLoading(const std::string &id)
{
m_icon_shown = false;
m_icon_downloaded = std::make_shared<bool>(m_addon.iconReady());
if (*m_icon_downloaded == false)
addons_manager->downloadIconForAddon(id, m_icon_downloaded);
loadFromFile("addons_loading.stkgui");
m_icon = getWidget<IconButtonWidget> ("icon" );
@ -297,7 +299,7 @@ void AddonsLoading::onUpdate(float delta)
} // if(m_progress->isVisible())
// See if the icon is loaded (but not yet displayed)
if(!m_icon_shown && m_addon.iconReady())
if (!m_icon_shown && *m_icon_downloaded == true)
{
const std::string icon = "icons/"+m_addon.getIconBasename();
m_icon->setImage( file_manager->getAddonsFile(icon).c_str(),

View File

@ -52,6 +52,7 @@ private:
/** True if the icon is being displayed. */
bool m_icon_shown;
std::shared_ptr<bool> m_icon_downloaded;
/** A pointer to the download request, which gives access
* to the progress of a download. */
std::shared_ptr<Online::HTTPRequest> m_download_request;