1
This commit is contained in:
483
engine/cl_demoactionmanager.cpp
Normal file
483
engine/cl_demoactionmanager.cpp
Normal file
@ -0,0 +1,483 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "client_pch.h"
|
||||
#include <vgui/VGUI.h>
|
||||
#include <vgui_controls/Controls.h>
|
||||
#include "cl_demoaction.h"
|
||||
#include "cl_demoactionmanager.h"
|
||||
#include "cl_demouipanel.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class CDemoActionManager : public IDemoActionManager
|
||||
{
|
||||
public:
|
||||
|
||||
CDemoActionManager();
|
||||
~CDemoActionManager();
|
||||
|
||||
// Public interface
|
||||
public:
|
||||
|
||||
virtual void Init( void );
|
||||
virtual void Shutdown( void );
|
||||
|
||||
virtual void StartPlaying( char const *demfilename );
|
||||
virtual void StopPlaying();
|
||||
|
||||
virtual void Update( bool newframe, int demotick, float demotime );
|
||||
|
||||
virtual void SaveToBuffer( CUtlBuffer& buf );
|
||||
virtual void SaveToFile( void );
|
||||
|
||||
virtual char const *GetCurrentDemoFile( void );
|
||||
|
||||
virtual int GetActionCount( void );
|
||||
virtual CBaseDemoAction *GetAction( int index );
|
||||
virtual void AddAction( CBaseDemoAction *action );
|
||||
virtual void RemoveAction( CBaseDemoAction *action );
|
||||
|
||||
virtual bool IsDirty( void ) const;
|
||||
virtual void SetDirty( bool dirty );
|
||||
|
||||
virtual void ReloadFromDisk( void );
|
||||
|
||||
virtual void DispatchEvents();
|
||||
virtual void InsertFireEvent( CBaseDemoAction *action );
|
||||
|
||||
virtual bool OverrideView( democmdinfo_t& info, int tick );
|
||||
private:
|
||||
void OnVDMLoaded( char const *demfilename );
|
||||
void ClearAll();
|
||||
|
||||
CUtlVector< CBaseDemoAction * > m_ActionStack;
|
||||
CUtlVector< CBaseDemoAction * > m_PendingFireActionStack;
|
||||
|
||||
|
||||
int m_nPrevTick;
|
||||
float m_flPrevTime;
|
||||
|
||||
|
||||
bool m_bDirty;
|
||||
char m_szCurrentFile[ MAX_OSPATH ];
|
||||
long m_lFileTime;
|
||||
};
|
||||
|
||||
static CDemoActionManager g_DemoActionManager;
|
||||
IDemoActionManager *demoaction = ( IDemoActionManager * )&g_DemoActionManager;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CDemoActionManager::CDemoActionManager()
|
||||
{
|
||||
m_nPrevTick = 0;
|
||||
m_flPrevTime = 0.0f;
|
||||
m_szCurrentFile[ 0 ] = 0;
|
||||
m_bDirty = false;
|
||||
m_lFileTime = -1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CDemoActionManager::~CDemoActionManager()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDemoActionManager::Init( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDemoActionManager::Shutdown( void )
|
||||
{
|
||||
StopPlaying();
|
||||
ClearAll();
|
||||
m_ActionStack.Purge();
|
||||
m_PendingFireActionStack.Purge();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Reload without saving
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDemoActionManager::ReloadFromDisk( void )
|
||||
{
|
||||
char metafile[ 512 ];
|
||||
Q_StripExtension( m_szCurrentFile, metafile, sizeof( metafile ) );
|
||||
Q_DefaultExtension( metafile, ".vdm", sizeof( metafile ) );
|
||||
|
||||
ClearAll();
|
||||
|
||||
//const char *buffer = NULL;
|
||||
//int sz = 0;
|
||||
//buffer = (const char *)COM_LoadFile( metafile, 5, &sz );
|
||||
// if ( buffer )
|
||||
// {
|
||||
m_lFileTime = g_pFileSystem->GetFileTime( metafile );
|
||||
|
||||
KeyValues *kv = new KeyValues( metafile );
|
||||
Assert( kv );
|
||||
if ( kv )
|
||||
{
|
||||
if ( kv->LoadFromFile( g_pFullFileSystem, metafile ) )
|
||||
{
|
||||
// Iterate over all metaclasses...
|
||||
KeyValues* pIter = kv->GetFirstSubKey();
|
||||
while( pIter )
|
||||
{
|
||||
char factorytouse[ 512 ];
|
||||
|
||||
Q_strncpy( factorytouse, pIter->GetName(), sizeof( factorytouse ) );
|
||||
|
||||
// New format is to put numbers in here
|
||||
if ( atoi( factorytouse ) > 0 )
|
||||
{
|
||||
Q_strncpy( factorytouse, pIter->GetString( "factory", "" ), sizeof( factorytouse ) );
|
||||
}
|
||||
|
||||
CBaseDemoAction *action = CBaseDemoAction::CreateDemoAction( CBaseDemoAction::TypeForName( factorytouse ) );
|
||||
if ( action )
|
||||
{
|
||||
if ( !action->Init( pIter ) )
|
||||
{
|
||||
delete action;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ActionStack.AddToTail( action );
|
||||
}
|
||||
}
|
||||
|
||||
pIter = pIter->GetNextKey();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveToFile();
|
||||
}
|
||||
}
|
||||
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// This will save out an empty .vdm of the proper name
|
||||
// SaveToFile();
|
||||
// }
|
||||
|
||||
OnVDMLoaded( m_szCurrentFile );
|
||||
|
||||
m_bDirty = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *demfilename -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDemoActionManager::StartPlaying( char const *demfilename )
|
||||
{
|
||||
Assert( demfilename );
|
||||
|
||||
// Clear anything currently pending
|
||||
StopPlaying();
|
||||
|
||||
bool changedfile = Q_strcasecmp( demfilename, m_szCurrentFile ) != 0;
|
||||
|
||||
Q_strncpy( m_szCurrentFile, demfilename, sizeof( m_szCurrentFile ) );
|
||||
|
||||
char metafile[ 512 ];
|
||||
Q_StripExtension( demfilename, metafile, sizeof( metafile ) );
|
||||
Q_DefaultExtension( metafile, ".vdm", sizeof( metafile ) );
|
||||
|
||||
long filetime = g_pFileSystem->GetFileTime( metafile );
|
||||
|
||||
// If didn't change file and the timestamps are the same, don't transition to new .vdm
|
||||
if ( !changedfile && ( m_lFileTime == filetime ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_bDirty )
|
||||
{
|
||||
SaveToFile();
|
||||
}
|
||||
|
||||
ReloadFromDisk();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDemoActionManager::ClearAll()
|
||||
{
|
||||
m_PendingFireActionStack.RemoveAll();
|
||||
|
||||
while ( m_ActionStack.Count() > 0 )
|
||||
{
|
||||
CBaseDemoAction *a = m_ActionStack[ 0 ];
|
||||
delete a;
|
||||
m_ActionStack.Remove( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDemoActionManager::StopPlaying()
|
||||
{
|
||||
int count = m_ActionStack.Count();
|
||||
for ( int i = 0; i < count; i++ )
|
||||
{
|
||||
CBaseDemoAction *a = m_ActionStack[ i ];
|
||||
a->Reset();
|
||||
}
|
||||
|
||||
// Reset counters
|
||||
m_nPrevTick = 0;
|
||||
m_flPrevTime = 0.0f;
|
||||
|
||||
m_PendingFireActionStack.RemoveAll();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : demoframe -
|
||||
// demotime -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDemoActionManager::Update( bool newframe, int demotick, float demotime )
|
||||
{
|
||||
// Nothing to do?
|
||||
int count = m_ActionStack.Count();
|
||||
if ( count <= 0 )
|
||||
return;
|
||||
|
||||
// Setup timing context
|
||||
DemoActionTimingContext ctx;
|
||||
ctx.prevtick = m_nPrevTick;
|
||||
ctx.curtick = demotick;
|
||||
ctx.prevtime = m_flPrevTime;
|
||||
ctx.curtime = demotime;
|
||||
|
||||
int i;
|
||||
for ( i = 0; i < count; i++ )
|
||||
{
|
||||
CBaseDemoAction *action = m_ActionStack[ i ];
|
||||
Assert( action );
|
||||
if ( !action )
|
||||
continue;
|
||||
|
||||
action->Update( ctx );
|
||||
}
|
||||
|
||||
m_nPrevTick = demotick;
|
||||
m_flPrevTime = demotime;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : buf -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDemoActionManager::SaveToBuffer( CUtlBuffer& buf )
|
||||
{
|
||||
buf.Printf( "demoactions\n" );
|
||||
buf.Printf( "{\n" );
|
||||
|
||||
int count = m_ActionStack.Count();
|
||||
int i;
|
||||
for ( i = 0; i < count; i++ )
|
||||
{
|
||||
CBaseDemoAction *action = m_ActionStack[ i ];
|
||||
Assert( action );
|
||||
if ( !action )
|
||||
continue;
|
||||
|
||||
action->SaveToBuffer( 1, i + 1, buf );
|
||||
}
|
||||
|
||||
buf.Printf( "}\n" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *demfilename -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDemoActionManager::SaveToFile( void )
|
||||
{
|
||||
// Nothing loaded
|
||||
if ( m_szCurrentFile[ 0 ] == 0 )
|
||||
return;
|
||||
|
||||
// It's not dirty
|
||||
if ( !m_bDirty )
|
||||
return;
|
||||
|
||||
char metafile[ 512 ];
|
||||
Q_StripExtension( m_szCurrentFile, metafile, sizeof( metafile ) );
|
||||
Q_DefaultExtension( metafile, ".vdm", sizeof( metafile ) );
|
||||
|
||||
// Save data
|
||||
CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
|
||||
SaveToBuffer( buf );
|
||||
|
||||
// Write to file
|
||||
FileHandle_t fh;
|
||||
fh = g_pFileSystem->Open( metafile, "w" );
|
||||
if ( fh != FILESYSTEM_INVALID_HANDLE )
|
||||
{
|
||||
g_pFileSystem->Write( buf.Base(), buf.TellPut(), fh );
|
||||
g_pFileSystem->Close( fh );
|
||||
}
|
||||
|
||||
m_bDirty = false;
|
||||
|
||||
// Make sure filetime is up to date
|
||||
m_lFileTime = g_pFileSystem->GetFileTime( metafile );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *demfilename -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDemoActionManager::OnVDMLoaded( char const *demfilename )
|
||||
{
|
||||
// Notify UI?
|
||||
|
||||
if ( g_pDemoUI )
|
||||
{
|
||||
g_pDemoUI->OnVDMChanged();
|
||||
}
|
||||
|
||||
if ( g_pDemoUI2 )
|
||||
{
|
||||
g_pDemoUI2->OnVDMChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char const *CDemoActionManager::GetCurrentDemoFile( void )
|
||||
{
|
||||
return m_szCurrentFile;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int CDemoActionManager::GetActionCount( void )
|
||||
{
|
||||
int count = m_ActionStack.Count();
|
||||
return count;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : index -
|
||||
// Output : CBaseDemoAction
|
||||
//-----------------------------------------------------------------------------
|
||||
CBaseDemoAction *CDemoActionManager::GetAction( int index )
|
||||
{
|
||||
int count = m_ActionStack.Count();
|
||||
if ( index < 0 || index >= count )
|
||||
return NULL;
|
||||
|
||||
return m_ActionStack[ index ];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *action -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDemoActionManager::AddAction( CBaseDemoAction *action )
|
||||
{
|
||||
m_bDirty = true;
|
||||
Assert( action );
|
||||
m_ActionStack.AddToTail( action );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *action -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDemoActionManager::RemoveAction( CBaseDemoAction *action )
|
||||
{
|
||||
Assert( action );
|
||||
m_bDirty = true;
|
||||
|
||||
m_ActionStack.FindAndRemove( action );
|
||||
delete action;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CDemoActionManager::IsDirty( void ) const
|
||||
{
|
||||
return m_bDirty;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : dirty -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDemoActionManager::SetDirty( bool dirty )
|
||||
{
|
||||
m_bDirty = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *action -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDemoActionManager::InsertFireEvent( CBaseDemoAction *action )
|
||||
{
|
||||
// BUGBUG: Sometimes this can get called multiple times for the same event before DispatchEvents() is called. Why?
|
||||
// If that gets fixed, remove this hack.
|
||||
if ( m_PendingFireActionStack.Find(action) >= 0 )
|
||||
return;
|
||||
|
||||
m_PendingFireActionStack.AddToTail( action );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDemoActionManager::DispatchEvents()
|
||||
{
|
||||
int c = m_PendingFireActionStack.Count();
|
||||
int i;
|
||||
for ( i = 0; i < c; i++ )
|
||||
{
|
||||
CBaseDemoAction *action = m_PendingFireActionStack[ i ];
|
||||
Assert( action );
|
||||
action->FireAction();
|
||||
action->SetActionFired( true );
|
||||
}
|
||||
|
||||
m_PendingFireActionStack.RemoveAll();
|
||||
}
|
||||
|
||||
bool CDemoActionManager::OverrideView( democmdinfo_t& info, int tick )
|
||||
{
|
||||
// override view
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user