|
|
//====== Copyright (c), 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; }
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;
if( !pMsgIn->InitFromPacket( pNetPacket ) ) return BYLDREPLY_MSG_TYPE_MISMATCH;
if ( pMsgIn->GetEMsg() != eMsg ) return BYLDREPLY_MSG_TYPE_MISMATCH;
return BYLDREPLY_SUCCESS; }
bool BYldSendMessageAndGetReply( CProtoBufMsgBase &msgOut, uint nTimeoutSec, CProtoBufMsgBase *pMsgIn, MsgType_t eMsg ) { BYldSendMessageAndGetReply_t result = BYldSendMessageAndGetReplyEx( msgOut, nTimeoutSec, pMsgIn, eMsg ); if ( result == BYLDREPLY_SUCCESS ) return true;
// Notify the client if the reply times out.
if ( result == BYLDREPLY_TIMEOUT ) m_pGCClient->MessageReplyTimedOut( eMsg, nTimeoutSec );
return false; }
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
|