Made NetworkHttp::downloadFileSynchron to be able to be used from a thread;

fixed addons_loading to display the icon correctly.
Note: addons installing will still crash.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@7198 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2010-12-30 23:05:54 +00:00
parent 9c94c3691f
commit 6129cfaa39
4 changed files with 68 additions and 61 deletions

View File

@ -104,7 +104,8 @@ void *NetworkHttp::mainLoop(void *obj)
me->updateNews(); me->updateNews();
break; break;
case HC_DOWNLOAD_FILE: case HC_DOWNLOAD_FILE:
me->downloadFileInternal(); me->downloadFileInternal(me->m_file, me->m_save_filename,
/*is_asynchron*/true );
} // switch(m_command) } // switch(m_command)
me->m_command = HC_SLEEP; me->m_command = HC_SLEEP;
} // while !m_abort } // while !m_abort
@ -221,25 +222,29 @@ std::string NetworkHttp::downloadToStrInternal(std::string url)
* will be added to file. * will be added to file.
* \param progress_data is used to have the state of the download (in %) * \param progress_data is used to have the state of the download (in %)
*/ */
bool NetworkHttp::downloadFileInternal() bool NetworkHttp::downloadFileInternal(const std::string &file,
const std::string &save_filename,
bool is_asynchron)
{ {
m_progress.set(0.0f);
CURL *session = curl_easy_init(); CURL *session = curl_easy_init();
std::string full_url = (std::string)UserConfigParams::m_server_addons std::string full_url = (std::string)UserConfigParams::m_server_addons
+ "/" + m_file; + "/" + file;
curl_easy_setopt(session, CURLOPT_URL, full_url.c_str()); curl_easy_setopt(session, CURLOPT_URL, full_url.c_str());
FILE * fout = fopen(file_manager->getAddonsFile(m_save_filename).c_str(), FILE * fout = fopen(file_manager->getAddonsFile(save_filename).c_str(),
"w"); "wb");
//from and out //from and out
curl_easy_setopt(session, CURLOPT_WRITEDATA, fout ); curl_easy_setopt(session, CURLOPT_WRITEDATA, fout );
curl_easy_setopt(session, CURLOPT_WRITEFUNCTION, fwrite); curl_easy_setopt(session, CURLOPT_WRITEFUNCTION, fwrite);
curl_easy_setopt(session, CURLOPT_PROGRESSFUNCTION, if(is_asynchron)
&NetworkHttp::progressDownload); {
// Necessary, oyherwise the progress function doesn't work curl_easy_setopt(session, CURLOPT_PROGRESSFUNCTION,
curl_easy_setopt(session, CURLOPT_NOPROGRESS, 0); &NetworkHttp::progressDownload);
// Necessary, oyherwise the progress function doesn't work
curl_easy_setopt(session, CURLOPT_NOPROGRESS, 0);
}
int success = curl_easy_perform(session); int success = curl_easy_perform(session);
@ -249,7 +254,8 @@ bool NetworkHttp::downloadFileInternal()
//stop curl //stop curl
curl_easy_cleanup(session); curl_easy_cleanup(session);
m_progress.set( (success==CURLE_OK) ? 1.0f : -1.0f ); if(is_asynchron)
m_progress.set( (success==CURLE_OK) ? 1.0f : -1.0f );
return success==CURLE_OK; return success==CURLE_OK;
} // downloadFileInternal } // downloadFileInternal
@ -263,10 +269,10 @@ bool NetworkHttp::downloadFileInternal()
bool NetworkHttp::downloadFileSynchron(const std::string &file, bool NetworkHttp::downloadFileSynchron(const std::string &file,
const std::string &save) const std::string &save)
{ {
m_file = file; const std::string &save_filename = (save!="") ? save : file;
m_save_filename = (save!="") ? save : file;
return downloadFileInternal(); return downloadFileInternal(file, save_filename,
/*is_asynchron*/false);
} // downloadFileSynchron } // downloadFileSynchron
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -73,7 +73,9 @@ private:
void updateNews(); void updateNews();
std::string downloadToStrInternal(std::string url); std::string downloadToStrInternal(std::string url);
bool downloadFileInternal(); bool downloadFileInternal(const std::string &file,
const std::string &save_filename,
bool is_asynchron);
static int progressDownload(void *clientp, float dltotal, float dlnow, static int progressDownload(void *clientp, float dltotal, float dlnow,
float ultotal, float ulnow); float ultotal, float ulnow);

View File

@ -39,17 +39,17 @@ using namespace irr::gui;
AddonsLoading::AddonsLoading(const float w, const float h, AddonsLoading::AddonsLoading(const float w, const float h,
const std::string &id) const std::string &id)
: ModalDialog(w, h) : ModalDialog(w, h)
, m_icon_loaded(ICON_NOT_LOADED)
{ {
m_addon = *(addons_manager->getAddon(id)); m_addon = *(addons_manager->getAddon(id));
loadFromFile("addons_view_dialog.stkgui"); loadFromFile("addons_view_dialog.stkgui");
m_can_install = false; m_can_install = false;
m_can_load_icon = false;
m_percent_update = false; m_percent_update = false;
pthread_mutex_init(&m_mutex_can_install, NULL); pthread_mutex_init(&m_mutex_can_install, NULL);
/*Init the icon here to be able to load a single image*/ /*Init the icon here to be able to load a single image*/
m_icon = getWidget<IconButtonWidget>("icon"); m_icon = getWidget<IconButtonWidget>("icon");
if(m_addon.isInstalled()) if(m_addon.isInstalled())
{ {
@ -59,12 +59,6 @@ AddonsLoading::AddonsLoading(const float w, const float h,
getWidget<ButtonWidget>("install")->setLabel(_("Uninstall")); getWidget<ButtonWidget>("install")->setLabel(_("Uninstall"));
} }
loadInfo();
}
// ----------------------------------------------------------------------------
void AddonsLoading::loadInfo()
{
core::stringw name = StringUtils::insertValues(_("Name: %i"), core::stringw name = StringUtils::insertValues(_("Name: %i"),
m_addon.getName().c_str() ); m_addon.getName().c_str() );
getWidget<LabelWidget>("name")->setText(name); getWidget<LabelWidget>("name")->setText(name);
@ -77,51 +71,50 @@ void AddonsLoading::loadInfo()
m_addon.getVersion()); m_addon.getVersion());
getWidget<LabelWidget>("version")->setText(version); getWidget<LabelWidget>("version")->setText(version);
pthread_t thread; pthread_t thread_id;
pthread_create(&thread, NULL, &AddonsLoading::downloadIcon, this); pthread_create(&thread_id, NULL, &AddonsLoading::downloadIcon, this);
} } // AddonsLoading
// ------------------------------------------------------------------------------------------------------ // ----------------------------------------------------------------------------
void * AddonsLoading::downloadIcon( void * pthis) void * AddonsLoading::downloadIcon( void * pthis)
{ {
AddonsLoading * pt = (AddonsLoading*)pthis; AddonsLoading *me = (AddonsLoading*)pthis;
std::string icon_name = StringUtils::getBasename(me->m_addon.getIcon());
std::string iconPath = "icon/" + pt->m_addon.getIcon(); std::string icon_path = "icon/" + me->m_addon.getIcon();
network_http->downloadFileAsynchron(iconPath, pt->m_addon.getName() + ".png");
// FIXME if (network_http->downloadFile(iconPath, addons_manager->getName() + ".png")) if(network_http->downloadFileSynchron(icon_path, icon_name))
{ {
pthread_mutex_lock(&(pt->m_mutex_can_install)); me->m_icon_loaded.set(ICON_LOADED);
pt->m_can_load_icon = true; }
pthread_mutex_unlock(&(pt->m_mutex_can_install)); else
}
// else
{ {
fprintf(stderr, "[Addons] Download icon '%s' failed\n", iconPath.c_str()); fprintf(stderr, "[Addons] Download icon '%s' failed\n",
icon_path.c_str());
} }
return NULL; return NULL;
} } // downloadIcon
// ------------------------------------------------------------------------------------------------------ // ----------------------------------------------------------------------------
GUIEngine::EventPropagation AddonsLoading::processEvent(const std::string& eventSource) GUIEngine::EventPropagation
AddonsLoading::processEvent(const std::string& eventSource)
{ {
if(eventSource == "cancel") if(eventSource == "cancel")
{ {
//input_manager->setMode(InputManager::MENU);
dismiss(); dismiss();
//return GUIEngine::EVENT_BLOCK; return GUIEngine::EVENT_BLOCK;
} }
else if(eventSource == "next") else if(eventSource == "next")
{ {
// addons_manager->nextType(addons_manager->getType()); // addons_manager->nextType(addons_manager->getType());
assert(false); assert(false);
loadInfo(); //loadInfo();
} }
else if(eventSource == "previous") else if(eventSource == "previous")
{ {
// FIXME: addons_manager->previousType(addons_manager->getType()); // FIXME: addons_manager->previousType(addons_manager->getType());
assert(false); assert(false);
loadInfo(); //loadInfo();
} }
if(eventSource == "install") if(eventSource == "install")
{ {
@ -160,8 +153,9 @@ GUIEngine::EventPropagation AddonsLoading::processEvent(const std::string& event
pthread_create(&thread, NULL, &AddonsLoading::startInstall, this); pthread_create(&thread, NULL, &AddonsLoading::startInstall, this);
} }
return GUIEngine::EVENT_LET; return GUIEngine::EVENT_LET;
} } // processEvent
// ------------------------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------
void AddonsLoading::onUpdate(float delta) void AddonsLoading::onUpdate(float delta)
{ {
@ -175,23 +169,25 @@ void AddonsLoading::onUpdate(float delta)
m_progress->setValue(addons_manager->getDownloadState()); m_progress->setValue(addons_manager->getDownloadState());
m_state->setText(addons_manager->getDownloadStateAsStr().c_str()); m_state->setText(addons_manager->getDownloadStateAsStr().c_str());
} }
if(m_can_load_icon) if(m_icon_loaded.get()==ICON_LOADED)
{ {
m_icon->setImage( (file_manager->getConfigDir() + "/" const std::string icon = StringUtils::getBasename(m_addon.getIcon());
+ m_addon.getName() + ".png").c_str(), m_icon->setImage( file_manager->getAddonsFile(icon).c_str(),
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE); IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE );
m_icon_loaded.set(ICON_SHOWN);
} }
pthread_mutex_unlock(&(m_mutex_can_install)); pthread_mutex_unlock(&(m_mutex_can_install));
} } // onUpdate
// ------------------------------------------------------------------------------------------------------ // ----------------------------------------------------------------------------
void AddonsLoading::close() void AddonsLoading::close()
{ {
AddonsScreen* curr_screen = AddonsScreen::getInstance(); AddonsScreen* curr_screen = AddonsScreen::getInstance();
((AddonsScreen*)curr_screen)->m_can_load_list = true; ((AddonsScreen*)curr_screen)->m_can_load_list = true;
dismiss(); dismiss();
} } // close
// ------------------------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------
void * AddonsLoading::startInstall(void* pthis) void * AddonsLoading::startInstall(void* pthis)
{ {
@ -209,5 +205,5 @@ void * AddonsLoading::startInstall(void* pthis)
obj->m_percent_update = false; obj->m_percent_update = false;
pthread_mutex_unlock(&(obj->m_mutex_can_install)); pthread_mutex_unlock(&(obj->m_mutex_can_install));
return NULL; return NULL;
} } // startInstall
#endif #endif

