Plug *Box::promotePlug( Plug *descendantPlug ) { validatePromotability( descendantPlug, /* throwExceptions = */ true ); PlugPtr externalPlug = descendantPlug->createCounterpart( promotedCounterpartName( descendantPlug ), descendantPlug->direction() ); externalPlug->setFlags( Plug::Dynamic, true ); // Flags are not automatically propagated to the children of compound plugs, // so we need to do that ourselves. We don't want to propagate them to the // children of plug types which create the children themselves during // construction though, hence the typeId checks for the base classes // which add no children during construction. I'm not sure this approach is // necessarily the best - the alternative would be to set everything dynamic // unconditionally and then implement Serialiser::childNeedsConstruction() // for types like CompoundNumericPlug that create children in their constructors. const Gaffer::TypeId compoundTypes[] = { PlugTypeId, ValuePlugTypeId, CompoundPlugTypeId, ArrayPlugTypeId }; const Gaffer::TypeId *compoundTypesEnd = compoundTypes + 4; if( find( compoundTypes, compoundTypesEnd, (Gaffer::TypeId)externalPlug->typeId() ) != compoundTypesEnd ) { for( RecursivePlugIterator it( externalPlug.get() ); it != it.end(); ++it ) { (*it)->setFlags( Plug::Dynamic, true ); if( find( compoundTypes, compoundTypesEnd, (Gaffer::TypeId)(*it)->typeId() ) != compoundTypesEnd ) { it.prune(); } } } if( externalPlug->direction() == Plug::In ) { if( ValuePlug *externalValuePlug = IECore::runTimeCast<ValuePlug>( externalPlug.get() ) ) { externalValuePlug->setFrom( static_cast<ValuePlug *>( descendantPlug ) ); } } // Copy over the metadata for nodule position, so the nodule appears in the expected spot. // This must be done before parenting the new plug, as the nodule is created from childAddedSignal(). copyMetadata( descendantPlug, externalPlug.get() ); addChild( externalPlug ); if( externalPlug->direction() == Plug::In ) { descendantPlug->setInput( externalPlug ); } else { externalPlug->setInput( descendantPlug ); } return externalPlug.get(); }
void Expression::addPlug( ValuePlug *parentPlug, const std::string &plugPath ) { Node *p = parent<Node>(); if( !p ) { throw IECore::Exception( "No parent" ); } ValuePlug *plug = p->descendant<ValuePlug>( plugPath ); if( !plug ) { throw IECore::Exception( boost::str( boost::format( "Plug \"%s\" does not exist" ) % plugPath ) ); } PlugPtr childPlug = plug->createCounterpart( "p0", parentPlug->direction() ); childPlug->setFlags( Plug::Dynamic, true ); parentPlug->addChild( childPlug ); if( childPlug->direction() == Plug::In ) { childPlug->setInput( plug ); } else { plug->setInput( childPlug ); } }
void Expression::updatePlug( ValuePlug *parentPlug, size_t childIndex, ValuePlug *plug ) { if( parentPlug->children().size() > childIndex ) { // See if we can reuse the existing plug Plug *existingChildPlug = parentPlug->getChild<Plug>( childIndex ); if( ( existingChildPlug->direction() == Plug::In && existingChildPlug->getInput<Plug>() == plug ) || ( existingChildPlug->direction() == Plug::Out && plug->getInput<Plug>() == existingChildPlug ) ) { return; } } // Existing plug not OK, so we need to create one. First we must remove all // plugs from childIndex onwards, so that when we add the new plug it gets // the right index. removeChildren( parentPlug, childIndex ); // Finally we can add the plug we need. PlugPtr childPlug = plug->createCounterpart( "p0", parentPlug->direction() ); childPlug->setFlags( Plug::Dynamic, true ); parentPlug->addChild( childPlug ); if( childPlug->direction() == Plug::In ) { childPlug->setInput( plug ); } else { plug->setInput( childPlug ); } }