bool ComponentCollection::ValidateComponent( const ComponentPtr &component, tstring& error ) const { HELIUM_ASSERT( component->GetSlot() != Reflect::ReservedTypes::Invalid ); // Check for duplicates. if ( ContainsComponent( component->GetSlot() ) ) { error = tstring( TXT( "The component '" ) )+ component->GetClass()->m_UIName + TXT( "' is a duplicate (a component already occupies that slot in the collection)." ); return false; } // Check to make sure this type of collection accepts this type of component. if ( !ValidateCompatible( component, error ) ) { return false; } // Check to make sure that each component already within the collection is valid with the new one. M_Component::const_iterator itr = m_Components.begin(); M_Component::const_iterator end = m_Components.end(); for ( ; itr != end; ++itr ) { // Check both directions so that the validation rule only has to be implemented in one place. if ( !itr->second->ValidateSibling( component, error ) || !component->ValidateSibling( itr->second.Ptr(), error ) ) { return false; } } return true; }
ComponentCollection::ComponentCollection( const ComponentPtr& component ) { HELIUM_ASSERT( component->GetSlot() != Reflect::ReservedTypes::Invalid ); m_Components.insert( M_Component::value_type( component->GetSlot(), component ) ); component->AddChangedListener( ElementChangeSignature::Delegate::Create<ComponentCollection, void (ComponentCollection::*)( const Reflect::ElementChangeArgs& )> ( this, &ComponentCollection::ComponentChanged ) ); m_Modified = true; }
ComponentCollection::ComponentCollection( const ComponentPtr& component ) { HELIUM_ASSERT( component->GetSlot() != NULL ); m_Components.insert( M_Component::value_type( component->GetSlot(), component ) ); component->e_Changed.Add( ObjectChangeSignature::Delegate::Create<ComponentCollection, void (ComponentCollection::*)( const Reflect::ObjectChangeArgs& )> ( this, &ComponentCollection::ComponentChanged ) ); m_Modified = true; }
bool ComponentCollection::ValidatePersistent( const ComponentPtr& component ) const { HELIUM_ASSERT( component->GetSlot() != Reflect::ReservedTypes::Invalid ); // by default, all attributes are persistent return true; }
bool ComponentCollection::ValidatePersistent( const ComponentPtr& component ) const { HELIUM_ASSERT( component->GetSlot() != NULL ); // by default, all attributes are persistent return true; }
bool ComponentCollection::SetComponent(const ComponentPtr& component, bool validate, std::string* error ) { HELIUM_ASSERT( component->GetSlot() != NULL ); M_Component::const_iterator found = m_Components.find( component->GetSlot() ); if (found != m_Components.end() && found->second == component) { return true; // nothing to do, this is already in the collection } std::string errorMessage; if ( validate && !ValidateComponent( component, errorMessage ) ) { if ( error ) { std::string componentName; Helium::ConvertString( component->GetMetaClass()->m_Name, componentName ); std::string collectionName; Helium::ConvertString( GetMetaClass()->m_Name, collectionName ); *error = std::string( TXT( "Component '" ) ) + componentName + TXT( "' is not valid for collection '" ) + collectionName + TXT( "': " ) + errorMessage; } return false; } // Event args ComponentCollectionChanged args ( this, component ); // Set the component and connect the collection m_Components[ component->GetSlot() ] = component; component->SetCollection( this ); // Start caring about change to the component component->e_Changed.Add( ObjectChangeSignature::Delegate::Create<ComponentCollection, void (ComponentCollection::*)( const Reflect::ObjectChangeArgs& )> ( this, &ComponentCollection::ComponentChanged ) ); // Raise event m_Modified = true; m_ComponentAdded.Raise( args ); return true; }
bool ComponentCollection::ValidateCompatible( const ComponentPtr& component, tstring& error ) const { HELIUM_ASSERT( component->GetSlot() != Reflect::ReservedTypes::Invalid ); if ( component->GetComponentBehavior() == ComponentBehaviors::Exclusive ) { error = component->GetClass()->m_UIName + TXT( " cannot be added to a(n) " ) + GetClass()->m_UIName + TXT( " because it is an exclusive component." ); return false; } return true; }
bool ComponentCollection::CopyComponentTo( ComponentCollection& destCollection, const ComponentPtr& destAttrib, const ComponentPtr& srcAttrib ) { bool inserted = false; Reflect::Registry* registry = Reflect::Registry::GetInstance(); tstring unused; // If there is already an component in the destination slot, or the // component is not in the destination, but is allowed to be... if ( destCollection.ValidateComponent( destAttrib, unused ) ) { // Component can be added to the destination collection, so do it! srcAttrib->CopyTo( destAttrib ); destCollection.SetComponent( destAttrib, false ); inserted = true; } else { ComponentPtr existing = destCollection.GetComponent( destAttrib->GetSlot() ); if ( existing.ReferencesObject() ) { destCollection.RemoveComponent( existing->GetSlot() ); if ( destCollection.ValidateComponent( destAttrib, unused ) ) { srcAttrib->CopyTo( destAttrib ); destCollection.SetComponent( destAttrib, false ); inserted = true; } else { destCollection.SetComponent( existing, false ); } } } return inserted; }
bool ComponentCollection::SetComponent(const ComponentPtr& component, bool validate, tstring* error ) { HELIUM_ASSERT( component->GetSlot() != Reflect::ReservedTypes::Invalid ); M_Component::const_iterator found = m_Components.find( component->GetSlot() ); if (found != m_Components.end() && found->second == component) { return true; // nothing to do, this is already in the collection } tstring errorMessage; if ( validate && !ValidateComponent( component, errorMessage ) ) { if ( error ) { *error = tstring( TXT( "Component '" ) ) + component->GetClass()->m_ShortName + TXT( "' is not valid for collection '" ) + GetClass()->m_ShortName + TXT( "': " ) + errorMessage; } return false; } // Event args ComponentCollectionChanged args ( this, component ); // Set the component and connect the collection m_Components[ component->GetSlot() ] = component; component->SetCollection( this ); // Start caring about change to the component component->AddChangedListener( ElementChangeSignature::Delegate::Create<ComponentCollection, void (ComponentCollection::*)( const Reflect::ElementChangeArgs& )> ( this, &ComponentCollection::ComponentChanged ) ); // Raise event m_Modified = true; m_ComponentAdded.Raise( args ); return true; }
bool ComponentCollection::ValidateCompatible( const ComponentPtr& component, std::string& error ) const { HELIUM_ASSERT( component->GetSlot() != NULL ); if ( component->GetComponentBehavior() == ComponentBehaviors::Exclusive ) { error = *component->GetMetaClass()->m_Name; error += TXT( " cannot be added to a(n) " ); error += *GetMetaClass()->m_Name; error += TXT( " because it is an exclusive component." ); return false; } return true; }