441 lines
14 KiB
C++
441 lines
14 KiB
C++
//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. =======
|
|
//
|
|
// Purpose:
|
|
//
|
|
//=============================================================================
|
|
|
|
#ifndef DMATTRIBUTE_H
|
|
#define DMATTRIBUTE_H
|
|
#ifdef _WIN32
|
|
#pragma once
|
|
#endif
|
|
|
|
#include "datamodel/attributeflags.h"
|
|
#include "datamodel/idatamodel.h"
|
|
#include "datamodel/dmattributetypes.h"
|
|
#include "datamodel/dmvar.h"
|
|
#include "tier1/utlhash.h"
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Forward declarations
|
|
//-----------------------------------------------------------------------------
|
|
class CDmElement;
|
|
class CUtlBuffer;
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Used for in-place modification
|
|
//-----------------------------------------------------------------------------
|
|
typedef void *DmAttributeModifyHandle_t;
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: A general purpose pAttribute. Eventually will be extensible to arbitrary user types
|
|
//-----------------------------------------------------------------------------
|
|
class CDmAttribute
|
|
{
|
|
public:
|
|
// Returns the type
|
|
DmAttributeType_t GetType() const;
|
|
const char *GetTypeString() const;
|
|
template< class T > bool IsA() const;
|
|
|
|
// ChangeType fails (and returns false) for external attributes (ones who's data is owned by their element)
|
|
bool ChangeType_UNSAFE( DmAttributeType_t type );
|
|
|
|
bool IsStandard() const;
|
|
|
|
// Returns the name. NOTE: The utlsymbol
|
|
// can be turned into a string by using g_pDataModel->String();
|
|
const char *GetName() const;
|
|
CUtlSymbolLarge GetNameSymbol() const;
|
|
void SetName( const char *newName );
|
|
|
|
// Gets the attribute value
|
|
// NOTE: GetValueUntyped is used with GetType() for use w/ SetValue( type, void* )
|
|
template< class T > const T& GetValue() const;
|
|
template< class T > const T& GetValue( const T& defaultValue ) const;
|
|
const char *GetValueString() const;
|
|
template< class E > E *GetValueElement() const;
|
|
const void *GetValueUntyped() const;
|
|
|
|
// Sets the attribute value
|
|
template< class T > void SetValue( const T &value );
|
|
template< class E > void SetValue( E* pValue );
|
|
void SetValue( const void *pValue, size_t nSize );
|
|
|
|
// Copies w/ type conversion (if possible) from another attribute
|
|
void SetValue( const CDmAttribute *pAttribute );
|
|
void SetValue( CDmAttribute *pAttribute );
|
|
void SetValue( DmAttributeType_t valueType, const void *pValue );
|
|
|
|
// Sets the attribute to its default value based on its type
|
|
void SetToDefaultValue();
|
|
|
|
// Convert to and from string
|
|
void SetValueFromString( const char *pValue );
|
|
const char *GetValueAsString( char *pBuffer, size_t nBufLen ) const;
|
|
|
|
// Used for in-place modification of the data; preferable to set value
|
|
// for large data like arrays or binary blocks
|
|
template< class T > T& BeginModifyValueInPlace( DmAttributeModifyHandle_t *pHandle );
|
|
template< class T > void EndModifyValueInPlace( DmAttributeModifyHandle_t handle );
|
|
|
|
// Used for element and element array attributes; it specifies which type of
|
|
// elements are valid to be referred to by this attribute
|
|
void SetElementTypeSymbol( CUtlSymbolLarge typeSymbol );
|
|
CUtlSymbolLarge GetElementTypeSymbol() const;
|
|
|
|
// Returns the next attribute
|
|
CDmAttribute *NextAttribute();
|
|
const CDmAttribute *NextAttribute() const;
|
|
|
|
// Returns the owner
|
|
CDmElement *GetOwner();
|
|
|
|
// Methods related to flags
|
|
void AddFlag( int flags );
|
|
void RemoveFlag( int flags );
|
|
void ClearFlags();
|
|
int GetFlags() const;
|
|
bool IsFlagSet( int flags ) const;
|
|
|
|
// Serialization
|
|
bool Serialize( CUtlBuffer &buf ) const;
|
|
bool Unserialize( CUtlBuffer &buf );
|
|
bool IsIdenticalToSerializedValue( CUtlBuffer &buf ) const;
|
|
|
|
// Serialization of a single element.
|
|
// First version of UnserializeElement adds to tail if it worked
|
|
// Second version overwrites, but does not add, the element at the specified index
|
|
bool SerializeElement( int nElement, CUtlBuffer &buf ) const;
|
|
bool UnserializeElement( CUtlBuffer &buf );
|
|
bool UnserializeElement( int nElement, CUtlBuffer &buf );
|
|
|
|
// Does this attribute serialize on multiple lines?
|
|
bool SerializesOnMultipleLines() const;
|
|
|
|
// Get the attribute/create an attribute handle
|
|
DmAttributeHandle_t GetHandle( bool bCreate = true );
|
|
|
|
// estimate memory overhead
|
|
int EstimateMemoryUsage( TraversalDepth_t depth ) const;
|
|
|
|
private:
|
|
// Class factory
|
|
static CDmAttribute *CreateAttribute( CDmElement *pOwner, DmAttributeType_t type, const char *pAttributeName );
|
|
static CDmAttribute *CreateExternalAttribute( CDmElement *pOwner, DmAttributeType_t type, const char *pAttributeName, void *pExternalMemory );
|
|
static void DestroyAttribute( CDmAttribute *pAttribute );
|
|
|
|
// Constructor, destructor
|
|
CDmAttribute( CDmElement *pOwner, DmAttributeType_t type, const char *pAttributeName );
|
|
CDmAttribute( CDmElement *pOwner, DmAttributeType_t type, const char *pAttributeName, void *pMemory );
|
|
~CDmAttribute();
|
|
|
|
// Used when constructing CDmAttributes
|
|
void Init( CDmElement *pOwner, DmAttributeType_t type, const char *pAttributeName );
|
|
|
|
// Used when shutting down, indicates DmAttributeHandle_t referring to this are invalid
|
|
void InvalidateHandle();
|
|
|
|
// Called when the attribute changes
|
|
void OnChanged( bool bArrayCountChanged = false, bool bIsTopological = false );
|
|
|
|
// Is modification allowed in this phase?
|
|
bool ModificationAllowed() const;
|
|
|
|
// Mark the attribute as being dirty
|
|
bool MarkDirty();
|
|
|
|
// Is the data inline in a containing element class?
|
|
bool IsDataInline() const;
|
|
|
|
// Allocates, frees internal data storage
|
|
void CreateAttributeData();
|
|
void DeleteAttributeData();
|
|
|
|
// Gets at the internal data storage
|
|
void* GetAttributeData();
|
|
const void* GetAttributeData() const;
|
|
template < class T > typename CDmAttributeInfo< T >::StorageType_t* GetData();
|
|
template < class T > const typename CDmAttributeInfo< T >::StorageType_t* GetData() const;
|
|
template < class T > typename CDmAttributeInfo< CUtlVector< T > >::StorageType_t* GetArrayData();
|
|
template < class T > const typename CDmAttributeInfo< CUtlVector< T > >::StorageType_t* GetArrayData() const;
|
|
|
|
// Used by CDmElement to manage the list of attributes it owns
|
|
CDmAttribute **GetNextAttributeRef();
|
|
|
|
// Implementational function used for memory consumption estimation computation
|
|
int EstimateMemoryUsageInternal( CUtlHash< DmElementHandle_t > &visited, TraversalDepth_t depth, int *pCategories ) const;
|
|
|
|
// Called by elements after unserialization of their attributes is complete
|
|
void OnUnserializationFinished();
|
|
|
|
template< class T > bool IsTypeConvertable() const;
|
|
template< class T > bool ShouldModify( const T& src );
|
|
template< class T > void CopyData( const T& src );
|
|
template< class T > void CopyDataOut( T& dest ) const;
|
|
|
|
private:
|
|
CDmAttribute *m_pNext;
|
|
void *m_pData;
|
|
CDmElement *m_pOwner;
|
|
DmAttributeHandle_t m_Handle;
|
|
uint16 m_nFlags;
|
|
CUtlSymbolLarge m_Name;
|
|
|
|
friend class CDmElement;
|
|
friend class CDmAttributeAccessor;
|
|
template< class T > friend class CDmrElementArray;
|
|
template< class E > friend class CDmrElementArrayConst;
|
|
template< class T > friend class CDmaArrayAccessor;
|
|
template< class T, class B > friend class CDmrDecorator;
|
|
template< class T, class B > friend class CDmrDecoratorConst;
|
|
template< class T > friend class CDmArrayAttributeOp;
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Inline methods
|
|
//-----------------------------------------------------------------------------
|
|
inline DmAttributeType_t CDmAttribute::GetType() const
|
|
{
|
|
return (DmAttributeType_t)( m_nFlags & FATTRIB_TYPEMASK );
|
|
}
|
|
|
|
template< class T > inline bool CDmAttribute::IsA() const
|
|
{
|
|
return GetType() == CDmAttributeInfo< T >::AttributeType();
|
|
}
|
|
|
|
inline const char *CDmAttribute::GetName() const
|
|
{
|
|
return m_Name.String();
|
|
}
|
|
|
|
inline CUtlSymbolLarge CDmAttribute::GetNameSymbol() const
|
|
{
|
|
return m_Name;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Iteration
|
|
//-----------------------------------------------------------------------------
|
|
inline CDmAttribute *CDmAttribute::NextAttribute()
|
|
{
|
|
return m_pNext;
|
|
}
|
|
|
|
inline const CDmAttribute *CDmAttribute::NextAttribute() const
|
|
{
|
|
return m_pNext;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns the owner
|
|
//-----------------------------------------------------------------------------
|
|
inline CDmElement *CDmAttribute::GetOwner()
|
|
{
|
|
return m_pOwner;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Value getting methods
|
|
//-----------------------------------------------------------------------------
|
|
template< class T >
|
|
inline const T& CDmAttribute::GetValue( const T& defaultValue ) const
|
|
{
|
|
if ( (int)GetType() == (int)CDmAttributeInfo< T >::ATTRIBUTE_TYPE )
|
|
return *reinterpret_cast< const T* >( m_pData );
|
|
|
|
if ( IsTypeConvertable< T >() )
|
|
{
|
|
static T tempVal;
|
|
CopyDataOut( tempVal );
|
|
return tempVal;
|
|
}
|
|
|
|
Assert( 0 );
|
|
return defaultValue;
|
|
}
|
|
|
|
template< class T >
|
|
inline const T& CDmAttribute::GetValue() const
|
|
{
|
|
static CDmaVar< T > defaultVal;
|
|
return GetValue( defaultVal.Get() );
|
|
}
|
|
|
|
inline const char *CDmAttribute::GetValueString() const
|
|
{
|
|
Assert( GetType() == AT_STRING );
|
|
if ( GetType() != AT_STRING )
|
|
return NULL;
|
|
|
|
CUtlSymbolLarge symbol = GetValue< CUtlSymbolLarge >();
|
|
return symbol.String();
|
|
}
|
|
|
|
// used with GetType() for use w/ SetValue( type, void* )
|
|
inline const void* CDmAttribute::GetValueUntyped() const
|
|
{
|
|
return m_pData;
|
|
}
|
|
|
|
#ifndef POSIX
|
|
template< class E >
|
|
inline E* CDmAttribute::GetValueElement() const
|
|
{
|
|
Assert( GetType() == AT_ELEMENT );
|
|
if ( GetType() == AT_ELEMENT )
|
|
return GetElement<E>( this->GetValue<DmElementHandle_t>( ) );
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Value setting methods
|
|
//-----------------------------------------------------------------------------
|
|
template< class E >
|
|
inline void CDmAttribute::SetValue( E* pValue )
|
|
{
|
|
Assert( GetType() == AT_ELEMENT );
|
|
if ( GetType() == AT_ELEMENT )
|
|
{
|
|
SetValue( pValue ? pValue->GetHandle() : DMELEMENT_HANDLE_INVALID );
|
|
}
|
|
}
|
|
|
|
template<>
|
|
inline void CDmAttribute::SetValue( const char *pValue )
|
|
{
|
|
CUtlSymbolLarge symbol = g_pDataModel->GetSymbol( pValue );
|
|
return SetValue( symbol );
|
|
}
|
|
|
|
template<>
|
|
inline void CDmAttribute::SetValue( char *pValue )
|
|
{
|
|
return SetValue( (const char *)pValue );
|
|
}
|
|
|
|
inline void CDmAttribute::SetValue( const void *pValue, size_t nSize )
|
|
{
|
|
CUtlBinaryBlock buf( pValue, nSize );
|
|
return SetValue( buf );
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Methods related to flags
|
|
//-----------------------------------------------------------------------------
|
|
inline void CDmAttribute::AddFlag( int nFlags )
|
|
{
|
|
m_nFlags |= ( nFlags & ~FATTRIB_TYPEMASK );
|
|
}
|
|
|
|
inline void CDmAttribute::RemoveFlag( int nFlags )
|
|
{
|
|
m_nFlags &= ~nFlags | FATTRIB_TYPEMASK;
|
|
}
|
|
|
|
inline void CDmAttribute::ClearFlags()
|
|
{
|
|
RemoveFlag( 0xffffffff );
|
|
}
|
|
|
|
inline int CDmAttribute::GetFlags() const
|
|
{
|
|
return m_nFlags & ~FATTRIB_TYPEMASK;
|
|
}
|
|
|
|
inline bool CDmAttribute::IsFlagSet( int nFlags ) const
|
|
{
|
|
return ( nFlags & GetFlags() ) != 0;
|
|
}
|
|
|
|
inline bool CDmAttribute::IsDataInline() const
|
|
{
|
|
return !IsFlagSet( FATTRIB_EXTERNAL );
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Gets at the internal data storage
|
|
//-----------------------------------------------------------------------------
|
|
inline void* CDmAttribute::GetAttributeData()
|
|
{
|
|
return m_pData;
|
|
}
|
|
|
|
inline const void* CDmAttribute::GetAttributeData() const
|
|
{
|
|
return m_pData;
|
|
}
|
|
|
|
template < class T >
|
|
inline typename CDmAttributeInfo< T >::StorageType_t* CDmAttribute::GetData()
|
|
{
|
|
return ( typename CDmAttributeInfo< T >::StorageType_t* )m_pData;
|
|
}
|
|
|
|
template < class T >
|
|
inline typename CDmAttributeInfo< CUtlVector< T > >::StorageType_t* CDmAttribute::GetArrayData()
|
|
{
|
|
return ( typename CDmAttributeInfo< CUtlVector< T > >::StorageType_t* )m_pData;
|
|
}
|
|
|
|
template < class T >
|
|
inline const typename CDmAttributeInfo< T >::StorageType_t* CDmAttribute::GetData() const
|
|
{
|
|
return ( const typename CDmAttributeInfo< T >::StorageType_t* )m_pData;
|
|
}
|
|
|
|
template < class T >
|
|
inline const typename CDmAttributeInfo< CUtlVector< T > >::StorageType_t* CDmAttribute::GetArrayData() const
|
|
{
|
|
return ( const typename CDmAttributeInfo< CUtlVector< T > >::StorageType_t* )m_pData;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Used by CDmElement to manage the list of attributes it owns
|
|
//-----------------------------------------------------------------------------
|
|
inline CDmAttribute **CDmAttribute::GetNextAttributeRef()
|
|
{
|
|
return &m_pNext;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// helper function for determining which attributes/elements to traverse during copy/find/save/etc.
|
|
//-----------------------------------------------------------------------------
|
|
inline bool ShouldTraverse( const CDmAttribute *pAttr, TraversalDepth_t depth )
|
|
{
|
|
switch ( depth )
|
|
{
|
|
case TD_NONE:
|
|
return false;
|
|
|
|
case TD_SHALLOW:
|
|
if ( !pAttr->IsFlagSet( FATTRIB_MUSTCOPY ) )
|
|
return false;
|
|
// fall-through intentional
|
|
case TD_DEEP:
|
|
if ( pAttr->IsFlagSet( FATTRIB_NEVERCOPY ) )
|
|
return false;
|
|
// fall-through intentional
|
|
case TD_ALL:
|
|
return true;
|
|
}
|
|
|
|
Assert( 0 );
|
|
return false;
|
|
}
|
|
|
|
#endif // DMATTRIBUTE_H
|