Use a proper interface for CFetchTask

This commit is contained in:
Learath2 2017-10-09 10:41:41 +02:00 committed by Learath
parent d15dcd3c58
commit 9bce7e8630
7 changed files with 83 additions and 73 deletions

View file

@ -1517,8 +1517,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket)
str_append(aUrl, aEscaped, sizeof(aUrl)); str_append(aUrl, aEscaped, sizeof(aUrl));
m_pMapdownloadTask = new CFetchTask; m_pMapdownloadTask = Fetcher()->FetchFile(aUrl, m_aMapdownloadFilename, IStorage::TYPE_SAVE, UseDDNetCA, true);
Fetcher()->FetchFile(m_pMapdownloadTask, aUrl, m_aMapdownloadFilename, IStorage::TYPE_SAVE, UseDDNetCA, true);
} }
else else
SendMapRequest(); SendMapRequest();
@ -2089,7 +2088,7 @@ void CClient::ResetMapDownload()
if(m_pMapdownloadTask) if(m_pMapdownloadTask)
{ {
m_pMapdownloadTask->Abort(); m_pMapdownloadTask->Abort();
delete m_pMapdownloadTask; m_pMapdownloadTask->Destroy();
m_pMapdownloadTask = NULL; m_pMapdownloadTask = NULL;
} }
m_MapdownloadFile = 0; m_MapdownloadFile = 0;
@ -2135,7 +2134,7 @@ void CClient::ResetDDNetInfo()
if(m_pDDNetInfoTask) if(m_pDDNetInfoTask)
{ {
m_pDDNetInfoTask->Abort(); m_pDDNetInfoTask->Abort();
delete m_pDDNetInfoTask; m_pDDNetInfoTask->Destroy();
m_pDDNetInfoTask = NULL; m_pDDNetInfoTask = NULL;
} }
} }
@ -2476,33 +2475,33 @@ void CClient::Update()
if(m_pMapdownloadTask) if(m_pMapdownloadTask)
{ {
if(m_pMapdownloadTask->State() == CFetchTask::STATE_DONE) if(m_pMapdownloadTask->State() == IFetchTask::STATE_DONE)
FinishMapDownload(); FinishMapDownload();
else if(m_pMapdownloadTask->State() == CFetchTask::STATE_ERROR) else if(m_pMapdownloadTask->State() == IFetchTask::STATE_ERROR)
{ {
dbg_msg("webdl", "http failed, falling back to gameserver"); dbg_msg("webdl", "http failed, falling back to gameserver");
ResetMapDownload(); ResetMapDownload();
SendMapRequest(); SendMapRequest();
} }
else if(m_pMapdownloadTask->State() == CFetchTask::STATE_ABORTED) else if(m_pMapdownloadTask->State() == IFetchTask::STATE_ABORTED)
{ {
delete m_pMapdownloadTask; m_pMapdownloadTask->Destroy();
m_pMapdownloadTask = NULL; m_pMapdownloadTask = NULL;
} }
} }
if(m_pDDNetInfoTask) if(m_pDDNetInfoTask)
{ {
if(m_pDDNetInfoTask->State() == CFetchTask::STATE_DONE) if(m_pDDNetInfoTask->State() == IFetchTask::STATE_DONE)
FinishDDNetInfo(); FinishDDNetInfo();
else if(m_pDDNetInfoTask->State() == CFetchTask::STATE_ERROR) else if(m_pDDNetInfoTask->State() == IFetchTask::STATE_ERROR)
{ {
dbg_msg("ddnet-info", "download failed"); dbg_msg("ddnet-info", "download failed");
ResetDDNetInfo(); ResetDDNetInfo();
} }
else if(m_pDDNetInfoTask->State() == CFetchTask::STATE_ABORTED) else if(m_pDDNetInfoTask->State() == IFetchTask::STATE_ABORTED)
{ {
delete m_pDDNetInfoTask; m_pDDNetInfoTask->Destroy();
m_pDDNetInfoTask = NULL; m_pDDNetInfoTask = NULL;
} }
} }
@ -3644,8 +3643,7 @@ void CClient::RequestDDNetInfo()
str_append(aUrl, aEscaped, sizeof(aUrl)); str_append(aUrl, aEscaped, sizeof(aUrl));
} }
m_pDDNetInfoTask = new CFetchTask; m_pDDNetInfoTask = Fetcher()->FetchFile(aUrl, "ddnet-info.json.tmp", IStorage::TYPE_SAVE, true, true);
Fetcher()->FetchFile(m_pDDNetInfoTask, aUrl, "ddnet-info.json.tmp", IStorage::TYPE_SAVE, true, true);
} }
int CClient::GetPredictionTime() int CClient::GetPredictionTime()

