mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-08 01:39:36 +00:00
1
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user