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));
m_pMapdownloadTask = new CFetchTask;
Fetcher()->FetchFile(m_pMapdownloadTask, aUrl, m_aMapdownloadFilename, IStorage::TYPE_SAVE, UseDDNetCA, true);
m_pMapdownloadTask = Fetcher()->FetchFile(aUrl, m_aMapdownloadFilename, IStorage::TYPE_SAVE, UseDDNetCA, true);
}
else
SendMapRequest();
@ -2089,7 +2088,7 @@ void CClient::ResetMapDownload()
if(m_pMapdownloadTask)
{
m_pMapdownloadTask->Abort();
delete m_pMapdownloadTask;
m_pMapdownloadTask->Destroy();
m_pMapdownloadTask = NULL;
}
m_MapdownloadFile = 0;
@ -2135,7 +2134,7 @@ void CClient::ResetDDNetInfo()
if(m_pDDNetInfoTask)
{
m_pDDNetInfoTask->Abort();
delete m_pDDNetInfoTask;
m_pDDNetInfoTask->Destroy();
m_pDDNetInfoTask = NULL;
}
}
@ -2476,33 +2475,33 @@ void CClient::Update()
if(m_pMapdownloadTask)
{
if(m_pMapdownloadTask->State() == CFetchTask::STATE_DONE)
if(m_pMapdownloadTask->State() == IFetchTask::STATE_DONE)
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");
ResetMapDownload();
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;
}
}
if(m_pDDNetInfoTask)
{
if(m_pDDNetInfoTask->State() == CFetchTask::STATE_DONE)
if(m_pDDNetInfoTask->State() == IFetchTask::STATE_DONE)
FinishDDNetInfo();
else if(m_pDDNetInfoTask->State() == CFetchTask::STATE_ERROR)
else if(m_pDDNetInfoTask->State() == IFetchTask::STATE_ERROR)
{
dbg_msg("ddnet-info", "download failed");
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;
}
}
@ -3644,8 +3643,7 @@ void CClient::RequestDDNetInfo()
str_append(aUrl, aEscaped, sizeof(aUrl));
}
m_pDDNetInfoTask = new CFetchTask;
Fetcher()->FetchFile(m_pDDNetInfoTask, aUrl, "ddnet-info.json.tmp", IStorage::TYPE_SAVE, true, true);
m_pDDNetInfoTask = Fetcher()->FetchFile(aUrl, "ddnet-info.json.tmp", IStorage::TYPE_SAVE, true, true);
}
int CClient::GetPredictionTime()

View file

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

View file

@ -10,6 +10,42 @@
#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()
{
m_pStorage = Kernel()->RequestInterface<IStorage>();
@ -26,8 +62,9 @@ void CFetcher::Escape(char *pBuf, size_t size, const char *pStr)
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;
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_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);
return pTask;
}
int CFetcher::FetcherThread(void *pUser)
@ -66,7 +105,7 @@ int CFetcher::FetcherThread(void *pUser)
if(!File)
{
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;
}
@ -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 ")");
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);
io_close(File);
if(ret != CURLE_OK)
{
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
{
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);

View file

@ -12,7 +12,7 @@ private:
public:
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);
static int FetcherThread(void *pUser);

View file

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

View file

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

View file

@ -5,38 +5,8 @@
#include "kernel.h"
#include "stddef.h"
#define WIN32_LEAN_AND_MEAN
#include "curl/curl.h"
class CFetchTask;
typedef void (*PROGFUNC)(CFetchTask *pTask, void *pUser);
typedef void (*COMPFUNC)(CFetchTask *pDest, void *pUser);
class CFetchTask
class 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:
enum
{
@ -47,21 +17,25 @@ public:
STATE_ABORTED,
};
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; };
virtual double Current() = 0;
virtual double Size() = 0;
virtual int Progress() = 0;
virtual int State() = 0;
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
{
MACRO_INTERFACE("fetcher", 0)
public:
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;
};