264 lines
11 KiB
C++
264 lines
11 KiB
C++
#include "StdAfx.h"
|
||
#include "Stream.h"
|
||
#include "BackgroundLoader.h"
|
||
#include "SundriesFunc.h"
|
||
#include "DnCommonUtil.h"
|
||
|
||
#ifdef _DEBUG
|
||
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
|
||
#endif
|
||
|
||
CBackgroundLoaderCallback::~CBackgroundLoaderCallback()
|
||
{
|
||
int i;
|
||
|
||
for( i = 0; i < ( int )m_vecCallbackPushedLoader.size(); i++ )
|
||
{
|
||
m_vecCallbackPushedLoader[ i ]->EraseCallback( this );
|
||
}
|
||
}
|
||
|
||
void CBackgroundLoaderCallback::OnLoadComplete( CBackgroundLoader *pLoader )
|
||
{
|
||
std::vector< CBackgroundLoader * >::iterator it;
|
||
|
||
it = std::find( m_vecCallbackPushedLoader.begin(), m_vecCallbackPushedLoader.end(), pLoader );
|
||
if( it != m_vecCallbackPushedLoader.end() )
|
||
{
|
||
m_vecCallbackPushedLoader.erase( it );
|
||
}
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
//
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
bool CBackgroundLoader::s_bBeginBackgroundLoad = false;
|
||
bool CBackgroundLoader::s_bNowLoading = false;
|
||
HANDLE CBackgroundLoader::s_hThread = NULL;
|
||
std::vector< SLoaderInfo > CBackgroundLoader::s_vecLoadList;
|
||
CSyncLock CBackgroundLoader::m_LoadListLock;
|
||
HANDLE CBackgroundLoader::s_hLoaderEvent[ 2 ] = { NULL, NULL };
|
||
|
||
|
||
CBackgroundLoader::CBackgroundLoader(void)
|
||
{
|
||
m_bReady = true;
|
||
}
|
||
|
||
CBackgroundLoader::~CBackgroundLoader(void)
|
||
{
|
||
}
|
||
|
||
void CBackgroundLoader::BeginBackgroundLoad()
|
||
{
|
||
int i;
|
||
|
||
s_bBeginBackgroundLoad = true;
|
||
|
||
for( i = 0; i < 2; i++ )
|
||
{
|
||
if( s_hLoaderEvent[ i ] == NULL )
|
||
{
|
||
s_hLoaderEvent[ i ] = CreateEvent( NULL, FALSE, FALSE, NULL );
|
||
}
|
||
}
|
||
if( s_hThread == NULL )
|
||
{
|
||
s_hThread = CreateThread( NULL, 0, BackgroundLoaderCallback, NULL, 0, NULL );
|
||
}
|
||
}
|
||
|
||
void CBackgroundLoader::EndBackgroundLoad()
|
||
{
|
||
int i;
|
||
|
||
if( s_bBeginBackgroundLoad )
|
||
{
|
||
if( s_hLoaderEvent[ 1 ] )
|
||
{
|
||
SetEvent( s_hLoaderEvent[ 1 ] );
|
||
}
|
||
for( i = 0; i < 2; i++ )
|
||
{
|
||
if( s_hLoaderEvent[ i ] )
|
||
{
|
||
CloseHandle( s_hLoaderEvent[ i ] );
|
||
}
|
||
}
|
||
}
|
||
if( s_hThread )
|
||
{
|
||
CloseHandle( s_hThread );
|
||
}
|
||
s_bBeginBackgroundLoad = false;
|
||
}
|
||
|
||
void CBackgroundLoader::SetReady( bool bReady )
|
||
{
|
||
m_LoadListLock.Lock();
|
||
m_bReady = bReady;
|
||
m_LoadListLock.UnLock();
|
||
}
|
||
|
||
bool CBackgroundLoader::AddCallback( CBackgroundLoaderCallback *pCallback )
|
||
{
|
||
bool bRet;
|
||
m_LoadListLock.Lock();
|
||
if( !m_bReady )
|
||
{
|
||
m_vecCallback.push_back( pCallback );
|
||
pCallback->CallbackPush( this );
|
||
bRet = true;
|
||
}
|
||
else
|
||
{
|
||
bRet = false;
|
||
}
|
||
m_LoadListLock.UnLock();
|
||
|
||
return bRet;
|
||
}
|
||
|
||
void CBackgroundLoader::EraseCallback( CBackgroundLoaderCallback *pCallback )
|
||
{
|
||
m_LoadListLock.Lock();
|
||
std::vector< CBackgroundLoaderCallback * >::iterator it;
|
||
|
||
it = std::find( m_vecCallback.begin(), m_vecCallback.end(), pCallback );
|
||
if( it != m_vecCallback.end() )
|
||
{
|
||
m_vecCallback.erase( it );
|
||
}
|
||
m_LoadListLock.UnLock();
|
||
}
|
||
|
||
|
||
void CBackgroundLoader::ProcessCallback()
|
||
{
|
||
int i;
|
||
|
||
m_LoadListLock.Lock();
|
||
for( i = 0; i < ( int )m_vecCallback.size(); i++ )
|
||
{
|
||
m_vecCallback[ i ]->OnLoadComplete( this );
|
||
}
|
||
m_LoadListLock.UnLock();
|
||
}
|
||
|
||
int CBackgroundLoader::GetRemainLoaderCount()
|
||
{
|
||
int nCount;
|
||
|
||
nCount = ( int )s_vecLoadList.size();
|
||
if( s_bNowLoading )
|
||
{
|
||
nCount++;
|
||
}
|
||
|
||
return nCount;
|
||
}
|
||
|
||
void CBackgroundLoader::PushLoader( CBackgroundLoader *pLoader, CStream *pStream )
|
||
{
|
||
SLoaderInfo LoaderInfo;
|
||
|
||
LoaderInfo.pLoader = pLoader;
|
||
LoaderInfo.pStream = pStream;
|
||
m_LoadListLock.Lock();
|
||
pLoader->SetReady( false );
|
||
if( s_vecLoadList.empty() )
|
||
{
|
||
SetEvent( s_hLoaderEvent[ 0 ] );
|
||
}
|
||
s_vecLoadList.push_back( LoaderInfo );
|
||
m_LoadListLock.UnLock();
|
||
}
|
||
|
||
bool CBackgroundLoader::PopLoader( SLoaderInfo &LoaderInfo )
|
||
{
|
||
bool bRet;
|
||
|
||
m_LoadListLock.Lock();
|
||
if( s_vecLoadList.empty() )
|
||
{
|
||
bRet = false;
|
||
}
|
||
else
|
||
{
|
||
bRet = true;
|
||
LoaderInfo = s_vecLoadList.front();
|
||
s_vecLoadList.erase( s_vecLoadList.begin() );
|
||
}
|
||
m_LoadListLock.UnLock();
|
||
|
||
return bRet;
|
||
}
|
||
|
||
DWORD WINAPI CBackgroundLoader::BackgroundLoaderCallback( LPVOID pParam )
|
||
{
|
||
while( 1 )
|
||
{
|
||
SLoaderInfo LoaderInfo;
|
||
|
||
if( PopLoader( LoaderInfo ) )
|
||
{
|
||
if( ( LoaderInfo.pLoader ) && ( LoaderInfo.pStream ) )
|
||
{
|
||
s_bNowLoading = true;
|
||
if( !LoaderInfo.pStream->IsValid() )
|
||
{
|
||
LoaderInfo.pStream->Activate();
|
||
}
|
||
if( LoaderInfo.pStream->IsValid() )
|
||
{
|
||
/* int nSize;
|
||
char *pLoadBuf;
|
||
CMemoryStream MemStream;
|
||
|
||
nSize = LoaderInfo.pStream->Size();
|
||
pLoadBuf = new char[ nSize ];
|
||
LoaderInfo.pStream->Read( pLoadBuf, nSize );
|
||
MemStream.Initialize( pLoadBuf, nSize );
|
||
LoaderInfo.pLoader->LoadResource( &MemStream );
|
||
delete [] pLoadBuf;*/
|
||
LoaderInfo.pLoader->LoadResource( LoaderInfo.pStream );
|
||
}
|
||
// OutputDebug( "ThreadLoad : %s\n", ((CFileStream*)LoaderInfo.pStream)->GetFileName() );
|
||
|
||
delete LoaderInfo.pStream;
|
||
LoaderInfo.pLoader->SetReady( true );
|
||
LoaderInfo.pLoader->ProcessCallback();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
s_bNowLoading = false;
|
||
while( 1 )
|
||
{
|
||
#if defined( PRE_FIX_CLIENT_FREEZING )
|
||
CommonUtil::PrintFreezingLog( "CBackgroundLoader::BackgroundLoaderCallback - Before" );
|
||
#endif
|
||
|
||
DWORD dwRet;
|
||
dwRet = WaitForMultipleObjects( 2, s_hLoaderEvent, FALSE, INFINITE );
|
||
|
||
#if defined( PRE_FIX_CLIENT_FREEZING )
|
||
CommonUtil::PrintFreezingLog( "CBackgroundLoader::BackgroundLoaderCallback - After\n" );
|
||
#endif
|
||
|
||
if( dwRet == WAIT_OBJECT_0 )
|
||
{
|
||
break;
|
||
}
|
||
else if( dwRet == WAIT_OBJECT_0 + 1 )
|
||
{
|
||
return 1;
|
||
}
|
||
}
|
||
}
|
||
Sleep(1);
|
||
}
|
||
|
||
return 0;
|
||
}
|