//- // ========================================================================== // Copyright (C) 1995 - 2005 Alias Systems Corp. and/or its licensors. All // rights reserved. // // The coded instructions, statements, computer programs, and/or related // material (collectively the "Data") in these files are provided by Alias // Systems Corp. ("Alias") and/or its licensors for the exclusive use of the // Customer (as defined in the Alias Software License Agreement that // accompanies this Alias software). Such Customer has the right to use, // modify, and incorporate the Data into other products and to distribute such // products for use by end-users. // // THE DATA IS PROVIDED "AS IS". ALIAS HEREBY DISCLAIMS ALL WARRANTIES // RELATING TO THE DATA, INCLUDING, WITHOUT LIMITATION, ANY AND ALL EXPRESS OR // IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. IN NO EVENT SHALL ALIAS BE LIABLE FOR ANY DAMAGES // WHATSOEVER, WHETHER DIRECT, INDIRECT, SPECIAL, OR PUNITIVE, WHETHER IN AN // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, OR IN EQUITY, // ARISING OUT OF ACCESS TO, USE OF, OR RELIANCE UPON THE DATA. // ========================================================================== //+ #include #define OPENMAYA_EXPORT #include #include #include #include #include #include #include #include /////////////////////////////////////////////////// // // Definitions // /////////////////////////////////////////////////// // Message flag // #define kMessageFlag "m" #define kMessageFlagLong "message" /////////////////////////////////////////////////// // // Declarations // /////////////////////////////////////////////////// // Callback function for messages // static void conditionChangedCB(bool state, void * data); // Array of callback ids. // typedef MCallbackId* MCallbackIdPtr; static MCallbackIdPtr callbackId = NULL; // Array of condition names. // static MStringArray conditionNames; /////////////////////////////////////////////////// // // Command class declaration // /////////////////////////////////////////////////// class conditionTest : public MPxCommand { public: conditionTest(); virtual ~conditionTest(); MStatus doIt( const MArgList& args ); static MSyntax newSyntax(); static void* creator(); private: MStatus parseArgs( const MArgList& args ); bool addMessage; bool delMessage; MStringArray conditions; }; /////////////////////////////////////////////////// // // Command class implementation // /////////////////////////////////////////////////// // Constructor // conditionTest::conditionTest() : addMessage(false) , delMessage(false) { conditions.clear(); } // Destructor // conditionTest::~conditionTest() { // Do nothing } // creator // void* conditionTest::creator() { return (void *) (new conditionTest); } // newSyntax // MSyntax conditionTest::newSyntax() { MSyntax syntax; syntax.addFlag(kMessageFlag, kMessageFlagLong, MSyntax::kBoolean); syntax.setObjectType(MSyntax::kStringObjects); return syntax; } // parseArgs // MStatus conditionTest::parseArgs(const MArgList& args) { MStatus status; MArgDatabase argData(syntax(), args); if (argData.isFlagSet(kMessageFlag)) { bool flag; status = argData.getFlagArgument(kMessageFlag, 0, flag); if (!status) { status.perror("could not parse message flag"); return status; } if (flag) { addMessage = true; } else { delMessage = true; } } status = argData.getObjects(conditions); if (!status) { status.perror("could not parse condition names"); } // If there are no conditions specified, operate on all of them // if (conditions.length() == 0) { // conditionNames is set in initializePlugin to all the // currently available condition names. // conditions = conditionNames; } return status; } // doIt // MStatus conditionTest::doIt(const MArgList& args) { MStatus status; status = parseArgs(args); if (!status) { return status; } // Allocate an array of indices. conditions[n] is a user provided // condition name. Look it up in the static conditionNames array // and set indices[n] to the index of the entry in conditionNames. // // This maps the user specified conditions to the global conditions // so we can track callback adds and removes globally. // int * indices = new int [conditions.length()]; int i, j; for (i = 0; i < (int)conditions.length(); ++i) { // Initialize the entry to "not found". // indices[i] = -1; // Search condition names for a match. // for (j = 0; j < (int)conditionNames.length(); ++j) { if (conditions[i] == conditionNames[j]) { // Found a match. Store the index and stop looking for // indices[i] = j; break; } } } for (i = 0; i < (int)conditions.length(); ++i) { j = indices[i]; if (j == -1) { MGlobal::displayWarning(conditions[i] + MString("is not a valid condition name\n")); break; } if (addMessage && callbackId[j] == 0) { callbackId[j] = MConditionMessage::addConditionCallback( conditions[i], conditionChangedCB, (void*)(size_t)j, &status); if (!status) { status.perror("failed to add callback for " + conditions[i]); callbackId[j] = 0; } } else if (delMessage && callbackId[j] != 0) { status = MMessage::removeCallback(callbackId[j]); if (!status) { status.perror("failed to remove callback for " + conditions[i]); } callbackId[j] = 0; } } // Ok, we've made all the necessary changes. Now show the status. // MGlobal::displayInfo("Condition Name State Msgs On\n"); MGlobal::displayInfo("-------------------- ----- -------\n"); char tmpStr[128]; bool state, msgs; for (i = 0; i < (int)conditions.length(); ++i) { j = indices[i]; if (j == -1) { continue; } state = MConditionMessage::getConditionState(conditions[i], &status); if (!status) { status.perror("failed to get status for " + conditions[i]); state = false; } msgs = (callbackId[j] != 0); sprintf(tmpStr, "%-20s %-5s %s\n", conditions[i].asChar(), state ? "true" : "false", msgs ? "yes" : "no"); MGlobal::displayInfo(tmpStr); } // Free up the indices we allocated. // delete [] indices; return status; } /////////////////////////////////////////////////// // // Plug-in functions // /////////////////////////////////////////////////// MStatus initializePlugin( MObject obj ) { MStatus status; MFnPlugin plugin( obj, "Alias", "3.0", "Any"); status = MConditionMessage::getConditionNames(conditionNames); if (!status) { return status; } printf("conditionTest: %d conditions are defined.\n", conditionNames.length()); callbackId = new MCallbackId [conditionNames.length()]; if (!callbackId) { return MStatus(MS::kInsufficientMemory); } for (unsigned int i = 0; i < conditionNames.length(); ++i) { callbackId[i] = 0; } // Register the command so we can actually do some work // status = plugin.registerCommand("conditionTest", conditionTest::creator, conditionTest::newSyntax); if (!status) { status.perror("registerCommand"); } return status; } MStatus uninitializePlugin( MObject obj) { MStatus status; MFnPlugin plugin( obj ); // Loop through all the ids and remove the callbacks // int i; int len = conditionNames.length(); for (i = 0; i < len; ++i) { if (callbackId[i] != 0) { MGlobal::displayWarning("Removing callback for " + conditionNames[i] + "\n"); MMessage::removeCallback(callbackId[i]); callbackId[i] = 0; } } conditionNames.clear(); delete [] callbackId; // Deregister the command // status = plugin.deregisterCommand("conditionTest"); if (!status) { status.perror("deregisterCommand"); } return status; } /////////////////////////////////////////////////// // // Callback function // /////////////////////////////////////////////////// static void conditionChangedCB(bool state, void * data) { int i = (int)(size_t)data; if (i > 0 && i < (MIntPtrSz)conditionNames.length()) { MGlobal::displayInfo("condition " + conditionNames[i] + " changed to " + (state ? "true\n" : "false\n")); } else { MGlobal::displayWarning("BOGUS client data in conditionChangedCB!\n"); } }