bool lockEvent::clearCallbackIds( ) // // Description: // Removes all currently attached callbacks. // { unsigned int idCount = callbackIds.length(); for ( unsigned int i = 0; i < idCount; i ++ ) { cerr << "callback #" << i << "; id = " << (unsigned)callbackIds[i] << endl; MMessage::removeCallback( (MCallbackId) callbackIds[i] ); } callbackIds.clear(); return true; }
MStatus dagMessageCmd::addGenericCallback(MDagPath *dagPath, MDagMessage::DagMessage msg, MString cbName) { MStatus status = MS::kFailure; if (NULL == dagPath) { MCallbackId id = MDagMessage::addDagCallback( msg, userDAGGenericCB, NULL, &status); if (MS::kSuccess == status) { MString info("Adding a callback for"); info += cbName; info += "on all nodes"; MGlobal::displayInfo(info); callbackIds.append( id ); } else { MString err("Could not add callback to"); err += dagPath->fullPathName(); MGlobal::displayError(err); } } else { MCallbackId id = MDagMessage::addDagCallback(*dagPath, msg, userDAGGenericCB, NULL, &status); if (MS::kSuccess == status) { MString info("Adding a callback for"); info += cbName; info += "on "; info += dagPath->fullPathName(); MGlobal::displayInfo(info); callbackIds.append( id ); } else { MString err("Could not add callback to"); err += dagPath->fullPathName(); MGlobal::displayError(err); } } return status; }
MStatus uninitializePlugin( MObject obj) { // Remove callbacks // for (unsigned int i=0; i<callbackIds.length(); i++ ) { MMessage::removeCallback( callbackIds[i] ); } MFnPlugin plugin( obj ); return plugin.deregisterCommand( kCmdName ); }
MStatus deletedMessage::doIt( const MArgList& args ) { MStatus status = MS::kSuccess; MArgDatabase argData(syntax(), args); MSelectionList objects; argData.getObjects(objects); for (unsigned int i = 0; i < objects.length(); i++) { MObject node; objects.getDependNode(i, node); callbackIds.append( MNodeMessage::addNodeAboutToDeleteCallback (node, aboutToDeleteCB, NULL, &status) ); if (!status) { MGlobal::displayWarning("Could not attach about to delete callback for node."); continue; } callbackIds.append( MNodeMessage::addNodePreRemovalCallback (node, preRemovalCB, NULL, &status) ); if (!status) { MGlobal::displayWarning("Could not attach pre-removal callback for node."); continue; } if (!nodeRemovedCBRegistered) { callbackIds.append( MDGMessage::addNodeRemovedCallback(removeCB, "dependNode", NULL, &status) ); if (!status) { MGlobal::displayWarning("Could not attach node removal callback."); continue; } nodeRemovedCBRegistered = true; } } return status; }
MStatus polyMessageCmd::doIt( const MArgList& ) // // Takes the nodes that are on the active selection list and adds an // attriubte changed callback to each one. // { MStatus stat; MObject node; MSelectionList list; MCallbackId id; // Register node callbacks for all nodes on the active list. // MGlobal::getActiveSelectionList( list ); for ( unsigned int i=0; i<list.length(); i++ ) { list.getDependNode( i, node ); MDagPath dp; MObject shapeNode = node; if ( MS::kSuccess == MDagPath::getAPathTo( node, dp ) ) if ( MS::kSuccess == dp.extendToShape() ) shapeNode = dp.node(); bool wantIdChanges[3]; wantIdChanges[MPolyMessage::kVertexIndex] = true; wantIdChanges[MPolyMessage::kEdgeIndex] = true; wantIdChanges[MPolyMessage::kFaceIndex] = true; id = MPolyMessage::addPolyComponentIdChangedCallback( shapeNode, wantIdChanges, 3, userCB, NULL, &stat); // If the callback was successfully added then add the // callback id to our callback table so it can be removed // when the plugin is unloaded. // if ( stat ) { callbackIds.append( id ); } else { cout << "MPolyMessage.addCallback failed\n"; } } return stat; }
MStatus uninitializePlugin( MObject obj ) // // Description: // this method is called when the plug-in is unloaded from Maya. It // deregisters all of the services that it was providing. // // Arguments: // obj - a handle to the plug-in object (use MFnPlugin to access it) // { MStatus status; MFnPlugin plugin( obj ); // Add plug-in feature deregistration here // status = plugin.deregisterCommand("sceneMsgCmd"); //- You are responsible to remove all the callbacks you have registered in your plug-in code MCallbackIdArray tempIds = sceneMsgCmd::IDs; if (tempIds.length() != 0) status = MSceneMessage::removeCallbacks(sceneMsgCmd::IDs); return status; }
MStatus initializePlugin( MObject obj ) // // Load the plugin ... // { MStatus status; MFnPlugin plugin( obj, VENDOR_TAG, PLUGIN_VERSION, "Any" ); status = plugin.registerCommand( MEL_COMMAND_NAME, lockEvent::creator, lockEvent::newSyntax ); callbackIds.clear(); return status; }
MStatus nodeMessageCmd::doIt( const MArgList& ) // // Takes the nodes that are on the active selection list and adds an // attriubte changed callback to each one. // { MStatus stat; MObject node; MSelectionList list; MCallbackId id; // Register node callbacks for all nodes on the active list. // MGlobal::getActiveSelectionList( list ); for ( unsigned int i=0; i<list.length(); i++ ) { list.getDependNode( i, node ); id = MNodeMessage::addAttributeChangedCallback( node, userCB, NULL, &stat); // If the callback was successfully added then add the // callback id to our callback table so it can be removed // when the plugin is unloaded. // if ( stat ) { callbackIds.append( id ); } else { cout << "MNodeMessage.addCallback failed\n"; } } return stat; }
MStatus dagMessageCmd::doIt( const MArgList& args) // // Takes the nodes that are on the active selection list and adds an // attriubte changed callback to each one. // { MStatus status; MSelectionList list; MArgDatabase argData(syntax(), args); status = argData.getObjects(list); if (MS::kSuccess != status) { MGlobal::displayError("Error getting objects"); return status; } // Get the flags // bool allDagUsed = argData.isFlagSet(kAllDagFlag); bool parentAddedUsed = argData.isFlagSet(kParentAddedFlag); bool parentRemovedUsed = argData.isFlagSet(kParentRemovedFlag); bool childAddedUsed = argData.isFlagSet(kChildAddedFlag); bool childRemovedUsed = argData.isFlagSet(kChildRemovedFlag); bool childReorderedUsed = argData.isFlagSet(kChildReorderedFlag); bool helpUsed = argData.isFlagSet(kHelpFlag); bool nothingSet = ( !allDagUsed && !parentAddedUsed && !parentRemovedUsed && !childAddedUsed && !childRemovedUsed && !childReorderedUsed && !helpUsed); if (nothingSet) { MGlobal::displayError("A flag must be used. dagMessage -help for availible flags."); return MS::kFailure; } if (argData.isFlagSet(kHelpFlag)) { MGlobal::displayInfo("dagMessage -help"); MGlobal::displayInfo("\tdagMessage adds a callback to the selected nodes,"); MGlobal::displayInfo("\tor if no nodes are selected, to all nodes. The callback"); MGlobal::displayInfo("\tprints a message when called. When the plug-in is unloaded"); MGlobal::displayInfo("\tthe callbacks are removed."); MGlobal::displayInfo(""); MGlobal::displayInfo("\t-h -help : This message is printed"); MGlobal::displayInfo("\t-ad -allDag : parent changes and child reorders"); MGlobal::displayInfo("\t-pa -parentAdded : A parent is added"); MGlobal::displayInfo("\t-pr -parentRemoved : A parent is removed"); MGlobal::displayInfo("\t-ca -childAdded : A child is added (only for individual nodes)"); MGlobal::displayInfo("\t-cr -childRemoved : A child is removed (only for individual nodes)"); MGlobal::displayInfo("\t-cro -childReordered : A child is reordered"); MGlobal::displayInfo(""); } unsigned nObjs = list.length(); if (nObjs == 0) { // Add the callback for all changes of the specified type. // if (allDagUsed) { MCallbackId id = MDagMessage::addAllDagChangesCallback(userDAGGenericCB, NULL, &status); if (status) { callbackIds.append( id ); MGlobal::displayInfo("Added a callback for all Dag changes on all nodes.\n"); } else { MGlobal::displayError("Could not add a -allDag callback"); return status; } } if (parentAddedUsed) { status = addGenericCallback(NULL, MDagMessage::kParentAdded, MString(" parent added ")); if (MS::kSuccess != status) { return status; } } if (parentRemovedUsed) { status = addGenericCallback(NULL, MDagMessage::kParentRemoved, MString(" parent removed ")); if (MS::kSuccess != status) { return status; } } if (childAddedUsed) { MGlobal::displayError("-childAdded can only be used when a node is selected"); status = MS::kFailure; return status; } if (childRemovedUsed) { MGlobal::displayError("-childRemoved can only be used when a node is selected"); status = MS::kFailure; return status; } if (childReorderedUsed) { status = addGenericCallback(NULL, MDagMessage::kChildReordered, MString(" child reordered ")); if (MS::kSuccess != status) { return status; } } } else { for (unsigned int i=0; i< nObjs; i++) { MDagPath dagPath; list.getDagPath(i, dagPath); if (!dagPath.isValid()) { continue; } // Add the callback for all changes of the specified type. // if (allDagUsed) { MCallbackId id = MDagMessage::addAllDagChangesCallback(dagPath, userDAGGenericCB, NULL, &status); if (status) { callbackIds.append( id ); MString infoStr("Added a callback for all Dag changes on "); infoStr += dagPath.fullPathName(); MGlobal::displayInfo(infoStr); } else { MGlobal::displayError("Could not add a -allDag callback"); return status; } } if (parentAddedUsed) { status = addGenericCallback(&dagPath, MDagMessage::kParentAdded, MString(" parent added ")); if (MS::kSuccess != status) { return status; } } if (parentRemovedUsed) { status = addGenericCallback(&dagPath, MDagMessage::kParentRemoved, MString(" parent removed ")); if (MS::kSuccess != status) { return status; } } if (childAddedUsed) { status = addGenericCallback(&dagPath, MDagMessage::kChildAdded, MString(" child added ")); if (MS::kSuccess != status) { return status; } } if (childRemovedUsed) { status = addGenericCallback(&dagPath, MDagMessage::kChildRemoved, MString(" child removed ")); if (MS::kSuccess != status) { return status; } } if (childReorderedUsed) { status = addGenericCallback(&dagPath, MDagMessage::kChildReordered, MString(" child reordered ")); if (MS::kSuccess != status) { return status; } } } } return status; }
MCallbackId lockEvent::installCallback( MItSelectionList &iter ) // // Description: // Uses given iterator and callback type to attach a new callback on // a node, dag path, or plug. The selection iterator must contain a // valid selection item for the target callback type (fAttach). That is, // if the callback type is three, then the iterator must contain // a dependency node on it the next list item. // { MStatus status; MCallbackId id = 0; MObject node, component; MDagPath path; switch (fAttach) { case 1: { status = iter.getDependNode( node ); if ( status ) { // Try to set the callback. Note: we check the status // flag at the end of the switch statement. // id = MLM::setNodeLockQueryCallback( node, lockDecision, NULL, &status ); } } break; case 2: { status = iter.getDagPath( path, component ); if ( status ) { // Try to set the callback. Note: we check the status // flag at the end of the switch statement. // id = MLM::setNodeLockDAGQueryCallback( path, lockDagDecision, NULL, &status ); } } break; case 3: { status = iter.getDependNode( node ); MStringArray plugName; iter.getStrings( plugName ); // Now we have to parse the plug string. // if ( status && plugName.length() > 0 ) { MFnDependencyNode depNode( node ); MStringArray attrName; plugName[0].split( '.', attrName ); MPlug plug = depNode.findPlug( attrName[1], &status ); if ( status ) { // Try to set the callback. Note: we check the status // flag at the end of the switch statement. // id = MLM::setPlugLockQueryCallback( plug, plugDecision, NULL,&status ); } } else { status = MS::kFailure; } } break; case 4: { status = iter.getDependNode( node ); if ( status ) { // Try to set the callback. Note: we check the status // flag at the end of the switch statement. // id = MLM::setPlugLockQueryCallback( node, nodePlugDecision, NULL, &status ); } } break; default: MGlobal::displayError( "Invalid callback attach type" ); status = MS::kFailure; }; MFnDependencyNode fnNode( node ); // Check the status flag here and report any particular problems // encountered. It is possible for the callback attach routines // to fail. // // This typically occurs when a callback has already been attached // to the node or plug. // if ( !status || !id ) { MString msg; msg = "Unable to add callback for node "; msg += fnNode.name(); MGlobal::displayError( msg ); status.perror( msg ); } else { // Store the result -- so we can clean up later -- and // echo some useful information. // cerr << "Callback attached to " << fnNode.name(); cerr << "; attachment type = " << fAttach << endl; callbackIds.append( (int)id ); } return id; }