Commands
[neuray Services API]
Description
Commands form the core of neuray services and the user is able to install custom commands to provide enhanced functionality. These commands have full access to the neuray library and are able to call other service commands.
Implementing commands
Commands are implemented by deriving a class from the mi::nservices::IService_command interface and implementing all methods.
Arguments and results
Arguments are passed to commands as a set of named parameters that can be obtained from the mi::nservices::ICommand_context supplied during execution. These arguments can be any mi::IData derived neuray services type. Commands return a single result which can also be any supported type. Command implementations are able to specify the set of arguments they accept, their type and default values. If this is done then neuray Services will automatically convert incoming arguments to the expected type and provide default values if none are supplied.
// An argument called "index" of type "Uint8" has been specified via // mi::nservices::IService_command::get_argument_description mi::nservices::ICommand_context *context = ....; const mi::INumber *arg = context->get_argument<mi::INumber>("index"); mi::Uint8 index; if (arg) { arg->get_value(index); arg->release(); } else { // error, no "index" argument supplied }The same applies to Map and User Type arguments. These should all be accessed as mi::IData_collection as the exact implementation supplied is not guaranteed.
The execution environment
The ICommand_context provided to the command's execute handler supplies the execution environment to the command. This consists of three items.
-
The current transaction
-
The user state transaction
-
Direct neuray library access.
Filesystem paths
Neuray services provides a system for mapping relative filesystem paths passed in as command arguments to absolute ones. An interface to do this is provided via an attachment called 'path_remapper'. The attachments can be accessed via ICommand_context::get_attachments() and the remapper retrieved via mi::IMap::get_value<mi::nservices::IPath_remapper>("path_remapper").
Errors
If a command encounters an error during execution it should specify the error using ICommand_response::set_error(). Neuray services reserves error codes less than 0 for internal use and positive error codes for command errors. Error code 0 indicates no error. See Errors.
Executing other commands
A command may execute another command by creating an ICommand_request with mi::nservices::IFactory::create("Command_request"). Set the name of the command to execute and it's arguments then pass it to ICommand_context::execute_command for execution. An ICommand_response is returned which contains the result of the command or any errors.
Sample command. Adds two vectors together.
Obviously nothing this trivial warrants its own command but it shows the basic structure.
#include <mi/nservices.h> #include <mi/base.h> using namespace mi; using namespace nservices; void set_argument_description( IArgument_description *arg, const char *name, const char *type_name, const char *description) { if (arg) { arg->set_name(name); arg->set_type_name(type_name); arg->set_description(description); } } class Service_command_vector3_add : public mi::base::Interface_implement<IService_command> { public: virtual const char *get_name() const { return "vector3_add"; }; virtual const char *get_namespace() const { return NULL; }; virtual const char *get_description() const { return "adds the two vector3 arguments together"; }; virtual mi::Sint32 get_argument_description( IFactory *factory, const char *argument_name, IArgument_description *argument) const { if (strcmp(argument_name,"op1") == 0) { set_argument_description(argument,"op1","Float32<3>","operand1"); return NRS_ERROR_NONE; }; if (strcmp(argument_name,"op2") == 0) { set_argument_description(argument,"op2","Float32<3>","operand2"); return NRS_ERROR_NONE; }; return NRS_ERROR_NOT_FOUND; }; virtual mi::Sint32 get_argument_description( IFactory *factory, mi::Uint32 index, IArgument_description *argument) const { switch (index) { case(0): return get_argument_description(factory,"op1",argument); break; case(1): return get_argument_description(factory,"op2",argument); break; } return NRS_ERROR_NOT_FOUND; }; virtual const char *get_return_type_name() const { return "Float32<3>"; }; virtual const ICommand_response *execute(ICommand_context *context) const { ICommand_response *response = NULL; if (context) { mi::base::Handle<IFactory> factory( context->get_factory() ); response = context->create_command_response(); if (response) { // sanity check if (strcmp(context->get_command_name(),get_name()) != 0) { // this isn't me and shouldn't happen response->set_error(NRS_ERROR_COMMAND_NEURAY_ERROR, "Incorrect command called"); return response; } // find arguments mi::base::Handle<const IFloat32_3> op1( context->get_argument<IFloat32_3>("op1")); if (op1.is_valid_interface()) { mi::base::Handle<const IFloat32_3> op2( context->get_argument<IFloat32_3>("op2")); if (op2.is_valid_interface()) { // create result mi::base::Handle<IFloat32_3> result( factory->create<IFloat32_3>("Float32<3>")); if (result.is_valid_interface()) { // add them up Float32_3_struct result_v; result_v.x = op1->get_value().x + op2->get_value().x; result_v.y = op1->get_value().y + op2->get_value().y; result_v.z = op1->get_value().z + op2->get_value().z; // set the result result->set_value(result_v); // pass the result into the response response->set_result(result.get()); } else { response->set_error(NRS_ERROR_COMMAND_NEURAY_ERROR, "Cannot create result"); } } else { response->set_error(NRS_ERROR_COMMAND_INVALID_PARAMS, "Cannot find Float32<3> parameter 'op2'"); } } else { response->set_error(NRS_ERROR_COMMAND_INVALID_PARAMS, "Cannot find Float32<3> parameter 'op1'"); } } } return response; }; };
Classes
- class
- Describes an argument to a service command. More...
- class
- The context is which a command is executed. More...
- class
- The context is which neuray commands are executed. More...
- class
- A request to execute a web service command. More...
- class
- A response from a neuray service command. More...
- class
- This class is used to map relative paths passed in as arguments to commands to absolute paths on the local filesystem. More...
- class
- Interface for Neuray Service Commands. More...