MSyntax - Adding better Argument Parsing for your Commands

 

   

 

 

Adding MSytax Into Your Commands

As seen previously, parsing arguments using the MArgList class is possible, however it is long winded and easy to slip in errors. To simplify this process Maya has added to utility classes :

MSyntax - used to define the syntax for your command

MArgDatabase - used to parse the command arguments

So then, the main thing we require is a static function that returns a new syntax object to Maya when we register a function.

This can be done like so :

 

 

 


 // When compiling under Win32, we need to define NT_PLUGIN or NT_APP before including
 // and maya headers. Under linux we need LINUX to be defined, this however is done 
 // for you in the mayacc and mayald scripts.
 // 
 #ifdef WIN32
     #define NT_PLUGIN
 #endif  

 #include <maya/MPxCommand.h>
 #include <maya/MGlobal.h>
 #include <maya/MArgList.h>
 #include <maya/MFnDependencyNode.h>
 #include <maya/MItDependencyNodes.h>

 class MyCommand : public MPxCommand {
 public:

	/// \brief	executes our function
	/// \param	args	-	the argument list specified
	/// \return	MS::kSuccess or MS::kFailure
	///
	virtual MStatus doIt( const MArgList& args ) ;
	
	/// \brief	This function is used by maya to create a new instance of the function
	/// 		object, each time the command is called. This only really makes sense 
	/// 		later when dealing with undo and redo. The function object will create a
	/// 		list of things to undo so maya can store this command in it's history.
	/// \return	a new instance of this function
	/// 
	static void* creator() {
		return new MyCommand;
	}
	
	/// \brief	a function to return the syntax object for this mel command
	/// \return	The syntax object set up for this mel command
	///
	static MSyntax newSyntax();
 };

 

 

 

Registering the Syntax

When we register this command within the initializePlugin function, we also need to specify the static function that will return the MSyntax object for this mel function.

 

 

 


 //------------------------------------------------------------------- 
 /// \brief initializePlugin( MObject obj )
 /// \param obj - the plugin handle
 /// \return MS::kSuccess if ok 
 /// \note Registers all of the new commands, file translators and new
 /// node types. 
 /// 
 MLL_EXPORT MStatus initializePlugin(MObject obj ) { 
 	MFnPlugin plugin( obj, "Rob Bateman", "1.0", "Any");  

	// register the mel command with the plugin function set.
	// Do this for each mel command your plugin is going to add into Maya
	//
	MStatus status = plugin.registerCommand( "myCommand",
						MyCommand::creator ,
						MyCommand::newSyntax); 
	if (!status) 
	{
		status.perror("Failed to register \"myCommand\"\n"); 
		return status; 
	}
	return status; 
 }  

 

 

 

Defining the Syntax

So then, what does this newSyntax() command actually do then? Put simply, it needs to specify a set of flags within an MSyntax object and return that object. Later we will see a few extra funcky features, but for now we'll keep it simple....

 

 

 


 // long and short names for our flags
 const char* g_IntLongName = "-intFlag";
 const char* g_IntName = "-if";

 const char* g_FloatLongName = "-floatFlag";
 const char* g_FloatName = "-ff";

 const char* g_StringLongName = "-stringFlag";
 const char* g_StringName = "-sf";

 const char* g_HelpLongName = "-help";
 const char* g_HelpName = "-h";

 /// \brief	this function simply selects all nodes in the scene of the specified type
 /// \param	type	-	the maya type of the nodes to select
 ///
 MSyntax MyCommand::newSyntax() {

	// The syntax object we will be returning
	MSyntax syn;
	
	syn.addFlag( g_HelpName, g_HelpLongName );
	syn.addFlag( g_IntName, g_IntLongName, MSyntax::kLong );
	syn.addFlag( g_FloatName, g_FloatLongName, MSyntax::kDouble );
	syn.addFlag( g_StringName, g_StringLongName, MSyntax::kString );

	// set the currently selected items
	return syn;
 }

 

 

 

Parsing the Arguments

Great so far! The next part is what to do with the syntax object when we actually parse the arguments.

 

 

 



 // some useful comments about our function... always nice to be helpful
 const char* g_HelpText = "i'm really helpful";


 MStatus MyCommand::doIt( const MArgList& args ) {

	// default values for our flag command arguments
	int intValue = 1;
	double floatValue = 1.0f;
	MString stringValue = "hello";

	// error status
	MStatus stat;

	// Create a parser for our arguments using the syntax for this command,
	// and the args passed to the function by the user
	MArgDatabase parser(syntax(),args,&stat);

	if(stat != MS::kSuccess) {
		// arguments could not be parsed!
		return stat;
	}

	// if the help flag is set, display some useful info.
	if(parser.isFlagSet(g_HelpName))
 		MGlobal::displayInfo(g_HelpText);
		return MS::kSuccess;
	}

	//
	// get the command line arguments that were specified
	//
	if(parser.isFlagSet(g_IntName)) 
		parser.getFlagArgument( g_IntName, 0, intValue );

	if(parser.isFlagSet(g_FloatName)) 
		parser.getFlagArgument( g_FloatName, 0, floatValue );

	if(parser.isFlagSet(g_StringName)) 
		parser.getFlagArgument( g_StringName, 0, stringValue );

	// 
	// Perform your function here using the specified args
	//

	return MS::kSuccess;
 }