diff options
Diffstat (limited to 'dmxloader/dmxserializationdictionary.cpp')
| -rw-r--r-- | dmxloader/dmxserializationdictionary.cpp | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/dmxloader/dmxserializationdictionary.cpp b/dmxloader/dmxserializationdictionary.cpp new file mode 100644 index 0000000..4e30efa --- /dev/null +++ b/dmxloader/dmxserializationdictionary.cpp @@ -0,0 +1,188 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include "dmxserializationdictionary.h" +#include "dmxloader/dmxelement.h" +#include "dmxloader/dmxattribute.h" + + +//----------------------------------------------------------------------------- +// +// Element dictionary used in serialization +// +//----------------------------------------------------------------------------- +CDmxSerializationDictionary::CDmxSerializationDictionary( int nElementsHint /* = 0 */ ) : + m_Dict( 0, nElementsHint, CDmxSerializationDictionary::LessFunc ) +{ +} + + +//----------------------------------------------------------------------------- +// Used to sort the list of elements +//----------------------------------------------------------------------------- +bool CDmxSerializationDictionary::LessFunc( const DmxElementInfo_t &lhs, const DmxElementInfo_t &rhs ) +{ + return lhs.m_pElement < rhs.m_pElement; +} + + +//----------------------------------------------------------------------------- +// Finds the handle of the element +//----------------------------------------------------------------------------- +DmxSerializationHandle_t CDmxSerializationDictionary::Find( CDmxElement *pElement ) +{ + DmxElementInfo_t find; + find.m_pElement = pElement; + return m_Dict.Find( find ); +} + + +//----------------------------------------------------------------------------- +// Creates the list of all things to serialize +//----------------------------------------------------------------------------- +void CDmxSerializationDictionary::BuildElementList_R( CDmxElement *pElement, bool bFlatMode, bool bIsRoot ) +{ + if ( !pElement ) + return; + + // FIXME: Right here we should ask the element if it's an external + // file reference and exit immediately if so. + + // This means we've already encountered this guy. + // Therefore, he can never be a root element + DmxSerializationHandle_t h = Find( pElement ); + if ( h != m_Dict.InvalidIndex() ) + { + m_Dict[h].m_bRoot = true; + return; + } + + DmxElementInfo_t info; + info.m_bRoot = bFlatMode || bIsRoot; + info.m_pElement = pElement; + m_Dict.Insert( info ); + + int nCount = pElement->AttributeCount(); + for ( int i = 0; i < nCount; ++i ) + { + CDmxAttribute *pAttribute = pElement->GetAttribute(i); + switch( pAttribute->GetType() ) + { + case AT_ELEMENT: + { + CDmxElement *pChild = pAttribute->GetValue<CDmxElement*>(); + if ( !pChild ) + break; + + BuildElementList_R( pChild, bFlatMode, false ); + } + break; + + case AT_ELEMENT_ARRAY: + { + const CUtlVector<CDmxElement*> &array = pAttribute->GetArray<CDmxElement*>( ); + int nCountArray = array.Count(); + for ( int j = 0; j < nCountArray; ++j ) + { + CDmxElement *pChild = array[ j ]; + if ( !pChild ) + break; + + BuildElementList_R( pChild, bFlatMode, false ); + } + } + break; + } + } +} + +void CDmxSerializationDictionary::BuildElementList( CDmxElement *pElement, bool bFlatMode ) +{ + BuildElementList_R( pElement, bFlatMode, true ); +} + + +//----------------------------------------------------------------------------- +// Should I inline the serialization of this element? +//----------------------------------------------------------------------------- +bool CDmxSerializationDictionary::ShouldInlineElement( CDmxElement *pElement ) +{ + // This means we've already encountered this guy. + // Therefore, he can never be a root element + DmxSerializationHandle_t h = Find( pElement ); + if ( h != m_Dict.InvalidIndex() ) + return !m_Dict[h].m_bRoot; + + // If we didn't find the element, it means it's a reference to an external + // element (or it's NULL), so don't inline ie. + return false; +} + + +//----------------------------------------------------------------------------- +// Clears the dictionary +//----------------------------------------------------------------------------- +void CDmxSerializationDictionary::Clear() +{ + m_Dict.RemoveAll(); +} + + +//----------------------------------------------------------------------------- +// How many root elements do we have? +//----------------------------------------------------------------------------- +int CDmxSerializationDictionary::RootElementCount() const +{ + int nCount = 0; + DmxSerializationHandle_t h = m_Dict.FirstInorder(); + while( h != m_Dict.InvalidIndex() ) + { + if ( m_Dict[h].m_bRoot ) + { + ++nCount; + } + h = m_Dict.NextInorder( h ); + } + return nCount; +} + + +//----------------------------------------------------------------------------- +// Iterates over all root elements to serialize +//----------------------------------------------------------------------------- +DmxSerializationHandle_t CDmxSerializationDictionary::FirstRootElement() const +{ + // NOTE: I don't have to use First/NextInorder here because there + // are guaranteed to be no removals from the dictionary. + // Also, using inorder traversal won't get my actual root element to be first in the file + int nCount = m_Dict.Count(); + for ( DmxSerializationHandle_t h = 0; h < nCount; ++h ) + { + if ( m_Dict[h].m_bRoot ) + return h; + } + return DMX_SERIALIZATION_HANDLE_INVALID; +} + +DmxSerializationHandle_t CDmxSerializationDictionary::NextRootElement( DmxSerializationHandle_t h ) const +{ + ++h; + int nCount = m_Dict.Count(); + for ( ; h < nCount; ++h ) + { + if ( m_Dict[h].m_bRoot ) + return h; + } + return DMX_SERIALIZATION_HANDLE_INVALID; +} + +CDmxElement *CDmxSerializationDictionary::GetRootElement( DmxSerializationHandle_t h ) +{ + Assert( m_Dict[h].m_bRoot ); + return m_Dict[h].m_pElement; +} + + |