コード例 #1
0
ファイル: ArchiveXML.cpp プロジェクト: euler0/Helium
void ArchiveXML::DeserializeArray( ArrayPusher& push, uint32_t flags )
{
    if ( m_Iterator.GetCurrent()->GetFirstChild() )
    {
        // advance to the first child (the first array element)
        m_Iterator.Advance();

#ifdef REFLECT_ARCHIVE_VERBOSE
        m_Indent.Get(stdout);
        Log::Print(TXT("Deserializing objects\n"));
        m_Indent.Push();
#endif

        for ( XMLElement* sibling = m_Iterator.GetCurrent(); sibling != NULL; sibling = sibling->GetNextSibling() )
        {
            HELIUM_ASSERT( m_Iterator.GetCurrent() == sibling );

            ObjectPtr object;
            DeserializeInstance(object);

            if (object.ReferencesObject())
            {
                if ( object->IsClass( m_SearchClass ) )
                {
                    m_Skip = true;
                }

                if ( flags & ArchiveFlags::Status )
                {
                    ArchiveStatus info( *this, ArchiveStates::ObjectProcessed );
#pragma TODO("Update progress value for inter-array processing")
                    //info.m_Progress = (int)(((float)(current - start_offset) / (float)m_Size) * 100.0f);
                    e_Status.Raise( info );

                    m_Abort |= info.m_Abort;
                }
            }

            push( object );
        }
    }
    else
    {
        // advance to the next element
        m_Iterator.Advance();
    }

#ifdef REFLECT_ARCHIVE_VERBOSE
    m_Indent.Pop();
#endif

    if ( flags & ArchiveFlags::Status )
    {
        ArchiveStatus info( *this, ArchiveStates::ObjectProcessed );
        info.m_Progress = 100;
        e_Status.Raise( info );
    }
}
コード例 #2
0
ファイル: ArchiveXML.cpp プロジェクト: euler0/Helium
void ArchiveXML::DeserializeFields( void* structure, const Structure* type )
{
    if ( m_Iterator.GetCurrent()->GetFirstChild() )
    {
        // advance to the first child
        m_Iterator.Advance();

        for ( XMLElement* sibling = m_Iterator.GetCurrent(); sibling != NULL; sibling = sibling->GetNextSibling() )
        {
            HELIUM_ASSERT( m_Iterator.GetCurrent() == sibling );

            const String* fieldNameStr = sibling->GetAttributeValue( Name( TXT("Name") ) );
            uint32_t fieldNameCrc = fieldNameStr ? Crc32( fieldNameStr->GetData() ) : 0x0;

            const Field* field = type->FindFieldByName(fieldNameCrc);
            if ( field )
            {
#ifdef REFLECT_ARCHIVE_VERBOSE
                m_Indent.Get(stdout);
                Log::Debug(TXT("Deserializing field %s\n"), field->m_Name);
                m_Indent.Push();
#endif

                // pull and structure and downcast to data
                DataPtr latentData = SafeCast<Data>( Allocate() );
                if (!latentData.ReferencesObject())
                {
                    // this should never happen, the type id read from the file is bogus
                    throw Reflect::TypeInformationException( TXT( "Unknown data for field %s (%s)" ), field->m_Name, m_Path.c_str() );
#pragma TODO("Support blind data")
                }

                // if the types match we are a natural fit to just deserialize directly into the field data
                if ( field->m_DataClass == field->m_DataClass )
                {
                    // set data pointer
                    latentData->ConnectField( structure, field );

                    // process natively
                    DeserializeInstance( (ObjectPtr&)latentData );

                    // disconnect
                    latentData->Disconnect();
                }
                else // else the type does not match, deserialize it into temp data then attempt to cast it into the field data
                {
                    REFLECT_SCOPE_TIMER(("Casting"));

                    // construct current serialization structure
                    ObjectPtr currentObject = Registry::GetInstance()->CreateInstance( field->m_DataClass );

                    // downcast to data
                    DataPtr currentData = SafeCast<Data>(currentObject);
                    if (!currentData.ReferencesObject())
                    {
                        // this should never happen, the type id in the rtti data is bogus
                        throw Reflect::TypeInformationException( TXT( "Invalid type id for field %s (%s)" ), field->m_Name, m_Path.c_str() );
                    }

                    // process into temporary memory
                    currentData->ConnectField(structure, field);

                    // process natively
                    DeserializeInstance( (ObjectPtr&)latentData );

                    // attempt cast data into new definition
                    Data::CastValue( latentData, currentData, DataFlags::Shallow );

                    // disconnect
                    currentData->Disconnect();
                }
            }

#ifdef REFLECT_ARCHIVE_VERBOSE
            m_Indent.Pop();
#endif
        }
    }
    else
    {
        // advance to the next element
        m_Iterator.Advance();
    }
}