mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2025-09-19 03:56:10 +08:00
First version of the SOurce SDK 2013
This commit is contained in:
35
public/datamodel/attributeflags.h
Normal file
35
public/datamodel/attributeflags.h
Normal file
@ -0,0 +1,35 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef ATTRIBUTEFLAGS_H
|
||||
#define ATTRIBUTEFLAGS_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
// NOTE: The first 5 flags bits are reserved for attribute type
|
||||
FATTRIB_TYPEMASK = 0x1F,
|
||||
|
||||
FATTRIB_READONLY = (1<<5), // Don't allow editing value in editors
|
||||
FATTRIB_DONTSAVE = (1<<6), // Don't persist to .dmx file
|
||||
FATTRIB_DIRTY = (1<<7), // Indicates the attribute has been changed since the resolve phase
|
||||
FATTRIB_HAS_CALLBACK = (1<<8), // Indicates that this will notify its owner and/or other elements when it changes
|
||||
FATTRIB_EXTERNAL = (1<<9), // Indicates this attribute's data is externally owned (in a CDmElement somewhere)
|
||||
FATTRIB_TOPOLOGICAL = (1<<10), // Indicates this attribute effects the scene's topology (ie it's an attribute name or element)
|
||||
FATTRIB_MUSTCOPY = (1<<11), // parent element must make a new copy during CopyInto, even for shallow copy
|
||||
FATTRIB_NEVERCOPY = (1<<12), // parent element shouldn't make a new copy during CopyInto, even for deep copy
|
||||
FATTRIB_STANDARD = (1<<13), // This flag is set if it's a "standard" attribute, namely "name"
|
||||
FATTRIB_USERDEFINED = (1<<14), // This flag is used to sort attributes in the element properties view. User defined flags come last.
|
||||
FATTRIB_NODUPLICATES = (1<<15),// For element array types, disallows duplicate values from being inserted into the array.
|
||||
FATTRIB_HAS_ARRAY_CALLBACK = (1<<16), // Indicates that this will notify its owner and/or other elements array elements changes. Note that when elements shift (say, inserting at head, or fast remove), callbacks are not executed for these elements.
|
||||
FATTRIB_HAS_PRE_CALLBACK = (1<<17), // Indicates that this will notify its owner and/or other elements right before it changes
|
||||
FATTRIB_OPERATOR_DIRTY = (1<<18),// Used and cleared only by operator phase of datamodel
|
||||
};
|
||||
|
||||
#endif // ATTRIBUTEFLAGS_H
|
768
public/datamodel/dmattribute.h
Normal file
768
public/datamodel/dmattribute.h
Normal file
@ -0,0 +1,768 @@
|
||||
//========= Copyright 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/dmelement.h"
|
||||
#include "datamodel/dmvar.h"
|
||||
#include "tier1/utlhash.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fast dynamic cast
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class E >
|
||||
inline E *CastElement( CDmElement *pElement )
|
||||
{
|
||||
if ( pElement && pElement->IsA( E::GetStaticTypeSymbol() ) )
|
||||
return static_cast< E* >( pElement );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// type-safe element creation and accessor helpers - infers type name string from actual type
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class E >
|
||||
inline E *GetElement( DmElementHandle_t hElement )
|
||||
{
|
||||
CDmElement *pElement = g_pDataModel->GetElement( hElement );
|
||||
return CastElement< E >( pElement );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Typesafe element creation + destruction
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class E >
|
||||
inline E *CreateElement( const char *pObjectName, DmFileId_t fileid = DMFILEID_INVALID, const DmObjectId_t *pObjectID = NULL )
|
||||
{
|
||||
return GetElement< E >( g_pDataModel->CreateElement( E::GetStaticTypeSymbol(), pObjectName, fileid, pObjectID ) );
|
||||
}
|
||||
|
||||
template< class E >
|
||||
inline E *CreateElement( const char *pElementType, const char *pObjectName, DmFileId_t fileid = DMFILEID_INVALID, const DmObjectId_t *pObjectID = NULL )
|
||||
{
|
||||
return GetElement< E >( g_pDataModel->CreateElement( pElementType, pObjectName, fileid, pObjectID ) );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Used for attribute change callbacks
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef unsigned short DmMailingList_t;
|
||||
enum
|
||||
{
|
||||
DMMAILINGLIST_INVALID = (DmMailingList_t)~0
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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;
|
||||
|
||||
// Returns the name. NOTE: The utlsymbol
|
||||
// can be turned into a string by using g_pDataModel->String();
|
||||
const char *GetName() const;
|
||||
UtlSymId_t 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 element and element array attributes; it specifies which type of
|
||||
// elements are valid to be referred to by this attribute
|
||||
void SetElementTypeSymbol( UtlSymId_t typeSymbol );
|
||||
UtlSymId_t 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 );
|
||||
|
||||
// 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 );
|
||||
|
||||
// Notify external elements upon change ( Calls OnAttributeChanged )
|
||||
// Pass false here to stop notification
|
||||
void NotifyWhenChanged( DmElementHandle_t h, bool bNotify );
|
||||
|
||||
// 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();
|
||||
|
||||
// Used when shutting down, indicates no more change notifications will be sent to listening elements
|
||||
void CleanupMailingList();
|
||||
|
||||
// Called when the attribute changes
|
||||
void PreChanged();
|
||||
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;
|
||||
int m_nFlags;
|
||||
DmAttributeHandle_t m_Handle;
|
||||
CUtlSymbol m_Name;
|
||||
DmMailingList_t m_hMailingList;
|
||||
|
||||
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 g_pDataModel->GetString( m_Name );
|
||||
}
|
||||
|
||||
inline UtlSymId_t 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 ( GetType() == ( DmAttributeType_t )( 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;
|
||||
|
||||
return GetValue< CUtlString >();
|
||||
}
|
||||
|
||||
// used with GetType() for use w/ SetValue( type, void* )
|
||||
inline const void* CDmAttribute::GetValueUntyped() const
|
||||
{
|
||||
return m_pData;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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 )
|
||||
{
|
||||
int nLen = pValue ? Q_strlen( pValue ) + 1 : 0;
|
||||
CUtlString str( pValue, nLen );
|
||||
return SetValue( str );
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
inline void CDmAttribute::RemoveFlag( int nFlags )
|
||||
{
|
||||
m_nFlags &= ~nFlags;
|
||||
}
|
||||
|
||||
inline void CDmAttribute::ClearFlags()
|
||||
{
|
||||
m_nFlags = 0;
|
||||
}
|
||||
|
||||
inline int CDmAttribute::GetFlags() const
|
||||
{
|
||||
return m_nFlags;
|
||||
}
|
||||
|
||||
inline bool CDmAttribute::IsFlagSet( int nFlags ) const
|
||||
{
|
||||
return ( nFlags & m_nFlags ) ? true : false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets attributes
|
||||
//-----------------------------------------------------------------------------
|
||||
inline CDmAttribute *CDmElement::GetAttribute( const char *pAttributeName, DmAttributeType_t type )
|
||||
{
|
||||
CDmAttribute *pAttribute = FindAttribute( pAttributeName );
|
||||
if ( ( type != AT_UNKNOWN ) && pAttribute && ( pAttribute->GetType() != type ) )
|
||||
return NULL;
|
||||
return pAttribute;
|
||||
}
|
||||
|
||||
inline const CDmAttribute *CDmElement::GetAttribute( const char *pAttributeName, DmAttributeType_t type ) const
|
||||
{
|
||||
CDmAttribute *pAttribute = FindAttribute( pAttributeName );
|
||||
if ( ( type != AT_UNKNOWN ) && pAttribute && ( pAttribute->GetType() != type ) )
|
||||
return NULL;
|
||||
return pAttribute;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// AddAttribute calls
|
||||
//-----------------------------------------------------------------------------
|
||||
inline CDmAttribute *CDmElement::AddAttribute( const char *pAttributeName, DmAttributeType_t type )
|
||||
{
|
||||
CDmAttribute *pAttribute = FindAttribute( pAttributeName );
|
||||
if ( pAttribute )
|
||||
return ( pAttribute->GetType() == type ) ? pAttribute : NULL;
|
||||
pAttribute = CreateAttribute( pAttributeName, type );
|
||||
return pAttribute;
|
||||
}
|
||||
|
||||
template< class E > inline CDmAttribute *CDmElement::AddAttributeElement( const char *pAttributeName )
|
||||
{
|
||||
CDmAttribute *pAttribute = AddAttribute( pAttributeName, AT_ELEMENT );
|
||||
if ( !pAttribute )
|
||||
return NULL;
|
||||
|
||||
// FIXME: If the attribute exists but has a different element type symbol, should we complain?
|
||||
pAttribute->SetElementTypeSymbol( E::GetStaticTypeSymbol() );
|
||||
return pAttribute;
|
||||
}
|
||||
|
||||
template< class E > inline CDmAttribute *CDmElement::AddAttributeElementArray( const char *pAttributeName )
|
||||
{
|
||||
CDmAttribute *pAttribute = AddAttribute( pAttributeName, AT_ELEMENT_ARRAY );
|
||||
if ( !pAttribute )
|
||||
return NULL;
|
||||
|
||||
// FIXME: If the attribute exists but has a different element type symbol, should we complain?
|
||||
pAttribute->SetElementTypeSymbol( E::GetStaticTypeSymbol() );
|
||||
return pAttribute;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GetValue methods
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template< class T >
|
||||
inline const T& CDmElement::GetValue( const char *pAttributeName ) const
|
||||
{
|
||||
static CDmaVar<T> defaultVal;
|
||||
return GetValue( pAttributeName, defaultVal.Get() );
|
||||
}
|
||||
|
||||
inline const char *CDmElement::GetValueString( const char *pAttributeName ) const
|
||||
{
|
||||
return GetValue<CUtlString>( pAttributeName ).Get();
|
||||
}
|
||||
|
||||
template< class E >
|
||||
inline E* CDmElement::GetValueElement( const char *pAttributeName ) const
|
||||
{
|
||||
DmElementHandle_t h = GetValue< DmElementHandle_t >( pAttributeName );
|
||||
return GetElement<E>( h );
|
||||
}
|
||||
|
||||
|
||||
template< class T >
|
||||
inline const T& CDmElement::GetValue( const char *pAttributeName, const T& defaultVal ) const
|
||||
{
|
||||
const CDmAttribute *pAttribute = FindAttribute( pAttributeName );
|
||||
if ( pAttribute != NULL )
|
||||
return pAttribute->GetValue<T>();
|
||||
return defaultVal;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SetValue methods
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T >
|
||||
inline CDmAttribute* CDmElement::SetValue( const char *pAttributeName, const T& value )
|
||||
{
|
||||
CDmAttribute *pAttribute = FindAttribute( pAttributeName );
|
||||
if ( !pAttribute )
|
||||
{
|
||||
pAttribute = CreateAttribute( pAttributeName, CDmAttributeInfo<T>::AttributeType() );
|
||||
}
|
||||
if ( pAttribute )
|
||||
{
|
||||
pAttribute->SetValue( value );
|
||||
return pAttribute;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
template< class E >
|
||||
inline CDmAttribute* CDmElement::SetValue( const char *pAttributeName, E* pElement )
|
||||
{
|
||||
DmElementHandle_t hElement = pElement ? pElement->GetHandle() : DMELEMENT_HANDLE_INVALID;
|
||||
return SetValue( pAttributeName, hElement );
|
||||
}
|
||||
|
||||
template<>
|
||||
inline CDmAttribute* CDmElement::SetValue( const char *pAttributeName, const char *pValue )
|
||||
{
|
||||
int nLen = pValue ? Q_strlen( pValue ) + 1 : 0;
|
||||
CUtlString str( pValue, nLen );
|
||||
return SetValue( pAttributeName, str );
|
||||
}
|
||||
|
||||
template<>
|
||||
inline CDmAttribute* CDmElement::SetValue( const char *pAttributeName, char *pValue )
|
||||
{
|
||||
return SetValue( pAttributeName, (const char *)pValue );
|
||||
}
|
||||
|
||||
inline CDmAttribute* CDmElement::SetValue( const char *pAttributeName, const void *pValue, size_t nSize )
|
||||
{
|
||||
CUtlBinaryBlock buf( pValue, nSize );
|
||||
return SetValue( pAttributeName, buf );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// AddValue methods( set value if not found )
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T >
|
||||
inline CDmAttribute* CDmElement::InitValue( const char *pAttributeName, const T& value )
|
||||
{
|
||||
CDmAttribute *pAttribute = GetAttribute( pAttributeName );
|
||||
if ( !pAttribute )
|
||||
return SetValue( pAttributeName, value );
|
||||
return pAttribute;
|
||||
}
|
||||
|
||||
template< class E >
|
||||
inline CDmAttribute* CDmElement::InitValue( const char *pAttributeName, E* pElement )
|
||||
{
|
||||
DmElementHandle_t hElement = pElement ? pElement->GetHandle() : DMELEMENT_HANDLE_INVALID;
|
||||
return InitValue( pAttributeName, hElement );
|
||||
}
|
||||
|
||||
inline CDmAttribute* CDmElement::InitValue( const char *pAttributeName, const void *pValue, size_t size )
|
||||
{
|
||||
CDmAttribute *pAttribute = GetAttribute( pAttributeName );
|
||||
if ( !pAttribute )
|
||||
return SetValue( pAttributeName, pValue, size );
|
||||
return pAttribute;
|
||||
}
|
||||
|
||||
template< class T >
|
||||
T *FindReferringElement( CDmElement *pElement, UtlSymId_t symAttrName, bool bMustBeInSameFile = true )
|
||||
{
|
||||
DmAttributeReferenceIterator_t i = g_pDataModel->FirstAttributeReferencingElement( pElement->GetHandle() );
|
||||
while ( i != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID )
|
||||
{
|
||||
CDmAttribute *pAttribute = g_pDataModel->GetAttribute( i );
|
||||
CDmElement *pDmeParent = pAttribute->GetOwner();
|
||||
if ( pDmeParent && pAttribute->GetNameSymbol() == symAttrName )
|
||||
{
|
||||
T *pParent = CastElement< T >( pDmeParent );
|
||||
if ( pParent )
|
||||
{
|
||||
if ( !bMustBeInSameFile || ( pParent->GetFileId() == pElement->GetFileId() ) )
|
||||
return pParent;
|
||||
}
|
||||
}
|
||||
i = g_pDataModel->NextAttributeReferencingElement( i );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
template< class T >
|
||||
T *FindAncestorReferencingElement( CDmElement *target )
|
||||
{
|
||||
if ( !target )
|
||||
return NULL;
|
||||
|
||||
for ( DmAttributeReferenceIterator_t it = g_pDataModel->FirstAttributeReferencingElement( target->GetHandle() );
|
||||
it != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID;
|
||||
it = g_pDataModel->NextAttributeReferencingElement( it ) )
|
||||
{
|
||||
CDmAttribute *attr = g_pDataModel->GetAttribute( it );
|
||||
Assert( attr );
|
||||
CDmElement *element = attr->GetOwner();
|
||||
Assert( element );
|
||||
if ( !element )
|
||||
continue;
|
||||
T *t = CastElement< T >( element );
|
||||
if ( !t )
|
||||
continue;
|
||||
|
||||
return t;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
template< class T >
|
||||
T *FindAncestorReferencingElement_R_Impl( CUtlRBTree< CDmElement * >& visited, CDmElement *check )
|
||||
{
|
||||
if ( visited.Find( check ) != visited.InvalidIndex() )
|
||||
return NULL;
|
||||
|
||||
visited.Insert( check );
|
||||
|
||||
// Pass one, see if it's in this ancestor list
|
||||
DmAttributeReferenceIterator_t it;
|
||||
for ( it = g_pDataModel->FirstAttributeReferencingElement( check->GetHandle() );
|
||||
it != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID;
|
||||
it = g_pDataModel->NextAttributeReferencingElement( it ) )
|
||||
{
|
||||
CDmAttribute *attr = g_pDataModel->GetAttribute( it );
|
||||
Assert( attr );
|
||||
CDmElement *element = attr->GetOwner();
|
||||
Assert( element );
|
||||
if ( !element )
|
||||
continue;
|
||||
T *t = CastElement< T >( element );
|
||||
if ( !t )
|
||||
continue;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
for ( it = g_pDataModel->FirstAttributeReferencingElement( check->GetHandle() );
|
||||
it != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID;
|
||||
it = g_pDataModel->NextAttributeReferencingElement( it ) )
|
||||
{
|
||||
CDmAttribute *attr = g_pDataModel->GetAttribute( it );
|
||||
Assert( attr );
|
||||
CDmElement *element = attr->GetOwner();
|
||||
Assert( element );
|
||||
if ( !element )
|
||||
continue;
|
||||
|
||||
T *found = FindAncestorReferencingElement_R_Impl< T >( visited, element );
|
||||
if ( found )
|
||||
return found;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
template< class T >
|
||||
void FindAncestorsReferencingElement( CDmElement *target, CUtlVector< T* >& list )
|
||||
{
|
||||
if ( !target )
|
||||
return;
|
||||
|
||||
list.RemoveAll();
|
||||
for ( DmAttributeReferenceIterator_t it = g_pDataModel->FirstAttributeReferencingElement( target->GetHandle() );
|
||||
it != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID;
|
||||
it = g_pDataModel->NextAttributeReferencingElement( it ) )
|
||||
{
|
||||
CDmAttribute *attr = g_pDataModel->GetAttribute( it );
|
||||
Assert( attr );
|
||||
CDmElement *element = attr->GetOwner();
|
||||
Assert( element );
|
||||
if ( !element )
|
||||
continue;
|
||||
T* t = CastElement< T >( element );
|
||||
if ( !t )
|
||||
continue;
|
||||
|
||||
if ( list.Find( t ) != list.InvalidIndex() )
|
||||
continue;
|
||||
|
||||
list.AddToTail( t );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template< class T >
|
||||
T *FindAncestorReferencingElement_R( CDmElement *target )
|
||||
{
|
||||
if ( !target )
|
||||
return NULL;
|
||||
|
||||
CUtlRBTree< CDmElement * > visited( 0, 0, DefLessFunc( CDmElement * ) );
|
||||
return FindAncestorReferencingElement_R_Impl< T >( visited, target );
|
||||
}
|
||||
|
||||
|
||||
#endif // DMATTRIBUTE_H
|
316
public/datamodel/dmattributetypes.h
Normal file
316
public/datamodel/dmattributetypes.h
Normal file
@ -0,0 +1,316 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef DMATTRIBUTETYPES_H
|
||||
#define DMATTRIBUTETYPES_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier1/utlvector.h"
|
||||
#include "tier1/utlstring.h"
|
||||
#include "tier1/uniqueid.h"
|
||||
#include "Color.h"
|
||||
#include "mathlib/vector2d.h"
|
||||
#include "mathlib/vector.h"
|
||||
#include "mathlib/vector4d.h"
|
||||
#include "mathlib/vmatrix.h"
|
||||
#include "datamodel/dmelementhandle.h"
|
||||
#include "tier1/utlsymbol.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Object Id
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef UniqueId_t DmObjectId_t;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Necessary for template specialization for AT_UNKNOWN
|
||||
//-----------------------------------------------------------------------------
|
||||
struct DmUnknownAttribute_t
|
||||
{
|
||||
bool operator==( const DmUnknownAttribute_t& src ) const { return true; }
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Element array
|
||||
//-----------------------------------------------------------------------------
|
||||
struct DmElementAttribute_t
|
||||
{
|
||||
DmElementAttribute_t() : m_ElementType( UTL_INVAL_SYMBOL ) {}
|
||||
|
||||
operator DmElementHandle_t&() { return m_Handle; }
|
||||
operator const DmElementHandle_t&() const { return m_Handle; }
|
||||
|
||||
DmElementHandle_t m_Handle;
|
||||
UtlSymId_t m_ElementType;
|
||||
};
|
||||
|
||||
struct DmElementArray_t : public CUtlVector< DmElementHandle_t >
|
||||
{
|
||||
DmElementArray_t() : m_ElementType( UTL_INVAL_SYMBOL ) {}
|
||||
|
||||
UtlSymId_t m_ElementType;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Attribute chunk type enum
|
||||
//-----------------------------------------------------------------------------
|
||||
enum DmAttributeType_t
|
||||
{
|
||||
AT_UNKNOWN = 0,
|
||||
|
||||
AT_FIRST_VALUE_TYPE,
|
||||
|
||||
AT_ELEMENT = AT_FIRST_VALUE_TYPE,
|
||||
AT_INT,
|
||||
AT_FLOAT,
|
||||
AT_BOOL,
|
||||
AT_STRING,
|
||||
AT_VOID,
|
||||
AT_OBJECTID,
|
||||
AT_COLOR, //rgba
|
||||
AT_VECTOR2,
|
||||
AT_VECTOR3,
|
||||
AT_VECTOR4,
|
||||
AT_QANGLE,
|
||||
AT_QUATERNION,
|
||||
AT_VMATRIX,
|
||||
|
||||
AT_FIRST_ARRAY_TYPE,
|
||||
|
||||
AT_ELEMENT_ARRAY = AT_FIRST_ARRAY_TYPE,
|
||||
AT_INT_ARRAY,
|
||||
AT_FLOAT_ARRAY,
|
||||
AT_BOOL_ARRAY,
|
||||
AT_STRING_ARRAY,
|
||||
AT_VOID_ARRAY,
|
||||
AT_OBJECTID_ARRAY,
|
||||
AT_COLOR_ARRAY,
|
||||
AT_VECTOR2_ARRAY,
|
||||
AT_VECTOR3_ARRAY,
|
||||
AT_VECTOR4_ARRAY,
|
||||
AT_QANGLE_ARRAY,
|
||||
AT_QUATERNION_ARRAY,
|
||||
AT_VMATRIX_ARRAY,
|
||||
AT_TYPE_COUNT,
|
||||
};
|
||||
|
||||
const char *GetTypeString( DmAttributeType_t type );
|
||||
|
||||
inline bool IsValueType( DmAttributeType_t type )
|
||||
{
|
||||
return type >= AT_FIRST_VALUE_TYPE && type < AT_FIRST_ARRAY_TYPE;
|
||||
}
|
||||
|
||||
inline bool IsArrayType( DmAttributeType_t type )
|
||||
{
|
||||
return type >= AT_FIRST_ARRAY_TYPE && type < AT_TYPE_COUNT;
|
||||
}
|
||||
|
||||
inline bool IsTopological( DmAttributeType_t type )
|
||||
{
|
||||
return type == AT_ELEMENT || type == AT_ELEMENT_ARRAY;
|
||||
}
|
||||
|
||||
inline DmAttributeType_t ValueTypeToArrayType( DmAttributeType_t type )
|
||||
{
|
||||
Assert( IsValueType( type ) );
|
||||
return ( DmAttributeType_t )( ( type - AT_FIRST_VALUE_TYPE ) + AT_FIRST_ARRAY_TYPE );
|
||||
}
|
||||
|
||||
inline DmAttributeType_t ArrayTypeToValueType( DmAttributeType_t type )
|
||||
{
|
||||
Assert( IsArrayType( type ) );
|
||||
return ( DmAttributeType_t )( ( type - AT_FIRST_ARRAY_TYPE ) + AT_FIRST_VALUE_TYPE );
|
||||
}
|
||||
|
||||
inline int NumComponents( DmAttributeType_t type )
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case AT_BOOL:
|
||||
case AT_INT:
|
||||
case AT_FLOAT:
|
||||
return 1;
|
||||
|
||||
case AT_VECTOR2:
|
||||
return 2;
|
||||
|
||||
case AT_VECTOR3:
|
||||
case AT_QANGLE:
|
||||
return 3;
|
||||
|
||||
case AT_COLOR: //rgba
|
||||
case AT_VECTOR4:
|
||||
case AT_QUATERNION:
|
||||
return 4;
|
||||
|
||||
case AT_VMATRIX:
|
||||
return 16;
|
||||
|
||||
case AT_ELEMENT:
|
||||
case AT_STRING:
|
||||
case AT_VOID:
|
||||
case AT_OBJECTID:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline float GetComponent( const T &value, int i )
|
||||
{
|
||||
Assert( 0 );
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
template <> inline float GetComponent( const bool &value, int i )
|
||||
{
|
||||
Assert( i == 0 );
|
||||
return value ? 1.0f : 0.0f;
|
||||
}
|
||||
|
||||
template <> inline float GetComponent( const int &value, int i )
|
||||
{
|
||||
Assert( i == 0 );
|
||||
return float( value );
|
||||
}
|
||||
|
||||
template <> inline float GetComponent( const float &value, int i )
|
||||
{
|
||||
Assert( i == 0 );
|
||||
return value;
|
||||
}
|
||||
|
||||
template <> inline float GetComponent( const Vector2D &value, int i )
|
||||
{
|
||||
return value[ i ];
|
||||
}
|
||||
|
||||
template <> inline float GetComponent( const Vector &value, int i )
|
||||
{
|
||||
return value[ i ];
|
||||
}
|
||||
|
||||
template <> inline float GetComponent( const QAngle &value, int i )
|
||||
{
|
||||
return value[ i ];
|
||||
}
|
||||
|
||||
template <> inline float GetComponent( const Color &value, int i )
|
||||
{
|
||||
return value[ i ];
|
||||
}
|
||||
|
||||
template <> inline float GetComponent( const Vector4D &value, int i )
|
||||
{
|
||||
return value[ i ];
|
||||
}
|
||||
|
||||
template <> inline float GetComponent( const Quaternion &value, int i )
|
||||
{
|
||||
return value[ i ];
|
||||
}
|
||||
|
||||
template <> inline float GetComponent( const VMatrix &value, int i )
|
||||
{
|
||||
return value.Base()[ i ];
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Attribute info...
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
class CDmAttributeInfo
|
||||
{
|
||||
public:
|
||||
enum { ATTRIBUTE_TYPE = AT_UNKNOWN };
|
||||
|
||||
typedef T StorageType_t;
|
||||
|
||||
static DmAttributeType_t AttributeType()
|
||||
{
|
||||
return AT_UNKNOWN;
|
||||
}
|
||||
|
||||
static const char *AttributeTypeName()
|
||||
{
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
static void SetDefaultValue( T& value )
|
||||
{
|
||||
Assert(0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#define DECLARE_ATTRIBUTE_TYPE_INTERNAL( _className, _storageType, _attributeType, _attributeName, _defaultSetStatement ) \
|
||||
template< > class CDmAttributeInfo< _className > \
|
||||
{ \
|
||||
public: \
|
||||
enum { ATTRIBUTE_TYPE = _attributeType }; \
|
||||
typedef _storageType StorageType_t; \
|
||||
static DmAttributeType_t AttributeType() { return _attributeType; } \
|
||||
static const char *AttributeTypeName() { return _attributeName; } \
|
||||
static void SetDefaultValue( _className& value ) { _defaultSetStatement } \
|
||||
}; \
|
||||
|
||||
#define DECLARE_ATTRIBUTE_ARRAY_TYPE_INTERNAL( _className, _storageType, _attributeType, _attributeName ) \
|
||||
template< > class CDmAttributeInfo< CUtlVector<_className> > \
|
||||
{ \
|
||||
public: \
|
||||
enum { ATTRIBUTE_TYPE = _attributeType }; \
|
||||
typedef _storageType StorageType_t; \
|
||||
static DmAttributeType_t AttributeType() { return _attributeType; } \
|
||||
static const char *AttributeTypeName() { return _attributeName; } \
|
||||
static void SetDefaultValue( CUtlVector< _className >& value ) { value.RemoveAll(); } \
|
||||
}; \
|
||||
|
||||
#define DECLARE_ATTRIBUTE_TYPE( _className, _attributeType, _attributeName, _defaultSetStatement ) \
|
||||
DECLARE_ATTRIBUTE_TYPE_INTERNAL( _className, _className, _attributeType, _attributeName, _defaultSetStatement )
|
||||
|
||||
#define DECLARE_ATTRIBUTE_ARRAY_TYPE( _className, _attributeType, _attributeName )\
|
||||
DECLARE_ATTRIBUTE_ARRAY_TYPE_INTERNAL( _className, CUtlVector< _className >, _attributeType, _attributeName )
|
||||
|
||||
// NOTE: If you add an attribute type here, also add it to the list of DEFINE_ATTRIBUTE_TYPES in dmattribute.cpp
|
||||
DECLARE_ATTRIBUTE_TYPE( int, AT_INT, "int", value = 0; )
|
||||
DECLARE_ATTRIBUTE_TYPE( float, AT_FLOAT, "float", value = 0.0f; )
|
||||
DECLARE_ATTRIBUTE_TYPE( bool, AT_BOOL, "bool", value = false; )
|
||||
DECLARE_ATTRIBUTE_TYPE( Color, AT_COLOR, "color", value.SetColor( 0, 0, 0, 255 ); )
|
||||
DECLARE_ATTRIBUTE_TYPE( Vector2D, AT_VECTOR2, "vector2", value.Init( 0.0f, 0.0f ); )
|
||||
DECLARE_ATTRIBUTE_TYPE( Vector, AT_VECTOR3, "vector3", value.Init( 0.0f, 0.0f, 0.0f ); )
|
||||
DECLARE_ATTRIBUTE_TYPE( Vector4D, AT_VECTOR4, "vector4", value.Init( 0.0f, 0.0f, 0.0f, 0.0f ); )
|
||||
DECLARE_ATTRIBUTE_TYPE( QAngle, AT_QANGLE, "qangle", value.Init( 0.0f, 0.0f, 0.0f ); )
|
||||
DECLARE_ATTRIBUTE_TYPE( Quaternion, AT_QUATERNION, "quaternion", value.Init( 0.0f, 0.0f, 0.0f, 1.0f ); )
|
||||
DECLARE_ATTRIBUTE_TYPE( VMatrix, AT_VMATRIX, "matrix", MatrixSetIdentity( value ); )
|
||||
DECLARE_ATTRIBUTE_TYPE( CUtlString, AT_STRING, "string", value.Set( NULL ); )
|
||||
DECLARE_ATTRIBUTE_TYPE( CUtlBinaryBlock, AT_VOID, "binary", value.Set( NULL, 0 ); )
|
||||
DECLARE_ATTRIBUTE_TYPE( DmObjectId_t, AT_OBJECTID, "elementid", InvalidateUniqueId( &value ); )
|
||||
DECLARE_ATTRIBUTE_TYPE_INTERNAL( DmElementHandle_t, DmElementAttribute_t, AT_ELEMENT, "element", value = DMELEMENT_HANDLE_INVALID; )
|
||||
|
||||
DECLARE_ATTRIBUTE_ARRAY_TYPE( int, AT_INT_ARRAY, "int_array" )
|
||||
DECLARE_ATTRIBUTE_ARRAY_TYPE( float, AT_FLOAT_ARRAY, "float_array" )
|
||||
DECLARE_ATTRIBUTE_ARRAY_TYPE( bool, AT_BOOL_ARRAY, "bool_array" )
|
||||
DECLARE_ATTRIBUTE_ARRAY_TYPE( Color, AT_COLOR_ARRAY, "color_array" )
|
||||
DECLARE_ATTRIBUTE_ARRAY_TYPE( Vector2D, AT_VECTOR2_ARRAY, "vector2_array" )
|
||||
DECLARE_ATTRIBUTE_ARRAY_TYPE( Vector, AT_VECTOR3_ARRAY, "vector3_array" )
|
||||
DECLARE_ATTRIBUTE_ARRAY_TYPE( Vector4D, AT_VECTOR4_ARRAY, "vector4_array" )
|
||||
DECLARE_ATTRIBUTE_ARRAY_TYPE( QAngle, AT_QANGLE_ARRAY, "qangle_array" )
|
||||
DECLARE_ATTRIBUTE_ARRAY_TYPE( Quaternion, AT_QUATERNION_ARRAY, "quaternion_array" )
|
||||
DECLARE_ATTRIBUTE_ARRAY_TYPE( VMatrix, AT_VMATRIX_ARRAY, "matrix_array" )
|
||||
DECLARE_ATTRIBUTE_ARRAY_TYPE( CUtlString, AT_STRING_ARRAY, "string_array" )
|
||||
DECLARE_ATTRIBUTE_ARRAY_TYPE( CUtlBinaryBlock, AT_VOID_ARRAY, "binary_array" )
|
||||
DECLARE_ATTRIBUTE_ARRAY_TYPE( DmObjectId_t, AT_OBJECTID_ARRAY, "elementid_array" )
|
||||
DECLARE_ATTRIBUTE_ARRAY_TYPE_INTERNAL( DmElementHandle_t, DmElementArray_t, AT_ELEMENT_ARRAY, "element_array" )
|
||||
|
||||
|
||||
#endif // DMATTRIBUTETYPES_H
|
1481
public/datamodel/dmattributevar.h
Normal file
1481
public/datamodel/dmattributevar.h
Normal file
File diff suppressed because it is too large
Load Diff
243
public/datamodel/dmehandle.h
Normal file
243
public/datamodel/dmehandle.h
Normal file
@ -0,0 +1,243 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// The copyright to the contents herein is the property of Valve, L.L.C.
|
||||
// The contents may be used and/or copied only with the written permission of
|
||||
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
|
||||
// the agreement/contract under which the contents have been supplied.
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef DMEHANDLE_H
|
||||
#define DMEHANDLE_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "datamodel/idatamodel.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "datamodel/dmattribute.h"
|
||||
#include "datamodel/dmattributevar.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: CDmeHandle is a templatized wrapper around DmElementHandle_t
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class DmeType, bool Counted = false >
|
||||
class CDmeHandle : public CDmeElementRefHelper
|
||||
{
|
||||
public:
|
||||
CDmeHandle() : m_handle( DMELEMENT_HANDLE_INVALID )
|
||||
{
|
||||
}
|
||||
|
||||
explicit CDmeHandle( CDmElement *pObject ) : m_handle( DMELEMENT_HANDLE_INVALID )
|
||||
{
|
||||
Set( pObject );
|
||||
}
|
||||
|
||||
CDmeHandle( DmElementHandle_t h ) : m_handle( DMELEMENT_HANDLE_INVALID )
|
||||
{
|
||||
Set( h );
|
||||
}
|
||||
|
||||
CDmeHandle( const CDmeHandle< DmeType, Counted > &handle ) : m_handle( DMELEMENT_HANDLE_INVALID )
|
||||
{
|
||||
Set( handle.m_handle );
|
||||
}
|
||||
|
||||
template < class T, bool B >
|
||||
CDmeHandle( const CDmeHandle< T, B > &handle ) : m_handle( DMELEMENT_HANDLE_INVALID )
|
||||
{
|
||||
DmeType *p = ( T* )NULL; // triggers compiler error if converting from invalid handle type
|
||||
NOTE_UNUSED( p );
|
||||
|
||||
Set( handle.GetHandle() );
|
||||
}
|
||||
|
||||
~CDmeHandle()
|
||||
{
|
||||
if ( !g_pDataModel )
|
||||
return; // some handles are static, and don't get destroyed until program termination
|
||||
|
||||
Unref( m_handle, Counted );
|
||||
}
|
||||
|
||||
template < class T, bool B >
|
||||
CDmeHandle& operator=( const CDmeHandle< T, B > &handle )
|
||||
{
|
||||
DmeType *p = ( T* )NULL; // triggers compiler error if converting from invalid handle type
|
||||
NOTE_UNUSED( p );
|
||||
|
||||
Set( handle.GetHandle() );
|
||||
return *this;
|
||||
}
|
||||
|
||||
DmeType *Get()
|
||||
{
|
||||
return static_cast< DmeType* >( g_pDataModel->GetElement( m_handle ) );
|
||||
}
|
||||
|
||||
const DmeType *Get() const
|
||||
{
|
||||
return static_cast< DmeType* >( g_pDataModel->GetElement( m_handle ) );
|
||||
}
|
||||
|
||||
DmElementHandle_t GetHandle() const
|
||||
{
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
void Set( CDmElement *pObject )
|
||||
{
|
||||
Set( pObject ? pObject->GetHandle() : DMELEMENT_HANDLE_INVALID );
|
||||
}
|
||||
|
||||
void Set( DmElementHandle_t h )
|
||||
{
|
||||
if ( h == m_handle )
|
||||
return;
|
||||
|
||||
Unref( m_handle, Counted );
|
||||
|
||||
m_handle = h;
|
||||
if ( h != DMELEMENT_HANDLE_INVALID )
|
||||
{
|
||||
CDmElement *pElement = g_pDataModel->GetElement( m_handle );
|
||||
Assert( pElement );
|
||||
if ( pElement && !pElement->IsA( DmeType::GetStaticTypeSymbol() ) )
|
||||
{
|
||||
m_handle = DMELEMENT_HANDLE_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
Ref( m_handle, Counted );
|
||||
}
|
||||
|
||||
operator DmeType*()
|
||||
{
|
||||
return Get();
|
||||
}
|
||||
|
||||
operator const DmeType*() const
|
||||
{
|
||||
return Get();
|
||||
}
|
||||
|
||||
operator DmElementHandle_t() const
|
||||
{
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
DmeType* operator->()
|
||||
{
|
||||
return Get();
|
||||
}
|
||||
|
||||
const DmeType* operator->() const
|
||||
{
|
||||
return Get();
|
||||
}
|
||||
|
||||
CDmeHandle& operator=( DmElementHandle_t h )
|
||||
{
|
||||
Set( h );
|
||||
return *this;
|
||||
}
|
||||
|
||||
CDmeHandle& operator=( CDmElement *pObject )
|
||||
{
|
||||
Set( pObject );
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==( const CDmeHandle< DmeType > &h ) const
|
||||
{
|
||||
return m_handle == h.m_handle;
|
||||
}
|
||||
|
||||
bool operator!=( const CDmeHandle< DmeType > &h ) const
|
||||
{
|
||||
return !operator==( h );
|
||||
}
|
||||
|
||||
bool operator<( const CDmeHandle< DmeType > &h ) const
|
||||
{
|
||||
return m_handle < h.m_handle;
|
||||
}
|
||||
|
||||
bool operator==( DmeType *pObject ) const
|
||||
{
|
||||
DmElementHandle_t h = pObject ? pObject->GetHandle() : DMELEMENT_HANDLE_INVALID;
|
||||
return m_handle == h;
|
||||
}
|
||||
|
||||
bool operator!=( DmeType *pObject ) const
|
||||
{
|
||||
return !operator==( pObject );
|
||||
}
|
||||
|
||||
bool operator==( DmElementHandle_t h ) const
|
||||
{
|
||||
return ( m_handle == h );
|
||||
}
|
||||
|
||||
bool operator!=( DmElementHandle_t h ) const
|
||||
{
|
||||
return ( m_handle != h );
|
||||
}
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return ( Get() != NULL );
|
||||
}
|
||||
|
||||
bool operator!() const
|
||||
{
|
||||
return ( Get() == NULL );
|
||||
}
|
||||
|
||||
private:
|
||||
DmElementHandle_t m_handle;
|
||||
};
|
||||
|
||||
typedef CDmeHandle< CDmElement, true > CDmeCountedHandle;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Vector of element handles
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef CUtlVector< CDmeHandle<CDmElement> > DmeHandleVec_t;
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// helper class for undo classes to allow them to hold onto refcounted element handles
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template< typename T >
|
||||
class CDmAttributeUndoStorageType
|
||||
{
|
||||
public:
|
||||
typedef T UndoStorageType;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CDmAttributeUndoStorageType< DmElementHandle_t >
|
||||
{
|
||||
public:
|
||||
typedef CDmeCountedHandle UndoStorageType;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CDmAttributeUndoStorageType< CUtlVector< DmElementHandle_t > >
|
||||
{
|
||||
public:
|
||||
typedef CUtlVector< CDmeCountedHandle > UndoStorageType;
|
||||
};
|
||||
|
||||
#endif // DMEHANDLE_H
|
618
public/datamodel/dmelement.h
Normal file
618
public/datamodel/dmelement.h
Normal file
@ -0,0 +1,618 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef DMELEMENT_H
|
||||
#define DMELEMENT_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier1/utlmap.h"
|
||||
#include "tier1/utlhash.h"
|
||||
#include "tier1/utlvector.h"
|
||||
#include "tier1/utlsymbol.h"
|
||||
#include "datamodel/attributeflags.h"
|
||||
#include "datamodel/idatamodel.h"
|
||||
#include "datamodel/dmvar.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef bool (CDmElement::*pfnCommandMethod)( const char *command, const char *args );
|
||||
|
||||
// element/element array traversal path item - assumes the full path does NOT contain cycles
|
||||
struct ElementPathItem_t
|
||||
{
|
||||
ElementPathItem_t( DmElementHandle_t hElem = DMELEMENT_HANDLE_INVALID,
|
||||
DmAttributeHandle_t hAttr = DMATTRIBUTE_HANDLE_INVALID,
|
||||
int idx = -1 )
|
||||
: hElement( hElem ), hAttribute( hAttr ), nIndex( idx )
|
||||
{
|
||||
}
|
||||
|
||||
// only uses hElement so that it can be used to search for elements
|
||||
bool operator==( const ElementPathItem_t &that ) const
|
||||
{
|
||||
return hElement == that.hElement;
|
||||
}
|
||||
|
||||
DmElementHandle_t hElement;
|
||||
DmAttributeHandle_t hAttribute;
|
||||
int nIndex;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// singly-linked attribute list
|
||||
//-----------------------------------------------------------------------------
|
||||
struct DmAttributeList_t
|
||||
{
|
||||
DmAttributeList_t() : m_hAttribute( DMATTRIBUTE_HANDLE_INVALID ), m_pNext( NULL ) {}
|
||||
DmAttributeHandle_t m_hAttribute;
|
||||
DmAttributeList_t *m_pNext;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// helper class to allow CDmeHandle access to g_pDataModelImp
|
||||
//-----------------------------------------------------------------------------
|
||||
class CDmeElementRefHelper
|
||||
{
|
||||
protected:
|
||||
void Ref ( DmElementHandle_t hElement, bool bStrong );
|
||||
void Unref( DmElementHandle_t hElement, bool bStrong );
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// element reference struct - containing attribute referrers and handle refcount
|
||||
//-----------------------------------------------------------------------------
|
||||
struct DmElementReference_t
|
||||
{
|
||||
explicit DmElementReference_t( DmElementHandle_t hElement = DMELEMENT_HANDLE_INVALID ) :
|
||||
m_hElement( hElement ), m_nWeakHandleCount( 0 ), m_nStrongHandleCount( 0 )
|
||||
{
|
||||
}
|
||||
DmElementReference_t( const DmElementReference_t &that ) :
|
||||
m_hElement( that.m_hElement ), m_nWeakHandleCount( that.m_nWeakHandleCount ),
|
||||
m_nStrongHandleCount( that.m_nStrongHandleCount ), m_attributes( that.m_attributes )
|
||||
{
|
||||
}
|
||||
DmElementReference_t &operator=( const DmElementReference_t &that )
|
||||
{
|
||||
m_hElement = that.m_hElement;
|
||||
m_nWeakHandleCount = that.m_nWeakHandleCount;
|
||||
m_nStrongHandleCount = that.m_nStrongHandleCount;
|
||||
m_attributes.m_hAttribute = that.m_attributes.m_hAttribute;
|
||||
m_attributes.m_pNext = that.m_attributes.m_pNext;
|
||||
return *this;
|
||||
}
|
||||
~DmElementReference_t()
|
||||
{
|
||||
// Assert( !IsStronglyReferenced() );
|
||||
}
|
||||
|
||||
void AddAttribute( CDmAttribute *pAttribute );
|
||||
void RemoveAttribute( CDmAttribute *pAttribute );
|
||||
|
||||
bool IsStronglyReferenced() // should this element be kept around (even if it's DmElementHandle_t is invalidated)
|
||||
{
|
||||
return m_attributes.m_hAttribute != DMATTRIBUTE_HANDLE_INVALID || m_nStrongHandleCount > 0;
|
||||
}
|
||||
|
||||
bool IsWeaklyReferenced() // should we keep this element's DmElementHandle_t mapped to it's id (even if the element is deleted)
|
||||
{
|
||||
return IsStronglyReferenced() || m_nWeakHandleCount > 0;
|
||||
}
|
||||
|
||||
int EstimateMemoryOverhead()
|
||||
{
|
||||
int nBytes = 0;
|
||||
for ( DmAttributeList_t *pLink = m_attributes.m_pNext; pLink; pLink = pLink->m_pNext )
|
||||
{
|
||||
nBytes += sizeof( DmAttributeList_t );
|
||||
}
|
||||
return nBytes;
|
||||
}
|
||||
|
||||
DmElementHandle_t m_hElement;
|
||||
unsigned short m_nWeakHandleCount; // CDmeHandle<T> - for auto-hookup once the element comes back, mainly used by UI
|
||||
unsigned short m_nStrongHandleCount; // CDmeCountedElementRef - for preventing elements from being truly deleted, mainly used by undo and file root
|
||||
DmAttributeList_t m_attributes;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Base DmElement we inherit from in higher-level classes
|
||||
//-----------------------------------------------------------------------------
|
||||
class CDmElement
|
||||
{
|
||||
public:
|
||||
// Can be overridden by derived classes
|
||||
virtual void OnAttributeChanged( CDmAttribute *pAttribute ) {}
|
||||
virtual void PreAttributeChanged( CDmAttribute *pAttribute ) {}
|
||||
virtual void OnAttributeArrayElementAdded( CDmAttribute *pAttribute, int nFirstElem, int nLastElem ) {}
|
||||
virtual void OnAttributeArrayElementRemoved( CDmAttribute *pAttribute, int nFirstElem, int nLastElem ) {}
|
||||
virtual void Resolve() {}
|
||||
virtual bool IsA( UtlSymId_t typeSymbol ) const;
|
||||
virtual int GetInheritanceDepth( UtlSymId_t typeSymbol ) const;
|
||||
virtual void OnElementUnserialized() {}
|
||||
virtual int AllocatedSize() const { return sizeof( CDmElement ); }
|
||||
|
||||
// Returns the element handle
|
||||
DmElementHandle_t GetHandle() const;
|
||||
|
||||
// Attribute iteration, finding
|
||||
// NOTE: Passing a type into GetAttribute will return NULL if the attribute exists but isn't that type
|
||||
bool HasAttribute( const char *pAttributeName, DmAttributeType_t type = AT_UNKNOWN ) const;
|
||||
CDmAttribute *GetAttribute( const char *pAttributeName, DmAttributeType_t type = AT_UNKNOWN );
|
||||
const CDmAttribute *GetAttribute( const char *pAttributeName, DmAttributeType_t type = AT_UNKNOWN ) const;
|
||||
int AttributeCount() const;
|
||||
CDmAttribute* FirstAttribute();
|
||||
const CDmAttribute* FirstAttribute() const;
|
||||
|
||||
// Element name, type, ID
|
||||
// WARNING: SetType() should only be used by format conversion methods (dmxconvert)
|
||||
UtlSymId_t GetType() const;
|
||||
const char * GetTypeString() const;
|
||||
const char * GetName() const;
|
||||
const DmObjectId_t& GetId() const;
|
||||
void SetType( const char *pType );
|
||||
void SetName( const char* pName );
|
||||
|
||||
// Attribute management
|
||||
CDmAttribute * AddAttribute( const char *pAttributeName, DmAttributeType_t type );
|
||||
template< class E > CDmAttribute* AddAttributeElement( const char *pAttributeName );
|
||||
template< class E > CDmAttribute* AddAttributeElementArray( const char *pAttributeName );
|
||||
void RemoveAttribute( const char *pAttributeName );
|
||||
void RemoveAttributeByPtr( CDmAttribute *pAttributeName );
|
||||
void RenameAttribute( const char *pAttributeName, const char *pNewName );
|
||||
|
||||
// get attribute value
|
||||
template< class T > const T& GetValue( const char *pAttributeName ) const;
|
||||
template< class T > const T& GetValue( const char *pAttributeName, const T& defaultValue ) const;
|
||||
const char * GetValueString( const char *pAttributeName ) const;
|
||||
template< class E > E* GetValueElement( const char *pAttributeName ) const;
|
||||
|
||||
// set attribute value
|
||||
CDmAttribute* SetValue( const char *pAttributeName, const void *value, size_t size );
|
||||
template< class T > CDmAttribute* SetValue( const char *pAttributeName, const T& value );
|
||||
template< class E > CDmAttribute* SetValue( const char *pAttributeName, E* value );
|
||||
|
||||
// set attribute value if the attribute doesn't already exist
|
||||
CDmAttribute* InitValue( const char *pAttributeName, const void *value, size_t size );
|
||||
template< class T > CDmAttribute* InitValue( const char *pAttributeName, const T& value );
|
||||
template< class E > CDmAttribute* InitValue( const char *pAttributeName, E* value );
|
||||
|
||||
// Parses an attribute from a string
|
||||
// Doesn't create an attribute if it doesn't exist and always preserves attribute type
|
||||
void SetValueFromString( const char *pAttributeName, const char *value );
|
||||
const char *GetValueAsString( const char *pAttributeName, char *pBuffer, size_t buflen ) const;
|
||||
|
||||
// Helpers for our RTTI
|
||||
template< class E > bool IsA() const;
|
||||
bool IsA( const char *pTypeName ) const;
|
||||
int GetInheritanceDepth( const char *pTypeName ) const;
|
||||
static CUtlSymbol GetStaticTypeSymbol();
|
||||
|
||||
// Indicates whether this element should be copied or not
|
||||
void SetShared( bool bShared );
|
||||
bool IsShared() const;
|
||||
|
||||
// Copies an element and all its attributes
|
||||
CDmElement* Copy( TraversalDepth_t depth = TD_DEEP ) const;
|
||||
|
||||
// Copies attributes from a specified element
|
||||
void CopyAttributesTo( CDmElement *pCopy, TraversalDepth_t depth = TD_DEEP ) const;
|
||||
|
||||
// recursively set fileid's, with option to only change elements in the matched file
|
||||
void SetFileId( DmFileId_t fileid, TraversalDepth_t depth, bool bOnlyIfMatch = false );
|
||||
DmFileId_t GetFileId() const;
|
||||
|
||||
bool IsAccessible() const;
|
||||
void MarkAccessible( bool bAccessible );
|
||||
void MarkAccessible( TraversalDepth_t depth = TD_ALL );
|
||||
|
||||
// returns the first path to the element found traversing all element/element
|
||||
// array attributes - not necessarily the shortest.
|
||||
// cycle-safe (skips any references to elements in the current path)
|
||||
// but may re-traverse elements via different paths
|
||||
bool FindElement( const CDmElement *pElement, CUtlVector< ElementPathItem_t > &elementPath, TraversalDepth_t depth ) const;
|
||||
bool FindReferer( DmElementHandle_t hElement, CUtlVector< ElementPathItem_t > &elementPath, TraversalDepth_t depth ) const;
|
||||
void RemoveAllReferencesToElement( CDmElement *pElement );
|
||||
bool IsStronglyReferenced() { return m_ref.IsStronglyReferenced(); }
|
||||
|
||||
// Estimates the memory usage of the element, its attributes, and child elements
|
||||
int EstimateMemoryUsage( TraversalDepth_t depth = TD_DEEP );
|
||||
|
||||
protected:
|
||||
// NOTE: These are protected to ensure that the factory is the only thing that can create these
|
||||
CDmElement( DmElementHandle_t handle, const char *objectType, const DmObjectId_t &id, const char *objectName, DmFileId_t fileid );
|
||||
virtual ~CDmElement();
|
||||
|
||||
// Used by derived classes to do construction and setting up CDmaVars
|
||||
void OnConstruction() { }
|
||||
void OnDestruction() { }
|
||||
virtual void PerformConstruction();
|
||||
virtual void PerformDestruction();
|
||||
|
||||
// Internal methods related to RTII
|
||||
static void SetTypeSymbol( CUtlSymbol sym );
|
||||
static bool IsA_Implementation( CUtlSymbol typeSymbol );
|
||||
static int GetInheritanceDepth_Implementation( CUtlSymbol typeSymbol, int nCurrentDepth );
|
||||
|
||||
// Internal method for creating a copy of this element
|
||||
CDmElement* CopyInternal( TraversalDepth_t depth = TD_DEEP ) const;
|
||||
|
||||
// helper for making attributevarelementarray cleanup easier
|
||||
template< class T > static void DeleteAttributeVarElementArray( T &array );
|
||||
|
||||
private:
|
||||
typedef CUtlMap< DmElementHandle_t, DmElementHandle_t, int > CRefMap;
|
||||
|
||||
// Bogus constructor
|
||||
CDmElement();
|
||||
|
||||
// internal recursive copy method - builds refmap of old element's handle -> copy's handle, and uses it to fixup references
|
||||
void CopyAttributesTo( CDmElement *pCopy, CRefMap &refmap, TraversalDepth_t depth ) const;
|
||||
void CopyElementAttribute( const CDmAttribute *pAttr, CDmAttribute *pCopyAttr, CRefMap &refmap, TraversalDepth_t depth ) const;
|
||||
void CopyElementArrayAttribute( const CDmAttribute *pAttr, CDmAttribute *pCopyAttr, CRefMap &refmap, TraversalDepth_t depth ) const;
|
||||
void FixupReferences( CUtlHashFast< DmElementHandle_t > &visited, const CRefMap &refmap, TraversalDepth_t depth );
|
||||
|
||||
void SetFileId( DmFileId_t fileid );
|
||||
void SetFileId_R( CUtlHashFast< DmElementHandle_t > &visited, DmFileId_t fileid, TraversalDepth_t depth, DmFileId_t match, bool bOnlyIfMatch );
|
||||
|
||||
CDmAttribute* CreateAttribute( const char *pAttributeName, DmAttributeType_t type );
|
||||
void RemoveAttribute( CDmAttribute **pAttrRef );
|
||||
CDmAttribute* AddExternalAttribute( const char *pAttributeName, DmAttributeType_t type, void *pMemory );
|
||||
CDmAttribute *FindAttribute( const char *pAttributeName ) const;
|
||||
|
||||
void Purge();
|
||||
void SetId( const DmObjectId_t &id );
|
||||
|
||||
bool IsDirty() const;
|
||||
void MarkDirty( bool dirty = true );
|
||||
void MarkAttributesClean();
|
||||
void MarkBeingUnserialized( bool beingUnserialized = true );
|
||||
bool IsBeingUnserialized() const;
|
||||
|
||||
// Used by the undo system only.
|
||||
void AddAttributeByPtr( CDmAttribute *ptr );
|
||||
void RemoveAttributeByPtrNoDelete( CDmAttribute *ptr );
|
||||
|
||||
// Should only be called from datamodel, who will take care of changing the fileset entry as well
|
||||
void ChangeHandle( DmElementHandle_t handle );
|
||||
|
||||
// returns element reference struct w/ list of referrers and handle count
|
||||
DmElementReference_t* GetReference();
|
||||
void SetReference( const DmElementReference_t &ref );
|
||||
|
||||
// Estimates memory usage
|
||||
int EstimateMemoryUsage( CUtlHash< DmElementHandle_t > &visited, TraversalDepth_t depth, int *pCategories );
|
||||
|
||||
protected:
|
||||
CDmaString m_Name;
|
||||
|
||||
private:
|
||||
CDmAttribute *m_pAttributes;
|
||||
DmElementReference_t m_ref;
|
||||
UtlSymId_t m_Type;
|
||||
bool m_bDirty : 1;
|
||||
bool m_bBeingUnserialized : 1;
|
||||
bool m_bIsAcessible : 1;
|
||||
unsigned char m_nReserved; // Makes Id be quad aligned
|
||||
DmObjectId_t m_Id;
|
||||
DmFileId_t m_fileId;
|
||||
|
||||
// Stores the type symbol
|
||||
static CUtlSymbol m_classType;
|
||||
|
||||
// Factories can access our constructors
|
||||
template <class T> friend class CDmElementFactory;
|
||||
template <class T> friend class CDmAbstractElementFactory;
|
||||
template< class T > friend class CDmaVar;
|
||||
template< class T > friend class CDmaArray;
|
||||
template< class T > friend class CDmaElementArray;
|
||||
template< class T, class B > friend class CDmaDecorator;
|
||||
template< class T > friend class CDmrElementArray;
|
||||
|
||||
friend class CDmElementFactoryDefault;
|
||||
friend class CDmeElementAccessor;
|
||||
friend class CDmeOperator;
|
||||
|
||||
friend void CopyElements( const CUtlVector< CDmElement* > &from, CUtlVector< CDmElement* > &to, TraversalDepth_t depth );
|
||||
};
|
||||
|
||||
|
||||
|
||||
inline void DestroyElement( CDmElement *pElement )
|
||||
{
|
||||
if ( pElement )
|
||||
{
|
||||
g_pDataModel->DestroyElement( pElement->GetHandle() );
|
||||
}
|
||||
}
|
||||
|
||||
void DestroyElement( CDmElement *pElement, TraversalDepth_t depth );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// copy groups of elements together so that references between them are maintained
|
||||
//-----------------------------------------------------------------------------
|
||||
void CopyElements( const CUtlVector< CDmElement* > &from, CUtlVector< CDmElement* > &to, TraversalDepth_t depth = TD_DEEP );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// allows elements to chain OnAttributeChanged up to their parents (or at least, referrers)
|
||||
//-----------------------------------------------------------------------------
|
||||
void InvokeOnAttributeChangedOnReferrers( DmElementHandle_t hElement, CDmAttribute *pChangedAttr );
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the type, name, id, fileId
|
||||
//-----------------------------------------------------------------------------
|
||||
inline UtlSymId_t CDmElement::GetType() const
|
||||
{
|
||||
return m_Type;
|
||||
}
|
||||
|
||||
inline const char *CDmElement::GetTypeString() const
|
||||
{
|
||||
return g_pDataModel->GetString( m_Type );
|
||||
}
|
||||
|
||||
inline const char *CDmElement::GetName() const
|
||||
{
|
||||
return m_Name.Get();
|
||||
}
|
||||
|
||||
inline void CDmElement::SetName( const char* pName )
|
||||
{
|
||||
m_Name.Set( pName );
|
||||
}
|
||||
|
||||
inline const DmObjectId_t& CDmElement::GetId() const
|
||||
{
|
||||
return m_Id;
|
||||
}
|
||||
|
||||
inline DmFileId_t CDmElement::GetFileId() const
|
||||
{
|
||||
return m_fileId;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Controls whether the element should be copied by default
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void CDmElement::SetShared( bool bShared )
|
||||
{
|
||||
if ( bShared )
|
||||
{
|
||||
SetValue< bool >( "shared", true );
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveAttribute( "shared" );
|
||||
}
|
||||
}
|
||||
|
||||
inline bool CDmElement::IsShared() const
|
||||
{
|
||||
return GetValue< bool >( "shared" ); // if attribute doesn't exist, returns default bool value, which is false
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copies attributes from a specified element
|
||||
//-----------------------------------------------------------------------------
|
||||
inline CDmElement* CDmElement::Copy( TraversalDepth_t depth ) const
|
||||
{
|
||||
return CopyInternal( depth );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RTTI
|
||||
//-----------------------------------------------------------------------------
|
||||
inline bool CDmElement::IsA_Implementation( CUtlSymbol typeSymbol )
|
||||
{
|
||||
return ( m_classType == typeSymbol ) || ( UTL_INVAL_SYMBOL == typeSymbol );
|
||||
}
|
||||
|
||||
inline int CDmElement::GetInheritanceDepth_Implementation( CUtlSymbol typeSymbol, int nCurrentDepth )
|
||||
{
|
||||
return IsA_Implementation( typeSymbol ) ? nCurrentDepth : -1;
|
||||
}
|
||||
|
||||
inline CUtlSymbol CDmElement::GetStaticTypeSymbol()
|
||||
{
|
||||
return m_classType;
|
||||
}
|
||||
|
||||
inline bool CDmElement::IsA( const char *pTypeName ) const
|
||||
{
|
||||
CUtlSymbol typeSymbol = g_pDataModel->GetSymbol( pTypeName );
|
||||
return IsA( typeSymbol );
|
||||
}
|
||||
|
||||
template< class E > inline bool CDmElement::IsA() const
|
||||
{
|
||||
return IsA( E::GetStaticTypeSymbol() );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper for finding elements that refer to this element
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T >
|
||||
T *FindReferringElement( CDmElement *pElement, const char *pAttrName, bool bMustBeInSameFile = true )
|
||||
{
|
||||
return FindReferringElement< T >( pElement, g_pDataModel->GetSymbol( pAttrName ), bMustBeInSameFile );
|
||||
}
|
||||
|
||||
|
||||
void RemoveElementFromRefereringAttributes( CDmElement *pElement, bool bPreserveOrder = true );
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// element-specific unique name generation methods
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// returns startindex if none found, 2 if only "prefix" found, and n+1 if "prefixn" found
|
||||
int GenerateUniqueNameIndex( const char *prefix, const CUtlVector< DmElementHandle_t > &array, int startindex = -1 );
|
||||
|
||||
bool GenerateUniqueName( char *name, int memsize, const char *prefix, const CUtlVector< DmElementHandle_t > &array );
|
||||
|
||||
void MakeElementNameUnique( CDmElement *pElement, const char *prefix, const CUtlVector< DmElementHandle_t > &array, bool forceIndex = false );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// helper for making attributevarelementarray cleanup easier
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T >
|
||||
inline void CDmElement::DeleteAttributeVarElementArray( T &array )
|
||||
{
|
||||
int nElements = array.Count();
|
||||
for ( int i = 0; i < nElements; ++i )
|
||||
{
|
||||
g_pDataModel->DestroyElement( array.GetHandle( i ) );
|
||||
}
|
||||
array.RemoveAll();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Default size computation
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T >
|
||||
int DmeEstimateMemorySize( T* pElement )
|
||||
{
|
||||
return sizeof( T );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper macro to create an element; this is used for elements that are helper base classes
|
||||
//-----------------------------------------------------------------------------
|
||||
#define DEFINE_UNINSTANCEABLE_ELEMENT( className, baseClassName ) \
|
||||
protected: \
|
||||
className( DmElementHandle_t handle, const char *pElementTypeName, const DmObjectId_t &id, const char *pElementName, DmFileId_t fileid ) : \
|
||||
baseClassName( handle, pElementTypeName, id, pElementName, fileid ) \
|
||||
{ \
|
||||
} \
|
||||
virtual ~className() \
|
||||
{ \
|
||||
} \
|
||||
void OnConstruction(); \
|
||||
void OnDestruction(); \
|
||||
virtual void PerformConstruction() \
|
||||
{ \
|
||||
BaseClass::PerformConstruction(); \
|
||||
OnConstruction(); \
|
||||
} \
|
||||
virtual void PerformDestruction() \
|
||||
{ \
|
||||
OnDestruction(); \
|
||||
BaseClass::PerformDestruction(); \
|
||||
} \
|
||||
virtual int AllocatedSize() const { return DmeEstimateMemorySize( this ); } \
|
||||
\
|
||||
private: \
|
||||
typedef baseClassName BaseClass; \
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper macro to create the class factory
|
||||
//-----------------------------------------------------------------------------
|
||||
#define DEFINE_ELEMENT( className, baseClassName ) \
|
||||
public: \
|
||||
virtual bool IsA( UtlSymId_t typeSymbol ) const \
|
||||
{ \
|
||||
return IsA_Implementation( typeSymbol );\
|
||||
} \
|
||||
\
|
||||
bool IsA( const char *pTypeName ) const \
|
||||
{ \
|
||||
CUtlSymbol typeSymbol = g_pDataModel->GetSymbol( pTypeName ); \
|
||||
return IsA( typeSymbol ); \
|
||||
} \
|
||||
\
|
||||
template< class T > bool IsA() const \
|
||||
{ \
|
||||
return IsA( T::GetStaticTypeSymbol() ); \
|
||||
} \
|
||||
\
|
||||
virtual int GetInheritanceDepth( UtlSymId_t typeSymbol ) const \
|
||||
{ \
|
||||
return GetInheritanceDepth_Implementation( typeSymbol, 0 ); \
|
||||
} \
|
||||
\
|
||||
static CUtlSymbol GetStaticTypeSymbol( ) \
|
||||
{ \
|
||||
return m_classType; \
|
||||
} \
|
||||
\
|
||||
className* Copy( TraversalDepth_t depth = TD_DEEP ) const \
|
||||
{ \
|
||||
return static_cast< className* >( CopyInternal( depth ) ); \
|
||||
} \
|
||||
protected: \
|
||||
className( DmElementHandle_t handle, const char *pElementTypeName, const DmObjectId_t &id, const char *pElementName, DmFileId_t fileid ) : \
|
||||
baseClassName( handle, pElementTypeName, id, pElementName, fileid ) \
|
||||
{ \
|
||||
} \
|
||||
virtual ~className() \
|
||||
{ \
|
||||
} \
|
||||
void OnConstruction(); \
|
||||
void OnDestruction(); \
|
||||
virtual void PerformConstruction() \
|
||||
{ \
|
||||
BaseClass::PerformConstruction(); \
|
||||
OnConstruction(); \
|
||||
} \
|
||||
virtual void PerformDestruction() \
|
||||
{ \
|
||||
OnDestruction(); \
|
||||
BaseClass::PerformDestruction(); \
|
||||
} \
|
||||
static void SetTypeSymbol( CUtlSymbol typeSymbol ) \
|
||||
{ \
|
||||
m_classType = typeSymbol; \
|
||||
} \
|
||||
\
|
||||
static bool IsA_Implementation( CUtlSymbol typeSymbol ) \
|
||||
{ \
|
||||
if ( typeSymbol == m_classType ) \
|
||||
return true; \
|
||||
return BaseClass::IsA_Implementation( typeSymbol ); \
|
||||
} \
|
||||
\
|
||||
static int GetInheritanceDepth_Implementation( CUtlSymbol typeSymbol, int nCurrentDepth ) \
|
||||
{ \
|
||||
if ( typeSymbol == m_classType ) \
|
||||
return nCurrentDepth; \
|
||||
return BaseClass::GetInheritanceDepth_Implementation( typeSymbol, nCurrentDepth+1 );\
|
||||
} \
|
||||
virtual int AllocatedSize() const { return DmeEstimateMemorySize( this ); } \
|
||||
\
|
||||
private: \
|
||||
typedef baseClassName BaseClass; \
|
||||
template <class T> friend class CDmElementFactory; \
|
||||
template <class T> friend class CDmAbstractElementFactory; \
|
||||
static CUtlSymbol m_classType
|
||||
|
||||
#define IMPLEMENT_ELEMENT( className ) \
|
||||
CUtlSymbol className::m_classType = UTL_INVAL_SYMBOL;
|
||||
|
||||
|
||||
#endif // DMELEMENT_H
|
190
public/datamodel/dmelementfactoryhelper.h
Normal file
190
public/datamodel/dmelementfactoryhelper.h
Normal file
@ -0,0 +1,190 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef DMELEMENTFACTORYHELPER_H
|
||||
#define DMELEMENTFACTORYHELPER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "datamodel/idatamodel.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "datamodel/dmattribute.h"
|
||||
#include "datamodel/dmattributevar.h"
|
||||
#include "tier1/utlvector.h"
|
||||
#include "tier1/utlsymbol.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Internal interface for IDmElementFactory
|
||||
//-----------------------------------------------------------------------------
|
||||
class IDmElementFactoryInternal : public IDmElementFactory
|
||||
{
|
||||
public:
|
||||
virtual void SetElementTypeSymbol( CUtlSymbol sym ) = 0;
|
||||
virtual bool IsAbstract() const = 0;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Class used to register factories into a global list
|
||||
//-----------------------------------------------------------------------------
|
||||
class CDmElementFactoryHelper
|
||||
{
|
||||
public:
|
||||
// Static list of helpers
|
||||
static CDmElementFactoryHelper *s_pHelpers[2];
|
||||
|
||||
// Create all the hud elements
|
||||
static void InstallFactories( );
|
||||
|
||||
public:
|
||||
// Construction
|
||||
CDmElementFactoryHelper( const char *pClassName, IDmElementFactoryInternal *pFactory, bool bIsStandardFactory );
|
||||
|
||||
// Accessors
|
||||
CDmElementFactoryHelper *GetNext( void );
|
||||
|
||||
const char *GetClassname();
|
||||
IDmElementFactoryInternal *GetFactory();
|
||||
|
||||
private:
|
||||
// Next factory in list
|
||||
CDmElementFactoryHelper *m_pNext;
|
||||
// Creation function to use for this technology
|
||||
IDmElementFactoryInternal *m_pFactory;
|
||||
const char *m_pszClassname;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Inline methods
|
||||
//-----------------------------------------------------------------------------
|
||||
inline const char *CDmElementFactoryHelper::GetClassname()
|
||||
{
|
||||
return m_pszClassname;
|
||||
}
|
||||
|
||||
inline IDmElementFactoryInternal *CDmElementFactoryHelper::GetFactory()
|
||||
{
|
||||
return m_pFactory;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper Template factory for simple creation of factories
|
||||
//-----------------------------------------------------------------------------
|
||||
template <class T >
|
||||
class CDmElementFactory : public IDmElementFactoryInternal
|
||||
{
|
||||
public:
|
||||
CDmElementFactory( const char *pLookupName ) : m_pLookupName( pLookupName ) {}
|
||||
|
||||
// Creation, destruction
|
||||
virtual CDmElement* Create( DmElementHandle_t handle, const char *pElementType, const char *pElementName, DmFileId_t fileid, const DmObjectId_t &id )
|
||||
{
|
||||
return new T( handle, m_pLookupName, id, pElementName, fileid );
|
||||
}
|
||||
|
||||
virtual void Destroy( DmElementHandle_t hElement )
|
||||
{
|
||||
CDmElement *pElement = g_pDataModel->GetElement( hElement );
|
||||
if ( pElement )
|
||||
{
|
||||
T *pActualElement = static_cast< T* >( pElement );
|
||||
delete pActualElement;
|
||||
}
|
||||
}
|
||||
|
||||
// Sets the type symbol, used for "isa" implementation
|
||||
virtual void SetElementTypeSymbol( CUtlSymbol sym )
|
||||
{
|
||||
T::SetTypeSymbol( sym );
|
||||
}
|
||||
|
||||
virtual bool IsAbstract() const { return false; }
|
||||
|
||||
private:
|
||||
const char *m_pLookupName;
|
||||
};
|
||||
|
||||
|
||||
template < class T >
|
||||
class CDmAbstractElementFactory : public IDmElementFactoryInternal
|
||||
{
|
||||
public:
|
||||
CDmAbstractElementFactory() {}
|
||||
|
||||
// Creation, destruction
|
||||
virtual CDmElement* Create( DmElementHandle_t handle, const char *pElementType, const char *pElementName, DmFileId_t fileid, const DmObjectId_t &id )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
virtual void Destroy( DmElementHandle_t hElement )
|
||||
{
|
||||
}
|
||||
|
||||
// Sets the type symbol, used for "isa" implementation
|
||||
virtual void SetElementTypeSymbol( CUtlSymbol sym )
|
||||
{
|
||||
T::SetTypeSymbol( sym );
|
||||
}
|
||||
|
||||
virtual bool IsAbstract() const { return true; }
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper macro to create the class factory
|
||||
//-----------------------------------------------------------------------------
|
||||
#if defined( MOVIEOBJECTS_LIB ) || defined ( DATAMODEL_LIB ) || defined ( DMECONTROLS_LIB )
|
||||
|
||||
#define IMPLEMENT_ELEMENT_FACTORY( lookupName, className ) \
|
||||
IMPLEMENT_ELEMENT( className ) \
|
||||
CDmElementFactory< className > g_##className##_Factory( #lookupName ); \
|
||||
CDmElementFactoryHelper g_##className##_Helper( #lookupName, &g_##className##_Factory, true ); \
|
||||
className *g_##className##LinkerHack = NULL;
|
||||
|
||||
#define IMPLEMENT_ABSTRACT_ELEMENT( lookupName, className ) \
|
||||
IMPLEMENT_ELEMENT( className ) \
|
||||
CDmAbstractElementFactory< className > g_##className##_Factory; \
|
||||
CDmElementFactoryHelper g_##className##_Helper( #lookupName, &g_##className##_Factory, true ); \
|
||||
className *g_##className##LinkerHack = NULL;
|
||||
|
||||
#else
|
||||
|
||||
#define IMPLEMENT_ELEMENT_FACTORY( lookupName, className ) \
|
||||
IMPLEMENT_ELEMENT( className ) \
|
||||
CDmElementFactory< className > g_##className##_Factory( #lookupName ); \
|
||||
CDmElementFactoryHelper g_##className##_Helper( #lookupName, &g_##className##_Factory, false ); \
|
||||
className *g_##className##LinkerHack = NULL;
|
||||
|
||||
#define IMPLEMENT_ABSTRACT_ELEMENT( lookupName, className ) \
|
||||
IMPLEMENT_ELEMENT( className ) \
|
||||
CDmAbstractElementFactory< className > g_##className##_Factory; \
|
||||
CDmElementFactoryHelper g_##className##_Helper( #lookupName, &g_##className##_Factory, false ); \
|
||||
className *g_##className##LinkerHack = NULL;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// Used by classes defined in movieobjects or scenedatabase that must be explicitly installed
|
||||
#define IMPLEMENT_ELEMENT_FACTORY_INSTALL_EXPLICITLY( lookupName, className ) \
|
||||
IMPLEMENT_ELEMENT( className ) \
|
||||
CDmElementFactory< className > g_##className##_Factory( #lookupName ); \
|
||||
CDmElementFactoryHelper g_##className##_Helper( #lookupName, &g_##className##_Factory, false ); \
|
||||
className *g_##className##LinkerHack = NULL;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Installs dm element factories
|
||||
//-----------------------------------------------------------------------------
|
||||
void InstallDmElementFactories( );
|
||||
|
||||
|
||||
#endif // DMELEMENTFACTORYHELPER_H
|
47
public/datamodel/dmelementhandle.h
Normal file
47
public/datamodel/dmelementhandle.h
Normal file
@ -0,0 +1,47 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef DMELEMENTHANDLE_H
|
||||
#define DMELEMENTHANDLE_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// handle to an CDmElement
|
||||
//-----------------------------------------------------------------------------
|
||||
#define PERFORM_HANDLE_TYPECHECKING 0
|
||||
#if PERFORM_HANDLE_TYPECHECKING
|
||||
|
||||
// this is here to make sure we're being type-safe about element handles
|
||||
// otherwise, the compiler lets us cast to bool incorrectly
|
||||
// the other solution would be to redefine DmElementHandle_t s.t. DMELEMENT_HANDLE_INVALID==0
|
||||
struct DmElementHandle_t
|
||||
{
|
||||
DmElementHandle_t() : handle( 0xffffffff ) {}
|
||||
explicit DmElementHandle_t( int h ) : handle( h ) {}
|
||||
inline bool operator==( const DmElementHandle_t &h ) const { return handle == h.handle; }
|
||||
inline bool operator!=( const DmElementHandle_t &h ) const { return handle != h.handle; }
|
||||
inline bool operator<( const DmElementHandle_t &h ) const { return handle < h.handle; }
|
||||
// inline operator int() const { return handle; } // if we're okay with implicit int casts, uncomment this method
|
||||
int handle;
|
||||
};
|
||||
const DmElementHandle_t DMELEMENT_HANDLE_INVALID;
|
||||
|
||||
#else // PERFORM_HANDLE_TYPECHECKING
|
||||
|
||||
enum DmElementHandle_t
|
||||
{
|
||||
DMELEMENT_HANDLE_INVALID = 0xffffffff
|
||||
};
|
||||
|
||||
#endif // PERFORM_HANDLE_TYPECHECKING
|
||||
|
||||
|
||||
|
||||
#endif // DMELEMENTHANDLE_H
|
93
public/datamodel/dmvar.h
Normal file
93
public/datamodel/dmvar.h
Normal file
@ -0,0 +1,93 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef DMVAR_H
|
||||
#define DMVAR_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
class CDmAttribute;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper template for external attributes
|
||||
//-----------------------------------------------------------------------------
|
||||
template< typename T >
|
||||
class CDmaVar
|
||||
{
|
||||
typedef typename CDmAttributeInfo< T >::StorageType_t D;
|
||||
|
||||
public:
|
||||
CDmaVar( );
|
||||
|
||||
// Setup to be used in OnConstruction methods of DmElements
|
||||
void Init( CDmElement *pOwner, const char *pAttributeName, int flags = 0 );
|
||||
void InitAndSet( CDmElement *pOwner, const char *pAttributeName, const T &value, int flags = 0 );
|
||||
|
||||
// Set/get
|
||||
const T& Set( const T &val );
|
||||
const T& Get() const;
|
||||
|
||||
// Cast operators
|
||||
operator const T&() const;
|
||||
const T* operator->() const;
|
||||
|
||||
// Assignment operator
|
||||
const CDmaVar<T>& operator=( const CDmaVar<T>& src );
|
||||
|
||||
// Math utility operations
|
||||
const T& operator=( const T &val );
|
||||
const T& operator+=( const T &val );
|
||||
const T& operator-=( const T &val );
|
||||
const T& operator/=( const T &val );
|
||||
const T& operator*=( const T &val );
|
||||
const T& operator^=( const T &val );
|
||||
const T& operator|=( const T &val );
|
||||
const T& operator&=( const T &val );
|
||||
T operator++();
|
||||
T operator--();
|
||||
T operator++( int ); // postfix version..
|
||||
T operator--( int ); // postfix version..
|
||||
|
||||
// Returns the attribute associated with the var
|
||||
CDmAttribute *GetAttribute();
|
||||
const CDmAttribute *GetAttribute() const;
|
||||
|
||||
// Is the attribute dirty?
|
||||
bool IsDirty() const;
|
||||
|
||||
protected:
|
||||
const T& Value() const;
|
||||
T& Value();
|
||||
const D& Storage() const;
|
||||
D& Storage();
|
||||
|
||||
private:
|
||||
D m_Storage;
|
||||
|
||||
protected:
|
||||
CDmAttribute *m_pAttribute;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Specialization for string
|
||||
//-----------------------------------------------------------------------------
|
||||
class CDmaString : public CDmaVar< CUtlString >
|
||||
{
|
||||
public:
|
||||
const char *Get( ) const;
|
||||
operator const char*() const;
|
||||
|
||||
void Set( const char *pValue );
|
||||
CDmaString &operator=( const char *src );
|
||||
const CDmaString& operator=( const CDmaString& src );
|
||||
|
||||
// Returns strlen
|
||||
int Length() const;
|
||||
};
|
||||
|
||||
#endif // DMVAR_H
|
938
public/datamodel/idatamodel.h
Normal file
938
public/datamodel/idatamodel.h
Normal file
@ -0,0 +1,938 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef IDATAMODEL_H
|
||||
#define IDATAMODEL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier1/interface.h"
|
||||
#include "tier1/utlvector.h"
|
||||
#include "tier1/utlsymbol.h"
|
||||
#include "appframework/IAppSystem.h"
|
||||
#include "datamodel/dmattributetypes.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations:
|
||||
//-----------------------------------------------------------------------------
|
||||
class CDmAttribute;
|
||||
class CDmElement;
|
||||
class IDmeOperator;
|
||||
class IElementForKeyValueCallback;
|
||||
|
||||
struct DmValueBase_t;
|
||||
class CUtlBuffer;
|
||||
class KeyValues;
|
||||
class CUtlSymbolTable;
|
||||
class CUtlCharConversion;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// data file format info
|
||||
//-----------------------------------------------------------------------------
|
||||
#define DMX_LEGACY_VERSION_STARTING_TOKEN "<!-- DMXVersion"
|
||||
#define DMX_LEGACY_VERSION_ENDING_TOKEN "-->"
|
||||
|
||||
#define DMX_VERSION_STARTING_TOKEN "<!-- dmx"
|
||||
#define DMX_VERSION_ENDING_TOKEN "-->"
|
||||
|
||||
#define GENERIC_DMX_FORMAT "dmx"
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
DMX_MAX_FORMAT_NAME_MAX_LENGTH = 64,
|
||||
DMX_MAX_HEADER_LENGTH = 40 + 2 * DMX_MAX_FORMAT_NAME_MAX_LENGTH,
|
||||
};
|
||||
|
||||
struct DmxHeader_t
|
||||
{
|
||||
char encodingName[ DMX_MAX_FORMAT_NAME_MAX_LENGTH ];
|
||||
int nEncodingVersion;
|
||||
char formatName[ DMX_MAX_FORMAT_NAME_MAX_LENGTH ];
|
||||
int nFormatVersion;
|
||||
|
||||
DmxHeader_t() : nEncodingVersion( -1 ), nFormatVersion( -1 )
|
||||
{
|
||||
encodingName[ 0 ] = formatName[ 0 ] = '\0';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// element framework phases
|
||||
//-----------------------------------------------------------------------------
|
||||
enum DmPhase_t
|
||||
{
|
||||
PH_EDIT,
|
||||
PH_EDIT_APPLY,
|
||||
PH_EDIT_RESOLVE,
|
||||
PH_DEPENDENCY,
|
||||
PH_OPERATE,
|
||||
PH_OPERATE_RESOLVE,
|
||||
PH_OUTPUT,
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// file id - also used to refer to elements that don't have file associations
|
||||
//-----------------------------------------------------------------------------
|
||||
enum DmFileId_t
|
||||
{
|
||||
DMFILEID_INVALID = 0xffffffff
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Handle to an CDmAttribute
|
||||
//-----------------------------------------------------------------------------
|
||||
enum DmAttributeHandle_t
|
||||
{
|
||||
DMATTRIBUTE_HANDLE_INVALID = 0xffffffff
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Handle to an DmAttributeList_t
|
||||
//-----------------------------------------------------------------------------
|
||||
enum DmAttributeReferenceIterator_t
|
||||
{
|
||||
DMATTRIBUTE_REFERENCE_ITERATOR_INVALID = 0
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// element framework interface
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IDmElementFramework : public IAppSystem
|
||||
{
|
||||
public:
|
||||
// Methods of IAppSystem
|
||||
virtual bool Connect( CreateInterfaceFn factory ) = 0;
|
||||
virtual void Disconnect() = 0;
|
||||
virtual void *QueryInterface( const char *pInterfaceName ) = 0;
|
||||
virtual InitReturnVal_t Init() = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
virtual DmPhase_t GetPhase() = 0;
|
||||
|
||||
virtual void SetOperators( const CUtlVector< IDmeOperator* > &operators ) = 0;
|
||||
|
||||
virtual void BeginEdit() = 0; // ends in edit phase, forces apply/resolve if from edit phase
|
||||
virtual void Operate( bool bResolve ) = 0; // ends in output phase
|
||||
virtual void Resolve() = 0;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Used only by aplpications to hook in the element framework
|
||||
//-----------------------------------------------------------------------------
|
||||
#define VDMELEMENTFRAMEWORK_VERSION "VDmElementFrameworkVersion001"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main interface
|
||||
//-----------------------------------------------------------------------------
|
||||
extern IDmElementFramework *g_pDmElementFramework;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// datamodel operator interface - for all elements that need to be sorted in the operator dependency graph
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IDmeOperator
|
||||
{
|
||||
public:
|
||||
virtual bool IsDirty() = 0; // ie needs to operate
|
||||
virtual void Operate() = 0;
|
||||
|
||||
virtual void GetInputAttributes ( CUtlVector< CDmAttribute * > &attrs ) = 0;
|
||||
virtual void GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs ) = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Class factory methods:
|
||||
//-----------------------------------------------------------------------------
|
||||
class IDmElementFactory
|
||||
{
|
||||
public:
|
||||
// Creation, destruction
|
||||
virtual CDmElement* Create( DmElementHandle_t handle, const char *pElementType, const char *pElementName, DmFileId_t fileid, const DmObjectId_t &id ) = 0;
|
||||
virtual void Destroy( DmElementHandle_t hElement ) = 0;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Various serialization methods can be installed into the data model factory
|
||||
//-----------------------------------------------------------------------------
|
||||
enum DmConflictResolution_t
|
||||
{
|
||||
CR_DELETE_NEW,
|
||||
CR_DELETE_OLD,
|
||||
CR_COPY_NEW,
|
||||
CR_FORCE_COPY,
|
||||
};
|
||||
|
||||
// convert files to elements and back
|
||||
// current file encodings supported: binary, xml, xml_flat, keyvalues2, keyvalues2_flat, keyvalues (vmf/vmt/actbusy), text? (qc/obj)
|
||||
class IDmSerializer
|
||||
{
|
||||
public:
|
||||
virtual const char *GetName() const = 0;
|
||||
virtual const char *GetDescription() const = 0;
|
||||
virtual bool IsBinaryFormat() const = 0;
|
||||
virtual bool StoresVersionInFile() const = 0;
|
||||
virtual int GetCurrentVersion() const = 0;
|
||||
|
||||
// Write into the UtlBuffer, return true if successful
|
||||
// if we decide to implement non-identity conversions between formats on write, then the source and dest format will need to be passed in here
|
||||
virtual bool Serialize( CUtlBuffer &buf, CDmElement *pRoot ) = 0;
|
||||
|
||||
// Read from the UtlBuffer, return true if successful, and return the read-in root in ppRoot.
|
||||
virtual bool Unserialize( CUtlBuffer &buf, const char *pEncodingName, int nEncodingVersion,
|
||||
const char *pSourceFormatName, int nSourceFormatVersion,
|
||||
DmFileId_t fileid, DmConflictResolution_t idConflictResolution, CDmElement **ppRoot ) = 0;
|
||||
};
|
||||
|
||||
// convert legacy elements to non-legacy elements
|
||||
// legacy formats include: sfm_vN, binary_vN, keyvalues2_v1, keyvalues2_flat_v1, xml, xml_flat
|
||||
// where N is a version number (1..9 for sfm, 1..2 for binary)
|
||||
class IDmLegacyUpdater
|
||||
{
|
||||
public:
|
||||
virtual const char *GetName() const = 0;
|
||||
virtual bool IsLatestVersion() const = 0;
|
||||
|
||||
// Updates ppRoot to first non-legacy generic dmx format, returns false if the conversion fails
|
||||
virtual bool Update( CDmElement **ppRoot ) = 0;
|
||||
};
|
||||
|
||||
// converts old elements to new elements
|
||||
// current formats include: sfm session, animset presets, particle definitions, exported maya character, etc.
|
||||
class IDmFormatUpdater
|
||||
{
|
||||
public:
|
||||
virtual const char *GetName() const = 0;
|
||||
virtual const char *GetDescription() const = 0;
|
||||
virtual const char *GetExtension() const = 0;
|
||||
virtual int GetCurrentVersion() const = 0;
|
||||
virtual const char *GetDefaultEncoding() const = 0;
|
||||
|
||||
// Converts pSourceRoot from nSourceVersion to the current version, returns false if the conversion fails
|
||||
virtual bool Update( CDmElement **pRoot, int nSourceVersion ) = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Interface for callbacks to supply element types for specific keys inside keyvalues files
|
||||
//-----------------------------------------------------------------------------
|
||||
class IElementForKeyValueCallback
|
||||
{
|
||||
public:
|
||||
virtual const char *GetElementForKeyValue( const char *pszKeyName, int iNestingLevel ) = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Optional helper passed in with clipboard data which is called when it's time to clean up the clipboard data in case the application
|
||||
// had some dynamically allocated data attached to a KV SetPtr object...
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IClipboardCleanup
|
||||
{
|
||||
public:
|
||||
virtual void ReleaseClipboardData( CUtlVector< KeyValues * >& list ) = 0;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Can be installed to be called back when data changes
|
||||
//-----------------------------------------------------------------------------
|
||||
enum DmNotifySource_t
|
||||
{
|
||||
// Sources
|
||||
NOTIFY_SOURCE_APPLICATION = 0,
|
||||
NOTIFY_SOURCE_UNDO,
|
||||
NOTIFY_SOURCE_FIRST_DME_CONTROL_SOURCE = 4, // Sources from dme_controls starts here
|
||||
NOTIFY_SOURCE_FIRST_APPLICATION_SOURCE = 8, // Sources from applications starts here
|
||||
};
|
||||
|
||||
enum DmNotifyFlags_t
|
||||
{
|
||||
// Does this dirty the document?
|
||||
NOTIFY_SOURCE_BITS = 8,
|
||||
NOTIFY_SETDIRTYFLAG = (1<<NOTIFY_SOURCE_BITS),
|
||||
|
||||
// Type of change (note NOTIFY_CHANGE_TOPOLOGICAL/NOTIFY_CHANGE_ATTRIBUTE_VALUE/NOTIFY_CHANGE_ATTRIBUTE_ARRAY_SIZE
|
||||
// are set by the Datamodel itself)
|
||||
NOTIFY_CHANGE_TOPOLOGICAL = (1<<(NOTIFY_SOURCE_BITS+4)), // Element created, destroyed, element attribute or element array attribute value changed
|
||||
NOTIFY_CHANGE_ATTRIBUTE_VALUE = (1<<(NOTIFY_SOURCE_BITS+5)), // Non-element attribute value changed
|
||||
NOTIFY_CHANGE_ATTRIBUTE_ARRAY_SIZE = (1<<(NOTIFY_SOURCE_BITS+6)), // Non-element array attribute added or removed
|
||||
NOTIFY_CHANGE_OTHER = (1<<(NOTIFY_SOURCE_BITS+7)), // Non attribute related change (a change in UI, for example)
|
||||
|
||||
NOTIFY_CHANGE_MASK = ( NOTIFY_CHANGE_TOPOLOGICAL | NOTIFY_CHANGE_ATTRIBUTE_VALUE | NOTIFY_CHANGE_ATTRIBUTE_ARRAY_SIZE | NOTIFY_CHANGE_OTHER ),
|
||||
|
||||
};
|
||||
|
||||
abstract_class IDmNotify
|
||||
{
|
||||
public:
|
||||
// See DmNotifySource_t and DmNotifyFlags_t
|
||||
virtual void NotifyDataChanged( const char *pReason, int nNotifySource, int nNotifyFlags ) = 0;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Helper for debugging undo system
|
||||
//-----------------------------------------------------------------------------
|
||||
struct UndoInfo_t
|
||||
{
|
||||
bool terminator;
|
||||
const char *desc;
|
||||
const char *undo;
|
||||
const char *redo;
|
||||
int numoperations;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Interface for undo
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IUndoElement
|
||||
{
|
||||
public:
|
||||
virtual void Undo() = 0;
|
||||
virtual void Redo() = 0;
|
||||
|
||||
virtual const char *UndoDesc() const = 0;
|
||||
virtual const char *RedoDesc() const = 0;
|
||||
virtual const char *GetDesc() const = 0;
|
||||
virtual void Release() = 0;
|
||||
|
||||
protected:
|
||||
virtual bool IsEndOfStream() const = 0;
|
||||
virtual void SetEndOfStream( bool end ) = 0;
|
||||
virtual ~IUndoElement() { }
|
||||
|
||||
friend class CUndoManager;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// traversal depth for copy, search, and other element/attribute traversals
|
||||
//-----------------------------------------------------------------------------
|
||||
enum TraversalDepth_t
|
||||
{
|
||||
TD_ALL, // traverse all attributes
|
||||
TD_DEEP, // traverse attributes with FATTRIB_NEVERCOPY clear
|
||||
TD_SHALLOW, // traverse attributes with FATTRIB_MUSTCOPY set
|
||||
TD_NONE, // don't traverse any attributes
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main interface for creation of all IDmeElements:
|
||||
//-----------------------------------------------------------------------------
|
||||
class IDataModel : public IAppSystem
|
||||
{
|
||||
public:
|
||||
// Installs factories used to instance elements
|
||||
virtual void AddElementFactory( const char *pElementTypeName, IDmElementFactory *pFactory ) = 0;
|
||||
|
||||
// This factory will be used to instance all elements whose type name isn't found.
|
||||
virtual void SetDefaultElementFactory( IDmElementFactory *pFactory ) = 0;
|
||||
|
||||
virtual int GetFirstFactory() const = 0;
|
||||
virtual int GetNextFactory( int index ) const = 0;
|
||||
virtual bool IsValidFactory( int index ) const = 0;
|
||||
virtual const char *GetFactoryName( int index ) const = 0;
|
||||
|
||||
// create/destroy element methods - proxies to installed element factories
|
||||
virtual DmElementHandle_t CreateElement( UtlSymId_t typeSymbol, const char *pElementName, DmFileId_t fileid = DMFILEID_INVALID, const DmObjectId_t *pObjectID = NULL ) = 0;
|
||||
virtual DmElementHandle_t CreateElement( const char *pTypeName, const char *pElementName, DmFileId_t fileid = DMFILEID_INVALID, const DmObjectId_t *pObjectID = NULL ) = 0;
|
||||
virtual void DestroyElement( DmElementHandle_t hElement ) = 0;
|
||||
|
||||
// element handle related methods
|
||||
virtual CDmElement* GetElement ( DmElementHandle_t hElement ) const = 0;
|
||||
virtual UtlSymId_t GetElementType ( DmElementHandle_t hElement ) const = 0;
|
||||
virtual const char* GetElementName ( DmElementHandle_t hElement ) const = 0;
|
||||
virtual const DmObjectId_t& GetElementId ( DmElementHandle_t hElement ) const = 0;
|
||||
|
||||
virtual const char* GetAttributeNameForType( DmAttributeType_t attType ) const = 0;
|
||||
virtual DmAttributeType_t GetAttributeTypeForName( const char *name ) const = 0;
|
||||
|
||||
// Adds various serializers and updaters
|
||||
virtual void AddSerializer( IDmSerializer *pSerializer ) = 0;
|
||||
virtual void AddLegacyUpdater( IDmLegacyUpdater *pUpdater ) = 0;
|
||||
virtual void AddFormatUpdater( IDmFormatUpdater *pUpdater ) = 0;
|
||||
|
||||
// file format methods
|
||||
virtual const char* GetFormatExtension( const char *pFormatName ) = 0;
|
||||
virtual const char* GetFormatDescription( const char *pFormatName ) = 0;
|
||||
virtual int GetFormatCount() const = 0;
|
||||
virtual const char * GetFormatName( int i ) const = 0;
|
||||
virtual const char * GetDefaultEncoding( const char *pFormatName ) = 0;
|
||||
|
||||
// file encoding methods
|
||||
virtual int GetEncodingCount() const = 0;
|
||||
virtual const char * GetEncodingName( int i ) const = 0;
|
||||
virtual bool IsEncodingBinary( const char *pEncodingName ) const = 0;
|
||||
virtual bool DoesEncodingStoreVersionInFile( const char *pEncodingName ) const = 0;
|
||||
|
||||
// For serialization, set the delimiter rules
|
||||
// These methods are meant to be used by importer/exporters
|
||||
virtual void SetSerializationDelimiter( CUtlCharConversion *pConv ) = 0;
|
||||
virtual void SetSerializationArrayDelimiter( const char *pDelimiter ) = 0;
|
||||
|
||||
// used to skip auto-creation of child elements during unserialization
|
||||
virtual bool IsUnserializing() = 0;
|
||||
|
||||
// Serialization of a element tree into a utlbuffer
|
||||
virtual bool Serialize( CUtlBuffer &outBuf, const char *pEncodingName, const char *pFormatName, DmElementHandle_t hRoot ) = 0;
|
||||
|
||||
// Unserializes, returns the root of the unserialized tree in hRoot
|
||||
// The file name passed in is simply for error messages and fileid creation
|
||||
virtual bool Unserialize( CUtlBuffer &inBuf, const char *pEncodingName, const char *pSourceFormatName, const char *pFormatHint,
|
||||
const char *pFileName, DmConflictResolution_t idConflictResolution, DmElementHandle_t &hRoot ) = 0;
|
||||
|
||||
// converts from elements from old file formats to elements for the current file format
|
||||
virtual bool UpdateUnserializedElements( const char *pSourceFormatName, int nSourceFormatVersion,
|
||||
DmFileId_t fileid, DmConflictResolution_t idConflictResolution, CDmElement **ppRoot ) = 0;
|
||||
|
||||
// force creation of untyped elements, ignoring type
|
||||
virtual void OnlyCreateUntypedElements( bool bEnable ) = 0;
|
||||
|
||||
// Finds a serializer by name
|
||||
virtual IDmSerializer* FindSerializer( const char *pEncodingName ) const = 0;
|
||||
virtual IDmLegacyUpdater* FindLegacyUpdater( const char *pLegacyFormatName ) const = 0;
|
||||
virtual IDmFormatUpdater* FindFormatUpdater( const char *pFormatName ) const = 0;
|
||||
|
||||
// saves element tree to a file
|
||||
virtual bool SaveToFile( const char *pFileName, const char *pPathID, const char *pEncodingName, const char *pFormatName, CDmElement *pRoot ) = 0;
|
||||
|
||||
// restores file into an element tree
|
||||
// NOTE: Format name is only used here for those formats which don't store
|
||||
// the format name in the file. Use NULL for those formats which store the
|
||||
// format name in the file.
|
||||
virtual DmFileId_t RestoreFromFile( const char *pFileName, const char *pPathID, const char *pFormatHint, CDmElement **ppRoot, DmConflictResolution_t idConflictResolution = CR_DELETE_NEW, DmxHeader_t *pHeaderOut = NULL ) = 0;
|
||||
|
||||
// Sets the name of the DME element to create in keyvalues serialization
|
||||
virtual void SetKeyValuesElementCallback( IElementForKeyValueCallback *pCallbackInterface ) = 0;
|
||||
virtual const char *GetKeyValuesElementName( const char *pszKeyName, int iNestingLevel ) = 0;
|
||||
|
||||
// Global symbol table for the datamodel system
|
||||
virtual UtlSymId_t GetSymbol( const char *pString ) = 0;
|
||||
virtual const char * GetString( UtlSymId_t sym ) const = 0;
|
||||
|
||||
// Returns the total number of elements allocated at the moment
|
||||
virtual int GetMaxNumberOfElements() = 0;
|
||||
virtual int GetElementsAllocatedSoFar() = 0;
|
||||
virtual int GetAllocatedAttributeCount() = 0;
|
||||
virtual int GetAllocatedElementCount() = 0;
|
||||
virtual DmElementHandle_t FirstAllocatedElement() = 0;
|
||||
virtual DmElementHandle_t NextAllocatedElement( DmElementHandle_t it ) = 0;
|
||||
|
||||
// estimate memory usage
|
||||
virtual int EstimateMemoryUsage( DmElementHandle_t hElement, TraversalDepth_t depth ) = 0;
|
||||
|
||||
// Undo/Redo support
|
||||
virtual void SetUndoEnabled( bool enable ) = 0;
|
||||
virtual bool IsUndoEnabled() const = 0;
|
||||
virtual bool UndoEnabledForElement( const CDmElement *pElement ) const = 0;
|
||||
virtual bool IsDirty() const = 0;
|
||||
virtual bool CanUndo() const = 0;
|
||||
virtual bool CanRedo() const = 0;
|
||||
// If chaining ID is != 0 and the next StartUndo uses the same ID, then the operations will be chained together into a single undo operation
|
||||
virtual void StartUndo( char const *undodesc, char const *redodesc, int nChainingID = 0 ) = 0;
|
||||
virtual void FinishUndo() = 0;
|
||||
virtual void AbortUndoableOperation() = 0; // called instead of FinishUndo, essentially performs and Undo() and WipeRedo() if any undo items have been added to the stack
|
||||
virtual void ClearRedo() = 0;
|
||||
virtual const char *GetUndoDesc() = 0;
|
||||
virtual const char *GetRedoDesc() = 0;
|
||||
// From the UI, perform the Undo operation
|
||||
virtual void Undo() = 0;
|
||||
virtual void Redo() = 0;
|
||||
virtual void TraceUndo( bool state ) = 0; // if true, undo records spew as they are added
|
||||
|
||||
// Wipes out all Undo data
|
||||
virtual void ClearUndo() = 0;
|
||||
|
||||
virtual void GetUndoInfo( CUtlVector< UndoInfo_t >& list ) = 0;
|
||||
|
||||
virtual void AddUndoElement( IUndoElement *pElement ) = 0;
|
||||
virtual UtlSymId_t GetUndoDescInternal( const char *context ) = 0;
|
||||
virtual UtlSymId_t GetRedoDescInternal( const char *context ) = 0;
|
||||
|
||||
virtual void EmptyClipboard() = 0;
|
||||
virtual void SetClipboardData( CUtlVector< KeyValues * >& data, IClipboardCleanup *pfnOptionalCleanuFunction = 0 ) = 0;
|
||||
virtual void AddToClipboardData( KeyValues *add ) = 0;
|
||||
virtual void GetClipboardData( CUtlVector< KeyValues * >& data ) = 0;
|
||||
virtual bool HasClipboardData() const = 0;
|
||||
|
||||
// Handles to attributes
|
||||
virtual CDmAttribute * GetAttribute( DmAttributeHandle_t h ) = 0;
|
||||
virtual bool IsAttributeHandleValid( DmAttributeHandle_t h ) const = 0;
|
||||
|
||||
// file id reference methods
|
||||
virtual int NumFileIds() = 0;
|
||||
virtual DmFileId_t GetFileId( int i ) = 0;
|
||||
virtual DmFileId_t FindOrCreateFileId( const char *pFilename ) = 0;
|
||||
virtual void RemoveFileId( DmFileId_t fileid ) = 0;
|
||||
virtual DmFileId_t GetFileId( const char *pFilename ) = 0;
|
||||
virtual const char * GetFileName( DmFileId_t fileid ) = 0;
|
||||
virtual void SetFileName( DmFileId_t fileid, const char *pFileName ) = 0;
|
||||
virtual const char * GetFileFormat( DmFileId_t fileid ) = 0;
|
||||
virtual void SetFileFormat( DmFileId_t fileid, const char *pFormat ) = 0;
|
||||
virtual DmElementHandle_t GetFileRoot( DmFileId_t fileid ) = 0;
|
||||
virtual void SetFileRoot( DmFileId_t fileid, DmElementHandle_t hRoot ) = 0;
|
||||
virtual bool IsFileLoaded( DmFileId_t fileid ) = 0;
|
||||
virtual void MarkFileLoaded( DmFileId_t fileid ) = 0;
|
||||
virtual void UnloadFile( DmFileId_t fileid ) = 0;
|
||||
virtual int NumElementsInFile( DmFileId_t fileid ) = 0;
|
||||
|
||||
virtual void DontAutoDelete( DmElementHandle_t hElement ) = 0;
|
||||
|
||||
// handle validity methods - these shouldn't really be here, but the undo system needs them...
|
||||
virtual void MarkHandleInvalid( DmElementHandle_t hElement ) = 0;
|
||||
virtual void MarkHandleValid( DmElementHandle_t hElement ) = 0;
|
||||
|
||||
virtual DmElementHandle_t FindElement( const DmObjectId_t &id ) = 0;
|
||||
|
||||
virtual DmAttributeReferenceIterator_t FirstAttributeReferencingElement( DmElementHandle_t hElement ) = 0;
|
||||
virtual DmAttributeReferenceIterator_t NextAttributeReferencingElement( DmAttributeReferenceIterator_t hAttrIter ) = 0;
|
||||
virtual CDmAttribute * GetAttribute( DmAttributeReferenceIterator_t hAttrIter ) = 0;
|
||||
|
||||
// Install, remove notify callbacks associated w/ undo contexts
|
||||
virtual bool InstallNotificationCallback( IDmNotify *pNotify ) = 0;
|
||||
virtual void RemoveNotificationCallback( IDmNotify *pNotify ) = 0;
|
||||
virtual bool IsSuppressingNotify( ) const = 0;
|
||||
virtual void SetSuppressingNotify( bool bSuppress ) = 0;
|
||||
virtual void PushNotificationScope( const char *pReason, int nNotifySource, int nNotifyFlags ) = 0;
|
||||
virtual void PopNotificationScope( bool bAbort = false ) = 0;
|
||||
virtual const char *GetUndoString( UtlSymId_t sym ) = 0;
|
||||
|
||||
virtual bool HasElementFactory( const char *pElementType ) const = 0;
|
||||
|
||||
// Call before you make any undo records
|
||||
virtual void SetUndoDepth( int nSize ) = 0;
|
||||
|
||||
// Displats memory stats to the console
|
||||
virtual void DisplayMemoryStats() = 0;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Used only by applications to hook in the data model
|
||||
//-----------------------------------------------------------------------------
|
||||
#define VDATAMODEL_INTERFACE_VERSION "VDataModelVersion001"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main interface accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
extern IDataModel *g_pDataModel;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Allows clients to implement customized undo elements
|
||||
//-----------------------------------------------------------------------------
|
||||
class CUndoElement : public IUndoElement
|
||||
{
|
||||
public:
|
||||
CUndoElement( const char *pDesc )
|
||||
{
|
||||
m_UndoDesc = g_pDataModel->GetUndoDescInternal( pDesc );
|
||||
m_RedoDesc = g_pDataModel->GetRedoDescInternal( pDesc );
|
||||
m_pDesc = pDesc;
|
||||
m_bEndOfStream = false;
|
||||
}
|
||||
|
||||
virtual void Release()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual const char *UndoDesc() const
|
||||
{
|
||||
return g_pDataModel->GetUndoString( m_UndoDesc );
|
||||
}
|
||||
|
||||
virtual const char *RedoDesc() const
|
||||
{
|
||||
return g_pDataModel->GetUndoString( m_RedoDesc );
|
||||
}
|
||||
|
||||
virtual const char *GetDesc() const
|
||||
{
|
||||
return m_pDesc;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual bool IsEndOfStream() const
|
||||
{
|
||||
return m_bEndOfStream;
|
||||
}
|
||||
|
||||
virtual void SetEndOfStream( bool end )
|
||||
{
|
||||
m_bEndOfStream = end;
|
||||
}
|
||||
|
||||
const char *m_pDesc;
|
||||
CUtlSymbol m_UndoDesc;
|
||||
CUtlSymbol m_RedoDesc;
|
||||
bool m_bEndOfStream;
|
||||
|
||||
private:
|
||||
friend class CUndoManager;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Simple helper class
|
||||
//-----------------------------------------------------------------------------
|
||||
class CUndoScopeGuard
|
||||
{
|
||||
public:
|
||||
explicit CUndoScopeGuard( const char *udesc, const char *rdesc = NULL )
|
||||
{
|
||||
m_bReleased = false;
|
||||
m_bNotify = false;
|
||||
m_pNotify = NULL;
|
||||
g_pDataModel->StartUndo( udesc, rdesc ? rdesc : udesc );
|
||||
}
|
||||
|
||||
explicit CUndoScopeGuard( int nChainingID, char const *udesc )
|
||||
{
|
||||
m_bReleased = false;
|
||||
m_bNotify = false;
|
||||
m_pNotify = NULL;
|
||||
g_pDataModel->StartUndo( udesc, udesc, nChainingID );
|
||||
}
|
||||
|
||||
explicit CUndoScopeGuard( int nNotifySource, int nNotifyFlags, const char *udesc, const char *rdesc = NULL, int nChainingID = 0 )
|
||||
{
|
||||
m_bReleased = false;
|
||||
m_bNotify = true;
|
||||
m_pNotify = NULL;
|
||||
g_pDataModel->StartUndo( udesc, rdesc ? rdesc : udesc, nChainingID );
|
||||
g_pDataModel->PushNotificationScope( udesc, nNotifySource, nNotifyFlags );
|
||||
}
|
||||
|
||||
explicit CUndoScopeGuard( int nNotifySource, int nNotifyFlags, IDmNotify *pNotify, const char *udesc, const char *rdesc = NULL, int nChainingID = 0 )
|
||||
{
|
||||
m_bReleased = false;
|
||||
m_bNotify = true;
|
||||
m_pNotify = NULL;
|
||||
g_pDataModel->StartUndo( udesc, rdesc ? rdesc : udesc, nChainingID );
|
||||
if ( pNotify )
|
||||
{
|
||||
if ( g_pDataModel->InstallNotificationCallback( pNotify ) )
|
||||
{
|
||||
m_pNotify = pNotify;
|
||||
}
|
||||
}
|
||||
g_pDataModel->PushNotificationScope( udesc, nNotifySource, nNotifyFlags );
|
||||
}
|
||||
|
||||
~CUndoScopeGuard()
|
||||
{
|
||||
Release();
|
||||
}
|
||||
|
||||
void Release()
|
||||
{
|
||||
if ( !m_bReleased )
|
||||
{
|
||||
g_pDataModel->FinishUndo();
|
||||
if ( m_bNotify )
|
||||
{
|
||||
g_pDataModel->PopNotificationScope( );
|
||||
m_bNotify = false;
|
||||
}
|
||||
if ( m_pNotify )
|
||||
{
|
||||
g_pDataModel->RemoveNotificationCallback( m_pNotify );
|
||||
m_pNotify = NULL;
|
||||
}
|
||||
m_bReleased = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Abort()
|
||||
{
|
||||
if ( !m_bReleased )
|
||||
{
|
||||
g_pDataModel->AbortUndoableOperation();
|
||||
if ( m_bNotify )
|
||||
{
|
||||
g_pDataModel->PopNotificationScope( true );
|
||||
m_bNotify = false;
|
||||
}
|
||||
if ( m_pNotify )
|
||||
{
|
||||
g_pDataModel->RemoveNotificationCallback( m_pNotify );
|
||||
m_pNotify = NULL;
|
||||
}
|
||||
m_bReleased = true;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
IDmNotify *m_pNotify;
|
||||
bool m_bReleased;
|
||||
bool m_bNotify;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Simple helper class to disable Undo/Redo operations when in scope
|
||||
//-----------------------------------------------------------------------------
|
||||
class CChangeUndoScopeGuard
|
||||
{
|
||||
public:
|
||||
CChangeUndoScopeGuard( bool bNewState )
|
||||
{
|
||||
m_bReleased = false;
|
||||
m_bNotify = false;
|
||||
m_pNotify = NULL;
|
||||
m_bOldValue = g_pDataModel->IsUndoEnabled();
|
||||
g_pDataModel->SetUndoEnabled( bNewState );
|
||||
};
|
||||
|
||||
CChangeUndoScopeGuard( bool bNewState, const char *pDesc, int nNotifySource, int nNotifyFlags, IDmNotify *pNotify = NULL )
|
||||
{
|
||||
m_bReleased = false;
|
||||
m_bOldValue = g_pDataModel->IsUndoEnabled();
|
||||
g_pDataModel->SetUndoEnabled( bNewState );
|
||||
|
||||
m_bNotify = true;
|
||||
m_pNotify = NULL;
|
||||
if ( pNotify )
|
||||
{
|
||||
if ( g_pDataModel->InstallNotificationCallback( pNotify ) )
|
||||
{
|
||||
m_pNotify = pNotify;
|
||||
}
|
||||
}
|
||||
g_pDataModel->PushNotificationScope( pDesc, nNotifySource, nNotifyFlags );
|
||||
};
|
||||
|
||||
~CChangeUndoScopeGuard()
|
||||
{
|
||||
Release();
|
||||
}
|
||||
|
||||
void Release()
|
||||
{
|
||||
// Releases the guard...
|
||||
if ( !m_bReleased )
|
||||
{
|
||||
g_pDataModel->SetUndoEnabled( m_bOldValue );
|
||||
m_bReleased = true;
|
||||
if ( m_bNotify )
|
||||
{
|
||||
g_pDataModel->PopNotificationScope( );
|
||||
m_bNotify = false;
|
||||
}
|
||||
if ( m_pNotify )
|
||||
{
|
||||
g_pDataModel->RemoveNotificationCallback( m_pNotify );
|
||||
m_pNotify = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
IDmNotify *m_pNotify;
|
||||
bool m_bOldValue;
|
||||
bool m_bReleased;
|
||||
bool m_bNotify;
|
||||
};
|
||||
|
||||
class CDisableUndoScopeGuard : public CChangeUndoScopeGuard
|
||||
{
|
||||
typedef CChangeUndoScopeGuard BaseClass;
|
||||
|
||||
public:
|
||||
CDisableUndoScopeGuard() : BaseClass( false ) { }
|
||||
CDisableUndoScopeGuard( const char *pDesc, int nNotifySource, int nNotifyFlags, IDmNotify *pNotify = NULL ) :
|
||||
BaseClass( false, pDesc, nNotifySource, nNotifyFlags, pNotify ) {}
|
||||
};
|
||||
|
||||
class CEnableUndoScopeGuard : public CChangeUndoScopeGuard
|
||||
{
|
||||
typedef CChangeUndoScopeGuard BaseClass;
|
||||
|
||||
public:
|
||||
CEnableUndoScopeGuard( ) : BaseClass( true ) { }
|
||||
CEnableUndoScopeGuard( const char *pDesc, int nNotifySource, int nNotifyFlags, IDmNotify *pNotify = NULL ) :
|
||||
BaseClass( true, pDesc, nNotifySource, nNotifyFlags, pNotify ) {}
|
||||
};
|
||||
|
||||
|
||||
#define DEFINE_SOURCE_UNDO_SCOPE_GUARD( _classnameprefix, _source ) \
|
||||
class C ## _classnameprefix ## UndoScopeGuard : public CUndoScopeGuard \
|
||||
{ \
|
||||
typedef CUndoScopeGuard BaseClass; \
|
||||
\
|
||||
public: \
|
||||
C ## _classnameprefix ## UndoScopeGuard( int nNotifyFlags, const char *pUndoDesc, const char *pRedoDesc = NULL, int nChainingID = 0 ) : \
|
||||
BaseClass( _source, nNotifyFlags, pUndoDesc, pRedoDesc, nChainingID ) \
|
||||
{ \
|
||||
} \
|
||||
C ## _classnameprefix ## UndoScopeGuard( int nNotifyFlags, IDmNotify *pNotify, const char *pUndoDesc, const char *pRedoDesc = NULL, int nChainingID = 0 ) : \
|
||||
BaseClass( _source, nNotifyFlags, pNotify, pUndoDesc, pRedoDesc, nChainingID ) \
|
||||
{ \
|
||||
} \
|
||||
C ## _classnameprefix ## UndoScopeGuard( int nNotifyFlags, const char *pUndoDesc, int nChainingID ) : \
|
||||
BaseClass( _source, nNotifyFlags, pUndoDesc, pUndoDesc, nChainingID ) \
|
||||
{ \
|
||||
} \
|
||||
}; \
|
||||
class C ## _classnameprefix ## DisableUndoScopeGuard : public CDisableUndoScopeGuard \
|
||||
{ \
|
||||
typedef CDisableUndoScopeGuard BaseClass; \
|
||||
\
|
||||
public: \
|
||||
C ## _classnameprefix ## DisableUndoScopeGuard( const char *pDesc, int nNotifyFlags, IDmNotify *pNotify = NULL ) : \
|
||||
BaseClass( pDesc, _source, nNotifyFlags, pNotify ) \
|
||||
{ \
|
||||
} \
|
||||
}; \
|
||||
class C ## _classnameprefix ## EnableUndoScopeGuard : public CEnableUndoScopeGuard \
|
||||
{ \
|
||||
typedef CEnableUndoScopeGuard BaseClass; \
|
||||
\
|
||||
public: \
|
||||
C ## _classnameprefix ## EnableUndoScopeGuard( const char *pDesc, int nNotifyFlags, IDmNotify *pNotify = NULL ) : \
|
||||
BaseClass( pDesc, _source, nNotifyFlags, pNotify ) \
|
||||
{ \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Simple helper class to disable NotifyDataChanged from current scope
|
||||
//-----------------------------------------------------------------------------
|
||||
class CNotifyScopeGuard
|
||||
{
|
||||
public:
|
||||
CNotifyScopeGuard( const char *pReason, int nNotifySource, int nNotifyFlags, IDmNotify *pNotify = NULL )
|
||||
{
|
||||
m_bReleased = false;
|
||||
m_pNotify = NULL;
|
||||
g_pDataModel->PushNotificationScope( pReason, nNotifySource, nNotifyFlags );
|
||||
if ( pNotify )
|
||||
{
|
||||
if ( g_pDataModel->InstallNotificationCallback( pNotify ) )
|
||||
{
|
||||
m_pNotify = pNotify;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
~CNotifyScopeGuard()
|
||||
{
|
||||
Release();
|
||||
}
|
||||
|
||||
void Release()
|
||||
{
|
||||
// Releases the guard...
|
||||
if ( !m_bReleased )
|
||||
{
|
||||
g_pDataModel->PopNotificationScope( );
|
||||
if ( m_pNotify )
|
||||
{
|
||||
g_pDataModel->RemoveNotificationCallback( m_pNotify );
|
||||
m_pNotify = NULL;
|
||||
}
|
||||
m_bReleased = true;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
CNotifyScopeGuard( const CNotifyScopeGuard& g );
|
||||
|
||||
private:
|
||||
IDmNotify *m_pNotify;
|
||||
bool m_bReleased;
|
||||
};
|
||||
|
||||
|
||||
#define DEFINE_SOURCE_NOTIFY_SCOPE_GUARD( _classnameprefix, _source ) \
|
||||
class C ## _classnameprefix ## NotifyScopeGuard : public CNotifyScopeGuard \
|
||||
{ \
|
||||
typedef CNotifyScopeGuard BaseClass; \
|
||||
\
|
||||
public: \
|
||||
C ## _classnameprefix ## NotifyScopeGuard( const char *pReason, int nNotifyFlags, IDmNotify *pNotify = NULL ) : \
|
||||
BaseClass( pReason, _source, nNotifyFlags, pNotify )\
|
||||
{ \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Simple helper class to disable notifications when in scope
|
||||
//-----------------------------------------------------------------------------
|
||||
class CChangeNotifyScopeGuard
|
||||
{
|
||||
public:
|
||||
CChangeNotifyScopeGuard( bool bNewState )
|
||||
{
|
||||
m_bReleased = false;
|
||||
m_bOldValue = g_pDataModel->IsSuppressingNotify();
|
||||
g_pDataModel->SetSuppressingNotify( bNewState );
|
||||
};
|
||||
|
||||
~CChangeNotifyScopeGuard()
|
||||
{
|
||||
Release();
|
||||
}
|
||||
|
||||
void Release()
|
||||
{
|
||||
// Releases the guard...
|
||||
if ( !m_bReleased )
|
||||
{
|
||||
g_pDataModel->SetSuppressingNotify( m_bOldValue );
|
||||
m_bReleased = true;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_bOldValue;
|
||||
bool m_bReleased;
|
||||
};
|
||||
|
||||
class CDisableNotifyScopeGuard : public CChangeNotifyScopeGuard
|
||||
{
|
||||
typedef CChangeNotifyScopeGuard BaseClass;
|
||||
|
||||
public:
|
||||
CDisableNotifyScopeGuard() : BaseClass( true ) { }
|
||||
|
||||
private:
|
||||
CDisableNotifyScopeGuard( const CDisableNotifyScopeGuard& g );
|
||||
};
|
||||
|
||||
class CEnableNotifyScopeGuard : public CChangeNotifyScopeGuard
|
||||
{
|
||||
typedef CChangeNotifyScopeGuard BaseClass;
|
||||
|
||||
public:
|
||||
CEnableNotifyScopeGuard( ) : BaseClass( false ) { }
|
||||
|
||||
private:
|
||||
CEnableNotifyScopeGuard( const CEnableNotifyScopeGuard& g );
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Standard undo/notify guards for the application
|
||||
//-----------------------------------------------------------------------------
|
||||
DEFINE_SOURCE_UNDO_SCOPE_GUARD( App, NOTIFY_SOURCE_APPLICATION );
|
||||
DEFINE_SOURCE_NOTIFY_SCOPE_GUARD( App, NOTIFY_SOURCE_APPLICATION );
|
||||
|
||||
|
||||
|
||||
#endif // IDATAMODEL_H
|
Reference in New Issue
Block a user