//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $Workfile: $ // $Date: $ // $NoKeywords: $ //===========================================================================// #ifndef COMMANDBUFFER_H #define COMMANDBUFFER_H #ifdef _WIN32 #pragma once #endif #include "tier1/utllinkedlist.h" #include "tier1/convar.h" //----------------------------------------------------------------------------- // Forward declarations //----------------------------------------------------------------------------- class CUtlBuffer; //----------------------------------------------------------------------------- // Invalid command handle //----------------------------------------------------------------------------- typedef intp CommandHandle_t; enum { COMMAND_BUFFER_INVALID_COMMAND_HANDLE = 0 }; //----------------------------------------------------------------------------- // A command buffer class- a queue of argc/argv based commands associated // with a particular time //----------------------------------------------------------------------------- class CCommandBuffer { public: // Constructor, destructor CCommandBuffer( ); ~CCommandBuffer(); // Inserts text into the command buffer bool AddText( const char *pText, int nTickDelay = 0 ); // Used to iterate over all commands appropriate for the current time void BeginProcessingCommands( int nDeltaTicks ); bool DequeueNextCommand( ); int DequeueNextCommand( const char **& ppArgv ); int ArgC() const; const char **ArgV() const; const char *ArgS() const; // All args that occur after the 0th arg, in string form const char *GetCommandString() const; // The entire command in string form, including the 0th arg const CCommand& GetCommand() const; void EndProcessingCommands(); // Are we in the middle of processing commands? bool IsProcessingCommands(); // Delays all queued commands to execute at a later time void DelayAllQueuedCommands( int nTickDelay ); // Indicates how long to delay when encoutering a 'wait' command void SetWaitDelayTime( int nTickDelay ); // Returns a handle to the next command to process // (useful when inserting commands into the buffer during processing // of commands to force immediate execution of those commands, // most relevantly, to implement a feature where you stream a file // worth of commands into the buffer, where the file size is too large // to entirely contain in the buffer). CommandHandle_t GetNextCommandHandle(); // Specifies a max limit of the args buffer. For unittesting. Size == 0 means use default void LimitArgumentBufferSize( int nSize ); void SetWaitEnabled( bool bEnable ) { m_bWaitEnabled = bEnable; } bool IsWaitEnabled( void ) { return m_bWaitEnabled; } int GetArgumentBufferSize() { return m_nArgSBufferSize; } int GetMaxArgumentBufferSize() { return m_nMaxArgSBufferLength; } private: enum { ARGS_BUFFER_LENGTH = 8192, }; struct Command_t { int m_nTick; int m_nFirstArgS; int m_nBufferSize; }; // Insert a command into the command queue at the appropriate time void InsertCommandAtAppropriateTime( CommandHandle_t hCommand ); // Insert a command into the command queue // Only happens if it's inserted while processing other commands void InsertImmediateCommand( CommandHandle_t hCommand ); // Insert a command into the command queue bool InsertCommand( const char *pArgS, int nCommandSize, int nTick ); // Returns the length of the next command, as well as the offset to the next command void GetNextCommandLength( const char *pText, int nMaxLen, int *pCommandLength, int *pNextCommandOffset ); // Compacts the command buffer void Compact(); // Parses argv0 out of the buffer bool ParseArgV0( CUtlBuffer &buf, char *pArgv0, int nMaxLen, const char **pArgs ); char m_pArgSBuffer[ ARGS_BUFFER_LENGTH ]; int m_nArgSBufferSize; CUtlFixedLinkedList< Command_t > m_Commands; int m_nCurrentTick; int m_nLastTickToProcess; int m_nWaitDelayTicks; CommandHandle_t m_hNextCommand; int m_nMaxArgSBufferLength; bool m_bIsProcessingCommands; bool m_bWaitEnabled; // NOTE: This is here to avoid the pointers returned by DequeueNextCommand // to become invalid by calling AddText. Is there a way we can avoid the memcpy? CCommand m_CurrentCommand; }; //----------------------------------------------------------------------------- // Returns the next command //----------------------------------------------------------------------------- inline int CCommandBuffer::ArgC() const { return m_CurrentCommand.ArgC(); } inline const char **CCommandBuffer::ArgV() const { return m_CurrentCommand.ArgV(); } inline const char *CCommandBuffer::ArgS() const { return m_CurrentCommand.ArgS(); } inline const char *CCommandBuffer::GetCommandString() const { return m_CurrentCommand.GetCommandString(); } inline const CCommand& CCommandBuffer::GetCommand() const { return m_CurrentCommand; } #endif // COMMANDBUFFER_H