- added an in progress bar when downloading tilesets

- clear the CRC cache after a new file is downloaded
This commit is contained in:
Mark Vejvoda 2011-01-04 08:44:00 +00:00
parent 3a1737d65e
commit f3eee457c0
9 changed files with 178 additions and 39 deletions

View File

@ -4160,7 +4160,20 @@ void Renderer::renderArrow(const Vec3f &pos1, const Vec3f &pos2,
glEnd();
}
void Renderer::renderProgressBar(int size, int x, int y, Font2D *font) {
void Renderer::renderProgressBar(int size, int x, int y, Font2D *font, int customWidth, string prefixLabel) {
int currentSize = size;
int maxSize = maxProgressBar;
string renderText = intToStr(static_cast<int>(size)) + "%";
if(customWidth > 0) {
if(size > 0) {
currentSize = size * (customWidth / size);
}
maxSize = customWidth;
}
if(prefixLabel != "") {
renderText = prefixLabel + renderText;
}
//bar
glBegin(GL_QUADS);
@ -4168,26 +4181,26 @@ void Renderer::renderProgressBar(int size, int x, int y, Font2D *font) {
glVertex2i(x, y);
glVertex2i(x, y+10);
glColor4fv(progressBarFront1.ptr());
glVertex2i(x+size, y+10);
glVertex2i(x+size, y);
glVertex2i(x + currentSize, y+10);
glVertex2i(x + currentSize, y);
glEnd();
//transp bar
glEnable(GL_BLEND);
glBegin(GL_QUADS);
glColor4fv(progressBarBack2.ptr());
glVertex2i(x+size, y);
glVertex2i(x+size, y+10);
glVertex2i(x + currentSize, y);
glVertex2i(x + currentSize, y+10);
glColor4fv(progressBarBack1.ptr());
glVertex2i(x+maxProgressBar, y+10);
glVertex2i(x+maxProgressBar, y);
glVertex2i(x + maxSize, y+10);
glVertex2i(x + maxSize, y);
glEnd();
glDisable(GL_BLEND);
//text
glColor3fv(defColor.ptr());
textRenderer->begin(font);
textRenderer->render(intToStr(static_cast<int>(size))+"%", x+maxProgressBar/2, y, true);
textRenderer->render(renderText.c_str(), x + maxSize / 2, y, true);
textRenderer->end();
}

View File

@ -397,7 +397,9 @@ public:
uint64 getCurrentPixelByteCount(ResourceScope rs=rsGame) const;
unsigned int getSaveScreenQueueSize();
Texture2D *saveScreenToTexture(int x, int y, int width, int height);
Texture2D *saveScreenToTexture(int x, int y, int width, int height);
void renderProgressBar(int size, int x, int y, Font2D *font,int customWidth=-1, string prefixLabel="");
private:
//private misc
@ -429,7 +431,6 @@ private:
//private aux drawing
void renderSelectionCircle(Vec3f v, int size, float radius);
void renderArrow(const Vec3f &pos1, const Vec3f &pos2, const Vec3f &color, float width);
void renderProgressBar(int size, int x, int y, Font2D *font);
void renderTile(const Vec2i &pos);
void renderQuad(int x, int y, int w, int h, const Texture2D *texture);

View File

@ -453,6 +453,8 @@ void MenuStateConnectedGame::mouseClick(int x, int y, MouseButton mouseButton){
if(ftpClientThread != NULL) {
ftpClientThread->addMapToRequests(getMissingMapFromFTPServer);
MutexSafeWrapper safeMutexFTPProgress(ftpClientThread->getProgressMutex());
fileFTPProgressList[getMissingMapFromFTPServer] = pair<int,string>(0,"");
}
}
else if(ftpMissingDataType == ftpmsg_MissingTileset) {
@ -464,6 +466,8 @@ void MenuStateConnectedGame::mouseClick(int x, int y, MouseButton mouseButton){
if(ftpClientThread != NULL) {
ftpClientThread->addTilesetToRequests(getMissingTilesetFromFTPServer);
MutexSafeWrapper safeMutexFTPProgress(ftpClientThread->getProgressMutex());
fileFTPProgressList[getMissingTilesetFromFTPServer] = pair<int,string>(0,"");
}
}
}
@ -748,6 +752,23 @@ void MenuStateConnectedGame::render() {
if(program != NULL) program->renderProgramMsgBox();
MutexSafeWrapper safeMutexFTPProgress(ftpClientThread->getProgressMutex());
if(fileFTPProgressList.size() > 0) {
int yLocation = buttonDisconnect.getY();
for(std::map<string,pair<int,string> >::iterator iterMap = fileFTPProgressList.begin();
iterMap != fileFTPProgressList.end(); ++iterMap) {
renderer.renderProgressBar(
iterMap->second.first,
10,
yLocation,
CoreData::getInstance().getDisplayFontSmall(),
350,"Downloading " + iterMap->first + " [" + iterMap->second.second + "] ");
yLocation -= 100;
}
}
safeMutexFTPProgress.ReleaseLock();
if(enableMapPreview && (mapPreview.hasFileLoaded() == true)) {
@ -1683,13 +1704,29 @@ void MenuStateConnectedGame::showFTPMessageBox(const string &text, const string
}
}
void MenuStateConnectedGame::FTPClient_CallbackEvent(string itemName, FTP_Client_CallbackType type, FTP_Client_ResultType result) {
void MenuStateConnectedGame::FTPClient_CallbackEvent(string itemName, FTP_Client_CallbackType type, FTP_Client_ResultType result, void *userdata) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(type == ftp_cct_Map) {
if(type == ftp_cct_DownloadProgress) {
FTPClientCallbackInterface::FtpProgressStats *stats = (FTPClientCallbackInterface::FtpProgressStats *)userdata;
if(stats != NULL) {
int fileProgress = 0;
if(stats->download_total > 0) {
fileProgress = (stats->download_now * 100.0 / stats->download_total);
}
printf("Got FTP Callback for [%s] fileProgress = %d [now = %f, total = %f]\n",itemName.c_str(),fileProgress,stats->download_now,stats->download_total);
fileFTPProgressList[itemName] = pair<int,string>(fileProgress,stats->currentFilename);
}
}
else if(type == ftp_cct_Map) {
getMissingMapFromFTPServerInProgress = false;
printf("Got FTP Callback for [%s] result = %d\n",itemName.c_str(),result);
MutexSafeWrapper safeMutexFTPProgress(ftpClientThread->getProgressMutex());
fileFTPProgressList.erase(itemName);
safeMutexFTPProgress.ReleaseLock();
NetworkManager &networkManager= NetworkManager::getInstance();
ClientInterface* clientInterface= networkManager.getClientInterface();
const GameSettings *gameSettings = clientInterface->getGameSettings();
@ -1711,6 +1748,10 @@ void MenuStateConnectedGame::FTPClient_CallbackEvent(string itemName, FTP_Client
getMissingTilesetFromFTPServerInProgress = false;
printf("Got FTP Callback for [%s] result = %d\n",itemName.c_str(),result);
MutexSafeWrapper safeMutexFTPProgress(ftpClientThread->getProgressMutex());
fileFTPProgressList.erase(itemName);
safeMutexFTPProgress.ReleaseLock();
NetworkManager &networkManager= NetworkManager::getInstance();
ClientInterface* clientInterface= networkManager.getClientInterface();
const GameSettings *gameSettings = clientInterface->getGameSettings();
@ -1720,10 +1761,46 @@ void MenuStateConnectedGame::FTPClient_CallbackEvent(string itemName, FTP_Client
sprintf(szMsg,"Player: %s SUCCESSFULLY downloaded the tileset: %s",getHumanPlayerName().c_str(),gameSettings->getTileset().c_str());
clientInterface->sendTextMessage(szMsg,-1, true);
// START
// Clear the CRC Cache if it is populated
//
vector<string> paths = Config::getInstance().getPathListForType(ptTilesets);
string cacheLookupId = CacheManager::getFolderTreeContentsCheckSumRecursivelyCacheLookupKey1;
std::map<string,int32> &crcTreeCache = CacheManager::getCachedItem< std::map<string,int32> >(cacheLookupId);
string pathSearchString = string("/") + itemName + string("/*");
const string filterFileExt = ".xml";
string cacheKey = "";
size_t count = paths.size();
for(size_t idx = 0; idx < count; ++idx) {
string path = paths[idx] + pathSearchString;
cacheKey += path + "_" + filterFileExt + "_";
}
if(crcTreeCache.find(cacheKey) != crcTreeCache.end()) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] CLEARING CACHED checksum for cacheKey [%s]\n",__FILE__,__FUNCTION__,__LINE__,cacheKey.c_str());
crcTreeCache.erase(cacheKey);
}
cacheLookupId = CacheManager::getFolderTreeContentsCheckSumRecursivelyCacheLookupKey2;
std::map<string,int32> &crcTreeCache2 = CacheManager::getCachedItem< std::map<string,int32> >(cacheLookupId);
count = paths.size();
for(size_t idx = 0; idx < count; ++idx) {
string path = paths[idx] + pathSearchString;
string cacheKey = path + "_" + filterFileExt;
if(crcTreeCache2.find(cacheKey) != crcTreeCache2.end()) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] CLEARING CACHED checksum for cacheKey [%s]\n",__FILE__,__FUNCTION__,__LINE__,cacheKey.c_str());
crcTreeCache2.erase(cacheKey);
}
}
// END
// Reload tilesets for the UI
findDirs(Config::getInstance().getPathListForType(ptTilesets), tileSets);
}
else {
curl_version_info_data *curlVersion= curl_version_info(CURLVERSION_NOW);
char szMsg[1024]="";

View File

@ -151,6 +151,8 @@ private:
string getMissingTilesetFromFTPServer;
bool getMissingTilesetFromFTPServerInProgress;
std::map<string,pair<int,string> > fileFTPProgressList;
public:
MenuStateConnectedGame(Program *program, MainMenu *mainMenu, JoinMenu joinMenuInfo=jmSimple, bool openNetworkSlots= false);
@ -181,7 +183,7 @@ private:
void showMessageBox(const string &text, const string &header, bool toggle);
void showFTPMessageBox(const string &text, const string &header, bool toggle);
virtual void FTPClient_CallbackEvent(string itemName, FTP_Client_CallbackType type, FTP_Client_ResultType result);
virtual void FTPClient_CallbackEvent(string itemName, FTP_Client_CallbackType type, FTP_Client_ResultType result,void *userdata);
};
}}//end namespace

View File

@ -30,6 +30,13 @@ namespace Shared { namespace PlatformCommon {
class CacheManager
{
public:
static const char *getFolderTreeContentsCheckSumRecursivelyCacheLookupKey1;
static const char *getFolderTreeContentsCheckSumRecursivelyCacheLookupKey2;
static const char *getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey1;
static const char *getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey2;
protected:
static Mutex mutexCache;

View File

@ -33,13 +33,23 @@ enum FTP_Client_ResultType {
};
enum FTP_Client_CallbackType {
ftp_cct_Map = 0,
ftp_cct_Tileset = 1
ftp_cct_Map = 0,
ftp_cct_Tileset = 1,
ftp_cct_DownloadProgress = 2
};
class FTPClientCallbackInterface {
public:
virtual void FTPClient_CallbackEvent(string itemName, FTP_Client_CallbackType type, FTP_Client_ResultType result) = 0;
struct FtpProgressStats {
double download_total;
double download_now;
double upload_total;
double upload_now;
string currentFilename;
};
virtual void FTPClient_CallbackEvent(string itemName, FTP_Client_CallbackType type, FTP_Client_ResultType result, void *userdata) = 0;
};
class FTPClientThread : public BaseThread
@ -63,6 +73,8 @@ protected:
void getTilesetFromServer(string tileSetName);
FTP_Client_ResultType getTilesetFromServer(string tileSetName, string tileSetNameSubfolder, string ftpUser, string ftpUserPassword);
Mutex mutexProgressMutex;
public:
FTPClientThread(int portNumber,string serverUrl, std::pair<string,string> mapsPath, std::pair<string,string> tilesetsPath, FTPClientCallbackInterface *pCBObject);
@ -72,6 +84,9 @@ public:
void addMapToRequests(string mapFilename);
void addTilesetToRequests(string tileSetName);
FTPClientCallbackInterface * getCallBackObject() { return pCBObject; }
Mutex * getProgressMutex() { return &mutexProgressMutex; }
};
}}//end namespace

View File

@ -14,5 +14,9 @@
namespace Shared { namespace PlatformCommon {
Mutex CacheManager::mutexCache;
const char *CacheManager::getFolderTreeContentsCheckSumRecursivelyCacheLookupKey1 = "CRC_Cache_FileTree1";
const char *CacheManager::getFolderTreeContentsCheckSumRecursivelyCacheLookupKey2 = "CRC_Cache_FileTree2";
const char *CacheManager::getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey1 = "CRC_Cache_FileTreeList1";
const char *CacheManager::getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey2 = "CRC_Cache_FileTreeList2";
}}//end namespace

View File

@ -369,12 +369,8 @@ bool EndsWith(const string &str, const string& key)
//finds all filenames like path and gets their checksum of all files combined
int32 getFolderTreeContentsCheckSumRecursively(vector<string> paths, string pathSearchString, const string filterFileExt, Checksum *recursiveChecksum) {
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
// !!! OLD local CACHE
//static std::map<string,int32> crcTreeCache;
string cacheLookupId = string(__FILE__) + intToStr(__LINE__);
string cacheLookupId = CacheManager::getFolderTreeContentsCheckSumRecursivelyCacheLookupKey1;
std::map<string,int32> &crcTreeCache = CacheManager::getCachedItem< std::map<string,int32> >(cacheLookupId);
string cacheKey = "";
@ -414,10 +410,7 @@ int32 getFolderTreeContentsCheckSumRecursively(vector<string> paths, string path
//finds all filenames like path and gets their checksum of all files combined
int32 getFolderTreeContentsCheckSumRecursively(const string &path, const string &filterFileExt, Checksum *recursiveChecksum) {
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path = [%s] filterFileExt = [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str(),filterFileExt.c_str());
// !!! OLD local CACHE
//static std::map<string,int32> crcTreeCache;
string cacheLookupId = string(__FILE__) + intToStr(__LINE__);
string cacheLookupId = CacheManager::getFolderTreeContentsCheckSumRecursivelyCacheLookupKey2;
std::map<string,int32> &crcTreeCache = CacheManager::getCachedItem< std::map<string,int32> >(cacheLookupId);
string cacheKey = path + "_" + filterFileExt;
@ -522,10 +515,8 @@ int32 getFolderTreeContentsCheckSumRecursively(const string &path, const string
}
vector<std::pair<string,int32> > getFolderTreeContentsCheckSumListRecursively(vector<string> paths, string pathSearchString, string filterFileExt, vector<std::pair<string,int32> > *recursiveMap) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//static std::map<string,vector<std::pair<string,int32> > > crcTreeCache;
string cacheLookupId = string(__FILE__) + intToStr(__LINE__);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
string cacheLookupId = CacheManager::getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey1;
std::map<string,vector<std::pair<string,int32> > > &crcTreeCache = CacheManager::getCachedItem< std::map<string,vector<std::pair<string,int32> > > >(cacheLookupId);
string cacheKey = "";
@ -564,9 +555,7 @@ vector<std::pair<string,int32> > getFolderTreeContentsCheckSumListRecursively(ve
//finds all filenames like path and gets the checksum of each file
vector<std::pair<string,int32> > getFolderTreeContentsCheckSumListRecursively(const string &path, const string &filterFileExt, vector<std::pair<string,int32> > *recursiveMap) {
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path = [%s] filterFileExt = [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str(),filterFileExt.c_str());
//static std::map<string,vector<std::pair<string,int32> > > crcTreeCache;
string cacheLookupId = string(__FILE__) + intToStr(__LINE__);
string cacheLookupId = CacheManager::getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey2;
std::map<string,vector<std::pair<string,int32> > > &crcTreeCache = CacheManager::getCachedItem< std::map<string,vector<std::pair<string,int32> > > >(cacheLookupId);
string cacheKey = path + "_" + filterFileExt;

View File

@ -32,10 +32,12 @@ namespace Shared { namespace PlatformCommon {
*/
struct FtpFile {
const char *itemName;
const char *filename;
const char *filepath;
FILE *stream;
FTPClientThread *ftpServer;
string currentFilename;
};
static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream) {
@ -88,6 +90,10 @@ static long file_is_comming(struct curl_fileinfo *finfo,void *data,int remains)
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n===> FTP Client thread file_is_comming: remains: [%3d] filename: [%s] size: [%10luB] ", remains, finfo->filename,(unsigned long)finfo->size);
if(out != NULL) {
out->currentFilename = finfo->filename;
}
switch(finfo->filetype) {
case CURLFILETYPE_DIRECTORY:
printf("DIR (creating [%s%s])\n",rootFilePath.c_str(),finfo->filename);
@ -131,6 +137,29 @@ static long file_is_downloaded(void *data) {
return CURL_CHUNK_END_FUNC_OK;
}
int file_progress(struct FtpFile *out,double download_total, double download_now, double upload_total,double upload_now) {
// printf("%d / %d (%g %%)\n", d, t, d*100.0/t);
//gdk_threads_enter();
//gtk_progress_set_value(GTK_PROGRESS(bar), d*100.0/t);
//gdk_threads_leave();
if(out != NULL &&
out->ftpServer != NULL &&
out->ftpServer->getCallBackObject() != NULL) {
FTPClientCallbackInterface::FtpProgressStats stats;
stats.download_total = download_total;
stats.download_now = download_now;
stats.upload_total = upload_total;
stats.upload_now = upload_now;
stats.currentFilename = out->currentFilename;
MutexSafeWrapper safeMutex(out->ftpServer->getProgressMutex());
out->ftpServer->getCallBackObject()->FTPClient_CallbackEvent(out->itemName, ftp_cct_DownloadProgress, ftp_crt_SUCCESS, &stats);
}
return 0;
}
FTPClientThread::FTPClientThread(int portNumber, string serverUrl, std::pair<string,string> mapsPath, std::pair<string,string> tilesetsPath, FTPClientCallbackInterface *pCBObject) : BaseThread() {
this->portNumber = portNumber;
this->serverUrl = serverUrl;
@ -171,6 +200,7 @@ FTP_Client_ResultType FTPClientThread::getMapFromServer(string mapFileName, stri
if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Client thread about to try to RETR into [%s]\n",destFile.c_str());
struct FtpFile ftpfile = {
NULL,
destFile.c_str(), /* name to store the file as if succesful */
NULL,
NULL,
@ -233,7 +263,7 @@ void FTPClientThread::getMapFromServer(string mapFileName) {
}
if(this->pCBObject != NULL) {
this->pCBObject->FTPClient_CallbackEvent(mapFileName,ftp_cct_Map,result);
this->pCBObject->FTPClient_CallbackEvent(mapFileName,ftp_cct_Map,result,NULL);
}
}
@ -258,7 +288,7 @@ void FTPClientThread::getTilesetFromServer(string tileSetName) {
}
if(this->pCBObject != NULL) {
this->pCBObject->FTPClient_CallbackEvent(tileSetName,ftp_cct_Tileset,result);
this->pCBObject->FTPClient_CallbackEvent(tileSetName,ftp_cct_Tileset,result,NULL);
}
}
@ -301,6 +331,7 @@ FTP_Client_ResultType FTPClientThread::getTilesetFromServer(string tileSetName,
if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Client thread about to try to RETR into [%s]\n",destFile.c_str());
struct FtpFile ftpfile = {
tileSetName.c_str(),
destFile.c_str(), // name to store the file as if succesful
destFile.c_str(),
NULL,
@ -328,13 +359,9 @@ FTP_Client_ResultType FTPClientThread::getTilesetFromServer(string tileSetName,
// callback is called before download of concrete file started
curl_easy_setopt(curl, CURLOPT_CHUNK_BGN_FUNCTION, file_is_comming);
// callback is called after data from the file have been transferred
curl_easy_setopt(curl, CURLOPT_CHUNK_END_FUNCTION, file_is_downloaded);
// put transfer data into callbacks
// helper data
//struct callback_data data = { 0 };
curl_easy_setopt(curl, CURLOPT_CHUNK_DATA, &ftpfile);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
@ -343,6 +370,10 @@ FTP_Client_ResultType FTPClientThread::getTilesetFromServer(string tileSetName,
// Set a pointer to our struct to pass to the callback
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, file_progress);
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &ftpfile);
// Switch on full protocol/debug output
if(SystemFlags::VERBOSE_MODE_ENABLED) curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);