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();
break;
case HC_DOWNLOAD_FILE:
me->downloadFileInternal();
me->downloadFileInternal(me->m_file, me->m_save_filename,
/*is_asynchron*/true );
} // switch(m_command)
me->m_command = HC_SLEEP;
} // while !m_abort
@ -221,25 +222,29 @@ std::string NetworkHttp::downloadToStrInternal(std::string url)
* will be added to file.
* \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();
std::string full_url = (std::string)UserConfigParams::m_server_addons
+ "/" + m_file;
+ "/" + file;
curl_easy_setopt(session, CURLOPT_URL, full_url.c_str());
FILE * fout = fopen(file_manager->getAddonsFile(m_save_filename).c_str(),
"w");
FILE * fout = fopen(file_manager->getAddonsFile(save_filename).c_str(),
"wb");
//from and out
curl_easy_setopt(session, CURLOPT_WRITEDATA, fout );
curl_easy_setopt(session, CURLOPT_WRITEFUNCTION, fwrite);
curl_easy_setopt(session, CURLOPT_PROGRESSFUNCTION,
&NetworkHttp::progressDownload);
// Necessary, oyherwise the progress function doesn't work
curl_easy_setopt(session, CURLOPT_NOPROGRESS, 0);
if(is_asynchron)
{
curl_easy_setopt(session, CURLOPT_PROGRESSFUNCTION,
&NetworkHttp::progressDownload);
// Necessary, oyherwise the progress function doesn't work
curl_easy_setopt(session, CURLOPT_NOPROGRESS, 0);
}
int success = curl_easy_perform(session);
@ -249,7 +254,8 @@ bool NetworkHttp::downloadFileInternal()
//stop curl
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;
} // downloadFileInternal
@ -263,10 +269,10 @@ bool NetworkHttp::downloadFileInternal()
bool NetworkHttp::downloadFileSynchron(const std::string &file,
const std::string &save)
{
m_file = file;
m_save_filename = (save!="") ? save : file;
const std::string &save_filename = (save!="") ? save : file;
return downloadFileInternal();
return downloadFileInternal(file, save_filename,
/*is_asynchron*/false);
} // downloadFileSynchron
// ----------------------------------------------------------------------------

View File

@ -73,7 +73,9 @@ private:
void updateNews();
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,
float ultotal, float ulnow);

View File

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

View File

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