diff options
Diffstat (limited to 'public/gcsdk/messagelist.h')
| -rw-r--r-- | public/gcsdk/messagelist.h | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/public/gcsdk/messagelist.h b/public/gcsdk/messagelist.h new file mode 100644 index 0000000..e48fc54 --- /dev/null +++ b/public/gcsdk/messagelist.h @@ -0,0 +1,174 @@ +//====== Copyright �, Valve Corporation, All rights reserved. ======= +// +// Purpose: Maps message types to strings and vice versa +// +//============================================================================= + +#ifndef MESSAGELIST_H +#define MESSAGELIST_H +#ifdef _WIN32 +#pragma once +#endif + +// Protobuf headers interfere with the valve min/max/malloc overrides. so we need to do all +// this funky wrapping to make the include happy. +#include <tier0/valve_minmax_off.h> +#include "google/protobuf/descriptor.h" +#include <tier0/valve_minmax_on.h> +#include "gcsdk/jobtime.h" + +namespace GCSDK +{ + +extern CGCEmitGroup g_EGMessages; +extern const char *PchMsgNameFromEMsg( MsgType_t eMsg ); + +//----------------------------------------------------------------------------- +// message type flags +//----------------------------------------------------------------------------- + +static const int MT_GC = 0x01; // this message is sent to or from a Game Coordinator (will be proxied by servers along the way) +static const int MT_GC_SYSTEM = 0x02; // this message was sent to or from the steam servers as a system message. Clients can't send these + +//----------------------------------------------------------------------------- +// Various info about each message type +//----------------------------------------------------------------------------- +struct MsgInfo_t +{ + MsgType_t eMsg; + int nFlags; + const char *pchMsgName; + + struct Stats_t + { + Stats_t() : nSourceMask(0), nCount( 0 ), uBytes( 0 ) {} + uint32 nSourceMask; + uint32 nCount; + uint64 uBytes; + }; + + enum EStatsType + { + k_EStatsTypeSent, + k_EStatsTypeReceived, + k_EStatsTypeMultiplexedSends, + k_EStatsTypeMultiplexedSendsRaw, + + k_EStatsType_Count + }; + + enum EStatsGroup + { + k_EStatsGroupGlobal, + k_EStatsGroupProfile, + k_EStatsGroupWindow, + + k_EStatsGroup_Count + }; + + + Stats_t stats[ k_EStatsGroup_Count ][ k_EStatsType_Count ]; +}; + +//----------------------------------------------------------------------------- +// Purpose: Using protobuf reflection, bind them into a message list +//----------------------------------------------------------------------------- +void MsgRegistrationFromEnumDescriptor( const ::google::protobuf::EnumDescriptor *pEnumDescriptor, int nTypeMask ); + +//----------------------------------------------------------------------------- +// manages a hashed list of messages, allowing fast tests for validity and +// info lookup. +//----------------------------------------------------------------------------- + +class CMessageList +{ +public: + CMessageList(); + ~CMessageList(); + + bool BInit( ); + + // returns false if a message isn't valid or isn't one of the types specified + // or true if the message is valid. ppMsgName can be NULL. + bool GetMessage( MsgType_t eMsg, const char **ppMsgName, int nTypeMask ); + + // make stats about sending messages + void TallySendMessage( MsgType_t eMsg, uint32 uMsgSize, uint32 nSourceMask = 0 ); + void TallyReceiveMessage( MsgType_t eMsg, uint32 uMsgSize, uint32 nSourceMask = 0); + void TallyMultiplexedMessage( MsgType_t eMsg, uint32 uSent, uint32 cRecipients, uint32 uMsgSize, uint32 nSourceMask = 0 ); + + // profiling + void EnableProfiling( bool bEnableProfiling ); + + // print out our stats + void PrintStats( bool bShowAll, bool bSortByFrequency, MsgInfo_t::EStatsGroup eGroup, MsgInfo_t::EStatsType eType, uint32 nSourceMask = 0 ) const; + void PrintMultiplexStats( MsgInfo_t::EStatsGroup eGroup, bool bSortByFrequency, uint32 nSourceMask = 0 ) const; + + // Window management - This is similar to profiling in many ways, but is separate so that the base system can monitor traffic rates without + // interfering with profiles. + + //called to obtain the totals for the timing window + const MsgInfo_t::Stats_t& GetWindowTotal( MsgInfo_t::EStatsType eType ) const; + //called to reset the window timings + void ResetWindow(); + //returns how long this window has been running in microseconds + uint64 GetWindowDuration() const { return GetGroupDuration( MsgInfo_t::k_EStatsGroupWindow ); } + + +private: + void TallyMessageInternal( MsgInfo_t &msgInfo, MsgInfo_t::EStatsType eBucket, uint32 unMsgSize, uint32 nSourceMask, uint32 cMessages = 1 ); + + void AssureBucket( int nBucket ); + + //----------------------------------------------------------------------------- + // given a particular message ID, find out what bucket it would be in, + // as well as which slot in that bucket. + //----------------------------------------------------------------------------- + static int HashMessage( MsgType_t eMsg, int &nSlot ) + { + // hash is everything except the lowest nibble, + // because buckets are 16 entries + int nBucket = eMsg / m_kcBucketSize; + nSlot = eMsg % m_kcBucketSize; + return nBucket; + } + + short GetMessageIndex( MsgType_t eMsg ); + + //given a group, this will return the time that the stats have been collected over + uint64 GetGroupDuration( MsgInfo_t::EStatsGroup eGroup ) const; + +private: + + //totalled stats for the current window. It would be too costly to total these all the time + MsgInfo_t::Stats_t m_WindowTotals[ MsgInfo_t::k_EStatsType_Count ]; + + //the time that we have been collecting each of these buckets + CJobTime m_sCollectTime[ MsgInfo_t::k_EStatsGroup_Count ]; + + //are we currently actively tracking a profile? + bool m_bProfiling; + //the duration of the last finished profile (if it is no longer running, otherwise use the timer) + uint64 m_ulProfileMicrosecs; + + CUtlVector< short* > m_vecMessageInfoBuckets; + CUtlVector<MsgInfo_t> m_vecMsgInfo; + static const int m_kcBucketSize = 16; +}; + +extern CMessageList g_theMessageList; + +//----------------------------------------------------------------------------- +// Purpose: Returns the true if the specified message is a valid GC system message. +// Input : eMsg - message type to test +// ppMsgName - Optional pointer to receive message name +//----------------------------------------------------------------------------- +inline bool BIsValidSystemMsg( MsgType_t eMsg, const char **ppMsgName ) +{ + return g_theMessageList.GetMessage( eMsg, ppMsgName, MT_GC_SYSTEM ); +} + + +} // namespace GCSDK + +#endif // MESSAGELIST_H
\ No newline at end of file |