|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
//=======================================================================================//
#include "baserecordingsession.h"
#include "baserecordingsessionblock.h"
#include "replay/irecordingsessionblockmanager.h"
#include "replay/replayutils.h"
#include "replay/iclientreplaycontext.h"
#include "replay/shared_defs.h"
#include "KeyValues.h"
#include "replay/replayutils.h"
#include "replay/ireplaycontext.h"
#include "filesystem.h"
#include "iserver.h"
#include "replaysystem.h"
#include "utlbuffer.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//----------------------------------------------------------------------------------------
CBaseRecordingSession::CBaseRecordingSession( IReplayContext *pContext ) : m_pContext( pContext ), m_bRecording( false ), m_bAutoDelete( false ), m_bBlocksLoaded( false ), m_flStartTime( 0.0f ) { }
CBaseRecordingSession::~CBaseRecordingSession() { }
void CBaseRecordingSession::AddBlock( CBaseRecordingSessionBlock *pBlock ) { AddBlock( pBlock, false ); }
bool CBaseRecordingSession::Read( KeyValues *pIn ) { if ( !BaseClass::Read( pIn ) ) return false;
m_strName = pIn->GetString( "name" ); if ( m_strName.IsEmpty() ) { CUtlBuffer buf; pIn->RecursiveSaveToFile( buf, 0 ); IF_REPLAY_DBG( Warning( "Session with no session name found - aborting load for this session. Data:\n---\n%s\n---\n", (const char *)buf.Base() ) ); return false; }
m_bRecording = pIn->GetBool( "recording" ); m_strBaseDownloadURL = pIn->GetString( "base_download_url" ); m_nServerStartRecordTick = pIn->GetInt( "server_start_record_tick", -1 );
return true; }
void CBaseRecordingSession::Write( KeyValues *pOut ) { BaseClass::Write( pOut );
pOut->SetString( "name", m_strName.Get() ); pOut->SetInt( "recording", m_bRecording ? 1 : 0 ); pOut->SetString( "base_download_url", m_strBaseDownloadURL.Get() ); pOut->SetInt( "server_start_record_tick", m_nServerStartRecordTick ); }
const char *CBaseRecordingSession::GetSubKeyTitle() const { return m_strName.Get(); }
const char *CBaseRecordingSession::GetPath() const { return Replay_va( "%s%s%c", m_pContext->GetBaseDir(), SUBDIR_SESSIONS, CORRECT_PATH_SEPARATOR ); }
const char *CBaseRecordingSession::GetSessionInfoURL() const { return Replay_va( "%s%s.%s", m_strBaseDownloadURL.Get(), m_strName.Get(), GENERIC_FILE_EXTENSION ); }
void CBaseRecordingSession::LoadBlocksForSession() { if ( m_bBlocksLoaded ) return;
IRecordingSessionBlockManager *pBlockManager = m_pContext->GetRecordingSessionBlockManager();
// Peek in directory and load files based on what's there
FileFindHandle_t hFind; CFmtStr fmtPath( "%s%s*.%s", pBlockManager->GetBlockPath(), m_strName.Get(), GENERIC_FILE_EXTENSION ); const char *pFilename = g_pFullFileSystem->FindFirst( fmtPath.Access(), &hFind ); while ( pFilename ) { // Load the block - this will add the block to this session
pBlockManager->LoadBlockFromFileName( pFilename, this );
// Get next file
pFilename = g_pFullFileSystem->FindNext( hFind ); }
// Blocks loaded
m_bBlocksLoaded = true; }
void CBaseRecordingSession::OnDelete() { BaseClass::OnDelete();
// Dynamically load blocks if necessary, then delete from the block manager and from disk
DeleteBlocks(); }
void CBaseRecordingSession::DeleteBlocks() { if ( !m_bBlocksLoaded ) { // Load blocks now based on the session name
LoadBlocksForSession(); }
// Delete all blocks associated w/ the session
FOR_EACH_VEC( m_vecBlocks, i ) { CBaseRecordingSessionBlock *pCurBlock = m_vecBlocks[ i ]; m_pContext->GetRecordingSessionBlockManager()->DeleteBlock( pCurBlock ); } }
void CBaseRecordingSession::OnUnload() { BaseClass::OnUnload();
FOR_EACH_VEC( m_vecBlocks, i ) { CBaseRecordingSessionBlock *pCurBlock = m_vecBlocks[ i ]; m_pContext->GetRecordingSessionBlockManager()->UnloadBlock( pCurBlock ); } }
void CBaseRecordingSession::PopulateWithRecordingData( int nCurrentRecordingStartTick ) { Assert( nCurrentRecordingStartTick >= 0 );
m_strBaseDownloadURL = Replay_GetDownloadURL(); m_bRecording = true; m_nServerStartRecordTick = nCurrentRecordingStartTick; }
void CBaseRecordingSession::AddBlock( CBaseRecordingSessionBlock *pBlock, bool bFlagForFlush ) { Assert( pBlock->m_hSession == GetHandle() );
Assert( m_vecBlocks.Find( pBlock ) == m_vecBlocks.InvalidIndex() ); m_vecBlocks.Insert( pBlock );
if ( bFlagForFlush ) { // Mark as dirty
m_pContext->GetRecordingSessionManager()->FlagSessionForFlush( this, false ); }
m_bBlocksLoaded = true; }
int CBaseRecordingSession::FindBlock( CBaseRecordingSessionBlock *pBlock ) const { int itResult = m_vecBlocks.Find( pBlock ); if ( itResult == m_vecBlocks.InvalidIndex() ) return -1;
return itResult; }
bool CBaseRecordingSession::ShouldDitchSession() const { return m_bAutoDelete; }
//----------------------------------------------------------------------------------------
bool CBaseRecordingSession::CLessFunctor::Less( const CBaseRecordingSessionBlock *pSrc1, const CBaseRecordingSessionBlock *pSrc2, void *pContext ) { return pSrc1->m_iReconstruction < pSrc2->m_iReconstruction; }
//----------------------------------------------------------------------------------------
|