2024-12-21 10:04:04 +08:00
|
|
|
#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;
|
|
|
|
|
}
|