View File

@ -21,11 +21,13 @@
#ifndef HEADER_ADDONS_LOADING_HPP #ifndef HEADER_ADDONS_LOADING_HPP
#define HEADER_ADDONS_LOADING_HPP #define HEADER_ADDONS_LOADING_HPP
#include <pthread.h>
#include "addons/addon.hpp" #include "addons/addon.hpp"
#include "addons/addons_manager.hpp" #include "addons/addons_manager.hpp"
#include "guiengine/widgets.hpp" #include "guiengine/widgets.hpp"
#include "guiengine/modaldialog.hpp" #include "guiengine/modaldialog.hpp"
#include <pthread.h> #include "utils/synchronised.hpp"
class AddonsLoading : public GUIEngine::ModalDialog class AddonsLoading : public GUIEngine::ModalDialog
{ {
@ -53,16 +55,17 @@ private:
* 'm_can_load_icon' and the onUpdate function reload the icon * 'm_can_load_icon' and the onUpdate function reload the icon
* */ * */
static void * downloadIcon(void*); static void * downloadIcon(void*);
void loadInfo();
/* These three bool are some flags. /* These three bool are some flags.
* m_can_install : when the installation is finidhed, onUpdate close the * m_can_install : when the installation is finidhed, onUpdate close the
* dialog. * dialog.
* m_percent_update : to reload the download percent * m_percent_update : to reload the download percent */
* m_can_load_icon see above (function downloadIcon)*/
bool m_can_install; bool m_can_install;
bool m_percent_update; bool m_percent_update;
bool m_can_load_icon;
/** True if the icon was successfully downloaded. */
enum IconState {ICON_NOT_LOADED, ICON_LOADED, ICON_SHOWN};
Synchronised<IconState> m_icon_loaded;
public: public:
/** /**