MStatus ParameterisedHolder<B>::createOrUpdateAttribute( IECore::ParameterPtr parameter, const MString &attributeName, bool callRestore ) { MObject node = B::thisMObject(); MFnDependencyNode fnDN( node ); MPlugArray connectionsFromMe, connectionsToMe; // try to reuse an old plug if we can MPlug plug = fnDN.findPlug( attributeName, false /* no networked plugs please */ ); if( !plug.isNull() ) { MStatus s = MS::kSuccess; if( callRestore ) { ParameterHandler::restore( plug, parameter ); } if( s ) { s = IECoreMaya::ParameterHandler::update( parameter, plug ); if( s ) { return MS::kSuccess; } } // failed to restore and/or update (parameter type probably changed). // remove the current attribute and fall through to the create // code // remember connections so we can remake them for the new // attribute. we have to be careful to only store non-networked plugs as // networked plugs are invalidated by the removal of the attribute. nonNetworkedConnections( plug, connectionsFromMe, connectionsToMe ); fnDN.removeAttribute( plug.attribute() ); } // reuse failed - create a new attribute /// \todo: update ParameterisedHolder to accept null plugs when the todo in ParameterHandler::create is addressed plug = IECoreMaya::ParameterHandler::create( parameter, attributeName, node ); if( plug.isNull() ) { msg( Msg::Error, "ParameterisedHolder::createOrUpdateAttribute", boost::format( "Failed to create attribute to represent parameter \"%s\" of type \"%s\"" ) % parameter->name() % parameter->typeName() ); return MS::kFailure; } // restore any existing connections if( connectionsFromMe.length() || connectionsToMe.length() ) { MDGModifier dgMod; for (unsigned i = 0; i < connectionsFromMe.length(); i++) { dgMod.connect( plug, connectionsFromMe[i] ); } for (unsigned i = 0; i < connectionsToMe.length(); i++) { dgMod.connect( connectionsToMe[i], plug ); } dgMod.doIt(); } /// and set the value of the attribute, in case it differs from the default return IECoreMaya::ParameterHandler::setValue( parameter, plug ); }