179 lines
4.4 KiB
C++
179 lines
4.4 KiB
C++
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
// $NoKeywords: $
|
|
//=============================================================================//
|
|
|
|
#ifndef COERCIBLEVARIANT_T_H
|
|
#define COERCIBLEVARIANT_T_H
|
|
#ifdef _WIN32
|
|
#pragma once
|
|
#endif
|
|
|
|
|
|
#include "ehandle.h"
|
|
|
|
class CBaseEntity;
|
|
|
|
|
|
//
|
|
// A variant class for use in response rule contexts.
|
|
// It provides implicit conversion between types.
|
|
// So, you can construct it as a string, but fetch it
|
|
// as an int, and so on.
|
|
// It caches these conversions to make them faster afterwards.
|
|
// If you construct from a string, it will make a copy of
|
|
// that string, so it's okay to pass in extemporaneous stack strings.
|
|
//
|
|
class coerciblevariant_t
|
|
{
|
|
// each of the types we store
|
|
bool bVal;
|
|
int iVal;
|
|
float flVal;
|
|
char * szVal; // generally this one is only computed on demand (because it eats memory)
|
|
CHandle<CBaseEntity> eVal; // this can't be in the union because it has a constructor.
|
|
|
|
// my native type -- but I can be implicitly converted to others.
|
|
fieldtype_t fieldType;
|
|
|
|
// store which types have been initialized
|
|
enum
|
|
{
|
|
kINIT_BOOLEAN = ( 1 << 0 ),
|
|
kINIT_INT = ( 1 << 1 ),
|
|
kINIT_FLOAT = ( 1 << 2 ),
|
|
kINIT_STRING = ( 1 << 3 ),
|
|
kINIT_EHANDLE = ( 1 << 4 ),
|
|
};
|
|
unsigned int m_bvInitFields;
|
|
|
|
enum
|
|
{
|
|
DEFAULT_VARIANT_STRING_SIZE = 64 // how big my allocated strings are, when I make them.
|
|
};
|
|
|
|
public:
|
|
|
|
// constructor
|
|
coerciblevariant_t() : fieldType(FIELD_VOID), iVal(0), bVal(false), szVal(NULL), flVal(0), m_bvInitFields(0) {}
|
|
~coerciblevariant_t();
|
|
// assignment ctors (private because not used yet, please don't use them
|
|
private:
|
|
coerciblevariant_t(const coerciblevariant_t &src);
|
|
coerciblevariant_t& operator=(const coerciblevariant_t &src);
|
|
public:
|
|
|
|
// convenience constructors
|
|
coerciblevariant_t( bool b );
|
|
coerciblevariant_t( const char * str );
|
|
coerciblevariant_t( int i );
|
|
coerciblevariant_t( float f );
|
|
coerciblevariant_t( const EHANDLE &handle );
|
|
coerciblevariant_t( CBaseEntity *ent );
|
|
|
|
inline bool Bool( void ) ;// const { return( fieldType == FIELD_BOOLEAN ) ? bVal : false; }
|
|
const char *String( void ) ;// const { return( fieldType == FIELD_STRING ) ? STRING(iszVal) : ToString(); }
|
|
inline int Int( void ) ;// const { return( fieldType == FIELD_INTEGER ) ? iVal : 0; }
|
|
inline float Float( void ) ;// const { return( fieldType == FIELD_FLOAT ) ? flVal : 0; }
|
|
inline const CHandle<CBaseEntity> &Entity(void) ;// const;
|
|
|
|
fieldtype_t FieldType( void ) { return fieldType; }
|
|
|
|
void SetBool( bool b );
|
|
void SetString( const char * str );
|
|
void SetInt( int val );
|
|
void SetFloat( float val );
|
|
void SetEntity( CBaseEntity *val );
|
|
|
|
protected:
|
|
|
|
// from my native type, make a float value if possible
|
|
float ConvertFloat() const;
|
|
|
|
// from my native type, make an int value if possible
|
|
int ConvertInt() const;
|
|
|
|
// from my native type, make a bool value if possible
|
|
bool ConvertBool() const;
|
|
|
|
// from my native type, make an entity if possible, NULL otherwise
|
|
CBaseEntity * ConvertEntity() const;
|
|
|
|
private:
|
|
// zero out my contents -- called at top of each Set
|
|
inline void Void( void );
|
|
};
|
|
|
|
// mark me as having no conversions, dump the string
|
|
// if there is one
|
|
void coerciblevariant_t::Void( void )
|
|
{
|
|
m_bvInitFields = 0;
|
|
|
|
if (szVal)
|
|
{
|
|
delete[] szVal;
|
|
szVal = NULL;
|
|
}
|
|
}
|
|
|
|
// get my bool contents
|
|
bool coerciblevariant_t::Bool( void )
|
|
{
|
|
if ( (m_bvInitFields & kINIT_BOOLEAN) == 0 )
|
|
{
|
|
// we need to convert
|
|
bVal = ConvertBool();
|
|
m_bvInitFields |= kINIT_BOOLEAN ;
|
|
}
|
|
|
|
return bVal;
|
|
}
|
|
|
|
// get my int contents
|
|
int coerciblevariant_t::Int( void )
|
|
{
|
|
if ( (m_bvInitFields & kINIT_INT) == 0 )
|
|
{
|
|
// we need to convert
|
|
iVal = ConvertInt();
|
|
m_bvInitFields |= kINIT_INT ;
|
|
}
|
|
|
|
return iVal;
|
|
}
|
|
|
|
// get my float contents
|
|
float coerciblevariant_t::Float( void )
|
|
{
|
|
if ( (m_bvInitFields & kINIT_FLOAT) == 0 )
|
|
{
|
|
// we need to convert
|
|
flVal = ConvertFloat();
|
|
m_bvInitFields |= kINIT_FLOAT ;
|
|
}
|
|
|
|
return flVal;
|
|
}
|
|
|
|
|
|
// get me as an entity
|
|
const CHandle<CBaseEntity> &coerciblevariant_t::Entity( void )
|
|
{
|
|
if ( (m_bvInitFields & kINIT_EHANDLE) == 0 )
|
|
{
|
|
// we need to convert
|
|
eVal = ConvertEntity();
|
|
m_bvInitFields |= kINIT_EHANDLE ;
|
|
}
|
|
|
|
return eVal;
|
|
}
|
|
|
|
|
|
typedef coerciblevariant_t cvariant_t; // easier typing!
|
|
|
|
#endif // VARIANT_T_H
|