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.
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); }