C++ API Conventions

# Classes vs. Structs

In general, classes are preferred, along with getX() / setX() methods. This allows extending the API in the future without breaking compatibility. In cases of "super-primitives" (like openni::RGB888Pixel), structs are used.

# Return Values from Methods

- All getters return the value as their return value, and cannot fail, for example: openni::VideoFrameRef::getWidth(). If the value is a complex type, it will be returned as const reference, for example: openni::Device::getDeviceInfo(). If a specific property doesn't exist for the specific object, a meaningful value will be returned.
- stop / destroy / close methods does not have return values, for example: openni::Device::close().
- All other methods return openni::Status, for example: openni::VideoStream::create().

# Arguments to Methods

- Output arguments, as well as in/out arguments are always passed as a pointer, for example: openni::VideoStream::readFrame().
- Input arguments:
  - Primitives are passed by value, for example: openni::VideoMode::setPixelFormat().
  - Complex types are passed as const reference, for example: openni::VideoStream::create().
  - In the rare cases where the object identity matters, and not it's content, it will be passed as a pointer, for example: openni::OpenNI::addListener().

# Object Lifetime

Some objects have their lifetime goverened by the user. For example, a openni::VideoStream is created using the create() method and destroyed by calling destroy(). In those cases, it is important that they get destroyed in the right order. For example, if you create a openni::VideoStream on a specific openni::Device, don't close the device before destroying that video stream. In the same manner, all openni::VideoFrameRef objects should be released before destroying the stream, and all OpenNI objects should be destroyed before calling openni::OpenNI::shutdown().

Other objects are not created by the user, but are actually members of other objects. For example, calling openni::Device::getDeviceInfo() returns a reference to a openni::DeviceInfo object. Note that once the openni::Device object that was used gets closed, the openni::DeviceInfo reference is no longer valid. Do not try to use it to access methods of the openni::DeviceInfo object.

# Arrays

Some methods return an array of items. We created a very simple template class, openni::Array, which only holds the pointer to the underlying C array and the number of elements in that array. Once the array has been released, the elements are no longer accessible. Do not keep a pointer to a specific item in the array and use it after releasing it.

# Properties and Commands

OpenNI has a mechanism for generic properties and commands, both for devices and for streams. Commands are used by calling openni::Device::invoke() or openni::VideoStream::invoke() and Properties can be read via openni::Device::getProperty() and openni::VideoStream::getProperty() and written via openni::Device::setProperty() and openni::VideoStream::setProperty().

Though both might use both primitives and complex types, generally, properties are used to encapsulate a logical data unit (even though complex) while commands are used in the following cases:

- The action requires some arguments (that are not part of the data unit).
- Obtaining a data unit via getProperty() have side effects.
- The operation is expensive enough that you want to communicate it to the user.
- The action has side effects.
- The data unit might be changed over time without an outside request.