source-engine/public/gcsdk/gcclientjob.h

140 lines
3.7 KiB
C
Raw Permalink Normal View History

2020-04-22 16:56:21 +00:00
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#ifndef GCCLIENTJOB_H
#define GCCLIENTJOB_H
#ifdef _WIN32
#pragma once
#endif
namespace GCSDK
{
class CGCClient;
//-----------------------------------------------------------------------------
// Purpose: handles a network message job from the client
//-----------------------------------------------------------------------------
class CGCClientJob : public CJob
{
public:
CGCClientJob( CGCClient *pGCClient ) : CJob( pGCClient->GetJobMgr() ), m_pGCClient( pGCClient ), m_cHeartbeatsBeforeTimeout( k_cJobHeartbeatsBeforeTimeoutDefault ) {}
// all GCClient jobs must implement one of these
virtual bool BYieldingRunGCJob( IMsgNetPacket *pNetPacket ) { return false; }
virtual bool BYieldingRunGCJob() { return false; }
virtual EServerType GetServerType() { return k_EServerTypeGCClient; }
protected:
CGCClient *m_pGCClient;
bool BYldSendMessageAndGetReply( CGCMsgBase &msgOut, uint nTimeoutSec, CGCMsgBase *pMsgIn, MsgType_t eMsg )
{
IMsgNetPacket *pNetPacket = NULL;
if ( !BYldSendMessageAndGetReply( msgOut, nTimeoutSec, &pNetPacket ) )
return false;
pMsgIn->SetPacket( pNetPacket );
if ( pMsgIn->Hdr().m_eMsg != eMsg )
return false;
return true;
}
bool BYldSendMessageAndGetReply( CGCMsgBase &msgOut, uint nTimeoutSec, IMsgNetPacket **ppNetPacket )
{
msgOut.ExpectingReply( GetJobID() );
if ( !m_pGCClient->BSendMessage( msgOut ) )
return false;
SetJobTimeout( nTimeoutSec );
return BYieldingWaitForMsg( ppNetPacket );
}
enum BYldSendMessageAndGetReply_t
{
BYLDREPLY_SUCCESS,
BYLDREPLY_SEND_FAILED,
BYLDREPLY_TIMEOUT,
BYLDREPLY_MSG_TYPE_MISMATCH,
};
BYldSendMessageAndGetReply_t BYldSendMessageAndGetReplyEx( CProtoBufMsgBase &msgOut, uint nTimeoutSec, CProtoBufMsgBase *pMsgIn, MsgType_t eMsg )
{
IMsgNetPacket *pNetPacket = NULL;
msgOut.ExpectingReply( GetJobID() );
if ( !m_pGCClient->BSendMessage( msgOut ) )
return BYLDREPLY_SEND_FAILED;
SetJobTimeout( nTimeoutSec );
if( !BYieldingWaitForMsg( &pNetPacket ) )
return BYLDREPLY_TIMEOUT;
pMsgIn->InitFromPacket( pNetPacket );
if ( pMsgIn->GetEMsg() != eMsg )
return BYLDREPLY_MSG_TYPE_MISMATCH;
return BYLDREPLY_SUCCESS;
}
bool BYldSendMessageAndGetReply( CProtoBufMsgBase &msgOut, uint nTimeoutSec, CProtoBufMsgBase *pMsgIn, MsgType_t eMsg )
{
if( BYldSendMessageAndGetReplyEx( msgOut, nTimeoutSec, pMsgIn, eMsg ) != BYLDREPLY_SUCCESS )
return false;
return true;
}
bool BYldSendMessageAndGetReply( CProtoBufMsgBase &msgOut, uint nTimeoutSec, IMsgNetPacket **ppNetPacket )
{
msgOut.ExpectingReply( GetJobID() );
if ( !m_pGCClient->BSendMessage( msgOut ) )
return false;
SetJobTimeout( nTimeoutSec );
return BYieldingWaitForMsg( ppNetPacket );
}
virtual uint32 CHeartbeatsBeforeTimeout() { return m_cHeartbeatsBeforeTimeout; }
void SetJobTimeout( uint nTimeoutSec ) { m_cHeartbeatsBeforeTimeout = 1 + ((nTimeoutSec * k_nMillion) / k_cMicroSecJobHeartbeat); }
private:
virtual bool BYieldingRunJobFromMsg( IMsgNetPacket *pNetPacket )
{
// Protection against a NULL GCClient. Yields so the job is not deleted instantly
if ( !m_pGCClient )
{
BYieldingWaitOneFrame();
return false;
}
return BYieldingRunGCJob( pNetPacket );
}
virtual bool BYieldingRunJob( void *pvStartParam )
{
// Protection against a NULL GCClient. Yields so the job is not deleted instantly
if ( !m_pGCClient )
{
BYieldingWaitOneFrame();
return false;
}
return BYieldingRunGCJob();
}
uint32 m_cHeartbeatsBeforeTimeout;
};
} // namespace GCSDK
#endif // GCCLIENTJOB_H