# SoftBank Robotics documentation What's new in NAOqi 2.8?

# Object type erasure

One kind of type is Object, which is complex enough to have its own section.

An object is something that has shared semantics. It can contain methods, signals and properties. It has no data exposed through type erasure (but you can expose accessor methods if you want).

The “signature” of an object is a `MetaObject`, it is unique for all instances of a same object. The `MetaObject` contains a list of `MetaMethod`, `MetaSignal` and `MetaProperty`. These three classes contain all the information required to characterize their respective entity.

Each method, signal and property has an id, which is fixed and stored in the meta object. Overloading is only supported for methods, over their arguments, as in C++.

Though it may be possible to change the meta object of an object after it has been created, it is not a good idea. This feature has not been well tested and is known not to work on the messaging layer because it caches the meta object to avoid sending them every time.

The `MetaObject` is returned by the `ObjectTypeInterface`. The method receives a `void*`, so different instances of the same type may have different meta objects (this feature is used by the `DynamicObjectTypeInterface`, discussed below).

## Typing

There are two classes that inherit from `ObjectTypeInterface`, `StaticObjectTypeBase` (which is not a base, this name is misleading) and `DynamicObjectTypeInterface`. It is of course possible to create your own implementation by inheriting from `ObjectTypeInterface`, but these two classes seem to handle all the cases already.

The names may be misleading, but `StaticObjectTypeBase` is for C++ objects and `DynamicObjectInterface` is for all other objects (from other languages, but also objects over the messaging layer). C++ is the only statically typed language that we support for the moment, but I think that if we are to support others, they must be implemented through `DynamicObjectTypeInterface` or have their own class.

With `StaticObjectTypeBase`, the meta object is contained in the type, but with `DynamicObjectTypeBase`, there is only one instance of that class per process and the meta objects are contained in the storage.

### DynamicObjectTypeInterface

`DynamicObjectTypeInterface` is never really used, the class is in the private file dynamicobject.cpp, and the only public access you have to it is `qi::getDynamicTypeInterface` which returns a singleton of that class. The storage corresponding to that class is a `DynamicObject` which contains all the information needed for the type to work. That class is defined in dynamicobject.hpp.

It is usually not necessary to deal with `DynamicObject` either actually. It is possible to use a builder to create a dynamic object. Such a builder create an abstraction that simplifies the task in C++.

The corresponding builder for dynamic objects is `DynamicObjectBuilder`, defined in dynamicobjectbuilder.hpp. It does not expose type interfaces, nor dynamic objects, but directly an `AnyObject` that you can manipulate. There is only one `AnyObject` per `DynamicObjectBuilder`, the `object` method always return the same instance.

`DynamicObjectBuilder` allows you to create an object with C++ functions, signals and properties easily. There is no `this` instance though, it is the user’s task to keep track of it. Here’s an example usage:

    struct Data {
      int val;
    };
    auto self = std::make_shared<Data>();

    DynamicObjectBuilder builder;

    // the builder can't deduce the signature of a lambda (thanks C++), so we
    // need an explicit cast
    // builders recognize anything AnyFunction recognizes
    builder.advertiseMethod("get", boost::function<int()>([self](){
        return self->val;
      }));
    builder.advertiseMethod("add", boost::function<void(int)>([self](int x){
        self->val += x;
      }));

    auto object = builder.object(); // can specify a destructor here

It is still a bit cumbersome. Dynamic objects like that are only used in tests. You can find a real example of dynamic object usage in the Python bindings in pyobject.cpp.

### StaticObjectTypeBase

Similarly to `DynamicObjectTypeInterface`, you don’t need to deal with `StaticObjectTypeBase` directly. For that too, you use a builder.

The corresponding builder is `ObjectTypeBuilder` (yes, the name is not very explicit), defined in objecttypebuilder.hpp. Its interface is similar to that of `DynamicObjectBuilder`, but has some more features.

First, it is templated on the class you want to register. This allows you to advertise the method pointers of the class directly.

It also has an `inherits` method that declares that your type inherits from another. This allows casting to parent types in type-erased contexts.

Warning

Virtual inheritance is not supported and this method will crash if used in that case.

This method relies on undefined behavior in C++, it was realized by professionals, do not try this at home.

You can see the definition of `inherits` in objecttypebuilder.hxx. It tries to create a pointer to a random address in memory, casts it, and saves the difference, without ever dereferencing it.

The problem with virtual inheritance is that the shift between the base class and the derived class is not fixed and is thus saved somewhere in the derived object’s memory. This means that this cast actually dereferences that invalid pointer and tries to read the address of the base class there.

We couldn’t find how to overcome this limitation in pure C++.

In the end, the `registerType` function must be called. It will register the type in the global map so that every time you use an object of type T, the correct type interface will be retrieved.

## Usage

Objects are usually handled by `AnyObject`, which contains a shared pointer to a `GenericObject`.

### GenericObject

At the lowest level, the object is type-erased as a `GenericObject`, defined in genericobject.hpp. This class contains a `void*` and an `ObjectTypeInterface*`. It does not own the object. It provides all the functions you need to call methods, trigger signals, connect to them and access properties.

It inherits from `Manageable` which adds some hidden methods for tracing and statistics. These methods are also exposed through type erasure.

### AnyObject

`AnyObject` wraps a `GenericObject`. It is defined in object.hxx. It owns the `GenericObject` through a shared pointer and this shared pointer owns the real object thanks to a custom destructor (or shared pointer refcount sharing).

It re-exposes all the methods of `GenericObject` through `GenericObjectBounce`.

### Object

`AnyObject` is actually not a class but only an alias to `Object<qi::Empty>`.

`Object` is defined in object.hxx. It has an `operator->()` that returns the `T` it has been specialized to (after a runtime check in the function `checkT` which can throw).

This allows you to write code like:

    qi::Object<MyClass> obj(new MyClass());
    obj->directCall();

Assuming `MyClass` is a type registered in the type system.

## About futures

Futures are not part of the function signature. A function returning a type `T` has the same signature as a function returning a `Future<T>` in the type system.

This implies some complex code to extract the potential future the method returns and unwrapping it. The code to do that is in `GenericObject::call` and `GenericObject::async`, in genericobject.hpp. This task is accomplished by `extractFuture` and `adaptFutureUnwrap`.

There is one more trick to that: futures are registered in the type system, as Objects. This case is explained in Registering template types.

Glossary Site map Index Support Contact Legal Notices