const char *DynamicConsoleMethodComponent::callOnBehaviors( U32 argc, const char *argv[] ) { // Set Owner SimObject *pThis; pThis = dynamic_cast<SimObject *>( this ); AssertFatal( pThis, "DynamicConsoleMethodComponent::callOnBehaviors : this should always exist!" ); const char* result = ""; bool handled = false; if( getComponentCount() > 0 ) { VectorPtr<SimComponent *>&componentList = lockComponentList(); for( SimComponentIterator nItr = (componentList.end()-1); nItr >= componentList.begin(); nItr-- ) { argv[0] = StringTable->insert(argv[0]); SimComponent *pComponent = (*nItr); AssertFatal( pComponent, "DynamicConsoleMethodComponent::callOnBehaviors - NULL component in list!" ); handled = pComponent->callMethodOnComponents(argc, argv, &result); if (handled) break; } unlockComponentList(); } if (!handled) { result = "ERR_CALL_NOT_HANDLED"; } return result; }
void SimComponent::onRemove() { _unregisterComponents(); // Delete all components VectorPtr<SimComponent *>&componentList = lockComponentList(); while(componentList.size() > 0) { SimComponent *c = componentList[0]; componentList.erase( componentList.begin() ); if( c->isProperlyAdded() ) c->deleteObject(); else if( !c->isRemoved() && !c->isDeleted() ) delete c; // else, something else is deleting this, don't mess with it } unlockComponentList(); Parent::onRemove(); }
// Call all components that implement methodName giving them a chance to operate // Components are called in reverse order of addition const char *DynamicConsoleMethodComponent::_callMethod( U32 argc, const char *argv[], bool callThis /* = true */ ) { // Set Owner SimObject *pThis = dynamic_cast<SimObject *>( this ); AssertFatal( pThis, "DynamicConsoleMethodComponent::callMethod : this should always exist!" ); const char *cbName = StringTable->insert(argv[0]); if( getComponentCount() > 0 ) { VectorPtr<SimComponent *>&componentList = lockComponentList(); for( SimComponentIterator nItr = (componentList.end()-1); nItr >= componentList.begin(); nItr-- ) { argv[0] = cbName; SimComponent *pComponent = (*nItr); AssertFatal( pComponent, "DynamicConsoleMethodComponent::callMethod - NULL component in list!" ); DynamicConsoleMethodComponent *pThisComponent = dynamic_cast<DynamicConsoleMethodComponent*>( pComponent ); AssertFatal( pThisComponent, "DynamicConsoleMethodComponent::callMethod - Non DynamicConsoleMethodComponent component attempting to callback!"); // Only call on first depth components // Should isMethod check these calls? [11/22/2006 justind] if(pComponent->isEnabled()) Con::execute( pThisComponent, argc, argv ); // Bail if this was the first element //if( nItr == componentList.begin() ) // break; } unlockComponentList(); } // Set Owner Field const char* result = ""; if(callThis) result = Con::execute( pThis, argc, argv, true ); // true - exec method onThisOnly, not on DCMCs return result; }
bool SimComponent::callMethodOnComponents( U32 argc, const char* argv[], const char** result ) { const char *cbName = StringTable->insert(argv[0]); if (isEnabled()) { if(isMethod(cbName)) { // This component can handle the given method *result = Con::execute( this, argc, argv, true ); return true; } else if( getComponentCount() > 0 ) { // Need to try the component's children bool handled = false; VectorPtr<SimComponent *>&componentList = lockComponentList(); for( SimComponentIterator nItr = (componentList.end()-1); nItr >= componentList.begin(); nItr-- ) { argv[0] = cbName; SimComponent *pComponent = (*nItr); AssertFatal( pComponent, "SimComponent::callMethodOnComponents - NULL component in list!" ); // Call on children handled = pComponent->callMethodOnComponents( argc, argv, result ); if (handled) break; } unlockComponentList(); if (handled) return true; } } return false; }
TEST(MoreAdvancedComponent, MoreAdvancedComponent) { // Create component instances and compose them. SimComponent *parentComponent = new SimComponent(); SimpleComponent *simpleComponent = new SimpleComponent(); MoreAdvancedComponent *moreAdvComponent = new MoreAdvancedComponent(); // CodeReview note that the interface pointer isn't initialized in a ctor // on the components, so it's bad memory against which you might // be checking in testDependentInterface [3/3/2007 justind] parentComponent->addComponent( simpleComponent ); parentComponent->addComponent( moreAdvComponent ); simpleComponent->registerObject(); moreAdvComponent->registerObject(); // Put a break-point here, follow the onAdd call, and observe the order in // which the SimComponent::onAdd function executes. You will see the interfaces // get cached, and the dependent interface query being made. parentComponent->registerObject(); // If the MoreAdvancedComponent found an interface, than the parentComponent // should have returned true, from onAdd, and should therefore be registered // properly with the Sim EXPECT_TRUE( parentComponent->isProperlyAdded() ) << "Parent component not properly added!"; // Now lets test the interface. You can step through this, as well. EXPECT_TRUE( moreAdvComponent->testDependentInterface() ) << "Dependent interface test failed."; // CodeReview is there a reason we can't just delete the parentComponent here? [3/3/2007 justind] // // Clean up parentComponent->removeComponent( simpleComponent ); parentComponent->removeComponent( moreAdvComponent ); parentComponent->deleteObject(); moreAdvComponent->deleteObject(); simpleComponent->deleteObject(); };