View file

@ -126,7 +126,7 @@ class CClient : public IClient, public CDemoPlayer::IListener
char m_aCmdConnect[256]; char m_aCmdConnect[256];
// map download // map download
CFetchTask *m_pMapdownloadTask; IFetchTask *m_pMapdownloadTask;
char m_aMapdownloadFilename[256]; char m_aMapdownloadFilename[256];
char m_aMapdownloadName[256]; char m_aMapdownloadName[256];
IOHANDLE m_MapdownloadFile; IOHANDLE m_MapdownloadFile;
@ -135,7 +135,7 @@ class CClient : public IClient, public CDemoPlayer::IListener
int m_MapdownloadAmount; int m_MapdownloadAmount;
int m_MapdownloadTotalsize; int m_MapdownloadTotalsize;
CFetchTask *m_pDDNetInfoTask; IFetchTask *m_pDDNetInfoTask;
// time // time
CSmoothTime m_GameTime[2]; CSmoothTime m_GameTime[2];
@ -300,7 +300,7 @@ public:
void FinishDDNetInfo(); void FinishDDNetInfo();
void LoadDDNetInfo(); void LoadDDNetInfo();
virtual CFetchTask *MapDownloadTask() { return m_pMapdownloadTask; } virtual IFetchTask *MapDownloadTask() { return m_pMapdownloadTask; }
virtual const char *MapDownloadName() { return m_aMapdownloadName; } virtual const char *MapDownloadName() { return m_aMapdownloadName; }
virtual int MapDownloadAmount() { return !m_pMapdownloadTask ? m_MapdownloadAmount : (int)m_pMapdownloadTask->Current(); } virtual int MapDownloadAmount() { return !m_pMapdownloadTask ? m_MapdownloadAmount : (int)m_pMapdownloadTask->Current(); }
virtual int MapDownloadTotalsize() { return !m_pMapdownloadTask ? m_MapdownloadTotalsize : (int)m_pMapdownloadTask->Size(); } virtual int MapDownloadTotalsize() { return !m_pMapdownloadTask ? m_MapdownloadTotalsize : (int)m_pMapdownloadTask->Size(); }

View file

