MAXScript functions also support optional arguments, using a mechanism called keyword argument passing. The keyword arguments are placed in the argument list of the C++ function after all the mandatory positional argument, and are preceded by a marker value. The marker value is accessible in the global variable keyarg_marker
which has type Value
*. The arguments are passed in pairs, a keyword name and the argument's value, in the arg_list
array.
There are several macros to help extract keyword arguments defined in the header file maxscrpt/maxscrpt.h
. These macros assume that the C++ function implementation uses the parameter names arg_list
and count
.
key_arg()
- gets the named argument value or returns &unsupplied
if not presentkey_arg_or_default()
- gets the named argument or the default value 'def' if not suppliedint_key_arg()
- gets the named key argument, and places it into the Value
*var
variable. The result is retuned as a C++ int, or else the result def
is returned if the key argument is not present. There also similar versions for float
and BOOL
types.check_arg_count_with_keys()
- Checks for positional argument counts in the presence of keyword arguments.The following 'delete_file' example shows an argument count check, conversion of first argument (arg_list[0]) to a string and the return of MAXScript 'true' or 'false' values.
def_visible_primitive(delete_file, "deleteFile");
Value* delete_file_cf(Value** arg_list, int count)
{
// deleteFile "file_name"
check_arg_count("deleteFile", 1, count);
BOOL result = DeleteFile(arg_list[0]->to_string());
return result ? &true_value : &false_value;
}
The 'file_in' example below shows working with an optional keyword argument 'quiet'. The required argument count is checked with the macro check_arg_count_with_keys()
in this case. Two typed value locals are declared, one to hold the temporary FileStream
instance and the other to hold the fileIn
result.
def_visible_primitive(file_in, "fileIn");
Value* file_in_cf(Value** arg_list, int count)
{
// fileIn "filename" [quiet:true]
check_arg_count_with_keys("fileIn", 1, count);
// declare local variables
two_typed_value_locals(FileStream* file, Value* result);
Value* quiet = key_arg_or_default(quiet, &true_value);
type_check(quiet, Boolean, "fileInquiet:");
Value* result;
// open a temporary fileStream
vl.file = (new FileStream)->open( arg_list[0]->to_string(), "rt");
if (vl.file == (FileStream*)&undefined)
throwRuntimeError (GetString(IDS_FILEIN_CANT_OPEN_FILE), arg_list[0]);
// pass it to the stream-based file_in
try
{
vl.result = file_in(vl.file, (quiet == &true_value));
}
catch (...)
{
// catch any errors and close the temp filestream
vl.file->close();
throw;
}
// pop value locals & return fileIn result
return_value(vl.result);
}