diff options
Diffstat (limited to 'public/dmxloader')
| -rw-r--r-- | public/dmxloader/dmxattribute.h | 183 | ||||
| -rw-r--r-- | public/dmxloader/dmxelement.h | 310 | ||||
| -rw-r--r-- | public/dmxloader/dmxloader.h | 72 |
3 files changed, 565 insertions, 0 deletions
diff --git a/public/dmxloader/dmxattribute.h b/public/dmxloader/dmxattribute.h new file mode 100644 index 0000000..1752366 --- /dev/null +++ b/public/dmxloader/dmxattribute.h @@ -0,0 +1,183 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef DMXATTRIBUTE_H +#define DMXATTRIBUTE_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "datamodel/dmattributetypes.h" +#include "tier1/utlvector.h" +#include "tier1/utlrbtree.h" +#include "tier1/utlsymbol.h" +#include "tier1/mempool.h" +#include "dmxloader/dmxloader.h" + + +//----------------------------------------------------------------------------- +// Forward declarations: +//----------------------------------------------------------------------------- +class CDmxElement; + + +//----------------------------------------------------------------------------- +// Attribute info, modified for use in mod code +//----------------------------------------------------------------------------- +DECLARE_ATTRIBUTE_TYPE( CDmxElement*, AT_ELEMENT, "element", value = 0; ) +DECLARE_ATTRIBUTE_ARRAY_TYPE( CDmxElement*, AT_ELEMENT_ARRAY, "element_array" ) + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CDmxAttribute +{ + DECLARE_DMX_ALLOCATOR( ); + +public: + // Returns attribute name and 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; + CUtlSymbol GetNameSymbol() const; + void SetName( const char *pName ); + + // Gets values + template< class T > const T& GetValue( ) const; + template< class T > const CUtlVector< T >& GetArray( ) const; + const char *GetValueString() const; + + // Sets values (+ type) + template< class T > void SetValue( const T& value ); + void SetValue( const char *pString ); + void SetValue( const void *pBuffer, size_t nLen ); + void SetValue( const CDmxAttribute *pAttribute ); + + // Method to set values in an array (just directly operate on the array) + // NOTE: This will create a new array of the appropriate type if + // the type doesn't match the current type + template< class T > CUtlVector< T >& GetArrayForEdit(); + + // 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; + + // Gets the size of an array, returns 0 if it's not an array type + int GetArrayCount() const; + + // Read from file + bool Unserialize( DmAttributeType_t type, CUtlBuffer &buf ); + bool UnserializeElement( DmAttributeType_t type, CUtlBuffer &buf ); + bool Serialize( CUtlBuffer &buf ) const; + bool SerializeElement( int nIndex, CUtlBuffer &buf ) const; + bool SerializesOnMultipleLines() const; + + // Returns the size of the variables storing the various attribute types + static int AttributeDataSize( DmAttributeType_t type ); + +private: + CDmxAttribute( const char *pAttributeName ); + CDmxAttribute( CUtlSymbol attributeName ); + ~CDmxAttribute(); + + // Allocate, free memory for data + void AllocateDataMemory( DmAttributeType_t type ); + void FreeDataMemory( ); + + // Untyped method for setting used by unpack + void SetValue( DmAttributeType_t type, const void *pSrc, int nLen ); + + DmAttributeType_t m_Type; + CUtlSymbol m_Name; + void *m_pData; + + static CUtlSymbolTableMT s_AttributeNameSymbols; + + friend class CDmxElement; +}; + + +//----------------------------------------------------------------------------- +// Inline methods +//----------------------------------------------------------------------------- +inline DmAttributeType_t CDmxAttribute::GetType() const +{ + return m_Type; +} + +template< class T > inline bool CDmxAttribute::IsA() const +{ + return GetType() == CDmAttributeInfo< T >::ATTRIBUTE_TYPE; +} + +inline CUtlSymbol CDmxAttribute::GetNameSymbol() const +{ + return m_Name; +} + + +//----------------------------------------------------------------------------- +// Sets a value in the attribute +//----------------------------------------------------------------------------- +template< class T > void CDmxAttribute::SetValue( const T& value ) +{ + AllocateDataMemory( CDmAttributeInfo<T>::AttributeType() ); + CopyConstruct( (T*)m_pData, value ); +} + + +//----------------------------------------------------------------------------- +// Returns data in the attribute +//----------------------------------------------------------------------------- +inline const char *CDmxAttribute::GetValueString() const +{ + if ( m_Type == AT_STRING ) + return *(CUtlString*)m_pData; + return ""; +} + +template< class T > +inline const T& CDmxAttribute::GetValue( ) const +{ + if ( CDmAttributeInfo<T>::AttributeType() == m_Type ) + return *(T*)m_pData; + + static T defaultValue; + CDmAttributeInfo<T>::SetDefaultValue( defaultValue ); + return defaultValue; +} + +template< class T > +inline const CUtlVector< T >& CDmxAttribute::GetArray( ) const +{ + if ( CDmAttributeInfo< CUtlVector< T > >::AttributeType() == m_Type ) + return *( CUtlVector< T > *)m_pData; + + static CUtlVector<T> defaultArray; + return defaultArray; +} + +template< class T > +inline CUtlVector< T >& CDmxAttribute::GetArrayForEdit( ) +{ + if ( CDmAttributeInfo< CUtlVector< T > >::AttributeType() == m_Type ) + return *( CUtlVector< T > *)m_pData; + + AllocateDataMemory( CDmAttributeInfo< CUtlVector< T > >::AttributeType() ); + Construct( (CUtlVector<T>*)m_pData ); + return *(CUtlVector< T > *)m_pData; +} + +#endif // DMXATTRIBUTE_H diff --git a/public/dmxloader/dmxelement.h b/public/dmxloader/dmxelement.h new file mode 100644 index 0000000..c4aadd8 --- /dev/null +++ b/public/dmxloader/dmxelement.h @@ -0,0 +1,310 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef DMXELEMENT_H +#define DMXELEMENT_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "datamodel/dmattributetypes.h" +#include "tier1/utlvector.h" +#include "tier1/utlrbtree.h" +#include "tier1/utlsymbol.h" +#include "tier1/mempool.h" +#include "tier1/UtlSortVector.h" +#include "dmxloader/dmxattribute.h" + + +//----------------------------------------------------------------------------- +// Sort functor class for attributes +//----------------------------------------------------------------------------- +class CDmxAttributeLess +{ +public: + bool Less( const CDmxAttribute * pAttribute1, const CDmxAttribute *pAttribute2, void *pContext ) + { + return pAttribute1->GetNameSymbol() < pAttribute2->GetNameSymbol(); + } +}; + + +//----------------------------------------------------------------------------- +// Used to unpack elements into a structure. Does not recurse +// Also does not work with arrays. +//----------------------------------------------------------------------------- +struct DmxElementUnpackStructure_t +{ + const char *m_pAttributeName; + const char *m_pDefaultString; + DmAttributeType_t m_AttributeType; + int m_nOffset; + int m_nSize; + const void *m_pUserData; // If you want to associate some app-specific data with each field +}; + +#define DECLARE_DMXELEMENT_UNPACK() \ + template <typename T> friend DmxElementUnpackStructure_t *DmxElementUnpackInit(T *); + +#define BEGIN_DMXELEMENT_UNPACK( _structName ) \ + template <typename T> DmxElementUnpackStructure_t *DmxElementUnpackInit(T *); \ + template <> DmxElementUnpackStructure_t *DmxElementUnpackInit<_structName>( _structName * ); \ + namespace _structName##_UnpackInit \ + { \ + static DmxElementUnpackStructure_t *s_pUnpack = DmxElementUnpackInit( (_structName *)NULL ); \ + } \ + \ + template <> DmxElementUnpackStructure_t *DmxElementUnpackInit<_structName>( _structName * ) \ + { \ + typedef _structName DestStructType_t; \ + static DmxElementUnpackStructure_t unpack[] = \ + { \ + +#define DMXELEMENT_UNPACK_FLTX4( _attributeName, _defaultString, _varName ) \ + { _attributeName, _defaultString, CDmAttributeInfo<float>::AttributeType(), (int)offsetof( DestStructType_t, _varName ), sizeof( fltx4 ), NULL }, +#define DMXELEMENT_UNPACK_FIELD( _attributeName, _defaultString, _type, _varName ) \ + { _attributeName, _defaultString, CDmAttributeInfo<_type>::AttributeType(), (int)offsetof( DestStructType_t, _varName ), sizeof( ((DestStructType_t *)0)->_varName), NULL }, +#define DMXELEMENT_UNPACK_FIELD_STRING( _attributeName, _defaultString, _varName ) \ + { _attributeName, _defaultString, AT_STRING, offsetof( DestStructType_t, _varName ), sizeof( ((DestStructType_t *)0)->_varName), NULL }, + +#define DMXELEMENT_UNPACK_FIELD_USERDATA( _attributeName, _defaultString, _type, _varName, _userData ) \ + { _attributeName, _defaultString, CDmAttributeInfo<_type>::AttributeType(), (int)offsetof( DestStructType_t, _varName ), sizeof( ((DestStructType_t *)0)->_varName), _userData }, +#define DMXELEMENT_UNPACK_FIELD_STRING_USERDATA( _attributeName, _defaultString, _varName, _userData ) \ + { _attributeName, _defaultString, AT_STRING, (int)offsetof( DestStructType_t, _varName ), sizeof( ((DestStructType_t *)0)->_varName), _userData }, + +#define END_DMXELEMENT_UNPACK( _structName, _varName ) \ + { NULL, NULL, AT_UNKNOWN, 0, 0, NULL } \ + }; \ + return unpack; \ + } \ + DmxElementUnpackStructure_t *_varName = _structName##_UnpackInit::s_pUnpack; + +#define END_DMXELEMENT_UNPACK_TEMPLATE( _structName, _varName ) \ + { NULL, NULL, AT_UNKNOWN, 0, 0, NULL } \ + }; \ + return unpack; \ + } \ + template<> DmxElementUnpackStructure_t *_varName = _structName##_UnpackInit::s_pUnpack; + + +//----------------------------------------------------------------------------- +// Element used to read dmx files from mod code. Similar to keyvalues. +//----------------------------------------------------------------------------- +class CDmxElement +{ + DECLARE_DMX_ALLOCATOR( ); + +public: + bool HasAttribute( const char *pAttributeName ) const; + CDmxAttribute *GetAttribute( const char *pAttributeName ); + const CDmxAttribute *GetAttribute( const char *pAttributeName ) const; + int AttributeCount() const; + CDmxAttribute *GetAttribute( int nIndex ); + const CDmxAttribute *GetAttribute( int nIndex ) const; + CUtlSymbol GetType() const; + const char* GetTypeString() const; + const char* GetName() const; + const DmObjectId_t &GetId() const; + + // Add+remove+rename can only occur during lock + // NOTE: AddAttribute will find or add; returning an existing attribute if + // one with the appropriate name exists + void LockForChanges( bool bLock ); + CDmxAttribute *AddAttribute( const char *pAttributeName ); + void RemoveAttribute( const char *pAttributeName ); + void RemoveAttributeByPtr( CDmxAttribute *pAttribute ); + void RemoveAllAttributes(); + void RenameAttribute( const char *pAttributeName, const char *pNewName ); + + // Simple methods to read attributes + const char *GetValueString( const char *pAttributeName ) const; + template< class T > const T& GetValue( const char *pAttributeName ) const; + template< class T > const T& GetValue( const char *pAttributeName, const T& defaultValue ) const; + + template< class T > const CUtlVector<T>& GetArray( const char *pAttributeName ) const; + template< class T > const CUtlVector<T>& GetArray( const char *pAttributeName, const CUtlVector<T>& defaultValue ) const; + + // Set methods + CDmxAttribute* SetValue( const char *pAttributeName, const char *pString ); + CDmxAttribute* SetValue( const char *pAttributeName, void *pBuffer, int nLen ); + template< class T > CDmxAttribute* SetValue( const char *pAttributeName, const T& value ); + + // Method to unpack data into a structure + void UnpackIntoStructure( void *pData, size_t DataSizeInBytes, const DmxElementUnpackStructure_t *pUnpack ) const; + + // Creates attributes based on the unpack structure + template <typename T> + void AddAttributesFromStructure( const T *pData, const DmxElementUnpackStructure_t *pUnpack ) + { + AddAttributesFromStructure_Internal( pData, sizeof(T), pUnpack ); + } + +private: + void AddAttributesFromStructure_Internal( const void *pData, size_t byteCount, const DmxElementUnpackStructure_t *pUnpack ); + typedef CUtlSortVector< CDmxAttribute*, CDmxAttributeLess > AttributeList_t; + + CDmxElement( const char *pType ); + ~CDmxElement(); + + // Removes all elements recursively + void RemoveAllElementsRecursive(); + + // Adds elements to delete to the deletion list + void AddElementsToDelete( CUtlVector< CDmxElement * >& elementsToDelete ); + + // Sorts the vector when a change has occurred + void Resort( ) const; + + // Finds an attribute by name + int FindAttribute( const char *pAttributeName ) const; + int FindAttribute( CUtlSymbol attributeName ) const; + + // Sets the object id + void SetId( const DmObjectId_t &id ); + + // Are we locked? + bool IsLocked() const; + + AttributeList_t m_Attributes; + DmObjectId_t m_Id; // We need this strictly because we support serialization + CUtlSymbol m_Type; + char m_nLockCount; + mutable bool m_bResortNeeded : 1; + bool m_bIsMarkedForDeletion : 1; + + static CUtlSymbolTableMT s_TypeSymbols; + + friend class CDmxSerializer; + friend class CDmxSerializerKeyValues2; + friend void CleanupDMX( CDmxElement* pElement ); + friend CDmxElement* CreateDmxElement( const char *pType ); +}; + + +//----------------------------------------------------------------------------- +// inline methods +//----------------------------------------------------------------------------- + +// Are we locked? +inline bool CDmxElement::IsLocked() const +{ + return m_nLockCount > 0; +} + +inline const char *CDmxElement::GetValueString( const char *pAttributeName ) const +{ + const CDmxAttribute* pAttribute = GetAttribute( pAttributeName ); + if ( pAttribute ) + return pAttribute->GetValueString(); + return ""; +} + +template< class T > +inline const T& CDmxElement::GetValue( const char *pAttributeName ) const +{ + const CDmxAttribute* pAttribute = GetAttribute( pAttributeName ); + if ( pAttribute ) + return pAttribute->GetValue<T>(); + + static T defaultValue; + CDmAttributeInfo<T>::SetDefaultValue( defaultValue ); + return defaultValue; +} + +template< class T > +inline const T& CDmxElement::GetValue( const char *pAttributeName, const T& defaultValue ) const +{ + const CDmxAttribute* pAttribute = GetAttribute( pAttributeName ); + if ( pAttribute ) + return pAttribute->GetValue<T>(); + return defaultValue; +} + +template< class T > +inline const CUtlVector<T>& CDmxElement::GetArray( const char *pAttributeName ) const +{ + const CDmxAttribute* pAttribute = GetAttribute( pAttributeName ); + if ( pAttribute ) + return pAttribute->GetArray<T>(); + + static CUtlVector<T> defaultValue; + return defaultValue; +} + +template< class T > +inline const CUtlVector<T>& CDmxElement::GetArray( const char *pAttributeName, const CUtlVector<T>& defaultValue ) const +{ + const CDmxAttribute* pAttribute = GetAttribute( pAttributeName ); + if ( pAttribute ) + return pAttribute->GetArray<T>(); + return defaultValue; +} + + +//----------------------------------------------------------------------------- +// Creates a dmx element +//----------------------------------------------------------------------------- +CDmxElement* CreateDmxElement( const char *pType ); + + +//----------------------------------------------------------------------------- +// Helper class to lock elements for changes +//----------------------------------------------------------------------------- +class CDmxElementModifyScope +{ +public: + CDmxElementModifyScope( CDmxElement *pElement ) : m_pElement( pElement ) + { + m_pElement->LockForChanges( true ); + } + ~CDmxElementModifyScope() + { + Release(); + } + void Release() + { + if ( m_pElement ) + { + m_pElement->LockForChanges( false ); + m_pElement = NULL; + } + } +private: + CDmxElement *m_pElement; +}; + + +//----------------------------------------------------------------------------- +// Set methods +//----------------------------------------------------------------------------- +inline CDmxAttribute* CDmxElement::SetValue( const char *pAttributeName, const char *pString ) +{ + CDmxElementModifyScope modify( this ); + CDmxAttribute *pAttribute = AddAttribute( pAttributeName ); + pAttribute->SetValue( pString ); + return pAttribute; +} + +inline CDmxAttribute* CDmxElement::SetValue( const char *pAttributeName, void *pBuffer, int nLen ) +{ + CDmxElementModifyScope modify( this ); + CDmxAttribute *pAttribute = AddAttribute( pAttributeName ); + pAttribute->SetValue( pBuffer, nLen ); + return pAttribute; +} + +template< class T > +inline CDmxAttribute* CDmxElement::SetValue( const char *pAttributeName, const T& value ) +{ + CDmxElementModifyScope modify( this ); + CDmxAttribute *pAttribute = AddAttribute( pAttributeName ); + pAttribute->SetValue( value ); + return pAttribute; +} + + +#endif // DMXELEMENT_H diff --git a/public/dmxloader/dmxloader.h b/public/dmxloader/dmxloader.h new file mode 100644 index 0000000..54815ae --- /dev/null +++ b/public/dmxloader/dmxloader.h @@ -0,0 +1,72 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef DMXLOADER_H +#define DMXLOADER_H + +#ifdef _WIN32 +#pragma once +#endif + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CUtlBuffer; +class CDmxElement; + + +//----------------------------------------------------------------------------- +// Serialization/Unserialization +//----------------------------------------------------------------------------- +bool SerializeDMX( CUtlBuffer &buf, CDmxElement *pRoot, const char *pFileName = NULL ); +bool SerializeDMX( const char *pFileName, const char *pPathID, bool bTextMode, CDmxElement *pRoot ); + +bool UnserializeDMX( CUtlBuffer &buf, CDmxElement **ppRoot, const char *pFileName = NULL ); +bool UnserializeDMX( const char *pFileName, const char *pPathID, bool bTextMode, CDmxElement **ppRoot ); + +//----------------------------------------------------------------------------- +// DMX elements/attributes can only be accessed inside a dmx context +//----------------------------------------------------------------------------- +void BeginDMXContext( ); +void EndDMXContext( bool bDecommitMemory ); +void DecommitDMXMemory(); + + +//----------------------------------------------------------------------------- +// Helper macro +//----------------------------------------------------------------------------- +class CDMXContextHelper +{ +public: + CDMXContextHelper( bool bDecommitMemory ) { m_bDecommitMemory = bDecommitMemory; BeginDMXContext(); } + ~CDMXContextHelper() { EndDMXContext( m_bDecommitMemory ); } + +private: + bool m_bDecommitMemory; +}; + +#define DECLARE_DMX_CONTEXT( ) CDMXContextHelper __dmxContextHelper( true ); +#define DECLARE_DMX_CONTEXT_NODECOMMIT( ) CDMXContextHelper __dmxContextHelper( false ); +#define DECLARE_DMX_CONTEXT_DECOMMIT( _decommit ) CDMXContextHelper __dmxContextHelper( _decommit ); + + +//----------------------------------------------------------------------------- +// Used for allocation. All will be freed when we leave the DMX context +//----------------------------------------------------------------------------- +void* DMXAlloc( size_t size ); + + +//----------------------------------------------------------------------------- +// Helper macro +//----------------------------------------------------------------------------- +#define DECLARE_DMX_ALLOCATOR( ) \ + public: \ + inline void* operator new( size_t size ) { MEM_ALLOC_CREDIT_( "DMXAlloc" ); return DMXAlloc(size); } \ + inline void* operator new( size_t size, int nBlockUse, const char *pFileName, int nLine ) { MEM_ALLOC_CREDIT_( "DMXAlloc" ); return DMXAlloc(size); } \ + inline void operator delete( void* p ) { } \ + inline void operator delete( void* p, int nBlockUse, const char *pFileName, int nLine ) { } \ + +#endif // DMXLOADER_H
\ No newline at end of file |