Click to See Complete Forum and Search --> : creating a new thread to UT (one threaded)


Zisu
December 14th, 2004, 08:11 AM
What I'm trying to accomplish is Redirected Downloads to an old UT based game Rune (I'm in a team creating a patch).

Unreal engine runs in one thread and hard locks if native C++ code takes too much time. This is why I need to create a new thread, for downloading files, unzipping and installing them.

For those who know some unrealscript, I plan to spawn a clientside class subclassing actor. This subclass will contain the native code that is implemented in dll (which in general is just a package of functions). When native function (which runs in the same thread as engine) is called, it will create a thread and return. I want the thread to stay running and complete its task. This, I think, is the easy part.

I don't think I can store the threadid anywhere (execution of the code, lets say X, that created this thread is finished) so it has to be standalone. Moreover, I want to inform the user about progress and when all is finished, I want to connect to the server. This can only be done by passing function pointers from X to the thread in the argument struct, since the thread cant directly connect to the engine. But can this passing of function pointers be done (and I dont want to include all the h files from X)? Anything that you find or otherwise comment in this is appreciated.

Andreas Masur
December 14th, 2004, 09:50 AM
Okay....I basically understand only half of what you have said, however, that might even due to the problem, that I do not know the game itself...anyway...maybe the following will help...

The following is a download class which downloads a file from a HTTP-Server in its own thread...

#define HTTPBUFLEN 512 // Size of HTTP buffer

class CDownload
{
public:
CDownload(const char *cszURL, const char *cszFileName)
{
m_URL = cszURL;
m_FileName = cszFileName;

// Create thread
m_hThread = ::CreateThread(0, 0, Thread, this, 0, 0);
}

virtual ~CDownload() { ::CloseHandle(m_hThread); }

CString &GetCause() { return Cause; }

private:
HANDLE m_hThread;
CString m_Cause;
CString m_URL;
CString m_FileName;

static UINT Thread(LPVOID pParam);
};


UINT CDownload::Thread(LPVOID pParam)
{
CDownload *pParent = static_cast<CDownload *>(pParam);

char szHTTPBuffer[HTTPBUFLEN] = "";
TCHAR szCause[255] = "";
CString Cause("YES");

TRY
{
CInternetSession InternetSession;

CStdioFile *pRemoteFile = InternetSession.OpenURL(pParent->m_URL,
1,
INTERNET_FLAG_TRANSFER_BINARY |
INTERNET_FLAG_RELOAD);

CFile LocalFile(pParent->m_FileName,
CFile::modeCreate | CFile::modeWrite | CFile::typeBinary);

int iNumOfBytes = 0;

while(iNumOfBytes = pRemoteFile->Read(static_cast<void *>(szHTTPBuffer),
sizeof(szHTTPBuffer)))
{
LocalFile.Write(static_cast<const void *>(szHTTPBuffer), iNumOfBytes);

// Clear buffer
memset(szHTTPBuffer, 0, sizeof(szHTTPBuffer));
}
}
CATCH_ALL(Exception)
{
Exception->GetErrorMessage(szCause, sizeof(szCause) - 1);
pParent->m_Cause = szCause;

return 1;
}

return 0;
}

In your application you can then start a download with the following...

CDownload DownloadOne("http://www.url.com/File_A.zip", "c:\\file_a.zip");
CDownload DownloadTwo("http://www.url.com/File_B.zip", "c:\\file_b.zip");

It is of course just a small sample to give you the idea...there is no functionality added like signaling the finishing of the download etc. :cool:

Zisu
December 14th, 2004, 03:36 PM
This is why I contacted this forum :)

Thanks. I will ask more when I decide I have done all I can and nothing still works

Andreas Masur
December 14th, 2004, 03:43 PM
You are welcome....