void SimpleElementMapSerializer<KeyT>::Deserialize(Archive& archive)
{
    V_Element components;
    archive.Deserialize(components, ArchiveFlags::Sparse);

    if (components.size() % 2 != 0)
    {
        throw Reflect::DataFormatException( TXT( "Unmatched map objects" ) );
    }

    // if we are referring to a real field, clear its contents
    m_Data->clear();

    V_Element::iterator itr = components.begin();
    V_Element::iterator end = components.end();
    for ( ; itr != end; ++itr )
    {
        Serializer* key = ObjectCast<Serializer>(*itr);
        Element* value = *(++itr);
        if ( key && value )
        {
            KeyT k;
            Serializer::GetValue( key, k );
            m_Data.Ref()[ k ] = value;
        }
    }
}
Beispiel #2
0
void SimpleSetSerializer<DataT, DataSer>::Serialize(Archive& archive) const
{
    int i = 0;
    V_Element components;
    components.resize( m_Data->size() );

    {
        DataType::const_iterator itr = m_Data->begin();
        DataType::const_iterator end = m_Data->end();
        for ( ; itr != end; ++itr )
        {
            ElementPtr dataElem;

            // query cache for a serializer of this type
            archive.GetCache().Create( Reflect::GetType<DataSer>(), dataElem );

            // downcast to serializer type
            DataSer* dataSer = DangerousCast<DataSer>(dataElem);

            // connect to our map data memory address
            dataSer->ConnectData(const_cast<DataT*>(&(*itr)));

            // serialize to the archive stream
            components[i++] = dataSer;
        }
    }

    archive.Serialize(components);

    V_Element::iterator itr = components.begin();
    V_Element::iterator end = components.end();
    for ( ; itr != end; ++itr )
    {
        // downcast to serializer type
        Serializer* ser = DangerousCast<Serializer>(*itr);

        // disconnect from memory
        ser->Disconnect();

        // restore serializer to the cache
        archive.GetCache().Free( ser );
    }
}
Beispiel #3
0
void SimpleSetSerializer<DataT, DataSer>::Deserialize(Archive& archive)
{
    V_Element components;
    archive.Deserialize(components);

    // if we are referring to a real field, clear its contents
    m_Data->clear();

    V_Element::iterator itr = components.begin();
    V_Element::iterator end = components.end();
    for ( ; itr != end; ++itr )
    {
        DataSer* data = ObjectCast<DataSer>(*itr);
        if (!data)
        {
            throw LogisticException( TXT( "Set value type has changed, this is unpossible" ) );
        }

        m_Data->insert(data->m_Data.Get());
    }
}
void SimpleElementMapSerializer<KeyT>::Serialize(Archive& archive) const
{
    V_Element components;
    components.resize(m_Data->size() * 2);

    {
        DataType::const_iterator itr = m_Data->begin();
        DataType::const_iterator end = m_Data->end();
        for ( int i = 0; itr != end; ++itr )
        {
            if (!itr->second.ReferencesObject())
            {
                continue;
            }

            ElementPtr elem;
            archive.GetCache().Create( Reflect::GetType<KeyT>(), elem );

            Serializer* ser = AssertCast<Serializer>(elem.Ptr());
            ser->ConnectData((void*)&(itr->first));

            components[i++] = ser;
            components[i++] = itr->second;
        }
    }

    archive.Serialize(components);

    {
        V_Element::iterator itr = components.begin();
        V_Element::iterator end = components.end();
        for ( ; itr != end; ++itr )
        {
            Serializer* ser = AssertCast<Serializer>(*itr);
            ser->Disconnect();
            archive.GetCache().Free(ser);
            ++itr;
        }
    }
}
Beispiel #5
0
void ReflectInterpreter::InterpretType(const std::vector<Reflect::Element*>& instances, Container* parent, i32 includeFlags, i32 excludeFlags, bool expandPanel)
{
  const Class* typeInfo = instances[0]->GetClass();
  
  // create a panel
  PanelPtr panel = m_Container->GetCanvas()->Create<Panel>(this);

  // parse
  ContainerPtr scriptOutput = m_Container->GetCanvas()->Create<Container>(this);

  tstring typeInfoUI;
  typeInfo->GetProperty( TXT( "UIScript" ), typeInfoUI );
  bool result = Script::Parse(typeInfoUI, this, parent->GetCanvas(), scriptOutput);

  // compute panel label
  tstring labelText;
  if (result)
  {
    V_Control::const_iterator itr = scriptOutput->GetControls().begin();
    V_Control::const_iterator end = scriptOutput->GetControls().end();
    for( ; itr != end; ++itr )
    {
      Label* label = Reflect::ObjectCast<Label>( *itr );
      if (label)
      {
          bool converted = Helium::ConvertString( label->GetText(), labelText );
          HELIUM_ASSERT( converted );
            
        if ( !labelText.empty() )
        {
          break;
        }
      }
    }
  }

  if (labelText.empty())
  {
    std::vector<Reflect::Element*>::const_iterator itr = instances.begin();
    std::vector<Reflect::Element*>::const_iterator end = instances.end();
    for ( ; itr != end; ++itr )
    {
      Reflect::Element* instance = *itr;

      if ( labelText.empty() )
      {
        labelText = instance->GetTitle();
      }
      else
      {
        if ( labelText != instance->GetTitle() )
        {
          labelText.clear();
          break;
        }
      }
    }

    if ( labelText.empty() )
    {
      labelText = typeInfo->m_UIName;
    }
  }

  tstring temp;
  bool converted = Helium::ConvertString( labelText, temp );
  HELIUM_ASSERT( converted );

  panel->SetText( temp );

  M_Panel panelsMap;
  panelsMap.insert( std::make_pair( TXT( "" ), panel) );

  // don't bother including Element's fields
  int offset = Reflect::GetClass<Element>()->m_LastFieldID;

  // for each field in the type
  M_FieldIDToInfo::const_iterator itr = typeInfo->m_FieldIDToInfo.find(offset + 1);
  M_FieldIDToInfo::const_iterator end = typeInfo->m_FieldIDToInfo.end();
  for ( ; itr != end; ++itr )
  {
    const Field* field = itr->second;

    bool noFlags = ( field->m_Flags == 0 && includeFlags == 0xFFFFFFFF );
    bool doInclude = ( field->m_Flags & includeFlags ) != 0;
    bool dontExclude = ( excludeFlags == 0 ) || !(field->m_Flags & excludeFlags );
    bool hidden = (field->m_Flags & Reflect::FieldFlags::Hide) != 0; 

    // if we don't have flags (or we are included, and we aren't excluded) then make UI
    if ( ( noFlags || doInclude ) && ( dontExclude ) )
    {
      //
      // Handle sub panels for grouping content
      // 

      bool groupExpanded = false;
      field->GetProperty( TXT( "UIGroupExpanded" ), groupExpanded );

      tstring fieldUIGroup;
      field->GetProperty( TXT( "UIGroup" ), fieldUIGroup );
      if ( !fieldUIGroup.empty() )
      {
        M_Panel::iterator itr = panelsMap.find( fieldUIGroup );
        if ( itr == panelsMap.end() )
        {
          // This panel isn't in our list so make a new one
          PanelPtr newPanel = m_Container->GetCanvas()->Create<Panel>(this);
          panelsMap.insert( std::make_pair(fieldUIGroup, newPanel) );

          PanelPtr parent;
          tstring groupName;
          size_t idx = fieldUIGroup.find_last_of( TXT( "/" ) );
          if ( idx != tstring::npos )
          {
            tstring parentName = fieldUIGroup.substr( 0, idx );
            groupName = fieldUIGroup.substr( idx+1 );
            if ( panelsMap.find( parentName ) == panelsMap.end() )
            {          
              parent = m_Container->GetCanvas()->Create<Panel>(this);

              // create the parent hierarchy since it hasn't already been made
              tstring currentParent = parentName;
              for (;;)
              {
                idx = currentParent.find_last_of( TXT( "/" ) );
                if ( idx == tstring::npos )
                {
                  // no more parents so we add it to the root
                  panelsMap.insert( std::make_pair(currentParent, parent) );
                  parent->SetText( currentParent );
                  panelsMap[ TXT( "" ) ]->AddControl( parent );
                  break;
                }
                else
                {
                  parent->SetText( currentParent.substr( idx+1 ) );
                  
                  if ( panelsMap.find( currentParent ) != panelsMap.end() )
                  {
                    break;
                  }
                  else
                  {
                    PanelPtr grandParent = m_Container->GetCanvas()->Create<Panel>(this);
                    grandParent->AddControl( parent );
                    panelsMap.insert( std::make_pair(currentParent, parent) );
                    
                    parent = grandParent;
                  }
                  currentParent = currentParent.substr( 0, idx );
                }
              }
              panelsMap.insert( std::make_pair(parentName, parent) );
            }
            parent = panelsMap[parentName];
          }
          else
          {
            parent = panelsMap[ TXT( "" )];
            groupName = fieldUIGroup;
          }
          newPanel->SetText( groupName );
          if( groupExpanded )
          {
            newPanel->SetExpanded( true );
          }
          parent->AddControl( newPanel );
        }
        
        panel = panelsMap[fieldUIGroup];
      }
      else
      {
        panel = panelsMap[ TXT( "" )];
      }


      //
      // Pointer support
      //

      if (field->m_SerializerID == Reflect::GetType<Reflect::PointerSerializer>())
      {
        if (hidden)
        {
          continue; 
        }        

        std::vector<Reflect::Element*> fieldInstances;

        std::vector<Reflect::Element*>::const_iterator elementItr = instances.begin();
        std::vector<Reflect::Element*>::const_iterator elementEnd = instances.end();
        for ( ; elementItr != elementEnd; ++elementItr )
        {
          uintptr fieldAddress = (uintptr)(*elementItr) + itr->second->m_Offset;

          Element* element = *((ElementPtr*)(fieldAddress));

          if ( element )
          {
            fieldInstances.push_back( element );
          }
        }

        if ( !fieldInstances.empty() && fieldInstances.size() == instances.size() )
        {
          InterpretType(fieldInstances, panel);
        }

        continue;
      }


      //
      // Attempt to find a handler via the factory
      //

      ReflectFieldInterpreterPtr fieldInterpreter;

      for ( const Reflect::Class* type = Registry::GetInstance()->GetClass( field->m_SerializerID );
            type != Reflect::GetClass<Reflect::Element>() && !fieldInterpreter;
            type = Reflect::Registry::GetInstance()->GetClass( type->m_Base ) )
      {
        fieldInterpreter = ReflectFieldInterpreterFactory::Create( type->m_TypeID, field->m_Flags, m_Container );
      }

      if ( fieldInterpreter.ReferencesObject() )
      {
        Interpreter::ConnectInterpreterEvents( this, fieldInterpreter );
        fieldInterpreter->InterpretField( field, instances, panel );
        m_Interpreters.push_back( fieldInterpreter );
        continue;
      }


      //
      // ElementArray support
      //

#pragma TODO("Move this out to an interpreter")
      if (field->m_SerializerID == Reflect::GetType<ElementArraySerializer>())
      {
        if (hidden)
        {
          continue;
        }

        if ( instances.size() == 1 )
        {
          uintptr fieldAddress = (uintptr)(instances.front()) + itr->second->m_Offset;

          V_Element* elements = (V_Element*)fieldAddress;

          if ( elements->size() > 0 )
          {
            PanelPtr childPanel = panel->GetCanvas()->Create<Panel>( this );

               tstring temp;
              bool converted = Helium::ConvertString( field->m_UIName, temp );
              HELIUM_ASSERT( converted );

              childPanel->SetText( temp );

            V_Element::const_iterator elementItr = elements->begin();
            V_Element::const_iterator elementEnd = elements->end();
            for ( ; elementItr != elementEnd; ++elementItr )
            {
              std::vector<Reflect::Element*> childInstances;
              childInstances.push_back(*elementItr);
              InterpretType(childInstances, childPanel);
            }

            panel->AddControl( childPanel );
          }
        }

        continue;
      }


      //
      // Lastly fall back to the value interpreter
      //

      const Reflect::Class* type = Registry::GetInstance()->GetClass( field->m_SerializerID );
      if ( !type->HasType( Reflect::GetType<Reflect::ContainerSerializer>() ) )
      {
        fieldInterpreter = CreateInterpreter< ReflectValueInterpreter >( m_Container );
        fieldInterpreter->InterpretField( field, instances, panel );
        m_Interpreters.push_back( fieldInterpreter );
        continue;
      }
    }
  }

  // Make sure we have the base panel
  panel = panelsMap[TXT( "" )];

  if (parent == m_Container)
  {
    panel->SetExpanded(expandPanel);
  }

  if ( !panel->GetControls().empty() )
  {
    parent->AddControl(panel);
  }
}