const ComponentPtr& ComponentCollection::GetComponent(i32 slotID) const { static const ComponentPtr kNull; const M_Component::const_iterator end = m_Components.end(); M_Component::const_iterator found = m_Components.find( slotID ); if ( found != end ) { return found->second; } else { // Travel up the inheritance hierarchy looking for a base class slot within // this collection. Reflect::Registry* registry = Reflect::Registry::GetInstance(); const Reflect::Class* type = registry->GetClass( slotID ); type = registry->GetInstance()->GetClass( type->m_Base ); // While we have base class type information, and we haven't hit the Component // base class, keep iterating. while ( type && ( type->m_TypeID != Reflect::GetType< ComponentBase >() ) ) { // See if the base class has a slot in this collection. found = m_Components.find( type->m_TypeID ); if ( found != end ) { return found->second; } type = registry->GetInstance()->GetClass( type->m_Base ); } } return kNull; }
void ComponentCollection::CopyTo(const Reflect::ElementPtr& destination) { __super::CopyTo( destination ); ComponentCollection* destCollection = Reflect::ObjectCast< ComponentCollection >( destination ); if ( destCollection ) { // Remove all attributes, we're going to bring them over manually destCollection->Clear(); // For each component in this component collection Reflect::Registry* registry = Reflect::Registry::GetInstance(); M_Component::const_iterator attrItr = m_Components.begin(); M_Component::const_iterator attrEnd = m_Components.end(); for ( ; attrItr != attrEnd; ++attrItr ) { // Create a new copy of the component and try to add it to the destination const ComponentPtr& attrib = attrItr->second; ComponentPtr destAttrib = Reflect::AssertCast< ComponentBase >( registry->CreateInstance( attrib->GetClass() ) ); if ( !CopyComponentTo( *destCollection, destAttrib, attrib ) ) { // Component could not be added to the destination collection, check sibling classes const std::set<tstring>& derived = ( registry->GetClass( attrib->GetClass()->m_Base ) )->m_Derived; std::set<tstring>::const_iterator derivedItr = derived.begin(); std::set<tstring>::const_iterator derivedEnd = derived.end(); for ( ; derivedItr != derivedEnd; ++derivedItr ) { const Reflect::Class* currentType = Reflect::Registry::GetInstance()->GetClass(*derivedItr); if ( currentType->m_TypeID != attrib->GetType() ) { destAttrib = Reflect::AssertCast< ComponentBase >( registry->CreateInstance( currentType ) ); if ( destAttrib.ReferencesObject() ) { if ( CopyComponentTo( *destCollection, destAttrib, attrib ) ) { break; } } } } } } } }