mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-15 05:06:57 +00:00
WIP: port alien swarm and extend engine for asw
This commit is contained in:
@@ -0,0 +1 @@
|
||||
#include "IAppSystem.h"
|
||||
@@ -0,0 +1,46 @@
|
||||
//===== Copyright © 1996-2009, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef BITTOOLS_H
|
||||
#define BITTOOLS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace bittools
|
||||
{
|
||||
template<int N, int C = 0>
|
||||
struct RecurseBit
|
||||
{
|
||||
enum {result = RecurseBit<N/2, C+1>::result};
|
||||
};
|
||||
|
||||
template<int C>
|
||||
struct RecurseBit<0, C>
|
||||
{
|
||||
enum {result = C};
|
||||
};
|
||||
|
||||
template<int N, int C = 1>
|
||||
struct RecursePow2
|
||||
{
|
||||
enum {result = RecursePow2<N/2, C*2>::result};
|
||||
};
|
||||
|
||||
template<int C>
|
||||
struct RecursePow2<0, C>
|
||||
{
|
||||
enum {result = C};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#define ROUND_TO_POWER_OF_2( n ) ( bittools::RecursePow2< (n) - 1 >::result )
|
||||
#define MINIMUM_BITS_NEEDED( n ) ( bittools::RecurseBit< (n) - 1 >::result )
|
||||
|
||||
#endif //BITTOOLS_H
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Macros for defining branching singletons.
|
||||
//
|
||||
// A branching singleton defines a singleton class within another class, and subclasses
|
||||
// of the outer class can automatically expand on that singleton at their node in the
|
||||
// class branching tree with the confidence that changes will be reflected in all
|
||||
// subclasses.
|
||||
//
|
||||
// The primary reason to have a branching singleton is to centralize management code
|
||||
// without being tied explicitly to one interface. The interface can possibly change
|
||||
// vastly as it gets passed down the tree to the point where all the original functions
|
||||
// are stubs and the interface uses an entirely different set of functions.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef BRANCHINGSINGLETON_H
|
||||
#define BRANCHINGSINGLETON_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#define START_BRANCHING_SINGLETON_DEFINITION_NOBASE( classname ) class classname
|
||||
|
||||
#define START_BRANCHING_SINGLETON_DEFINITION( classname ) class classname : public Base##classname
|
||||
|
||||
#define _END_BRANCHING_SINGLETON_DEFINITION( classname );\
|
||||
static classname *Get_##classname##_Static( void )\
|
||||
{\
|
||||
static classname s_Singleton;\
|
||||
return &s_Singleton;\
|
||||
}\
|
||||
\
|
||||
virtual Root##classname *Get_##classname##( void )\
|
||||
{\
|
||||
return Get_##classname##_Static();\
|
||||
}\
|
||||
typedef classname Base##classname;
|
||||
|
||||
#define END_BRANCHING_SINGLETON_DEFINITION( classname ) _END_BRANCHING_SINGLETON_DEFINITION( classname )
|
||||
|
||||
#define END_BRANCHING_SINGLETON_DEFINITION_NOBASE( classname );\
|
||||
typedef classname Root##classname;\
|
||||
_END_BRANCHING_SINGLETON_DEFINITION( classname );
|
||||
|
||||
#endif //#ifndef BRANCHINGSINGLETON_H
|
||||
@@ -59,6 +59,7 @@ class IFileList;
|
||||
class CRenamedRecvTableInfo;
|
||||
class CMouthInfo;
|
||||
class IConVar;
|
||||
class ISPSharedMemory;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This data structure is filled in by the engine when the client .dll requests information about
|
||||
@@ -519,6 +520,9 @@ public:
|
||||
virtual uint OnStorageDeviceAttached( void ) = 0;
|
||||
virtual void OnStorageDeviceDetached( void ) = 0;
|
||||
|
||||
//Finds or Creates a shared memory space, the returned pointer will automatically be AddRef()ed
|
||||
virtual ISPSharedMemory *GetSinglePlayerSharedMemorySpace( const char *szName, int ent_num = MAX_EDICTS ) = 0;
|
||||
|
||||
virtual void ResetDemoInterpolation( void ) = 0;
|
||||
|
||||
// Methods to set/get a gamestats data container so client & server running in same process can send combined data
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
#include "closedcaptions.h"
|
||||
#include "filesystem.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
// Assumed to be set up by calling code
|
||||
bool AsyncCaption_t::LoadFromFile( char const *pchFullPath )
|
||||
{
|
||||
FileHandle_t fh = g_pFullFileSystem->Open( pchFullPath, "rb" );
|
||||
if ( FILESYSTEM_INVALID_HANDLE == fh )
|
||||
return false;
|
||||
|
||||
MEM_ALLOC_CREDIT();
|
||||
|
||||
CUtlBuffer dirbuffer;
|
||||
|
||||
// Read the header
|
||||
g_pFullFileSystem->Read( &m_Header, sizeof( m_Header ), fh );
|
||||
if ( m_Header.magic != COMPILED_CAPTION_FILEID )
|
||||
{
|
||||
if( IsPS3() )
|
||||
return false;
|
||||
else
|
||||
Error( "Invalid file id for %s\n", pchFullPath );
|
||||
}
|
||||
if ( m_Header.version != COMPILED_CAPTION_VERSION )
|
||||
{
|
||||
if( IsPS3() )
|
||||
return false;
|
||||
else
|
||||
Error( "Invalid file version for %s\n", pchFullPath );
|
||||
}
|
||||
if ( m_Header.directorysize < 0 || m_Header.directorysize > 64 * 1024 )
|
||||
{
|
||||
if( IsPS3() )
|
||||
return false;
|
||||
else
|
||||
Error( "Invalid directory size %d for %s\n", m_Header.directorysize, pchFullPath );
|
||||
}
|
||||
//if ( m_Header.blocksize != MAX_BLOCK_SIZE )
|
||||
// Error( "Invalid block size %d, expecting %d for %s\n", m_Header.blocksize, MAX_BLOCK_SIZE, pchFullPath );
|
||||
|
||||
int directoryBytes = m_Header.directorysize * sizeof( CaptionLookup_t );
|
||||
m_CaptionDirectory.EnsureCapacity( m_Header.directorysize );
|
||||
dirbuffer.EnsureCapacity( directoryBytes );
|
||||
|
||||
g_pFullFileSystem->Read( dirbuffer.Base(), directoryBytes, fh );
|
||||
g_pFullFileSystem->Close( fh );
|
||||
|
||||
m_CaptionDirectory.CopyArray( (const CaptionLookup_t *)dirbuffer.PeekGet(), m_Header.directorysize );
|
||||
m_CaptionDirectory.RedoSort( true );
|
||||
|
||||
m_DataBaseFile = pchFullPath;
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef CLOSEDCAPTIONS_H
|
||||
#define CLOSEDCAPTIONS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "captioncompiler.h"
|
||||
#include "tier1/utlsymbol.h"
|
||||
#include "tier1/utlsortvector.h"
|
||||
|
||||
FORWARD_DECLARE_HANDLE( memhandle_t );
|
||||
|
||||
typedef CUtlSortVector< CaptionLookup_t, CCaptionLookupLess > CaptionDictionary_t;
|
||||
struct AsyncCaption_t
|
||||
{
|
||||
AsyncCaption_t() :
|
||||
m_DataBaseFile( UTL_INVAL_SYMBOL ),
|
||||
m_RequestedBlocks( 0, 0, BlockInfo_t::Less )
|
||||
{
|
||||
Q_memset( &m_Header, 0, sizeof( m_Header ) );
|
||||
}
|
||||
|
||||
struct BlockInfo_t
|
||||
{
|
||||
int fileindex;
|
||||
int blocknum;
|
||||
memhandle_t handle;
|
||||
|
||||
static bool Less( const BlockInfo_t& lhs, const BlockInfo_t& rhs )
|
||||
{
|
||||
if ( lhs.fileindex != rhs.fileindex )
|
||||
return lhs.fileindex < rhs.fileindex;
|
||||
|
||||
return lhs.blocknum < rhs.blocknum;
|
||||
}
|
||||
};
|
||||
|
||||
AsyncCaption_t& operator =( const AsyncCaption_t& rhs )
|
||||
{
|
||||
if ( this == &rhs )
|
||||
return *this;
|
||||
|
||||
m_CaptionDirectory = rhs.m_CaptionDirectory;
|
||||
m_Header = rhs.m_Header;
|
||||
m_DataBaseFile = rhs.m_DataBaseFile;
|
||||
|
||||
for ( int i = rhs.m_RequestedBlocks.FirstInorder(); i != rhs.m_RequestedBlocks.InvalidIndex(); i = rhs.m_RequestedBlocks.NextInorder( i ) )
|
||||
{
|
||||
m_RequestedBlocks.Insert( rhs.m_RequestedBlocks[ i ] );
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool LoadFromFile( char const *pchFullPath );
|
||||
|
||||
CUtlRBTree< BlockInfo_t, unsigned short > m_RequestedBlocks;
|
||||
|
||||
CaptionDictionary_t m_CaptionDirectory;
|
||||
CompiledCaptionHeader_t m_Header;
|
||||
CUtlSymbol m_DataBaseFile;
|
||||
};
|
||||
|
||||
#endif // CLOSEDCAPTIONS_H
|
||||
@@ -0,0 +1,8 @@
|
||||
//========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "Color.h"
|
||||
@@ -0,0 +1,51 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef IPRECACHESYSTEM_H
|
||||
#define IPRECACHESYSTEM_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier0/dbg.h"
|
||||
#include "tier2/tier2.h"
|
||||
#include "tier2/resourceprecacher.h"
|
||||
#include "appframework/iappsystem.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Resource access control API
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// IResourceAccessControl
|
||||
// Purpose: Maintains lists of resources to use them as filters to prevent access
|
||||
// to ensure proper precache behavior in game code
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IPrecacheSystem : public IAppSystem
|
||||
{
|
||||
public:
|
||||
// Precaches/uncaches all resources used by a particular system
|
||||
virtual void Cache( IPrecacheHandler *pPrecacheHandler, PrecacheSystem_t nSystem,
|
||||
const char *pName, bool bPrecache, ResourceList_t hResourceList, bool bBuildResourceList ) = 0;
|
||||
|
||||
virtual void UncacheAll( IPrecacheHandler *pPrecacheHandler ) = 0 ;
|
||||
|
||||
virtual void Register( IResourcePrecacher *pResourcePrecacherFirst, PrecacheSystem_t nSystem ) = 0;
|
||||
|
||||
// Limits resource access to only resources used by this particular system
|
||||
// Use GLOBAL system, and NULL name to disable limited resource access
|
||||
virtual void LimitResourceAccess( PrecacheSystem_t nSystem, const char *pName ) = 0;
|
||||
virtual void EndLimitedResourceAccess() = 0;
|
||||
};
|
||||
|
||||
DECLARE_TIER2_INTERFACE( IPrecacheSystem, g_pPrecacheSystem );
|
||||
|
||||
|
||||
#endif // IPRECACHESYSTEM_H
|
||||
@@ -249,6 +249,17 @@ typedef void (CBaseEntity::*inputfunc_t)(inputdata_t &data);
|
||||
struct datamap_t;
|
||||
struct typedescription_t;
|
||||
|
||||
#if 0
|
||||
enum
|
||||
{
|
||||
PC_NON_NETWORKED_ONLY = 0,
|
||||
PC_NETWORKED_ONLY,
|
||||
|
||||
PC_COPYTYPE_COUNT,
|
||||
PC_EVERYTHING = PC_COPYTYPE_COUNT,
|
||||
};
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
TD_OFFSET_NORMAL = 0,
|
||||
|
||||
@@ -61,6 +61,7 @@ public:
|
||||
int maxEntities;
|
||||
|
||||
int serverCount;
|
||||
edict_t *pEdicts;
|
||||
};
|
||||
|
||||
inline CGlobalVars::CGlobalVars( bool bIsClient ) :
|
||||
|
||||
@@ -60,6 +60,7 @@ class CSteamID;
|
||||
class IReplayFactory;
|
||||
class IReplaySystem;
|
||||
class IServer;
|
||||
class ISPSharedMemory;
|
||||
|
||||
typedef struct player_info_s player_info_t;
|
||||
|
||||
@@ -402,6 +403,10 @@ public:
|
||||
|
||||
// Returns the SteamID of the specified player. It'll be NULL if the player hasn't authenticated yet.
|
||||
virtual const CSteamID *GetClientSteamIDByPlayerIndex( int entnum ) = 0;
|
||||
|
||||
//Finds or Creates a shared memory space, the returned pointer will automatically be AddRef()ed
|
||||
virtual ISPSharedMemory *GetSinglePlayerSharedMemorySpace( const char *szName, int ent_num = MAX_EDICTS ) = 0;
|
||||
|
||||
// Gets a list of all clusters' bounds. Returns total number of clusters.
|
||||
virtual int GetClusterCount() = 0;
|
||||
virtual int GetAllClusterBounds( bbox_t *pBBoxList, int maxBBox ) = 0;
|
||||
|
||||
@@ -32,8 +32,10 @@ public:
|
||||
// These methods return the bounds of an OBB measured in "collision" space
|
||||
// which can be retreived through the CollisionToWorldTransform or
|
||||
// GetCollisionOrigin/GetCollisionAngles methods
|
||||
#if !SOURCE_ASW
|
||||
virtual const Vector& OBBMinsPreScaled() const = 0;
|
||||
virtual const Vector& OBBMaxsPreScaled() const = 0;
|
||||
#endif
|
||||
virtual const Vector& OBBMins() const = 0;
|
||||
virtual const Vector& OBBMaxs() const = 0;
|
||||
|
||||
|
||||
+12
-4
@@ -1,4 +1,4 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
@@ -75,24 +75,32 @@ public:
|
||||
// Data access
|
||||
virtual bool GetBool( const char *keyName = NULL, bool defaultValue = false ) = 0;
|
||||
virtual int GetInt( const char *keyName = NULL, int defaultValue = 0 ) = 0;
|
||||
virtual uint64 GetUint64( const char *keyName = NULL, uint64 defaultValue = 0 ) = 0;
|
||||
virtual float GetFloat( const char *keyName = NULL, float defaultValue = 0.0f ) = 0;
|
||||
virtual const char *GetString( const char *keyName = NULL, const char *defaultValue = "" ) = 0;
|
||||
|
||||
virtual void SetBool( const char *keyName, bool value ) = 0;
|
||||
virtual void SetInt( const char *keyName, int value ) = 0;
|
||||
virtual void SetUint64( const char *keyName, uint64 value ) = 0;
|
||||
virtual void SetFloat( const char *keyName, float value ) = 0;
|
||||
virtual void SetString( const char *keyName, const char *value ) = 0;
|
||||
};
|
||||
|
||||
#define EVENT_DEBUG_ID_INIT 42
|
||||
#define EVENT_DEBUG_ID_SHUTDOWN 13
|
||||
|
||||
abstract_class IGameEventListener2
|
||||
{
|
||||
public:
|
||||
virtual ~IGameEventListener2( void ) {};
|
||||
|
||||
// FireEvent is called by EventManager if event just occurred
|
||||
// FireEvent is called by EventManager if event just occured
|
||||
// KeyValue memory will be freed by manager if not needed anymore
|
||||
virtual void FireGameEvent( IGameEvent *event ) = 0;
|
||||
|
||||
#if SOURCE_ASW
|
||||
virtual int GetEventDebugID( void ) = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
abstract_class IGameEventManager2 : public IBaseInterface
|
||||
@@ -117,7 +125,7 @@ public:
|
||||
|
||||
// create an event by name, but doesn't fire it. returns NULL is event is not
|
||||
// known or no listener is registered for it. bForce forces the creation even if no listener is active
|
||||
virtual IGameEvent *CreateEvent( const char *name, bool bForce = false ) = 0;
|
||||
virtual IGameEvent *CreateEvent( const char *name, bool bForce = false, int *pCookie = NULL ) = 0;
|
||||
|
||||
// fires a server event created earlier, if bDontBroadcast is set, event is not send to clients
|
||||
virtual bool FireEvent( IGameEvent *event, bool bDontBroadcast = false ) = 0;
|
||||
@@ -143,7 +151,7 @@ abstract_class IGameEventListener
|
||||
public:
|
||||
virtual ~IGameEventListener( void ) {};
|
||||
|
||||
// FireEvent is called by EventManager if event just occurred
|
||||
// FireEvent is called by EventManager if event just occured
|
||||
// KeyValue memory will be freed by manager if not needed anymore
|
||||
virtual void FireGameEvent( KeyValues * event) = 0;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef ISPSHAREDMEMORY_H
|
||||
#define ISPSHAREDMEMORY_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "basetypes.h"
|
||||
#include "platform.h"
|
||||
|
||||
abstract_class ISPSharedMemory
|
||||
{
|
||||
public:
|
||||
virtual bool Init( size_t iSize ) = 0; //Initial implementation assumes the size is fixed/hardcoded, returns true if this call actually created the memory, false if it already existed
|
||||
virtual uint8 * Base( void ) = 0;
|
||||
virtual size_t Size( void ) = 0;
|
||||
|
||||
virtual void AddRef( void ) = 0;
|
||||
virtual void Release( void ) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
|
||||
+163
-123
@@ -1,4 +1,4 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
@@ -21,9 +21,10 @@
|
||||
|
||||
#pragma warning( disable : 4284 ) // warning C4284: return type for 'CNetworkVarT<int>::operator ->' is 'int *' (ie; not a UDT or reference to a UDT. Will produce errors if applied using infix notation)
|
||||
|
||||
#define MyOffsetOf( type, var ) ( (intp)&((type*)0)->var )
|
||||
#define MyOffsetOf( type, var ) ( (int)&((type*)0)->var )
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef new
|
||||
extern bool g_bUseNetworkVars;
|
||||
#define CHECK_USENETWORKVARS if(g_bUseNetworkVars)
|
||||
#else
|
||||
@@ -32,6 +33,44 @@
|
||||
|
||||
|
||||
|
||||
// network vars use memcmp when fields are set. To ensure proper behavior your
|
||||
// object's memory should be initialized to zero. This happens for entities automatically
|
||||
// use this for other classes.
|
||||
class CMemZeroOnNew
|
||||
{
|
||||
public:
|
||||
void *operator new( size_t nSize )
|
||||
{
|
||||
void *pMem = MemAlloc_Alloc( nSize );
|
||||
V_memset( pMem, 0, nSize );
|
||||
return pMem;
|
||||
}
|
||||
|
||||
void* operator new( size_t nSize, int nBlockUse, const char *pFileName, int nLine )
|
||||
{
|
||||
void *pMem = MemAlloc_Alloc( nSize, pFileName, nLine );
|
||||
V_memset( pMem, 0, nSize );
|
||||
return pMem;
|
||||
}
|
||||
|
||||
void operator delete(void *pData)
|
||||
{
|
||||
if ( pData )
|
||||
{
|
||||
g_pMemAlloc->Free(pData);
|
||||
}
|
||||
}
|
||||
|
||||
void operator delete( void* pData, int nBlockUse, const char *pFileName, int nLine )
|
||||
{
|
||||
if ( pData )
|
||||
{
|
||||
g_pMemAlloc->Free(pData, pFileName, nLine );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline int InternalCheckDeclareClass( const char *pClassName, const char *pClassNameMatch, void *pTestPtr, void *pBasePtr )
|
||||
{
|
||||
// This makes sure that casting from ThisClass to BaseClass works right. You'll get a compiler error if it doesn't
|
||||
@@ -166,6 +205,7 @@ static inline void DispatchNetworkStateChanged( T *pObj, void *pVar )
|
||||
template< class T > NetworkVar_##name& operator=( const T &val ) { *((type*)this) = val; return *this; } \
|
||||
public: \
|
||||
void CopyFrom( const type &src ) { *((type *)this) = src; NetworkStateChanged(); } \
|
||||
type & GetForModify( void ) { NetworkStateChanged(); return *((type *)this); } \
|
||||
virtual void NetworkStateChanged() \
|
||||
{ \
|
||||
DispatchNetworkStateChanged( (ThisClass_##name*)( ((char*)this) - GetOffset_##name() ) ); \
|
||||
@@ -177,34 +217,32 @@ static inline void DispatchNetworkStateChanged( T *pObj, void *pVar )
|
||||
}; \
|
||||
NetworkVar_##name name;
|
||||
|
||||
template<typename T>
|
||||
FORCEINLINE void NetworkVarConstruct( T &x ) { x = T(0); }
|
||||
FORCEINLINE void NetworkVarConstruct( color32_s &x ) { x.r = x.g = x.b = x.a = 0; }
|
||||
|
||||
|
||||
template< class Type, class Changer >
|
||||
class CNetworkVarBase
|
||||
{
|
||||
public:
|
||||
inline CNetworkVarBase()
|
||||
CNetworkVarBase()
|
||||
{
|
||||
NetworkVarConstruct( m_Value );
|
||||
}
|
||||
|
||||
template< class C >
|
||||
const Type& operator=( const C &val )
|
||||
{
|
||||
return Set( ( const Type )val );
|
||||
}
|
||||
|
||||
template< class C >
|
||||
const Type& operator=( const CNetworkVarBase< C, Changer > &val )
|
||||
{
|
||||
return Set( ( const Type )val.m_Value );
|
||||
}
|
||||
|
||||
const Type& Set( const Type &val )
|
||||
FORCEINLINE explicit CNetworkVarBase( Type val )
|
||||
: m_Value( val )
|
||||
{
|
||||
if ( memcmp( &m_Value, &val, sizeof(Type) ) )
|
||||
NetworkStateChanged();
|
||||
}
|
||||
|
||||
FORCEINLINE const Type& SetDirect( const Type &val )
|
||||
{
|
||||
NetworkStateChanged();
|
||||
m_Value = val;
|
||||
return m_Value;
|
||||
}
|
||||
|
||||
FORCEINLINE const Type& Set( const Type &val )
|
||||
{
|
||||
if ( m_Value != val )
|
||||
{
|
||||
NetworkStateChanged();
|
||||
m_Value = val;
|
||||
@@ -212,66 +250,78 @@ public:
|
||||
return m_Value;
|
||||
}
|
||||
|
||||
Type& GetForModify()
|
||||
template< class C >
|
||||
FORCEINLINE const Type& operator=( const C &val )
|
||||
{
|
||||
return Set( ( const Type )val );
|
||||
}
|
||||
|
||||
template< class C >
|
||||
FORCEINLINE const Type& operator=( const CNetworkVarBase< C, Changer > &val )
|
||||
{
|
||||
return Set( ( const Type )val.m_Value );
|
||||
}
|
||||
|
||||
FORCEINLINE Type& GetForModify()
|
||||
{
|
||||
NetworkStateChanged();
|
||||
return m_Value;
|
||||
}
|
||||
|
||||
template< class C >
|
||||
const Type& operator+=( const C &val )
|
||||
FORCEINLINE const Type& operator+=( const C &val )
|
||||
{
|
||||
return Set( m_Value + ( const Type )val );
|
||||
}
|
||||
|
||||
template< class C >
|
||||
const Type& operator-=( const C &val )
|
||||
FORCEINLINE const Type& operator-=( const C &val )
|
||||
{
|
||||
return Set( m_Value - ( const Type )val );
|
||||
}
|
||||
|
||||
template< class C >
|
||||
const Type& operator/=( const C &val )
|
||||
FORCEINLINE const Type& operator/=( const C &val )
|
||||
{
|
||||
return Set( m_Value / ( const Type )val );
|
||||
}
|
||||
|
||||
template< class C >
|
||||
const Type& operator*=( const C &val )
|
||||
FORCEINLINE const Type& operator*=( const C &val )
|
||||
{
|
||||
return Set( m_Value * ( const Type )val );
|
||||
}
|
||||
|
||||
template< class C >
|
||||
const Type& operator^=( const C &val )
|
||||
FORCEINLINE const Type& operator^=( const C &val )
|
||||
{
|
||||
return Set( m_Value ^ ( const Type )val );
|
||||
}
|
||||
|
||||
template< class C >
|
||||
const Type& operator|=( const C &val )
|
||||
FORCEINLINE const Type& operator|=( const C &val )
|
||||
{
|
||||
return Set( m_Value | ( const Type )val );
|
||||
}
|
||||
|
||||
const Type& operator++()
|
||||
FORCEINLINE const Type& operator++()
|
||||
{
|
||||
return (*this += 1);
|
||||
}
|
||||
|
||||
Type operator--()
|
||||
FORCEINLINE Type operator--()
|
||||
{
|
||||
return (*this -= 1);
|
||||
}
|
||||
|
||||
Type operator++( int ) // postfix version..
|
||||
FORCEINLINE Type operator++( int ) // postfix version..
|
||||
{
|
||||
Type val = m_Value;
|
||||
(*this += 1);
|
||||
return val;
|
||||
}
|
||||
|
||||
Type operator--( int ) // postfix version..
|
||||
FORCEINLINE Type operator--( int ) // postfix version..
|
||||
{
|
||||
Type val = m_Value;
|
||||
(*this -= 1);
|
||||
@@ -282,22 +332,22 @@ public:
|
||||
// CNetworkVarBase<unsigned char> = 0x1
|
||||
// (it warns about converting from an int to an unsigned char).
|
||||
template< class C >
|
||||
const Type& operator&=( const C &val )
|
||||
FORCEINLINE const Type& operator&=( const C &val )
|
||||
{
|
||||
return Set( m_Value & ( const Type )val );
|
||||
}
|
||||
|
||||
operator const Type&() const
|
||||
FORCEINLINE operator const Type&() const
|
||||
{
|
||||
return m_Value;
|
||||
}
|
||||
|
||||
const Type& Get() const
|
||||
FORCEINLINE const Type& Get() const
|
||||
{
|
||||
return m_Value;
|
||||
}
|
||||
|
||||
const Type* operator->() const
|
||||
FORCEINLINE const Type* operator->() const
|
||||
{
|
||||
return &m_Value;
|
||||
}
|
||||
@@ -305,16 +355,16 @@ public:
|
||||
Type m_Value;
|
||||
|
||||
protected:
|
||||
inline void NetworkStateChanged()
|
||||
FORCEINLINE void NetworkStateChanged()
|
||||
{
|
||||
Changer::NetworkStateChanged( this );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template< class Type, class Changer >
|
||||
class CNetworkColor32Base : public CNetworkVarBase< Type, Changer >
|
||||
{
|
||||
typedef CNetworkVarBase< Type, Changer > base;
|
||||
public:
|
||||
inline void Init( byte rVal, byte gVal, byte bVal )
|
||||
{
|
||||
@@ -332,29 +382,29 @@ public:
|
||||
|
||||
const Type& operator=( const Type &val )
|
||||
{
|
||||
return this->Set( val );
|
||||
return Set( val );
|
||||
}
|
||||
|
||||
const Type& operator=( const CNetworkColor32Base<Type,Changer> &val )
|
||||
{
|
||||
return CNetworkVarBase<Type,Changer>::Set( val.m_Value );
|
||||
return base::Set( val.m_Value );
|
||||
}
|
||||
|
||||
inline byte GetR() const { return CNetworkColor32Base<Type,Changer>::m_Value.r; }
|
||||
inline byte GetG() const { return CNetworkColor32Base<Type,Changer>::m_Value.g; }
|
||||
inline byte GetB() const { return CNetworkColor32Base<Type,Changer>::m_Value.b; }
|
||||
inline byte GetA() const { return CNetworkColor32Base<Type,Changer>::m_Value.a; }
|
||||
inline void SetR( byte val ) { SetVal( CNetworkColor32Base<Type,Changer>::m_Value.r, val ); }
|
||||
inline void SetG( byte val ) { SetVal( CNetworkColor32Base<Type,Changer>::m_Value.g, val ); }
|
||||
inline void SetB( byte val ) { SetVal( CNetworkColor32Base<Type,Changer>::m_Value.b, val ); }
|
||||
inline void SetA( byte val ) { SetVal( CNetworkColor32Base<Type,Changer>::m_Value.a, val ); }
|
||||
inline byte GetR() const { return this->m_Value.r; }
|
||||
inline byte GetG() const { return this->m_Value.g; }
|
||||
inline byte GetB() const { return this->m_Value.b; }
|
||||
inline byte GetA() const { return this->m_Value.a; }
|
||||
inline void SetR( byte val ) { SetVal( this->m_Value.r, val ); }
|
||||
inline void SetG( byte val ) { SetVal( this->m_Value.g, val ); }
|
||||
inline void SetB( byte val ) { SetVal( this->m_Value.b, val ); }
|
||||
inline void SetA( byte val ) { SetVal( this->m_Value.a, val ); }
|
||||
|
||||
protected:
|
||||
inline void SetVal( byte &out, const byte &in )
|
||||
{
|
||||
if ( out != in )
|
||||
{
|
||||
CNetworkVarBase< Type, Changer >::NetworkStateChanged();
|
||||
this->NetworkStateChanged();
|
||||
out = in;
|
||||
}
|
||||
}
|
||||
@@ -365,80 +415,79 @@ protected:
|
||||
template< class Type, class Changer >
|
||||
class CNetworkVectorBase : public CNetworkVarBase< Type, Changer >
|
||||
{
|
||||
typedef CNetworkVarBase< Type, Changer > base;
|
||||
public:
|
||||
inline void Init( float ix=0, float iy=0, float iz=0 )
|
||||
FORCEINLINE void Init( float ix=0, float iy=0, float iz=0 )
|
||||
{
|
||||
SetX( ix );
|
||||
SetY( iy );
|
||||
SetZ( iz );
|
||||
base::Set( Type( ix, iy, iz ) );
|
||||
}
|
||||
|
||||
const Type& operator=( const Type &val )
|
||||
FORCEINLINE const Type& operator=( const Type &val )
|
||||
{
|
||||
return CNetworkVarBase< Type, Changer >::Set( val );
|
||||
return base::Set( val );
|
||||
}
|
||||
|
||||
const Type& operator=( const CNetworkVectorBase<Type,Changer> &val )
|
||||
FORCEINLINE const Type& operator=( const CNetworkVectorBase<Type,Changer> &val )
|
||||
{
|
||||
return CNetworkVarBase<Type,Changer>::Set( val.m_Value );
|
||||
return base::Set( val.m_Value );
|
||||
}
|
||||
|
||||
inline float GetX() const { return CNetworkVectorBase<Type,Changer>::m_Value.x; }
|
||||
inline float GetY() const { return CNetworkVectorBase<Type,Changer>::m_Value.y; }
|
||||
inline float GetZ() const { return CNetworkVectorBase<Type,Changer>::m_Value.z; }
|
||||
inline float operator[]( int i ) const { return CNetworkVectorBase<Type,Changer>::m_Value[i]; }
|
||||
FORCEINLINE float GetX() const { return this->m_Value.x; }
|
||||
FORCEINLINE float GetY() const { return this->m_Value.y; }
|
||||
FORCEINLINE float GetZ() const { return this->m_Value.z; }
|
||||
FORCEINLINE float operator[]( int i ) const { return this->m_Value[i]; }
|
||||
|
||||
inline void SetX( float val ) { DetectChange( CNetworkVectorBase<Type,Changer>::m_Value.x, val ); }
|
||||
inline void SetY( float val ) { DetectChange( CNetworkVectorBase<Type,Changer>::m_Value.y, val ); }
|
||||
inline void SetZ( float val ) { DetectChange( CNetworkVectorBase<Type,Changer>::m_Value.z, val ); }
|
||||
inline void Set( int i, float val ) { DetectChange( CNetworkVectorBase<Type,Changer>::m_Value[i], val ); }
|
||||
FORCEINLINE void SetX( float val ) { DetectChange( this->m_Value.x, val ); }
|
||||
FORCEINLINE void SetY( float val ) { DetectChange( this->m_Value.y, val ); }
|
||||
FORCEINLINE void SetZ( float val ) { DetectChange( this->m_Value.z, val ); }
|
||||
FORCEINLINE void Set( int i, float val ) { DetectChange( this->m_Value[i], val ); }
|
||||
|
||||
bool operator==( const Type &val ) const
|
||||
FORCEINLINE bool operator==( const Type &val ) const
|
||||
{
|
||||
return CNetworkVectorBase<Type,Changer>::m_Value == (Type)val;
|
||||
return this->m_Value == (Type)val;
|
||||
}
|
||||
|
||||
bool operator!=( const Type &val ) const
|
||||
FORCEINLINE bool operator!=( const Type &val ) const
|
||||
{
|
||||
return CNetworkVectorBase<Type,Changer>::m_Value != (Type)val;
|
||||
return this->m_Value != (Type)val;
|
||||
}
|
||||
|
||||
const Type operator+( const Type &val ) const
|
||||
FORCEINLINE const Type operator+( const Type &val ) const
|
||||
{
|
||||
return CNetworkVectorBase<Type,Changer>::m_Value + val;
|
||||
return this->m_Value + val;
|
||||
}
|
||||
|
||||
const Type operator-( const Type &val ) const
|
||||
FORCEINLINE const Type operator-( const Type &val ) const
|
||||
{
|
||||
return CNetworkVectorBase<Type,Changer>::m_Value - val;
|
||||
return this->m_Value - val;
|
||||
}
|
||||
|
||||
const Type operator*( const Type &val ) const
|
||||
FORCEINLINE const Type operator*( const Type &val ) const
|
||||
{
|
||||
return CNetworkVectorBase<Type,Changer>::m_Value * val;
|
||||
return this->m_Value * val;
|
||||
}
|
||||
|
||||
const Type& operator*=( float val )
|
||||
FORCEINLINE const Type& operator*=( float val )
|
||||
{
|
||||
return CNetworkVarBase< Type, Changer >::Set( CNetworkVectorBase<Type,Changer>::m_Value * val );
|
||||
return base::Set( this->m_Value * val );
|
||||
}
|
||||
|
||||
const Type operator*( float val ) const
|
||||
FORCEINLINE const Type operator*( float val ) const
|
||||
{
|
||||
return CNetworkVectorBase<Type,Changer>::m_Value * val;
|
||||
return this->m_Value * val;
|
||||
}
|
||||
|
||||
const Type operator/( const Type &val ) const
|
||||
FORCEINLINE const Type operator/( const Type &val ) const
|
||||
{
|
||||
return CNetworkVectorBase<Type,Changer>::m_Value / val;
|
||||
return this->m_Value / val;
|
||||
}
|
||||
|
||||
private:
|
||||
inline void DetectChange( float &out, float in )
|
||||
FORCEINLINE void DetectChange( float &out, float in )
|
||||
{
|
||||
if ( out != in )
|
||||
{
|
||||
CNetworkVectorBase<Type,Changer>::NetworkStateChanged();
|
||||
this->NetworkStateChanged();
|
||||
out = in;
|
||||
}
|
||||
}
|
||||
@@ -449,75 +498,73 @@ private:
|
||||
template< class Type, class Changer >
|
||||
class CNetworkQuaternionBase : public CNetworkVarBase< Type, Changer >
|
||||
{
|
||||
typedef CNetworkVarBase< Type, Changer > base;
|
||||
public:
|
||||
inline void Init( float ix=0, float iy=0, float iz=0, float iw = 0 )
|
||||
{
|
||||
SetX( ix );
|
||||
SetY( iy );
|
||||
SetZ( iz );
|
||||
SetW( iw );
|
||||
base::Set( Quaternion( ix, iy, iz, iw ) );
|
||||
}
|
||||
|
||||
const Type& operator=( const Type &val )
|
||||
{
|
||||
return CNetworkVarBase< Type, Changer >::Set( val );
|
||||
return Set( val );
|
||||
}
|
||||
|
||||
const Type& operator=( const CNetworkQuaternionBase<Type,Changer> &val )
|
||||
{
|
||||
return CNetworkVarBase<Type,Changer>::Set( val.m_Value );
|
||||
return Set( val.m_Value );
|
||||
}
|
||||
|
||||
inline float GetX() const { return CNetworkQuaternionBase<Type,Changer>::m_Value.x; }
|
||||
inline float GetY() const { return CNetworkQuaternionBase<Type,Changer>::m_Value.y; }
|
||||
inline float GetZ() const { return CNetworkQuaternionBase<Type,Changer>::m_Value.z; }
|
||||
inline float GetW() const { return CNetworkQuaternionBase<Type,Changer>::m_Value.w; }
|
||||
inline float operator[]( int i ) const { return CNetworkQuaternionBase<Type,Changer>::m_Value[i]; }
|
||||
inline float GetX() const { return this->m_Value.x; }
|
||||
inline float GetY() const { return this->m_Value.y; }
|
||||
inline float GetZ() const { return this->m_Value.z; }
|
||||
inline float GetW() const { return this->m_Value.w; }
|
||||
inline float operator[]( int i ) const { return this->m_Value[i]; }
|
||||
|
||||
inline void SetX( float val ) { DetectChange( CNetworkQuaternionBase<Type,Changer>::m_Value.x, val ); }
|
||||
inline void SetY( float val ) { DetectChange( CNetworkQuaternionBase<Type,Changer>::m_Value.y, val ); }
|
||||
inline void SetZ( float val ) { DetectChange( CNetworkQuaternionBase<Type,Changer>::m_Value.z, val ); }
|
||||
inline void SetW( float val ) { DetectChange( CNetworkQuaternionBase<Type,Changer>::m_Value.w, val ); }
|
||||
inline void Set( int i, float val ) { DetectChange( CNetworkQuaternionBase<Type,Changer>::m_Value[i], val ); }
|
||||
inline void SetX( float val ) { DetectChange( this->m_Value.x, val ); }
|
||||
inline void SetY( float val ) { DetectChange( this->m_Value.y, val ); }
|
||||
inline void SetZ( float val ) { DetectChange( this->m_Value.z, val ); }
|
||||
inline void SetW( float val ) { DetectChange( this->m_Value.w, val ); }
|
||||
inline void Set( int i, float val ) { DetectChange( this->m_Value[i], val ); }
|
||||
|
||||
bool operator==( const Type &val ) const
|
||||
{
|
||||
return CNetworkQuaternionBase<Type,Changer>::m_Value == (Type)val;
|
||||
return this->m_Value == (Type)val;
|
||||
}
|
||||
|
||||
bool operator!=( const Type &val ) const
|
||||
{
|
||||
return CNetworkQuaternionBase<Type,Changer>::m_Value != (Type)val;
|
||||
return this->m_Value != (Type)val;
|
||||
}
|
||||
|
||||
const Type operator+( const Type &val ) const
|
||||
{
|
||||
return CNetworkQuaternionBase<Type,Changer>::m_Value + val;
|
||||
return this->m_Value + val;
|
||||
}
|
||||
|
||||
const Type operator-( const Type &val ) const
|
||||
{
|
||||
return CNetworkQuaternionBase<Type,Changer>::m_Value - val;
|
||||
return this->m_Value - val;
|
||||
}
|
||||
|
||||
const Type operator*( const Type &val ) const
|
||||
{
|
||||
return CNetworkQuaternionBase<Type,Changer>::m_Value * val;
|
||||
return this->m_Value * val;
|
||||
}
|
||||
|
||||
const Type& operator*=( float val )
|
||||
{
|
||||
return CNetworkQuaternionBase< Type, Changer >::Set( CNetworkQuaternionBase<Type,Changer>::m_Value * val );
|
||||
return Set( this->m_Value * val );
|
||||
}
|
||||
|
||||
const Type operator*( float val ) const
|
||||
{
|
||||
return CNetworkQuaternionBase<Type,Changer>::m_Value * val;
|
||||
return this->m_Value * val;
|
||||
}
|
||||
|
||||
const Type operator/( const Type &val ) const
|
||||
{
|
||||
return CNetworkQuaternionBase<Type,Changer>::m_Value / val;
|
||||
return this->m_Value / val;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -525,7 +572,7 @@ private:
|
||||
{
|
||||
if ( out != in )
|
||||
{
|
||||
CNetworkQuaternionBase<Type,Changer>::NetworkStateChanged();
|
||||
this->NetworkStateChanged();
|
||||
out = in;
|
||||
}
|
||||
}
|
||||
@@ -534,11 +581,10 @@ private:
|
||||
|
||||
// Network ehandle wrapper.
|
||||
#if defined( CLIENT_DLL ) || defined( GAME_DLL )
|
||||
inline void NetworkVarConstruct( CBaseHandle &x ) {}
|
||||
|
||||
template< class Type, class Changer >
|
||||
class CNetworkHandleBase : public CNetworkVarBase< CBaseHandle, Changer >
|
||||
{
|
||||
typedef CNetworkVarBase< CBaseHandle, Changer > base;
|
||||
public:
|
||||
const Type* operator=( const Type *val )
|
||||
{
|
||||
@@ -553,12 +599,12 @@ private:
|
||||
|
||||
bool operator !() const
|
||||
{
|
||||
return !CNetworkHandleBase<Type,Changer>::m_Value.Get();
|
||||
return !this->m_Value.Get();
|
||||
}
|
||||
|
||||
operator Type*() const
|
||||
{
|
||||
return static_cast< Type* >( CNetworkHandleBase<Type,Changer>::m_Value.Get() );
|
||||
return static_cast< Type* >( this->m_Value.Get() );
|
||||
}
|
||||
|
||||
const Type* Set( const Type *val )
|
||||
@@ -678,7 +724,6 @@ private:
|
||||
class NetworkVar_##name \
|
||||
{ \
|
||||
public: \
|
||||
NetworkVar_##name() { m_Value[0] = '\0'; } \
|
||||
operator const char*() const { return m_Value; } \
|
||||
const char* Get() const { return m_Value; } \
|
||||
char* GetForModify() \
|
||||
@@ -708,11 +753,6 @@ private:
|
||||
class NetworkVar_##name \
|
||||
{ \
|
||||
public: \
|
||||
inline NetworkVar_##name() \
|
||||
{ \
|
||||
for ( int i = 0 ; i < count ; ++i ) \
|
||||
NetworkVarConstruct( m_Value[i] ); \
|
||||
} \
|
||||
template <typename T> friend int ServerClassInit(T *); \
|
||||
const type& operator[]( int i ) const \
|
||||
{ \
|
||||
@@ -743,12 +783,12 @@ private:
|
||||
} \
|
||||
const type* Base() const { return m_Value; } \
|
||||
int Count() const { return count; } \
|
||||
protected: \
|
||||
inline void NetworkStateChanged( int net_change_index ) \
|
||||
{ \
|
||||
CHECK_USENETWORKVARS ((ThisClass*)(((char*)this) - MyOffsetOf(ThisClass,name)))->stateChangedFn( &m_Value[net_change_index] ); \
|
||||
} \
|
||||
type m_Value[count]; \
|
||||
protected: \
|
||||
inline void NetworkStateChanged( int index ) \
|
||||
{ \
|
||||
CHECK_USENETWORKVARS ((ThisClass*)(((char*)this) - MyOffsetOf(ThisClass,name)))->stateChangedFn( &m_Value[index] ); \
|
||||
} \
|
||||
}; \
|
||||
NetworkVar_##name name;
|
||||
|
||||
|
||||
@@ -0,0 +1,341 @@
|
||||
//===================== Copyright (c) Valve Corporation. All Rights Reserved. ======================
|
||||
//
|
||||
// Included by networkvar.h
|
||||
//
|
||||
//==================================================================================================
|
||||
|
||||
#ifndef NETWORKVAR_VECTOR_H
|
||||
#define NETWORKVAR_VECTOR_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
// This is the normal case.. you've got a SendPropVector to match your CNetworkVector
|
||||
#define CNetworkVector( name ) CNetworkVectorInternal( Vector, name, NetworkStateChanged, CNetworkVectorBase )
|
||||
|
||||
// This variant of a CNetworkVector should be used if you want to use SendPropFloat
|
||||
// on each individual component of the vector.
|
||||
#define CNetworkVectorXYZ( name ) CNetworkVectorInternal( Vector, name, NetworkStateChanged, CNetworkVectorXYZBase )
|
||||
|
||||
// This variant of a CNetworkVector should be used if you want to use SendPropVectorXY
|
||||
// for the XY components and SendPropFloat for the Z component.
|
||||
#define CNetworkVectorXY_SeparateZ( name ) CNetworkVectorInternal( Vector, name, NetworkStateChanged, CNetworkVectorXY_SeparateZBase )
|
||||
|
||||
|
||||
|
||||
// This is the normal case.. you've got a SendPropQAngle to match your CNetworkQAngle
|
||||
#define CNetworkQAngle( name ) CNetworkVectorInternal( QAngle, name, NetworkStateChanged, CNetworkVectorBase )
|
||||
|
||||
// This variant of a CNetworkQAngle should be used if you want to use SendPropFloat
|
||||
// on each individual component of the vector.
|
||||
#define CNetworkQAngleXYZ( name ) CNetworkVectorInternal( QAngle, name, NetworkStateChanged, CNetworkVectorXYZBase )
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Use these variants if you want the networkvar to not trigger a change in the baseclass
|
||||
// version but you might want it to trigger changes in derived classes that do network that variable.
|
||||
//
|
||||
#define CNetworkVectorForDerived( name ) \
|
||||
virtual void NetworkStateChanged_##name() {} \
|
||||
virtual void NetworkStateChanged_##name( void *pVar ) {} \
|
||||
CNetworkVectorInternal( Vector, name, NetworkStateChanged_##name, CNetworkVectorBase )
|
||||
|
||||
#define CNetworkVectorXYZForDerived( name ) \
|
||||
virtual void NetworkStateChanged_##name() {} \
|
||||
virtual void NetworkStateChanged_##name( void *pVar ) {} \
|
||||
CNetworkVectorInternal( Vector, name, NetworkStateChanged_##name, CNetworkVectorXYZBase )
|
||||
|
||||
|
||||
|
||||
|
||||
#define CNetworkVectorInternal( type, name, stateChangedFn, baseClass ) \
|
||||
NETWORK_VAR_START( type, name ) \
|
||||
NETWORK_VAR_END( type, name, baseClass, stateChangedFn )
|
||||
|
||||
|
||||
|
||||
// Network vector wrapper.
|
||||
//
|
||||
// The common base is shared between all CNetworkVectors.
|
||||
// It includes everything but the Set() and operator=() functions,
|
||||
// because the behavior of each of those is different for each vector type.
|
||||
template< class Type, class Changer >
|
||||
class CNetworkVectorCommonBase : public CNetworkVarBase< Type, Changer >
|
||||
{
|
||||
typedef CNetworkVarBase< Type, Changer > base;
|
||||
public:
|
||||
|
||||
FORCEINLINE void Init( float ix=0, float iy=0, float iz=0 )
|
||||
{
|
||||
base::Set( Type( ix, iy, iz ) );
|
||||
}
|
||||
|
||||
FORCEINLINE float GetX() const { return this->m_Value.x; }
|
||||
FORCEINLINE float GetY() const { return this->m_Value.y; }
|
||||
FORCEINLINE float GetZ() const { return this->m_Value.z; }
|
||||
FORCEINLINE float operator[]( int i ) const { return this->m_Value[i]; }
|
||||
|
||||
FORCEINLINE bool operator==( const Type &val ) const
|
||||
{
|
||||
return this->m_Value == (Type)val;
|
||||
}
|
||||
|
||||
FORCEINLINE bool operator!=( const Type &val ) const
|
||||
{
|
||||
return this->m_Value != (Type)val;
|
||||
}
|
||||
|
||||
FORCEINLINE const Type operator+( const Type &val ) const
|
||||
{
|
||||
return this->m_Value + val;
|
||||
}
|
||||
|
||||
FORCEINLINE const Type operator-( const Type &val ) const
|
||||
{
|
||||
return this->m_Value - val;
|
||||
}
|
||||
|
||||
FORCEINLINE const Type operator*( const Type &val ) const
|
||||
{
|
||||
return this->m_Value * val;
|
||||
}
|
||||
|
||||
FORCEINLINE const Type& operator*=( float val )
|
||||
{
|
||||
return base::Set( this->m_Value * val );
|
||||
}
|
||||
|
||||
FORCEINLINE const Type operator*( float val ) const
|
||||
{
|
||||
return this->m_Value * val;
|
||||
}
|
||||
|
||||
FORCEINLINE const Type operator/( const Type &val ) const
|
||||
{
|
||||
return this->m_Value / val;
|
||||
}
|
||||
|
||||
protected:
|
||||
FORCEINLINE void DetectChange( float &out, float in )
|
||||
{
|
||||
if ( out != in )
|
||||
{
|
||||
this->NetworkStateChanged();
|
||||
out = in;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// This is for a CNetworkVector that only generates one change offset.
|
||||
// It should only ever be used with SendPropVector/QAngle.
|
||||
//
|
||||
// Single-component things like SendPropFloat should never refer to it because
|
||||
// they require the network var to report an offset for each component.
|
||||
//
|
||||
template< class Type, class Changer >
|
||||
class CNetworkVectorBase : public CNetworkVectorCommonBase< Type, Changer >
|
||||
{
|
||||
typedef CNetworkVarBase< Type, Changer > base;
|
||||
public:
|
||||
static FORCEINLINE int GetNetworkVarFlags() { return NETWORKVAR_IS_A_VECTOR; }
|
||||
|
||||
FORCEINLINE const Type& operator=( const Type &val )
|
||||
{
|
||||
return base::Set( val );
|
||||
}
|
||||
|
||||
FORCEINLINE const Type& operator=( const CNetworkVectorBase<Type,Changer> &val )
|
||||
{
|
||||
return base::Set( val.m_Value );
|
||||
}
|
||||
FORCEINLINE void SetX( float val ) { this->DetectChange( this->m_Value.x, val ); }
|
||||
FORCEINLINE void SetY( float val ) { this->DetectChange( this->m_Value.y, val ); }
|
||||
FORCEINLINE void SetZ( float val ) { this->DetectChange( this->m_Value.z, val ); }
|
||||
FORCEINLINE void Set( int i, float val ) { this->DetectChange( this->m_Value[i], val ); }
|
||||
|
||||
FORCEINLINE const Type& operator*=( float val )
|
||||
{
|
||||
return base::Set( this->m_Value * val );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// This variant of a CNetworkVector should be used if you want to use SendPropFloat
|
||||
// on each individual component of the vector.
|
||||
//
|
||||
template< class Type, class Changer >
|
||||
class CNetworkVectorXYZBase : public CNetworkVectorCommonBase< Type, Changer >
|
||||
{
|
||||
typedef CNetworkVectorCommonBase< Type, Changer > base;
|
||||
public:
|
||||
|
||||
static FORCEINLINE int GetNetworkVarFlags() { return NETWORKVAR_IS_A_VECTOR | NETWORKVAR_VECTOR_XYZ_FLAG; }
|
||||
|
||||
FORCEINLINE const Type& operator=( const Type &val )
|
||||
{
|
||||
return Set( val );
|
||||
}
|
||||
|
||||
FORCEINLINE const Type& operator=( const CNetworkVectorBase<Type,Changer> &val )
|
||||
{
|
||||
return Set( val.m_Value );
|
||||
}
|
||||
|
||||
FORCEINLINE const Type& Set( const Type &val )
|
||||
{
|
||||
SetX( val.x );
|
||||
SetY( val.y );
|
||||
SetZ( val.z );
|
||||
|
||||
return this->m_Value;
|
||||
}
|
||||
|
||||
FORCEINLINE Type& GetForModify()
|
||||
{
|
||||
this->NetworkStateChanged( &((float*)this)[0] );
|
||||
this->NetworkStateChanged( &((float*)this)[1] );
|
||||
this->NetworkStateChanged( &((float*)this)[2] );
|
||||
return this->m_Value;
|
||||
}
|
||||
|
||||
FORCEINLINE const Type& SetDirect( const Type &val )
|
||||
{
|
||||
GetForModify() = val;
|
||||
return this->m_Value;
|
||||
}
|
||||
|
||||
FORCEINLINE void SetX( float val ) { DetectChange( 0, val ); }
|
||||
FORCEINLINE void SetY( float val ) { DetectChange( 1, val ); }
|
||||
FORCEINLINE void SetZ( float val ) { DetectChange( 2, val ); }
|
||||
FORCEINLINE void Set( int i, float val ) { DetectChange( i, val ); }
|
||||
|
||||
FORCEINLINE const Type& operator+=( const Type &val )
|
||||
{
|
||||
return Set( this->m_Value + val );
|
||||
}
|
||||
|
||||
FORCEINLINE const Type& operator-=( const Type &val )
|
||||
{
|
||||
return Set( this->m_Value - val );
|
||||
}
|
||||
|
||||
FORCEINLINE const Type& operator*=( float val )
|
||||
{
|
||||
return Set( this->m_Value * val );
|
||||
}
|
||||
|
||||
FORCEINLINE const Type& operator/=( float val )
|
||||
{
|
||||
return Set( this->m_Value / val );
|
||||
}
|
||||
|
||||
private:
|
||||
FORCEINLINE void DetectChange( int nComponent, float in )
|
||||
{
|
||||
float *pVar = &((float*)this)[nComponent];
|
||||
if ( *pVar != in )
|
||||
{
|
||||
if ( pVar != &((float*)this)[0] )
|
||||
{
|
||||
this->NetworkStateChanged( &((float*)this)[0] ); // Always mark the start of the vector as changed
|
||||
}
|
||||
this->NetworkStateChanged( pVar );
|
||||
*pVar = in;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// This variant of a CNetworkVector should be used if you want to use SendPropVectorXY
|
||||
// for the XY components and SendPropFloat for the Z component.
|
||||
//
|
||||
template< class Type, class Changer >
|
||||
class CNetworkVectorXY_SeparateZBase : public CNetworkVectorCommonBase< Type, Changer >
|
||||
{
|
||||
typedef CNetworkVectorCommonBase< Type, Changer > base;
|
||||
public:
|
||||
|
||||
static FORCEINLINE int GetNetworkVarFlags() { return NETWORKVAR_IS_A_VECTOR | NETWORKVAR_VECTOR_XY_SEPARATEZ_FLAG; }
|
||||
|
||||
FORCEINLINE const Type& operator=( const Type &val )
|
||||
{
|
||||
return Set( val );
|
||||
}
|
||||
|
||||
FORCEINLINE const Type& operator=( const CNetworkVectorBase<Type,Changer> &val )
|
||||
{
|
||||
return Set( val.m_Value );
|
||||
}
|
||||
|
||||
FORCEINLINE const Type& Set( const Type &val )
|
||||
{
|
||||
SetX( val.x );
|
||||
SetY( val.y );
|
||||
SetZ( val.z );
|
||||
|
||||
return this->m_Value;
|
||||
}
|
||||
|
||||
FORCEINLINE Type& GetForModify()
|
||||
{
|
||||
this->NetworkStateChanged( &((float*)this)[0] ); // Mark the offset of our XY SendProp as changed.
|
||||
this->NetworkStateChanged( &((float*)this)[2] ); // Mark the offset of our Z SendProp as changed.
|
||||
return this->m_Value;
|
||||
}
|
||||
|
||||
FORCEINLINE const Type& SetDirect( const Type &val )
|
||||
{
|
||||
GetForModify() = val;
|
||||
return this->m_Value;
|
||||
}
|
||||
|
||||
FORCEINLINE void SetX( float val ) { DetectChange( 0, val ); }
|
||||
FORCEINLINE void SetY( float val ) { DetectChange( 1, val ); }
|
||||
FORCEINLINE void SetZ( float val ) { DetectChange( 2, val ); }
|
||||
FORCEINLINE void Set( int i, float val ) { DetectChange( i, val ); }
|
||||
|
||||
FORCEINLINE const Type& operator+=( const Type &val )
|
||||
{
|
||||
return Set( this->m_Value + val );
|
||||
}
|
||||
|
||||
FORCEINLINE const Type& operator-=( const Type &val )
|
||||
{
|
||||
return Set( this->m_Value - val );
|
||||
}
|
||||
|
||||
FORCEINLINE const Type& operator*=( float val )
|
||||
{
|
||||
return Set( this->m_Value * val );
|
||||
}
|
||||
|
||||
FORCEINLINE const Type& operator/=( float val )
|
||||
{
|
||||
return Set( this->m_Value / val );
|
||||
}
|
||||
|
||||
private:
|
||||
FORCEINLINE void DetectChange( int nComponent, float in )
|
||||
{
|
||||
float *pVar = &((float*)this)[nComponent];
|
||||
if ( *pVar != in )
|
||||
{
|
||||
this->NetworkStateChanged( &((float*)this)[0] ); // Mark the offset of our XY SendProp as changed.
|
||||
this->NetworkStateChanged( &((float*)this)[2] ); // Mark the offset of our Z SendProp as changed.
|
||||
|
||||
*pVar = in;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // NETWORKVAR_VECTOR_H
|
||||
|
||||
@@ -0,0 +1,768 @@
|
||||
//============ Copyright (c) Valve Corporation, All rights reserved. ============
|
||||
//
|
||||
// Logging system declarations.
|
||||
//
|
||||
// The logging system is a channel-based output mechanism which allows
|
||||
// subsystems to route their text/diagnostic output to various listeners
|
||||
//
|
||||
//===============================================================================
|
||||
|
||||
#ifndef LOGGING_H
|
||||
#define LOGGING_H
|
||||
|
||||
#if !defined(__SPU__)
|
||||
|
||||
#if defined( COMPILER_MSVC )
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "color.h"
|
||||
#include "icommandline.h"
|
||||
#include <stdio.h>
|
||||
|
||||
// For XBX_** functions
|
||||
#if defined( _X360 )
|
||||
#include "xbox/xbox_console.h"
|
||||
#endif
|
||||
|
||||
// Used by CColorizedLoggingListener
|
||||
#if defined( _WIN32 ) || (defined(POSIX) && !defined(_GAMECONSOLE))
|
||||
#include "tier0/win32consoleio.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
---- Logging System ----
|
||||
|
||||
The logging system is a channel-based mechanism for all code (engine,
|
||||
mod, tool) across all platforms to output information, warnings,
|
||||
errors, etc.
|
||||
|
||||
This system supersedes the existing Msg(), Warning(), Error(), DevMsg(), ConMsg() etc. functions.
|
||||
There are channels defined in the new system through which all old messages are routed;
|
||||
see LOG_GENERAL, LOG_CONSOLE, LOG_DEVELOPER, etc.
|
||||
|
||||
To use the system, simply call one of the predefined macros:
|
||||
|
||||
Log_Msg( ChannelID, [Color], Message, ... )
|
||||
Log_Warning( ChannelID, [Color], Message, ... )
|
||||
Log_Error( ChannelID, [Color], Message, ... )
|
||||
|
||||
A ChannelID is typically created by defining a logging channel with the
|
||||
log channel macros:
|
||||
|
||||
DEFINE_LOGGING_CHANNEL_NO_TAGS( LOG_ChannelName, "ChannelName", [Flags], [MinimumSeverity], [Color] );
|
||||
|
||||
or
|
||||
|
||||
BEGIN_DEFINE_LOGGING_CHANNEL( LOG_ChannelName, "ChannelName", [Flags], [MinimumSeverity], [Color] );
|
||||
ADD_LOGGING_CHANNEL_TAG( "Tag1" );
|
||||
ADD_LOGGING_CHANNEL_TAG( "Tag2" );
|
||||
END_DEFINE_LOGGING_CHANNEL();
|
||||
|
||||
These macros create a global channel ID variable with the name specified
|
||||
by the first parameter (in this example, LOG_ChannelName). This channel ID
|
||||
can be used by various LoggingSystem_** functions to manipulate the channel settings.
|
||||
|
||||
The optional [Flags] parameter is an OR'd together set of LoggingChannelFlags_t
|
||||
values (default: 0).
|
||||
|
||||
The optional [MinimumSeverity] parameter is the lowest threshold
|
||||
above which messages will be processed (inclusive). The default is LS_MESSAGE,
|
||||
which results in all messages, warnings, and errors being logged.
|
||||
Variadic parameters to the Log_** functions will be ignored if a channel
|
||||
is not enabled for a given severity (for performance reasons).
|
||||
|
||||
Logging channels can have their minimum severity modified by name, ID, or tag.
|
||||
|
||||
Logging channels are not hierarchical since there are situations in which
|
||||
a channel needs to belong to multiple hierarchies. Use tags to create
|
||||
categories or shallow hierarchies.
|
||||
|
||||
@TODO (Feature wishlist):
|
||||
1) Callstack logging support
|
||||
2) Registering dynamic channels and unregistering channels at runtime
|
||||
3) Sentient robot to clean up the thousands of places using the old/legacy logging system.
|
||||
*/
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Constants, Types, Forward Declares
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CLoggingSystem;
|
||||
class CThreadFastMutex;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Maximum length of a sprintf'ed logging message.
|
||||
//-----------------------------------------------------------------------------
|
||||
const int MAX_LOGGING_MESSAGE_LENGTH = 2048;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Maximum length of a channel or tag name.
|
||||
//-----------------------------------------------------------------------------
|
||||
const int MAX_LOGGING_IDENTIFIER_LENGTH = 32;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Maximum number of logging channels. Increase if needed.
|
||||
//-----------------------------------------------------------------------------
|
||||
const int MAX_LOGGING_CHANNEL_COUNT = 256;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Maximum number of logging tags across all channels. Increase if needed.
|
||||
//-----------------------------------------------------------------------------
|
||||
const int MAX_LOGGING_TAG_COUNT = 1024;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Maximum number of characters across all logging tags. Increase if needed.
|
||||
//-----------------------------------------------------------------------------
|
||||
const int MAX_LOGGING_TAG_CHARACTER_COUNT = 8192;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Maximum number of concurrent logging listeners in a given logging state.
|
||||
//-----------------------------------------------------------------------------
|
||||
const int MAX_LOGGING_LISTENER_COUNT = 16;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// An invalid color set on a channel to imply that it should use
|
||||
// a device-dependent default color where applicable.
|
||||
//-----------------------------------------------------------------------------
|
||||
const Color UNSPECIFIED_LOGGING_COLOR( 0, 0, 0, 0 );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// An ID returned by the logging system to refer to a logging channel.
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef int LoggingChannelID_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A sentinel value indicating an invalid logging channel ID.
|
||||
//-----------------------------------------------------------------------------
|
||||
const LoggingChannelID_t INVALID_LOGGING_CHANNEL_ID = -1;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// The severity of a logging operation.
|
||||
//-----------------------------------------------------------------------------
|
||||
enum LoggingSeverity_t
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
// An informative logging message.
|
||||
//-----------------------------------------------------------------------------
|
||||
LS_MESSAGE = 0,
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A warning, typically non-fatal
|
||||
//-----------------------------------------------------------------------------
|
||||
LS_WARNING = 1,
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A message caused by an Assert**() operation.
|
||||
//-----------------------------------------------------------------------------
|
||||
LS_ASSERT = 2,
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// An error, typically fatal/unrecoverable.
|
||||
//-----------------------------------------------------------------------------
|
||||
LS_ERROR = 3,
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A placeholder level, higher than any legal value.
|
||||
// Not a real severity value!
|
||||
//-----------------------------------------------------------------------------
|
||||
LS_HIGHEST_SEVERITY = 4,
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Action which should be taken by logging system as a result of
|
||||
// a given logged message.
|
||||
//
|
||||
// The logging system invokes ILoggingResponsePolicy::OnLog() on
|
||||
// the specified policy object, which returns a LoggingResponse_t.
|
||||
//-----------------------------------------------------------------------------
|
||||
enum LoggingResponse_t
|
||||
{
|
||||
LR_CONTINUE,
|
||||
LR_DEBUGGER,
|
||||
LR_ABORT,
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Logging channel behavior flags, set on channel creation.
|
||||
//-----------------------------------------------------------------------------
|
||||
enum LoggingChannelFlags_t
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
// Indicates that the spew is only relevant to interactive consoles.
|
||||
//-----------------------------------------------------------------------------
|
||||
LCF_CONSOLE_ONLY = 0x00000001,
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Indicates that spew should not be echoed to any output devices.
|
||||
// A suitable logging listener must be registered which respects this flag
|
||||
// (e.g. a file logger).
|
||||
//-----------------------------------------------------------------------------
|
||||
LCF_DO_NOT_ECHO = 0x00000002,
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A callback function used to register tags on a logging channel
|
||||
// during initialization.
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef void ( *RegisterTagsFunc )();
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A context structure passed to logging listeners and response policy classes.
|
||||
//-----------------------------------------------------------------------------
|
||||
struct LoggingContext_t
|
||||
{
|
||||
// ID of the channel being logged to.
|
||||
LoggingChannelID_t m_ChannelID;
|
||||
// Flags associated with the channel.
|
||||
LoggingChannelFlags_t m_Flags;
|
||||
// Severity of the logging event.
|
||||
LoggingSeverity_t m_Severity;
|
||||
// Color of logging message if one was specified to Log_****() macro.
|
||||
// If not specified, falls back to channel color.
|
||||
// If channel color is not specified, this value is UNSPECIFIED_LOGGING_COLOR
|
||||
// and indicates that a suitable default should be chosen.
|
||||
Color m_Color;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Interface for classes to handle logging output.
|
||||
//
|
||||
// The Log() function of this class is called synchronously and serially
|
||||
// by the logging system on all registered instances of ILoggingListener
|
||||
// in the current "logging state".
|
||||
//
|
||||
// Derived classes may do whatever they want with the message (write to disk,
|
||||
// write to console, send over the network, drop on the floor, etc.).
|
||||
//
|
||||
// In general, derived classes should do one, simple thing with the output
|
||||
// to allow callers to register multiple, orthogonal logging listener classes.
|
||||
//-----------------------------------------------------------------------------
|
||||
class ILoggingListener
|
||||
{
|
||||
public:
|
||||
virtual void Log( const LoggingContext_t *pContext, const tchar *pMessage ) = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Interface for policy classes which determine how to behave when a
|
||||
// message is logged.
|
||||
//
|
||||
// Can return:
|
||||
// LR_CONTINUE (continue execution)
|
||||
// LR_DEBUGGER (break into debugger if one is present, otherwise continue)
|
||||
// LR_ABORT (terminate process immediately with a failure code of 1)
|
||||
//-----------------------------------------------------------------------------
|
||||
class ILoggingResponsePolicy
|
||||
{
|
||||
public:
|
||||
virtual LoggingResponse_t OnLog( const LoggingContext_t *pContext ) = 0;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Common Logging Listeners & Logging Response Policies
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A basic logging listener which prints to stdout and the debug channel.
|
||||
//-----------------------------------------------------------------------------
|
||||
class CSimpleLoggingListener : public ILoggingListener
|
||||
{
|
||||
public:
|
||||
CSimpleLoggingListener( bool bQuietPrintf = false, bool bQuietDebugger = false ) :
|
||||
m_bQuietPrintf( bQuietPrintf ),
|
||||
m_bQuietDebugger( bQuietDebugger )
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Log( const LoggingContext_t *pContext, const tchar *pMessage )
|
||||
{
|
||||
#ifdef _X360
|
||||
if ( !m_bQuietDebugger && XBX_IsConsoleConnected() )
|
||||
{
|
||||
// send to console
|
||||
XBX_DebugString( XMAKECOLOR( 0,0,0 ), pMessage );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#if !defined( _CERT ) && !defined( DBGFLAG_STRINGS_STRIP )
|
||||
if ( !m_bQuietPrintf )
|
||||
{
|
||||
_tprintf( _T("%s"), pMessage );
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
if ( !m_bQuietDebugger && Plat_IsInDebugSession() )
|
||||
{
|
||||
Plat_DebugString( pMessage );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// If set to true, does not print anything to stdout.
|
||||
bool m_bQuietPrintf;
|
||||
// If set to true, does not print anything to debugger.
|
||||
bool m_bQuietDebugger;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A basic logging listener for GUI applications
|
||||
//-----------------------------------------------------------------------------
|
||||
class CSimpleWindowsLoggingListener : public ILoggingListener
|
||||
{
|
||||
public:
|
||||
virtual void Log( const LoggingContext_t *pContext, const tchar *pMessage )
|
||||
{
|
||||
if ( Plat_IsInDebugSession() )
|
||||
{
|
||||
Plat_DebugString( pMessage );
|
||||
}
|
||||
if ( pContext->m_Severity == LS_ERROR )
|
||||
{
|
||||
if ( Plat_IsInDebugSession() )
|
||||
DebuggerBreak();
|
||||
|
||||
Plat_MessageBox( "Error", pMessage );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ** NOTE FOR INTEGRATION **
|
||||
// This was copied over from source 2 rather than integrated because
|
||||
// source 2 has more significantly refactored tier0 logging.
|
||||
//
|
||||
// A logging listener with Win32 console API color support which which prints
|
||||
// to stdout and the debug channel.
|
||||
//-----------------------------------------------------------------------------
|
||||
#if !defined(_GAMECONSOLE)
|
||||
class CColorizedLoggingListener : public CSimpleLoggingListener
|
||||
{
|
||||
public:
|
||||
CColorizedLoggingListener( bool bQuietPrintf = false, bool bQuietDebugger = false ) : CSimpleLoggingListener( bQuietPrintf, bQuietDebugger )
|
||||
{
|
||||
InitWin32ConsoleColorContext( &m_ColorContext );
|
||||
}
|
||||
|
||||
virtual void Log( const LoggingContext_t *pContext, const tchar *pMessage )
|
||||
{
|
||||
if ( !m_bQuietPrintf )
|
||||
{
|
||||
int nPrevColor = -1;
|
||||
|
||||
if ( pContext->m_Color != UNSPECIFIED_LOGGING_COLOR )
|
||||
{
|
||||
nPrevColor = SetWin32ConsoleColor( &m_ColorContext,
|
||||
pContext->m_Color.r(), pContext->m_Color.g(), pContext->m_Color.b(),
|
||||
MAX( MAX( pContext->m_Color.r(), pContext->m_Color.g() ), pContext->m_Color.b() ) > 128 );
|
||||
}
|
||||
|
||||
_tprintf( _T("%s"), pMessage );
|
||||
|
||||
if ( nPrevColor >= 0 )
|
||||
{
|
||||
RestoreWin32ConsoleColor( &m_ColorContext, nPrevColor );
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if ( !m_bQuietDebugger && Plat_IsInDebugSession() )
|
||||
{
|
||||
Plat_DebugString( pMessage );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Win32ConsoleColorContext_t m_ColorContext;
|
||||
};
|
||||
#endif // !_GAMECONSOLE
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Default logging response policy used when one is not specified.
|
||||
//-----------------------------------------------------------------------------
|
||||
class CDefaultLoggingResponsePolicy : public ILoggingResponsePolicy
|
||||
{
|
||||
public:
|
||||
virtual LoggingResponse_t OnLog( const LoggingContext_t *pContext )
|
||||
{
|
||||
if ( pContext->m_Severity == LS_ASSERT && !CommandLine()->FindParm( "-noassert" ) )
|
||||
{
|
||||
return LR_DEBUGGER;
|
||||
}
|
||||
else if ( pContext->m_Severity == LS_ERROR )
|
||||
{
|
||||
return LR_ABORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return LR_CONTINUE;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A logging response policy which never terminates the process, even on error.
|
||||
//-----------------------------------------------------------------------------
|
||||
class CNonFatalLoggingResponsePolicy : public ILoggingResponsePolicy
|
||||
{
|
||||
public:
|
||||
virtual LoggingResponse_t OnLog( const LoggingContext_t *pContext )
|
||||
{
|
||||
if ( ( pContext->m_Severity == LS_ASSERT && !CommandLine()->FindParm( "-noassert" ) ) || pContext->m_Severity == LS_ERROR )
|
||||
{
|
||||
return LR_DEBUGGER;
|
||||
}
|
||||
else
|
||||
{
|
||||
return LR_CONTINUE;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Central Logging System
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// The central logging system.
|
||||
//
|
||||
// Multiple instances can exist, though all exported tier0 functionality
|
||||
// specifically works with a single global instance
|
||||
// (via GetGlobalLoggingSystem()).
|
||||
//-----------------------------------------------------------------------------
|
||||
class CLoggingSystem
|
||||
{
|
||||
public:
|
||||
struct LoggingChannel_t;
|
||||
|
||||
CLoggingSystem();
|
||||
~CLoggingSystem();
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Register a logging channel with the logging system.
|
||||
// The same channel can be registered multiple times, but the parameters
|
||||
// in each call to RegisterLoggingChannel must either match across all calls
|
||||
// or be set to defaults on any given call
|
||||
//
|
||||
// This function is not thread-safe and should generally only be called
|
||||
// by a single thread. Using the logging channel definition macros ensures
|
||||
// that this is called on the static initialization thread.
|
||||
//-----------------------------------------------------------------------------
|
||||
LoggingChannelID_t RegisterLoggingChannel( const char *pChannelName, RegisterTagsFunc registerTagsFunc, int flags = 0, LoggingSeverity_t minimumSeverity = LS_MESSAGE, Color spewColor = UNSPECIFIED_LOGGING_COLOR );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets a channel ID from a string name.
|
||||
// Performs a simple linear search; cache the value whenever possible
|
||||
// or re-register the logging channel to get a global ID.
|
||||
//-----------------------------------------------------------------------------
|
||||
LoggingChannelID_t FindChannel( const char *pChannelName ) const;
|
||||
|
||||
int GetChannelCount() const { return m_nChannelCount; }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets a pointer to the logging channel description.
|
||||
//-----------------------------------------------------------------------------
|
||||
LoggingChannel_t *GetChannel( LoggingChannelID_t channelID );
|
||||
const LoggingChannel_t *GetChannel( LoggingChannelID_t channelID ) const;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns true if the given channel has the specified tag.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool HasTag( LoggingChannelID_t channelID, const char *pTag ) const { return GetChannel( channelID )->HasTag( pTag ); }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns true if the given channel has been initialized.
|
||||
// The main purpose is catching m_nChannelCount being zero because no channels have been registered.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool IsValidChannelID( LoggingChannelID_t channelID ) const { return ( channelID >= 0 ) && ( channelID < m_nChannelCount ); }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns true if the given channel will spew at the given severity level.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool IsChannelEnabled( LoggingChannelID_t channelID, LoggingSeverity_t severity ) const { return IsValidChannelID( channelID ) && GetChannel( channelID )->IsEnabled( severity ); }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Functions to set the spew level of a channel either directly by ID or
|
||||
// string name, or for all channels with a given tag.
|
||||
//
|
||||
// These functions are not technically thread-safe but calling them across
|
||||
// multiple threads should cause no significant problems
|
||||
// (the underlying data types being changed are 32-bit/atomic).
|
||||
//-----------------------------------------------------------------------------
|
||||
void SetChannelSpewLevel( LoggingChannelID_t channelID, LoggingSeverity_t minimumSeverity );
|
||||
void SetChannelSpewLevelByName( const char *pName, LoggingSeverity_t minimumSeverity );
|
||||
void SetChannelSpewLevelByTag( const char *pTag, LoggingSeverity_t minimumSeverity );
|
||||
void SetGlobalSpewLevel( LoggingSeverity_t minimumSeverity );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets or sets the color of a logging channel.
|
||||
// (The functions are not thread-safe, but the consequences are not
|
||||
// significant.)
|
||||
//-----------------------------------------------------------------------------
|
||||
Color GetChannelColor( LoggingChannelID_t channelID ) const { return GetChannel( channelID )->m_SpewColor; }
|
||||
void SetChannelColor( LoggingChannelID_t channelID, Color color ) { GetChannel( channelID )->m_SpewColor = color; }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets or sets the flags on a logging channel.
|
||||
// (The functions are not thread-safe, but the consequences are not
|
||||
// significant.)
|
||||
//-----------------------------------------------------------------------------
|
||||
LoggingChannelFlags_t GetChannelFlags( LoggingChannelID_t channelID ) const { return GetChannel( channelID )->m_Flags; }
|
||||
void SetChannelFlags( LoggingChannelID_t channelID, LoggingChannelFlags_t flags ) { GetChannel( channelID )->m_Flags = flags; }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Adds a string tag to a channel.
|
||||
// This is not thread-safe and should only be called by a RegisterTagsFunc
|
||||
// callback passed in to RegisterLoggingChannel (via the
|
||||
// channel definition macros).
|
||||
//-----------------------------------------------------------------------------
|
||||
void AddTagToCurrentChannel( const char *pTagName );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Functions to save/restore the current logging state.
|
||||
// Set bThreadLocal to true on a matching Push/Pop call if the intent
|
||||
// is to override the logging listeners on the current thread only.
|
||||
//
|
||||
// Pushing the current logging state onto the state stack results
|
||||
// in the current state being cleared by default (no listeners, default logging response policy).
|
||||
// Set bClearState to false to copy the existing listener pointers to the new state.
|
||||
//
|
||||
// These functions which mutate logging state ARE thread-safe and are
|
||||
// guarded by m_StateMutex.
|
||||
//-----------------------------------------------------------------------------
|
||||
void PushLoggingState( bool bThreadLocal = false, bool bClearState = true );
|
||||
void PopLoggingState( bool bThreadLocal = false );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Registers a logging listener (a class which handles logged messages).
|
||||
//-----------------------------------------------------------------------------
|
||||
void RegisterLoggingListener( ILoggingListener *pListener );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns whether the specified logging listener is registered.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool IsListenerRegistered( ILoggingListener *pListener );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Clears out all of the current logging state (removes all listeners,
|
||||
// sets the response policy to the default).
|
||||
//-----------------------------------------------------------------------------
|
||||
void ResetCurrentLoggingState();
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets a policy class to decide what should happen when messages of a
|
||||
// particular severity are logged
|
||||
// (e.g. exit on error, break into debugger).
|
||||
// If pLoggingResponse is NULL, uses the default response policy class.
|
||||
//-----------------------------------------------------------------------------
|
||||
void SetLoggingResponsePolicy( ILoggingResponsePolicy *pLoggingResponse );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Logs a message to the specified channel using a given severity and
|
||||
// spew color. Passing in UNSPECIFIED_LOGGING_COLOR for 'color' allows
|
||||
// the logging listeners to provide a default.
|
||||
// NOTE: test 'IsChannelEnabled(channelID,severity)' before calling this!
|
||||
//-----------------------------------------------------------------------------
|
||||
LoggingResponse_t LogDirect( LoggingChannelID_t channelID, LoggingSeverity_t severity, Color color, const tchar *pMessage );
|
||||
|
||||
// Internal data to represent a logging tag
|
||||
struct LoggingTag_t
|
||||
{
|
||||
const char *m_pTagName;
|
||||
LoggingTag_t *m_pNextTag;
|
||||
};
|
||||
|
||||
// Internal data to represent a logging channel.
|
||||
struct LoggingChannel_t
|
||||
{
|
||||
bool HasTag( const char *pTag ) const
|
||||
{
|
||||
LoggingTag_t *pCurrentTag = m_pFirstTag;
|
||||
while( pCurrentTag != NULL )
|
||||
{
|
||||
if ( stricmp( pCurrentTag->m_pTagName, pTag ) == 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
pCurrentTag = pCurrentTag->m_pNextTag;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool IsEnabled( LoggingSeverity_t severity ) const { return severity >= m_MinimumSeverity; }
|
||||
void SetSpewLevel( LoggingSeverity_t severity ) { m_MinimumSeverity = severity; }
|
||||
|
||||
LoggingChannelID_t m_ID;
|
||||
LoggingChannelFlags_t m_Flags; // an OR'd combination of LoggingChannelFlags_t
|
||||
LoggingSeverity_t m_MinimumSeverity; // The minimum severity level required to activate this channel.
|
||||
Color m_SpewColor;
|
||||
char m_Name[MAX_LOGGING_IDENTIFIER_LENGTH];
|
||||
LoggingTag_t *m_pFirstTag;
|
||||
};
|
||||
|
||||
private:
|
||||
// Represents the current state of the logger (registered listeners, response policy class, etc.) and can
|
||||
// vary from thread-to-thread. It can also be pushed/popped to save/restore listener/response state.
|
||||
struct LoggingState_t
|
||||
{
|
||||
// Index of the previous entry on the listener set stack.
|
||||
int m_nPreviousStackEntry;
|
||||
|
||||
// Number of active listeners in this set. Cannot exceed MAX_LOGGING_LISTENER_COUNT.
|
||||
// If set to -1, implies that this state structure is not in use.
|
||||
int m_nListenerCount;
|
||||
// Array of registered logging listener objects.
|
||||
ILoggingListener *m_RegisteredListeners[MAX_LOGGING_LISTENER_COUNT];
|
||||
|
||||
// Specific policy class to determine behavior of logging system under specific message types.
|
||||
ILoggingResponsePolicy *m_pLoggingResponse;
|
||||
};
|
||||
|
||||
// These state functions to assume the caller has already grabbed the mutex.
|
||||
LoggingState_t *GetCurrentState();
|
||||
const LoggingState_t *GetCurrentState() const;
|
||||
|
||||
int FindUnusedStateIndex();
|
||||
LoggingTag_t *AllocTag( const char *pTagName );
|
||||
|
||||
int m_nChannelCount;
|
||||
LoggingChannel_t m_RegisteredChannels[MAX_LOGGING_CHANNEL_COUNT];
|
||||
|
||||
int m_nChannelTagCount;
|
||||
LoggingTag_t m_ChannelTags[MAX_LOGGING_TAG_COUNT];
|
||||
|
||||
// Index to first free character in name pool.
|
||||
int m_nTagNamePoolIndex;
|
||||
// Pool of character data used for tag names.
|
||||
char m_TagNamePool[MAX_LOGGING_TAG_CHARACTER_COUNT];
|
||||
|
||||
// Protects all data in this class except the registered channels
|
||||
// (which are supposed to be registered using the macros at static/global init time).
|
||||
// It is assumed that this mutex is reentrant safe on all platforms.
|
||||
CThreadFastMutex *m_pStateMutex;
|
||||
|
||||
// The index of the current "global" state of the logging system. By default, all threads use this state
|
||||
// for logging unless a given thread has pushed the logging state with bThreadLocal == true.
|
||||
// If a thread-local state has been pushed, g_nThreadLocalStateIndex (a global thread-local integer) will be non-zero.
|
||||
// By default, g_nThreadLocalStateIndex is 0 for all threads.
|
||||
int m_nGlobalStateIndex;
|
||||
|
||||
// A pool of logging states used to store a stack (potentially per-thread).
|
||||
static const int MAX_LOGGING_STATE_COUNT = 16;
|
||||
LoggingState_t m_LoggingStates[MAX_LOGGING_STATE_COUNT];
|
||||
|
||||
// Default policy class which determines behavior.
|
||||
CDefaultLoggingResponsePolicy m_DefaultLoggingResponse;
|
||||
|
||||
// Default spew function.
|
||||
CSimpleLoggingListener m_DefaultLoggingListener;
|
||||
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Logging Macros
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This macro will resolve to the most appropriate overload of LoggingSystem_Log() depending on the number of parameters passed in.
|
||||
#ifdef DBGFLAG_STRINGS_STRIP
|
||||
#define InternalMsg( Channel, Severity, /* [Color], Message, */ ... ) do { if ( Severity == LS_ERROR && LoggingSystem_IsChannelEnabled( Channel, Severity ) ) LoggingSystem_Log( Channel, Severity, /* [Color], Message, */ ##__VA_ARGS__ ); } while( 0 )
|
||||
#else
|
||||
#define InternalMsg( Channel, Severity, /* [Color], Message, */ ... ) do { if ( LoggingSystem_IsChannelEnabled( Channel, Severity ) ) LoggingSystem_Log( Channel, Severity, /* [Color], Message, */ ##__VA_ARGS__ ); } while( 0 )
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// New macros, use these!
|
||||
//
|
||||
// The macros take an optional Color parameter followed by the message
|
||||
// and the message formatting.
|
||||
// We rely on the variadic macro (__VA_ARGS__) operator to paste in the
|
||||
// extra parameters and resolve to the appropriate overload.
|
||||
//-----------------------------------------------------------------------------
|
||||
#define Log_Msg( Channel, /* [Color], Message, */ ... ) InternalMsg( Channel, LS_MESSAGE, /* [Color], Message, */ ##__VA_ARGS__ )
|
||||
#define Log_Warning( Channel, /* [Color], Message, */ ... ) InternalMsg( Channel, LS_WARNING, /* [Color], Message, */ ##__VA_ARGS__ )
|
||||
#define Log_Error( Channel, /* [Color], Message, */ ... ) InternalMsg( Channel, LS_ERROR, /* [Color], Message, */ ##__VA_ARGS__ )
|
||||
#ifdef DBGFLAG_STRINGS_STRIP
|
||||
#define Log_Assert( ... ) LR_CONTINUE
|
||||
#else
|
||||
#define Log_Assert( Message, ... ) LoggingSystem_LogAssert( Message, ##__VA_ARGS__ )
|
||||
#endif
|
||||
|
||||
|
||||
#define DECLARE_LOGGING_CHANNEL( Channel ) extern LoggingChannelID_t Channel
|
||||
|
||||
#define DEFINE_LOGGING_CHANNEL_NO_TAGS( Channel, ChannelName, /* [Flags], [Severity], [Color] */ ... ) \
|
||||
LoggingChannelID_t Channel = LoggingSystem_RegisterLoggingChannel( ChannelName, NULL, ##__VA_ARGS__ )
|
||||
|
||||
#define BEGIN_DEFINE_LOGGING_CHANNEL( Channel, ChannelName, /* [Flags], [Severity], [Color] */ ... ) \
|
||||
static void Register_##Channel##_Tags(); \
|
||||
LoggingChannelID_t Channel = LoggingSystem_RegisterLoggingChannel( ChannelName, Register_##Channel##_Tags, ##__VA_ARGS__ ); \
|
||||
void Register_##Channel##_Tags() \
|
||||
{
|
||||
|
||||
#define ADD_LOGGING_CHANNEL_TAG( Tag ) LoggingSystem_AddTagToCurrentChannel( Tag )
|
||||
|
||||
#define END_DEFINE_LOGGING_CHANNEL() \
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// DLL Exports
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// For documentation on these functions, please look at the corresponding function
|
||||
// in CLoggingSystem (unless otherwise specified).
|
||||
PLATFORM_INTERFACE LoggingChannelID_t LoggingSystem_RegisterLoggingChannel( const char *pName, RegisterTagsFunc registerTagsFunc, int flags = 0, LoggingSeverity_t severity = LS_MESSAGE, Color color = UNSPECIFIED_LOGGING_COLOR );
|
||||
|
||||
PLATFORM_INTERFACE void LoggingSystem_RegisterLoggingListener( ILoggingListener *pListener );
|
||||
PLATFORM_INTERFACE void LoggingSystem_UnregisterLoggingListener(ILoggingListener *pListener);
|
||||
PLATFORM_INTERFACE void LoggingSystem_ResetCurrentLoggingState();
|
||||
PLATFORM_INTERFACE void LoggingSystem_SetLoggingResponsePolicy( ILoggingResponsePolicy *pResponsePolicy );
|
||||
// NOTE: PushLoggingState() saves the current logging state on a stack and results in a new clear state
|
||||
// (no listeners, default logging response policy).
|
||||
PLATFORM_INTERFACE void LoggingSystem_PushLoggingState( bool bThreadLocal = false, bool bClearState = true );
|
||||
PLATFORM_INTERFACE void LoggingSystem_PopLoggingState( bool bThreadLocal = false );
|
||||
|
||||
PLATFORM_INTERFACE void LoggingSystem_AddTagToCurrentChannel( const char *pTagName );
|
||||
|
||||
// Returns INVALID_LOGGING_CHANNEL_ID if not found
|
||||
PLATFORM_INTERFACE LoggingChannelID_t LoggingSystem_FindChannel( const char *pChannelName );
|
||||
PLATFORM_INTERFACE int LoggingSystem_GetChannelCount();
|
||||
PLATFORM_INTERFACE LoggingChannelID_t LoggingSystem_GetFirstChannelID();
|
||||
// Returns INVALID_LOGGING_CHANNEL_ID when there are no channels remaining.
|
||||
PLATFORM_INTERFACE LoggingChannelID_t LoggingSystem_GetNextChannelID( LoggingChannelID_t channelID );
|
||||
PLATFORM_INTERFACE const CLoggingSystem::LoggingChannel_t *LoggingSystem_GetChannel( LoggingChannelID_t channelID );
|
||||
|
||||
PLATFORM_INTERFACE bool LoggingSystem_HasTag( LoggingChannelID_t channelID, const char *pTag );
|
||||
|
||||
PLATFORM_INTERFACE bool LoggingSystem_IsChannelEnabled( LoggingChannelID_t channelID, LoggingSeverity_t severity );
|
||||
PLATFORM_INTERFACE void LoggingSystem_SetChannelSpewLevel( LoggingChannelID_t channelID, LoggingSeverity_t minimumSeverity );
|
||||
PLATFORM_INTERFACE void LoggingSystem_SetChannelSpewLevelByName( const char *pName, LoggingSeverity_t minimumSeverity );
|
||||
PLATFORM_INTERFACE void LoggingSystem_SetChannelSpewLevelByTag( const char *pTag, LoggingSeverity_t minimumSeverity );
|
||||
PLATFORM_INTERFACE void LoggingSystem_SetGlobalSpewLevel( LoggingSeverity_t minimumSeverity );
|
||||
|
||||
// Color is represented as an int32 due to C-linkage restrictions
|
||||
PLATFORM_INTERFACE int32 LoggingSystem_GetChannelColor( LoggingChannelID_t channelID );
|
||||
PLATFORM_INTERFACE void LoggingSystem_SetChannelColor( LoggingChannelID_t channelID, int color );
|
||||
|
||||
PLATFORM_INTERFACE LoggingChannelFlags_t LoggingSystem_GetChannelFlags( LoggingChannelID_t channelID );
|
||||
PLATFORM_INTERFACE void LoggingSystem_SetChannelFlags( LoggingChannelID_t channelID, LoggingChannelFlags_t flags );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Logs a variable-argument to a given channel with the specified severity.
|
||||
// NOTE: if adding overloads to this function, remember that the Log_***
|
||||
// macros simply pass their variadic parameters through to LoggingSystem_Log().
|
||||
// Therefore, you need to ensure that the parameters are in the same general
|
||||
// order and that there are no ambiguities with the overload.
|
||||
//-----------------------------------------------------------------------------
|
||||
PLATFORM_INTERFACE LoggingResponse_t LoggingSystem_Log( LoggingChannelID_t channelID, LoggingSeverity_t severity, PRINTF_FORMAT_STRING const char *pMessageFormat, ... ) FMTFUNCTION( 3, 4 );
|
||||
PLATFORM_OVERLOAD LoggingResponse_t LoggingSystem_Log( LoggingChannelID_t channelID, LoggingSeverity_t severity, Color spewColor, PRINTF_FORMAT_STRING const char *pMessageFormat, ... ) FMTFUNCTION( 4, 5 );
|
||||
|
||||
PLATFORM_INTERFACE LoggingResponse_t LoggingSystem_LogDirect( LoggingChannelID_t channelID, LoggingSeverity_t severity, Color spewColor, const char *pMessage );
|
||||
PLATFORM_INTERFACE LoggingResponse_t LoggingSystem_LogAssert( PRINTF_FORMAT_STRING const char *pMessageFormat, ... ) FMTFUNCTION( 1, 2 );
|
||||
|
||||
#endif //#if !defined(__SPU__)
|
||||
|
||||
#endif // LOGGING_H
|
||||
@@ -472,6 +472,18 @@ typedef void * HINSTANCE;
|
||||
#endif
|
||||
#define DebuggerBreakIfDebugging() if ( !Plat_IsInDebugSession() ) ; else DebuggerBreak()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Message Box
|
||||
//-----------------------------------------------------------------------------
|
||||
//#if defined( PLATFORM_WINDOWS_PC )
|
||||
//PLATFORM_INTERFACE void Plat_MessageBox( const char *pTitle, const tchar *pMessage );
|
||||
//#else
|
||||
// TODO(nillerusr): add message box later
|
||||
#define Plat_MessageBox( t, m ) ((void)0)
|
||||
//#endif
|
||||
|
||||
|
||||
#ifdef STAGING_ONLY
|
||||
#define DebuggerBreakIfDebugging_StagingOnly() if ( !Plat_IsInDebugSession() ) ; else DebuggerBreak()
|
||||
#else
|
||||
@@ -626,6 +638,12 @@ typedef void * HINSTANCE;
|
||||
#define NO_ASAN
|
||||
#endif
|
||||
|
||||
#if defined( COMPILER_MSVC )
|
||||
#define TEMPLATE_STATIC static
|
||||
#else
|
||||
#define TEMPLATE_STATIC
|
||||
#endif
|
||||
|
||||
#if defined( _WIN32 )
|
||||
|
||||
// Used for dll exporting and importing
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
//======= Copyright © 1996-2006, Valve Corporation, All rights reserved. ======
|
||||
//
|
||||
// Purpose: Win32 Console API helpers
|
||||
//
|
||||
//=============================================================================
|
||||
#ifndef WIN32_CONSOLE_IO_H
|
||||
#define WIN32_CONSOLE_IO_H
|
||||
|
||||
#if defined( COMPILER_MSVC )
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// Function to attach a console for I/O to a Win32 GUI application in a reasonably smart fashion.
|
||||
PLATFORM_INTERFACE bool SetupWin32ConsoleIO();
|
||||
|
||||
// Win32 Console Color API Helpers, originally from cmdlib.
|
||||
|
||||
struct Win32ConsoleColorContext_t
|
||||
{
|
||||
int m_InitialColor;
|
||||
uint16 m_LastColor;
|
||||
uint16 m_BadColor;
|
||||
uint16 m_BackgroundFlags;
|
||||
};
|
||||
|
||||
PLATFORM_INTERFACE void InitWin32ConsoleColorContext( Win32ConsoleColorContext_t *pContext );
|
||||
|
||||
PLATFORM_INTERFACE uint16 SetWin32ConsoleColor( Win32ConsoleColorContext_t *pContext, int nRed, int nGreen, int nBlue, int nIntensity );
|
||||
|
||||
PLATFORM_INTERFACE void RestoreWin32ConsoleColor( Win32ConsoleColorContext_t *pContext, uint16 prevColor );
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,195 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose: Utilities for setting vproject settings
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef _RESOURCEPRECACHER_H
|
||||
#define _RESOURCEPRECACHER_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Resource list
|
||||
//-----------------------------------------------------------------------------
|
||||
FORWARD_DECLARE_HANDLE( ResourceList_t );
|
||||
#define RESOURCE_LIST_INVALID ( (ResourceList_t)-1 )
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Resource 'systems', which use other resources
|
||||
// NOTE: If you add types here, be sure to fix s_pResourceSystemName
|
||||
//-----------------------------------------------------------------------------
|
||||
enum PrecacheSystem_t
|
||||
{
|
||||
CLIENTGLOBAL = 0, // Always precache these
|
||||
SERVERGLOBAL,
|
||||
VGUI_PANEL, // What to precache when using a vgui panel
|
||||
DISPATCH_EFFECT, // What to precache when using a dispatch effect
|
||||
SHARED_SYSTEM, // Precache lists which are reused and can be referenced as a resource type
|
||||
|
||||
PRECACHE_SYSTEM_COUNT,
|
||||
|
||||
#if defined( GAME_DLL )
|
||||
GLOBAL = SERVERGLOBAL,
|
||||
#elif defined( CLIENT_DLL ) || defined( GAMEUI_EXPORTS )
|
||||
GLOBAL = CLIENTGLOBAL,
|
||||
#endif
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Resource types
|
||||
// NOTE: If you add a type here, modify s_pResourceTypeName in resourceaccesscontrol.cpp
|
||||
//-----------------------------------------------------------------------------
|
||||
enum ResourceTypeOld_t // called 'Old' to disambiguate with ResourceSystem
|
||||
{
|
||||
RESOURCE_VGUI_PANEL = 0, // .res file
|
||||
RESOURCE_MATERIAL, // .vmt file
|
||||
RESOURCE_MODEL, // .mdl file
|
||||
RESOURCE_PARTICLE_SYSTEM, // particle system
|
||||
RESOURCE_GAMESOUND, // game sound
|
||||
|
||||
RESOURCE_TYPE_OLD_COUNT,
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Resource types
|
||||
// NOTE: If you add types here, be sure to fix s_pPrecacheResourceTypeName
|
||||
// A compile-time assert will trigger if you don't.
|
||||
//-----------------------------------------------------------------------------
|
||||
enum PrecacheResourceType_t
|
||||
{
|
||||
VGUI_RESOURCE = 0, // .res file
|
||||
MATERIAL, // .vmt file
|
||||
MODEL, // .mdl file
|
||||
GAMESOUND, // sound
|
||||
PARTICLE_SYSTEM, // particle system
|
||||
ENTITY, // Other entity
|
||||
DECAL, // A decal
|
||||
PARTICLE_MATERIAL, // A particle system material (old-style, obsolete)
|
||||
KV_DEP_FILE, // keyvalues file containing a resource dependency list
|
||||
GAME_MATERIAL_DECALS, // All decals related to game materials ( resource name is ignored )
|
||||
PHYSICS_GAMESOUNDS, // Resource names are either "BulletSounds", "StepSounds", or "PhysicsImpactSounds"
|
||||
SHARED, // a shared precache group (see PrecacheSystem_t SHARED)
|
||||
|
||||
PRECACHE_RESOURCE_TYPE_COUNT,
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Callback interface for handler who knows how to precache particular kinds of resources
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IPrecacheHandler
|
||||
{
|
||||
public:
|
||||
virtual void CacheResource( PrecacheResourceType_t nType, const char *pName,
|
||||
bool bPrecache, ResourceList_t hResourceList, int *pIndex = NULL ) = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Interface to automated system for precaching resources
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IResourcePrecacher
|
||||
{
|
||||
public:
|
||||
virtual void Cache( IPrecacheHandler *pPrecacheHandler, bool bPrecache, ResourceList_t hResourceList, bool bIgnoreConditionals ) = 0;
|
||||
virtual PrecacheSystem_t GetSystem() = 0;
|
||||
virtual const char *GetName() = 0;
|
||||
virtual IResourcePrecacher *GetNext() = 0;
|
||||
virtual void SetNext( IResourcePrecacher * pNext ) = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Actually does the precaching
|
||||
//-----------------------------------------------------------------------------
|
||||
class CBaseResourcePrecacher : public IResourcePrecacher
|
||||
{
|
||||
// Other public methods
|
||||
public:
|
||||
CBaseResourcePrecacher( PrecacheSystem_t nSystem, const char *pName )
|
||||
{
|
||||
m_nSystem = nSystem;
|
||||
m_pName = pName;
|
||||
m_pNext = sm_pFirst[nSystem];
|
||||
sm_pFirst[nSystem] = this;
|
||||
}
|
||||
|
||||
static void RegisterAll();
|
||||
|
||||
PrecacheSystem_t GetSystem() { return m_nSystem; }
|
||||
const char *GetName() { return m_pName; }
|
||||
IResourcePrecacher *GetNext() { return m_pNext; }
|
||||
void SetNext( IResourcePrecacher * pNext ) { m_pNext = pNext; }
|
||||
|
||||
static CBaseResourcePrecacher *sm_pFirst[PRECACHE_SYSTEM_COUNT];
|
||||
|
||||
PrecacheSystem_t m_nSystem;
|
||||
const char *m_pName;
|
||||
IResourcePrecacher *m_pNext;
|
||||
|
||||
friend class CPrecacheRegister;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Automatic precache macros
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Beginning
|
||||
#define PRECACHE_REGISTER_BEGIN_CONDITIONAL( _system, _className, _condition ) \
|
||||
namespace _className ## Precache \
|
||||
{ \
|
||||
class CResourcePrecacher : public CBaseResourcePrecacher\
|
||||
{ \
|
||||
public: \
|
||||
CResourcePrecacher() : CBaseResourcePrecacher( _system, #_className ) {} \
|
||||
public: \
|
||||
virtual void Cache( IPrecacheHandler *pPrecacheHandler, bool bPrecache, ResourceList_t hResourceList, bool bIgnoreConditionals ); \
|
||||
}; \
|
||||
void CResourcePrecacher::Cache( IPrecacheHandler *pPrecacheHandler, bool bPrecache, ResourceList_t hResourceList, bool bIgnoreConditionals ) \
|
||||
{ \
|
||||
if ( !bIgnoreConditionals && !( _condition ) ) \
|
||||
return;
|
||||
|
||||
#define PRECACHE_REGISTER_BEGIN( _system, _className ) \
|
||||
PRECACHE_REGISTER_BEGIN_CONDITIONAL( _system, _className, true )
|
||||
|
||||
// Resource precache definitions
|
||||
#define PRECACHE( _type, _name ) pPrecacheHandler->CacheResource( _type, _name, bPrecache, hResourceList, NULL );
|
||||
|
||||
// NOTE: PRECACHE_INDEX_CONDITIONAL doesn't initialize the index to 0
|
||||
// on the assumption that some other conditional will
|
||||
|
||||
//MCCLEANUP //NOTE: PRECACHE_INDEX and PRECACHE_INDEX_CONDITIONAL won't work in 64 bit because the old-school particle mgr is sending ptr data types into here. Hopefully the old-school particle mgr will die before this is an issue.
|
||||
|
||||
#define PRECACHE_INDEX( _type, _name, _index ) pPrecacheHandler->CacheResource( _type, _name, bPrecache, hResourceList, (int*)( &(_index) ) );
|
||||
#define PRECACHE_CONDITIONAL( _type, _name, _condition ) \
|
||||
if ( !bIgnoreConditionals && ( _condition ) ) \
|
||||
pPrecacheHandler->CacheResource( _type, _name, bPrecache, hResourceList, NULL );
|
||||
#define PRECACHE_INDEX_CONDITIONAL( _type, _name, _index, _func ) \
|
||||
if ( bIgnoreConditionals || ( _condition ) ) \
|
||||
{ \
|
||||
pPrecacheHandler->CacheResource( _type, _name, bPrecache, hResourceList, (int*)( &(_index) ) ); \
|
||||
}
|
||||
|
||||
//End
|
||||
#define PRECACHE_REGISTER_END( ) \
|
||||
} \
|
||||
CResourcePrecacher s_ResourcePrecacher; \
|
||||
}
|
||||
|
||||
// FIXME: Remove! Backward compat
|
||||
#define PRECACHE_WEAPON_REGISTER( _className ) \
|
||||
PRECACHE_REGISTER_BEGIN( GLOBAL, _className ) \
|
||||
PRECACHE( ENTITY, #_className ) \
|
||||
PRECACHE_REGISTER_END()
|
||||
|
||||
#define PRECACHE_REGISTER( _className ) \
|
||||
PRECACHE_REGISTER_BEGIN( GLOBAL, _className ) \
|
||||
PRECACHE( ENTITY, #_className ) \
|
||||
PRECACHE_REGISTER_END()
|
||||
|
||||
#endif // _RESOURCEPRECACHER_H
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
//============ Copyright (c) Valve Corporation, All rights reserved. ============
|
||||
//
|
||||
// Tier2 logging helpers. Adds support for file I/O
|
||||
//
|
||||
//===============================================================================
|
||||
|
||||
#ifndef TIER2_LOGGING_H
|
||||
#define TIER2_LOGGING_H
|
||||
|
||||
#if defined( COMPILER_MSVC )
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "logging.h"
|
||||
|
||||
|
||||
const int MAX_SIMULTANEOUS_LOGGING_FILE_COUNT = 16;
|
||||
const int INVALID_LOGGING_FILE_HANDLE = -1;
|
||||
|
||||
typedef int LoggingFileHandle_t;
|
||||
typedef void * FileHandle_t;
|
||||
|
||||
#define FILELOGGINGLISTENER_INTERFACE_VERSION "FileLoggingListener001"
|
||||
|
||||
abstract_class IFileLoggingListener : public ILoggingListener
|
||||
{
|
||||
public:
|
||||
virtual void Log( const LoggingContext_t *pContext, const char *pMessage ) = 0;
|
||||
|
||||
virtual LoggingFileHandle_t BeginLoggingToFile( const char *pFilename, const char *pOptions, const char *pPathID = NULL ) = 0;
|
||||
virtual void EndLoggingToFile( LoggingFileHandle_t fileHandle ) = 0;
|
||||
|
||||
virtual void AssignLogChannel( LoggingChannelID_t channelID, LoggingFileHandle_t loggingFileHandle ) = 0;
|
||||
virtual void UnassignLogChannel( LoggingChannelID_t channelID ) = 0;
|
||||
virtual void AssignAllLogChannels( LoggingFileHandle_t loggingFileHandle ) = 0;
|
||||
virtual void UnassignAllLogChannels() = 0;
|
||||
};
|
||||
|
||||
class CFileLoggingListener : public IFileLoggingListener
|
||||
{
|
||||
public:
|
||||
CFileLoggingListener();
|
||||
~CFileLoggingListener();
|
||||
|
||||
virtual void Log( const LoggingContext_t *pContext, const char *pMessage );
|
||||
|
||||
virtual LoggingFileHandle_t BeginLoggingToFile( const char *pFilename, const char *pOptions, const char *pPathID = NULL );
|
||||
virtual void EndLoggingToFile( LoggingFileHandle_t fileHandle );
|
||||
|
||||
virtual void AssignLogChannel( LoggingChannelID_t channelID, LoggingFileHandle_t loggingFileHandle );
|
||||
virtual void UnassignLogChannel( LoggingChannelID_t channelID );
|
||||
virtual void AssignAllLogChannels( LoggingFileHandle_t loggingFileHandle );
|
||||
virtual void UnassignAllLogChannels();
|
||||
|
||||
private:
|
||||
int GetUnusedFileInfo() const;
|
||||
|
||||
struct FileInfo_t
|
||||
{
|
||||
FileHandle_t m_FileHandle;
|
||||
|
||||
bool IsOpen() const { return m_FileHandle != 0; }
|
||||
void Reset() { m_FileHandle = 0; }
|
||||
};
|
||||
|
||||
FileInfo_t m_OpenFiles[MAX_SIMULTANEOUS_LOGGING_FILE_COUNT];
|
||||
|
||||
// Table which maps logging channel IDs to open files
|
||||
int m_FileIndices[MAX_LOGGING_CHANNEL_COUNT];
|
||||
};
|
||||
|
||||
#endif // TIER2_LOGGING_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,521 @@
|
||||
//========== Copyright (c) 2008, Valve Corporation, All rights reserved. ========
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef VSCRIPT_TEMPLATES_H
|
||||
#define VSCRIPT_TEMPLATES_H
|
||||
|
||||
#include "tier0/basetypes.h"
|
||||
|
||||
#if defined( _WIN32 )
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#define FUNC_APPEND_PARAMS_0
|
||||
#define FUNC_APPEND_PARAMS_1 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 1 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) );
|
||||
#define FUNC_APPEND_PARAMS_2 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 2 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) );
|
||||
#define FUNC_APPEND_PARAMS_3 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 3 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) );
|
||||
#define FUNC_APPEND_PARAMS_4 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 4 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) );
|
||||
#define FUNC_APPEND_PARAMS_5 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 5 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) );
|
||||
#define FUNC_APPEND_PARAMS_6 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 6 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) );
|
||||
#define FUNC_APPEND_PARAMS_7 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 7 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) );
|
||||
#define FUNC_APPEND_PARAMS_8 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 8 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) );
|
||||
#define FUNC_APPEND_PARAMS_9 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 9 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_9 ) );
|
||||
#define FUNC_APPEND_PARAMS_10 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 10 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_9 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_10 ) );
|
||||
#define FUNC_APPEND_PARAMS_11 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 11 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_9 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_10 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_11 ) );
|
||||
#define FUNC_APPEND_PARAMS_12 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 12 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_9 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_10 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_11 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_12 ) );
|
||||
#define FUNC_APPEND_PARAMS_13 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 13 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_9 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_10 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_11 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_12 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_13 ) );
|
||||
#define FUNC_APPEND_PARAMS_14 pDesc->m_Parameters.SetGrowSize( 1 ); pDesc->m_Parameters.EnsureCapacity( 14 ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_1 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_2 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_3 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_4 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_5 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_6 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_7 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_8 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_9 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_10 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_11 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_12 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_13 ) ); pDesc->m_Parameters.AddToTail( ScriptDeduceType( FUNC_ARG_TYPE_14 ) );
|
||||
|
||||
#define DEFINE_NONMEMBER_FUNC_TYPE_DEDUCER(N) \
|
||||
template <typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
|
||||
inline void ScriptDeduceFunctionSignature(ScriptFuncDescriptor_t *pDesc, FUNCTION_RETTYPE (*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) ) \
|
||||
{ \
|
||||
pDesc->m_ReturnType = ScriptDeduceType(FUNCTION_RETTYPE); \
|
||||
FUNC_APPEND_PARAMS_##N \
|
||||
}
|
||||
|
||||
FUNC_GENERATE_ALL( DEFINE_NONMEMBER_FUNC_TYPE_DEDUCER );
|
||||
|
||||
#define DEFINE_MEMBER_FUNC_TYPE_DEDUCER(N) \
|
||||
template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
|
||||
inline void ScriptDeduceFunctionSignature(ScriptFuncDescriptor_t *pDesc, OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) ) \
|
||||
{ \
|
||||
pDesc->m_ReturnType = ScriptDeduceType(FUNCTION_RETTYPE); \
|
||||
FUNC_APPEND_PARAMS_##N \
|
||||
}
|
||||
|
||||
FUNC_GENERATE_ALL( DEFINE_MEMBER_FUNC_TYPE_DEDUCER );
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
#define DEFINE_CONST_MEMBER_FUNC_TYPE_DEDUCER(N) \
|
||||
template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
|
||||
inline void ScriptDeduceFunctionSignature(ScriptFuncDescriptor_t *pDesc, OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const ) \
|
||||
{ \
|
||||
pDesc->m_ReturnType = ScriptDeduceType(FUNCTION_RETTYPE); \
|
||||
FUNC_APPEND_PARAMS_##N \
|
||||
}
|
||||
|
||||
FUNC_GENERATE_ALL( DEFINE_CONST_MEMBER_FUNC_TYPE_DEDUCER );
|
||||
|
||||
#define ScriptInitMemberFuncDescriptor_( pDesc, class, func, scriptName ) if ( 0 ) {} else { (pDesc)->m_pszScriptName = scriptName; (pDesc)->m_pszFunction = #func; ScriptDeduceFunctionSignature( pDesc, (class *)(0), &class::func ); }
|
||||
|
||||
#define ScriptInitFuncDescriptorNamed( pDesc, func, scriptName ) if ( 0 ) {} else { (pDesc)->m_pszScriptName = scriptName; (pDesc)->m_pszFunction = #func; ScriptDeduceFunctionSignature( pDesc, &func ); }
|
||||
#define ScriptInitFuncDescriptor( pDesc, func ) ScriptInitFuncDescriptorNamed( pDesc, func, #func )
|
||||
#define ScriptInitMemberFuncDescriptorNamed( pDesc, class, func, scriptName ) ScriptInitMemberFuncDescriptor_( pDesc, class, func, scriptName )
|
||||
#define ScriptInitMemberFuncDescriptor( pDesc, class, func ) ScriptInitMemberFuncDescriptorNamed( pDesc, class, func, #func )
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <typename FUNCPTR_TYPE>
|
||||
inline ScriptFunctionBindingStorageType_t ScriptConvertFreeFuncPtrToVoid( FUNCPTR_TYPE pFunc )
|
||||
{
|
||||
#if defined(_PS3) || defined(POSIX)
|
||||
COMPILE_TIME_ASSERT( sizeof( FUNCPTR_TYPE ) == sizeof( void* ) * 2 || sizeof( FUNCPTR_TYPE ) == sizeof( void* ) );
|
||||
|
||||
if ( sizeof( FUNCPTR_TYPE ) == 4 )
|
||||
{
|
||||
union FuncPtrConvertMI
|
||||
{
|
||||
FUNCPTR_TYPE pFunc;
|
||||
ScriptFunctionBindingStorageType_t stype;
|
||||
};
|
||||
|
||||
FuncPtrConvertMI convert;
|
||||
convert.pFunc = pFunc;
|
||||
return convert.stype;
|
||||
}
|
||||
else
|
||||
{
|
||||
union FuncPtrConvertMI
|
||||
{
|
||||
FUNCPTR_TYPE pFunc;
|
||||
struct
|
||||
{
|
||||
ScriptFunctionBindingStorageType_t stype;
|
||||
intptr_t iToc;
|
||||
} fn8;
|
||||
};
|
||||
|
||||
FuncPtrConvertMI convert;
|
||||
convert.fn8.iToc = 0;
|
||||
convert.pFunc = pFunc;
|
||||
if ( !convert.fn8.iToc )
|
||||
return convert.fn8.stype;
|
||||
|
||||
Assert( 0 );
|
||||
DebuggerBreak();
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
return ( ScriptFunctionBindingStorageType_t ) pFunc;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename FUNCPTR_TYPE>
|
||||
inline FUNCPTR_TYPE ScriptConvertFreeFuncPtrFromVoid( ScriptFunctionBindingStorageType_t p )
|
||||
{
|
||||
#if defined(_PS3) || defined(POSIX)
|
||||
COMPILE_TIME_ASSERT( sizeof( FUNCPTR_TYPE ) == sizeof(void*)*2 || sizeof( FUNCPTR_TYPE ) == sizeof(void*) );
|
||||
|
||||
if ( sizeof( FUNCPTR_TYPE ) == 4 )
|
||||
{
|
||||
union FuncPtrConvertMI
|
||||
{
|
||||
FUNCPTR_TYPE pFunc;
|
||||
ScriptFunctionBindingStorageType_t stype;
|
||||
};
|
||||
|
||||
FuncPtrConvertMI convert;
|
||||
convert.pFunc = 0;
|
||||
convert.stype = p;
|
||||
return convert.pFunc;
|
||||
}
|
||||
else
|
||||
{
|
||||
union FuncPtrConvertMI
|
||||
{
|
||||
FUNCPTR_TYPE pFunc;
|
||||
struct
|
||||
{
|
||||
ScriptFunctionBindingStorageType_t stype;
|
||||
intptr_t iToc;
|
||||
} fn8;
|
||||
};
|
||||
|
||||
FuncPtrConvertMI convert;
|
||||
convert.pFunc = 0;
|
||||
convert.fn8.stype = p;
|
||||
convert.fn8.iToc = 0;
|
||||
return convert.pFunc;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
return (FUNCPTR_TYPE) p;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename FUNCPTR_TYPE>
|
||||
inline ScriptFunctionBindingStorageType_t ScriptConvertFuncPtrToVoid( FUNCPTR_TYPE pFunc )
|
||||
{
|
||||
typedef FUNCPTR_TYPE FuncPtr_t;
|
||||
size_t funcPtrSize = sizeof( FuncPtr_t ); funcPtrSize;
|
||||
|
||||
#if defined(_PS3) || defined(POSIX)
|
||||
return ScriptConvertFreeFuncPtrToVoid<FUNCPTR_TYPE>( pFunc );
|
||||
#else
|
||||
|
||||
if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) ) )
|
||||
{
|
||||
// simple inheritance
|
||||
union FuncPtrConvert
|
||||
{
|
||||
void *p;
|
||||
FUNCPTR_TYPE pFunc;
|
||||
};
|
||||
|
||||
FuncPtrConvert convert;
|
||||
convert.pFunc = pFunc;
|
||||
return convert.p;
|
||||
}
|
||||
#if MSVC
|
||||
else if ( ( IsPlatformWindowsPC32() && ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + sizeof( int ) ) ) ||
|
||||
( IsPlatformWindowsPC64() && ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + sizeof( int ) * 2 ) ) )
|
||||
{
|
||||
// multiple and virtual inheritance
|
||||
struct MicrosoftUnknownMFP
|
||||
{
|
||||
void *p;
|
||||
int m_delta;
|
||||
};
|
||||
|
||||
union FuncPtrConvertMI
|
||||
{
|
||||
MicrosoftUnknownMFP mfp;
|
||||
FUNCPTR_TYPE pFunc;
|
||||
};
|
||||
|
||||
FuncPtrConvertMI convert;
|
||||
convert.pFunc = pFunc;
|
||||
if ( convert.mfp.m_delta == 0 )
|
||||
{
|
||||
return convert.mfp.p;
|
||||
}
|
||||
AssertMsg( 0, "Function pointer must be from primary vtable" );
|
||||
}
|
||||
else if ( ( IsPlatformWindowsPC32() && ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + ( sizeof( int ) * 3 ) ) ) ||
|
||||
( IsPlatformWindowsPC64() && ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + ( sizeof( int ) * 4 ) ) ) )
|
||||
{
|
||||
// unknown_inheritance case
|
||||
struct MicrosoftUnknownMFP
|
||||
{
|
||||
void *p;
|
||||
int m_delta;
|
||||
int m_vtordisp;
|
||||
int m_vtable_index;
|
||||
};
|
||||
|
||||
union FuncPtrConvertMI
|
||||
{
|
||||
MicrosoftUnknownMFP mfp;
|
||||
FUNCPTR_TYPE pFunc;
|
||||
};
|
||||
|
||||
FuncPtrConvertMI convert;
|
||||
convert.pFunc = pFunc;
|
||||
if ( convert.mfp.m_delta == 0 )
|
||||
{
|
||||
return convert.mfp.p;
|
||||
}
|
||||
AssertMsg( 0, "Function pointer must be from primary vtable" );
|
||||
}
|
||||
#elif defined( GNUC )
|
||||
else if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + sizeof( int ) ) )
|
||||
{
|
||||
AssertMsg( 0, "Note: This path has not been verified yet. See comments below in #else case." );
|
||||
|
||||
struct GnuMFP
|
||||
{
|
||||
union
|
||||
{
|
||||
void *funcadr; // If vtable_index_2 is even, then this is the function pointer.
|
||||
int vtable_index_2; // If vtable_index_2 is odd, then this = vindex*2+1.
|
||||
};
|
||||
int delta;
|
||||
};
|
||||
|
||||
GnuMFP *p = (GnuMFP*)&pFunc;
|
||||
if ( p->vtable_index_2 & 1 )
|
||||
{
|
||||
char **delta = (char**)p->delta;
|
||||
char *pCur = *delta + (p->vtable_index_2+1)/2;
|
||||
return (void*)( pCur + 4 );
|
||||
}
|
||||
else
|
||||
{
|
||||
return p->funcadr;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#error "Need to implement code to crack non-offset member function pointer case"
|
||||
// For gcc, see: http://www.codeproject.com/KB/cpp/FastDelegate.aspx
|
||||
//
|
||||
// Current versions of the GNU compiler use a strange and tricky
|
||||
// optimization. It observes that, for virtual inheritance, you have to look
|
||||
// up the vtable in order to get the voffset required to calculate the this
|
||||
// pointer. While you're doing that, you might as well store the function
|
||||
// pointer in the vtable. By doing this, they combine the m_func_address and
|
||||
// m_vtable_index fields into one, and they distinguish between them by
|
||||
// ensuring that function pointers always point to even addresses but vtable
|
||||
// indices are always odd:
|
||||
//
|
||||
// // GNU g++ uses a tricky space optimisation, also adopted by IBM's VisualAge and XLC.
|
||||
// struct GnuMFP {
|
||||
// union {
|
||||
// CODEPTR funcadr; // always even
|
||||
// int vtable_index_2; // = vindex*2+1, always odd
|
||||
// };
|
||||
// int delta;
|
||||
// };
|
||||
// adjustedthis = this + delta
|
||||
// if (funcadr & 1) CALL (* ( *delta + (vindex+1)/2) + 4)
|
||||
// else CALL funcadr
|
||||
//
|
||||
// The G++ method is well documented, so it has been adopted by many other
|
||||
// vendors, including IBM's VisualAge and XLC compilers, recent versions of
|
||||
// Open64, Pathscale EKO, and Metrowerks' 64-bit compilers. A simpler scheme
|
||||
// used by earlier versions of GCC is also very common. SGI's now
|
||||
// discontinued MIPSPro and Pro64 compilers, and Apple's ancient MrCpp
|
||||
// compiler used this method. (Note that the Pro64 compiler has become the
|
||||
// open source Open64 compiler).
|
||||
|
||||
#endif
|
||||
else
|
||||
AssertMsg( 0, "Member function pointer not supported. Why on earth are you using virtual inheritance!?" );
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename FUNCPTR_TYPE>
|
||||
inline FUNCPTR_TYPE ScriptConvertFuncPtrFromVoid( ScriptFunctionBindingStorageType_t p )
|
||||
{
|
||||
#if defined(_PS3) || defined(POSIX)
|
||||
return ScriptConvertFreeFuncPtrFromVoid<FUNCPTR_TYPE>( p );
|
||||
#else
|
||||
|
||||
if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) ) )
|
||||
{
|
||||
union FuncPtrConvert
|
||||
{
|
||||
void *p;
|
||||
FUNCPTR_TYPE pFunc;
|
||||
};
|
||||
|
||||
FuncPtrConvert convert;
|
||||
convert.p = p;
|
||||
return convert.pFunc;
|
||||
}
|
||||
|
||||
#if MSVC
|
||||
if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + sizeof( int ) ) )
|
||||
{
|
||||
struct MicrosoftUnknownMFP
|
||||
{
|
||||
void *p;
|
||||
int m_delta;
|
||||
};
|
||||
|
||||
union FuncPtrConvertMI
|
||||
{
|
||||
MicrosoftUnknownMFP mfp;
|
||||
FUNCPTR_TYPE pFunc;
|
||||
};
|
||||
|
||||
FuncPtrConvertMI convert;
|
||||
convert.mfp.p = p;
|
||||
convert.mfp.m_delta = 0;
|
||||
return convert.pFunc;
|
||||
}
|
||||
if ( ( sizeof( FUNCPTR_TYPE ) == sizeof( void * ) + ( sizeof( int ) * 3 ) ) )
|
||||
{
|
||||
struct MicrosoftUnknownMFP
|
||||
{
|
||||
void *p;
|
||||
int m_delta;
|
||||
int m_vtordisp;
|
||||
int m_vtable_index;
|
||||
};
|
||||
|
||||
union FuncPtrConvertMI
|
||||
{
|
||||
MicrosoftUnknownMFP mfp;
|
||||
FUNCPTR_TYPE pFunc;
|
||||
};
|
||||
|
||||
FuncPtrConvertMI convert;
|
||||
convert.mfp.p = p;
|
||||
convert.mfp.m_delta = 0;
|
||||
return convert.pFunc;
|
||||
}
|
||||
#elif defined( POSIX )
|
||||
AssertMsg( 0, "Note: This path has not been implemented yet." );
|
||||
#else
|
||||
#error "Need to implement code to crack non-offset member function pointer case"
|
||||
#endif
|
||||
Assert( 0 );
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_0
|
||||
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_1 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_1
|
||||
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_2 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_2
|
||||
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_3 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_3
|
||||
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_4 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_4
|
||||
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_5 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_5
|
||||
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_6 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_6
|
||||
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_7 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_7
|
||||
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_8 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_8
|
||||
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_9 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_9
|
||||
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_10 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_10
|
||||
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_11 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_11
|
||||
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_12 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_12
|
||||
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_13 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_13
|
||||
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_14 , FUNC_BASE_TEMPLATE_FUNC_PARAMS_14
|
||||
|
||||
#define SCRIPT_BINDING_ARGS_0
|
||||
#define SCRIPT_BINDING_ARGS_1 pArguments[0]
|
||||
#define SCRIPT_BINDING_ARGS_2 pArguments[0], pArguments[1]
|
||||
#define SCRIPT_BINDING_ARGS_3 pArguments[0], pArguments[1], pArguments[2]
|
||||
#define SCRIPT_BINDING_ARGS_4 pArguments[0], pArguments[1], pArguments[2], pArguments[3]
|
||||
#define SCRIPT_BINDING_ARGS_5 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4]
|
||||
#define SCRIPT_BINDING_ARGS_6 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5]
|
||||
#define SCRIPT_BINDING_ARGS_7 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6]
|
||||
#define SCRIPT_BINDING_ARGS_8 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7]
|
||||
#define SCRIPT_BINDING_ARGS_9 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8]
|
||||
#define SCRIPT_BINDING_ARGS_10 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9]
|
||||
#define SCRIPT_BINDING_ARGS_11 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9], pArguments[10]
|
||||
#define SCRIPT_BINDING_ARGS_12 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9], pArguments[10], pArguments[11]
|
||||
#define SCRIPT_BINDING_ARGS_13 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9], pArguments[10], pArguments[11], pArguments[12]
|
||||
#define SCRIPT_BINDING_ARGS_14 pArguments[0], pArguments[1], pArguments[2], pArguments[3], pArguments[4], pArguments[5], pArguments[6], pArguments[7], pArguments[8], pArguments[9], pArguments[10], pArguments[11], pArguments[12], pArguments[13]
|
||||
|
||||
|
||||
#define DEFINE_SCRIPT_BINDINGS(N) \
|
||||
template <typename FUNC_TYPE, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
|
||||
class CNonMemberScriptBinding##N \
|
||||
{ \
|
||||
public: \
|
||||
static bool Call( ScriptFunctionBindingStorageType_t pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ) \
|
||||
{ \
|
||||
Assert( nArguments == N ); \
|
||||
Assert( pReturn ); \
|
||||
Assert( !pContext ); \
|
||||
\
|
||||
if ( nArguments != N || !pReturn || pContext ) \
|
||||
{ \
|
||||
return false; \
|
||||
} \
|
||||
*pReturn = (ScriptConvertFreeFuncPtrFromVoid<FUNC_TYPE>(pFunction))( SCRIPT_BINDING_ARGS_##N ); \
|
||||
if ( pReturn->m_type == FIELD_VECTOR ) \
|
||||
pReturn->m_pVector = new Vector(*pReturn->m_pVector); \
|
||||
return true; \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
template <typename FUNC_TYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
|
||||
class CNonMemberScriptBinding##N<FUNC_TYPE, void FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_##N> \
|
||||
{ \
|
||||
public: \
|
||||
static bool Call( ScriptFunctionBindingStorageType_t pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ) \
|
||||
{ \
|
||||
Assert( nArguments == N ); \
|
||||
Assert( !pReturn ); \
|
||||
Assert( !pContext ); \
|
||||
\
|
||||
if ( nArguments != N || pReturn || pContext ) \
|
||||
{ \
|
||||
return false; \
|
||||
} \
|
||||
(ScriptConvertFreeFuncPtrFromVoid<FUNC_TYPE>(pFunction))( SCRIPT_BINDING_ARGS_##N ); \
|
||||
return true; \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
template <class OBJECT_TYPE_PTR, typename FUNC_TYPE, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
|
||||
class CMemberScriptBinding##N \
|
||||
{ \
|
||||
public: \
|
||||
static bool Call( ScriptFunctionBindingStorageType_t pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ) \
|
||||
{ \
|
||||
Assert( nArguments == N ); \
|
||||
Assert( pReturn ); \
|
||||
Assert( pContext ); \
|
||||
\
|
||||
if ( nArguments != N || !pReturn || !pContext ) \
|
||||
{ \
|
||||
return false; \
|
||||
} \
|
||||
*pReturn = (((OBJECT_TYPE_PTR)(pContext))->*ScriptConvertFuncPtrFromVoid<FUNC_TYPE>(pFunction))( SCRIPT_BINDING_ARGS_##N ); \
|
||||
if ( pReturn->m_type == FIELD_VECTOR ) \
|
||||
pReturn->m_pVector = new Vector(*pReturn->m_pVector); \
|
||||
return true; \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
template <class OBJECT_TYPE_PTR, typename FUNC_TYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
|
||||
class CMemberScriptBinding##N<OBJECT_TYPE_PTR, FUNC_TYPE, void FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_##N> \
|
||||
{ \
|
||||
public: \
|
||||
static bool Call( ScriptFunctionBindingStorageType_t pFunction, void *pContext, ScriptVariant_t *pArguments, int nArguments, ScriptVariant_t *pReturn ) \
|
||||
{ \
|
||||
Assert( nArguments == N ); \
|
||||
Assert( !pReturn ); \
|
||||
Assert( pContext ); \
|
||||
\
|
||||
if ( nArguments != N || pReturn || !pContext ) \
|
||||
{ \
|
||||
return false; \
|
||||
} \
|
||||
(((OBJECT_TYPE_PTR)(pContext))->*ScriptConvertFuncPtrFromVoid<FUNC_TYPE>(pFunction))( SCRIPT_BINDING_ARGS_##N ); \
|
||||
return true; \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
template <typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
|
||||
inline ScriptBindingFunc_t ScriptCreateBinding(FUNCTION_RETTYPE (*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) ) \
|
||||
{ \
|
||||
typedef FUNCTION_RETTYPE (*Func_t)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N); \
|
||||
return &CNonMemberScriptBinding##N<Func_t, FUNCTION_RETTYPE FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_##N>::Call; \
|
||||
} \
|
||||
\
|
||||
template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
|
||||
inline ScriptBindingFunc_t ScriptCreateBinding(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE (FUNCTION_CLASS::*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) ) \
|
||||
{ \
|
||||
typedef FUNCTION_RETTYPE (FUNCTION_CLASS::*Func_t)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N); \
|
||||
return &CMemberScriptBinding##N<OBJECT_TYPE_PTR, Func_t, FUNCTION_RETTYPE FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_##N>::Call; \
|
||||
} \
|
||||
\
|
||||
template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N> \
|
||||
inline ScriptBindingFunc_t ScriptCreateBinding(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE (FUNCTION_CLASS::*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const ) \
|
||||
{ \
|
||||
typedef FUNCTION_RETTYPE (FUNCTION_CLASS::*Func_t)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N); \
|
||||
return &CMemberScriptBinding##N<OBJECT_TYPE_PTR, Func_t, FUNCTION_RETTYPE FUNC_BASE_TEMPLATE_FUNC_PARAMS_PASSTHRU_##N>::Call; \
|
||||
}
|
||||
|
||||
FUNC_GENERATE_ALL( DEFINE_SCRIPT_BINDINGS );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // VSCRIPT_TEMPLATES_H
|
||||
Reference in New Issue
Block a user