@ -10,6 +10,42 @@
#include "fetcher.h" #include "fetcher.h"
class CFetchTask : IFetchTask
{
friend class CFetcher;
class CFetcher *m_pFetcher;
CJob m_Job;
CURL *m_pHandle;
void *m_pUser;
char m_aUrl[256];
char m_aDest[128];
int m_StorageType;
bool m_UseDDNetCA;
bool m_CanTimeout;
PROGFUNC m_pfnProgressCallback;
COMPFUNC m_pfnCompCallback;
double m_Size;
double m_Current;
int m_Progress;
int m_State;
bool m_Abort;
public:
double Current() const { return m_Current; };
double Size() const { return m_Size; };
int Progress() const { return m_Progress; };
int State() const { return m_State; };
const char *Dest() const { return m_aDest; };
void Abort() { m_Abort = true; };
void Destroy() { mem_free(this); };
};
bool CFetcher::Init() bool CFetcher::Init()
{ {
m_pStorage = Kernel()->RequestInterface<IStorage>(); m_pStorage = Kernel()->RequestInterface<IStorage>();
@ -26,8 +62,9 @@ void CFetcher::Escape(char *pBuf, size_t size, const char *pStr)
curl_free(pEsc); curl_free(pEsc);
} }
void CFetcher::FetchFile(CFetchTask *pTask, const char *pUrl, const char *pDest, int StorageType, bool UseDDNetCA, bool CanTimeout, void *pUser, COMPFUNC pfnCompCb, PROGFUNC pfnProgCb) IFetchTask *CFetcher::FetchFile(const char *pUrl, const char *pDest, int StorageType, bool UseDDNetCA, bool CanTimeout, void *pUser, COMPFUNC pfnCompCb, PROGFUNC pfnProgCb)
{ {
CFetchTask *pTask = (CFetchTask *)mem_alloc(sizeof *pTask, 1);
pTask->m_pFetcher = this; pTask->m_pFetcher = this;
str_copy(pTask->m_aUrl, pUrl, sizeof(pTask->m_aUrl)); str_copy(pTask->m_aUrl, pUrl, sizeof(pTask->m_aUrl));
@ -40,8 +77,10 @@ void CFetcher::FetchFile(CFetchTask *pTask, const char *pUrl, const char *pDest,
pTask->m_Abort = false; pTask->m_Abort = false;
pTask->m_Size = pTask->m_Progress = 0; pTask->m_Size = pTask->m_Progress = 0;
pTask->m_State = CFetchTask::STATE_QUEUED; pTask->m_State = IFetchTask::STATE_QUEUED;
m_pEngine->AddJob(&pTask->m_Job, FetcherThread, pTask); m_pEngine->AddJob(&pTask->m_Job, FetcherThread, pTask);
return pTask;
} }
int CFetcher::FetcherThread(void *pUser) int CFetcher::FetcherThread(void *pUser)
@ -66,7 +105,7 @@ int CFetcher::FetcherThread(void *pUser)
if(!File) if(!File)
{ {
dbg_msg("fetcher", "i/o error, cannot open file: %s", pTask->m_aDest); dbg_msg("fetcher", "i/o error, cannot open file: %s", pTask->m_aDest);
pTask->m_State = CFetchTask::STATE_ERROR; pTask->m_State = IFetchTask::STATE_ERROR;
return 1; return 1;
} }
@ -105,18 +144,18 @@ int CFetcher::FetcherThread(void *pUser)
curl_easy_setopt(pTask->m_pHandle, CURLOPT_USERAGENT, "DDNet " GAME_RELEASE_VERSION " (" CONF_PLATFORM_STRING "; " CONF_ARCH_STRING ")"); curl_easy_setopt(pTask->m_pHandle, CURLOPT_USERAGENT, "DDNet " GAME_RELEASE_VERSION " (" CONF_PLATFORM_STRING "; " CONF_ARCH_STRING ")");
dbg_msg("fetcher", "downloading %s", pTask->m_aDest); dbg_msg("fetcher", "downloading %s", pTask->m_aDest);
pTask->m_State = CFetchTask::STATE_RUNNING; pTask->m_State = IFetchTask::STATE_RUNNING;
int ret = curl_easy_perform(pTask->m_pHandle); int ret = curl_easy_perform(pTask->m_pHandle);
io_close(File); io_close(File);
if(ret != CURLE_OK) if(ret != CURLE_OK)
{ {
dbg_msg("fetcher", "task failed. libcurl error: %s", aErr); dbg_msg("fetcher", "task failed. libcurl error: %s", aErr);
pTask->m_State = (ret == CURLE_ABORTED_BY_CALLBACK) ? CFetchTask::STATE_ABORTED : CFetchTask::STATE_ERROR; pTask->m_State = (ret == CURLE_ABORTED_BY_CALLBACK) ? IFetchTask::STATE_ABORTED : IFetchTask::STATE_ERROR;
} }
else else
{ {
dbg_msg("fetcher", "task done %s", pTask->m_aDest); dbg_msg("fetcher", "task done %s", pTask->m_aDest);
pTask->m_State = CFetchTask::STATE_DONE; pTask->m_State = IFetchTask::STATE_DONE;
} }
curl_easy_cleanup(pTask->m_pHandle); curl_easy_cleanup(pTask->m_pHandle);

View file

@ -12,7 +12,7 @@ private:
public: public:
virtual bool Init(); virtual bool Init();
virtual void FetchFile(CFetchTask *pTask, const char *pUrl, const char *pDest, int StorageType = -2, bool UseDDNetCA = false, bool CanTimeout = true, void *pUser = 0, COMPFUNC pfnCompCb = 0, PROGFUNC pfnProgCb = 0); virtual IFetchTask *FetchFile(const char *pUrl, const char *pDest, int StorageType = -2, bool UseDDNetCA = false, bool CanTimeout = true, void *pUser = 0, COMPFUNC pfnCompCb = 0, PROGFUNC pfnProgCb = 0);
virtual void Escape(char *pBud, size_t size, const char *pStr); virtual void Escape(char *pBud, size_t size, const char *pStr);
static int FetcherThread(void *pUser); static int FetcherThread(void *pUser);

View file

@ -32,14 +32,14 @@ void CUpdater::Init()
#endif #endif
} }
void CUpdater::ProgressCallback(CFetchTask *pTask, void *pUser) void CUpdater::ProgressCallback(IFetchTask *pTask, void *pUser)
{ {
CUpdater *pUpdate = (CUpdater *)pUser; CUpdater *pUpdate = (CUpdater *)pUser;
str_copy(pUpdate->m_Status, pTask->Dest(), sizeof(pUpdate->m_Status)); str_copy(pUpdate->m_Status, pTask->Dest(), sizeof(pUpdate->m_Status));
pUpdate->m_Percent = pTask->Progress(); pUpdate->m_Percent = pTask->Progress();
} }
void CUpdater::CompletionCallback(CFetchTask *pTask, void *pUser) void CUpdater::CompletionCallback(IFetchTask *pTask, void *pUser)
{ {
CUpdater *pUpdate = (CUpdater *)pUser; CUpdater *pUpdate = (CUpdater *)pUser;
const char *b = 0; const char *b = 0;
@ -49,19 +49,19 @@ void CUpdater::CompletionCallback(CFetchTask *pTask, void *pUser)
b = b ? b : pTask->Dest(); b = b ? b : pTask->Dest();
if(!str_comp(b, "update.json")) if(!str_comp(b, "update.json"))
{ {
if(pTask->State() == CFetchTask::STATE_DONE) if(pTask->State() == IFetchTask::STATE_DONE)
pUpdate->m_State = GOT_MANIFEST; pUpdate->m_State = GOT_MANIFEST;
else if(pTask->State() == CFetchTask::STATE_ERROR) else if(pTask->State() == IFetchTask::STATE_ERROR)
pUpdate->m_State = FAIL; pUpdate->m_State = FAIL;
} }
else if(!str_comp(b, pUpdate->m_aLastFile)) else if(!str_comp(b, pUpdate->m_aLastFile))
{ {
if(pTask->State() == CFetchTask::STATE_DONE) if(pTask->State() == IFetchTask::STATE_DONE)
pUpdate->m_State = MOVE_FILES; pUpdate->m_State = MOVE_FILES;
else if(pTask->State() == CFetchTask::STATE_ERROR) else if(pTask->State() == IFetchTask::STATE_ERROR)
pUpdate->m_State = FAIL; pUpdate->m_State = FAIL;
} }
delete pTask; pTask->Destroy();
} }
void CUpdater::FetchFile(const char *pFile, const char *pDestPath) void CUpdater::FetchFile(const char *pFile, const char *pDestPath)
@ -71,8 +71,7 @@ void CUpdater::FetchFile(const char *pFile, const char *pDestPath)
if(!pDestPath) if(!pDestPath)
pDestPath = pFile; pDestPath = pFile;
str_format(aPath, sizeof(aPath), "update/%s", pDestPath); str_format(aPath, sizeof(aPath), "update/%s", pDestPath);
CFetchTask *Task = new CFetchTask; m_pFetcher->FetchFile(aBuf, aPath, -2, true, false, this, &CUpdater::CompletionCallback, &CUpdater::ProgressCallback);
m_pFetcher->FetchFile(Task, aBuf, aPath, -2, true, false, this, &CUpdater::CompletionCallback, &CUpdater::ProgressCallback);
} }
void CUpdater::MoveFile(const char *pFile) void CUpdater::MoveFile(const char *pFile)

