Working with Arguments

 
 
 

For scripted commands, the Execute callback takes the same arguments as the command. The order in which you add the arguments determines how Softimage passes data into the Execute callback.

// [ JScript ]
function MyCommand_Init( ctxt )
{
	// Get the Command object from the callback context
	var oCmd;
	oCmd = ctxt.Source;

	// Get the ArgumentCollection
	var oArgs;
	oArgs = oCmd.Arguments;

	oArgs.AddWithHandler("Arg0","Collection");
	oArgs.Add( "Arg1", siArgumentInput, false );

	return true;
}
function MyCommand_Execute( Arg0, Arg1 )
{
	...
}

A C++ command gets a Context object that contains the command arguments in its Arguments attribute:

// C++
XSIPLUGINCALLBACK CStatus MyCommand_Execute( CRef& in_ctxt )
{
	Context ctxt( in_ctxt );
	CValueArray args = ctxt.GetAttribute(L"Arguments");

	CValue objects = args[0];
	CValue flag = args[1];

#ifdef _DEBUG
	Application app;
	for (long i=0; i<args.GetCount(); i++)
	{
		app.LogMessage( L"Arg" + CValue(i).GetAsText() + L" : " 
			+ L"DataType = " + CValue( (long)args[i].m_t ).GetAsText() );
	}
#endif
	...
	return CStatus::OK;
}

The Arguments attribute is a CValueArray. Each element of this array is a CValue object that stores an argument, which could be a boolean, numeric, or string value, a single Softimage object, or a collection of objects. For example, if you add an argument using the Collection argument handler:

oArgs.AddWithHandler( L"objects", L"Collection" );

then in the CValueArray of arguments, there will be a CValue element that stores a collection of objects:

XSIPLUGINCALLBACK CStatus MyCommand_Execute( CRef& in_ctxt )
{
	Context ctxt( in_ctxt );
	CValueArray args = ctxt.GetAttribute(L"Arguments");

	// CValue::operator CValueArray() automatically converts 
	// args[0], which is a CValue, to a CValueArray
	CValueArray objects = args[0];
	for (long i=0; i<objects.GetCount(); i++)
	{
		// objects[i] is a CValue object that holds a CRef to an object
		CRef ref = objects[i];			// CValue::operator CRef() does the conversion for us
		if ( ref.GetClassID() == siX3DObjectID )
		{
			// Construct an X3DObject from the CRef
			X3DObject obj( ref );
			...
		}		
	}
	...
}

Note that if you use the SDK Command Wizard to generate your C++ command, the wizard always assigns the arguments to CValue objects like this:

CValue Arg0 = args[0];
CValue Arg1 = args[1];

However, args[i] is a CValue, and the CValue class provides a set of conversion operators that allow you to do this instead:

CValueArray objects = args[0];	// arg that uses the Collection arg handler
CRef obj_ref = args[1];// arg that uses the SingleObj arg handler
bool flag = args[1];// boolean arg
CString name = args[2];// string arg