View file

@ -63,8 +63,8 @@ class CUpdater : public IUpdater
public: public:
CUpdater(); CUpdater();
static void ProgressCallback(CFetchTask *pTask, void *pUser); static void ProgressCallback(IFetchTask *pTask, void *pUser);
static void CompletionCallback(CFetchTask *pTask, void *pUser); static void CompletionCallback(IFetchTask *pTask, void *pUser);
int GetCurrentState() { return m_State; }; int GetCurrentState() { return m_State; };
char *GetCurrentFile() { return m_Status; }; char *GetCurrentFile() { return m_Status; };

View file

@ -5,38 +5,8 @@
#include "kernel.h" #include "kernel.h"
#include "stddef.h" #include "stddef.h"
#define WIN32_LEAN_AND_MEAN class IFetchTask
#include "curl/curl.h"
class CFetchTask;
typedef void (*PROGFUNC)(CFetchTask *pTask, void *pUser);
typedef void (*COMPFUNC)(CFetchTask *pDest, void *pUser);
class CFetchTask
{ {
friend class CFetcher;
class CFetcher *m_pFetcher;
CJob m_Job;
CURL *m_pHandle;
void *m_pUser;
char m_aUrl[256];
char m_aDest[128];
int m_StorageType;
bool m_UseDDNetCA;
bool m_CanTimeout;
PROGFUNC m_pfnProgressCallback;
COMPFUNC m_pfnCompCallback;
double m_Size;
double m_Current;
int m_Progress;
int m_State;
bool m_Abort;
public: public:
enum enum
{ {
@ -47,21 +17,25 @@ public:
STATE_ABORTED, STATE_ABORTED,
}; };
double Current() const { return m_Current; }; virtual double Current() = 0;
double Size() const { return m_Size; }; virtual double Size() = 0;
int Progress() const { return m_Progress; }; virtual int Progress() = 0;
int State() const { return m_State; }; virtual int State() = 0;
const char *Dest() const { return m_aDest; }; virtual const char *Dest() = 0;
virtual void Abort() = 0;
void Abort() { m_Abort = true; }; virtual void Destroy() = 0;
}; };
typedef void (*PROGFUNC)(IFetchTask *pTask, void *pUser);
typedef void (*COMPFUNC)(IFetchTask *pDest, void *pUser);
class IFetcher : public IInterface class IFetcher : public IInterface
{ {
MACRO_INTERFACE("fetcher", 0) MACRO_INTERFACE("fetcher", 0)
public: public:
virtual bool Init() = 0; virtual bool Init() = 0;
virtual void FetchFile(CFetchTask *pTask, const char *pUrl, const char *pDest, int StorageType = -2, bool UseDDNetCA = false, bool CanTimeout = true, void *pUser = 0, COMPFUNC pfnCompCb = 0, PROGFUNC pfnProgCb = 0) = 0; virtual IFetchTask *FetchFile(const char *pUrl, const char *pDest, int StorageType = -2, bool UseDDNetCA = false, bool CanTimeout = true, void *pUser = 0, COMPFUNC pfnCompCb = 0, PROGFUNC pfnProgCb = 0) = 0;
virtual void Escape(char *pBud, size_t size, const char *pStr) = 0; virtual void Escape(char *pBud, size_t size, const char *pStr) = 0;
}; };