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

# Call code path

A call in libqi employs a very twisted code path before arriving to its destination. This section will try to decompose that path and explain what each part does.

## Method advertising

As explained in Object type erasure, you must advertise your methods so that they can be used in type-erased contexts. When you advertise them, they are wrapped in an `AnyFunction` with `AnyFunction::from`.

That `from` function is defined in anyfunctionfactory.hxx and try to match the type you give it (a member function pointer, a boost function, etc) with `AnyFunctionMaker`. This will create a type interface for your function which implements `FunctionTypeInterface` which is defined in anyfunction.hpp.

When instantiating the `FunctionTypeInterfaceEq`, a mask is given to the constructor. This mask tells if each argument must be transfered by value or by pointer (see Pointer as pointer and pointer as value). Bit 0 is for return type, other bits are for arguments.

`transformRef` adds the indirection for each argument that need it. Then the `makeCall` functions, defined by the `makeCall` macro call the function and cast each argument to the correct type. It should be possible to rewrite this code without using macros, only with meta programing.

The return value of the function is caught by `AnyReferenceCopy` which allocates a copy of the return value on the heap so that it can travel in a type-erased manner. It overrides its `operator,` as a trick to get the return value of the function and not having a compilation failure when the function returns `void`.

As we’ll see below, the return value is returned as an AnyReference which must be `destroy()`-ed by the caller.

## Calling a method on an AnyObject/GenericObject

`AnyObject` re-exposes the interfaced of `GenericObject` through `GenericObjectBounce`, defined in object.hxx, from which it inherits. `GenericObject` has generic `call` and `async` methods defined in genericobject.hpp.

These method catch all their arguments by `AutoAnyReference` which is the same as `AnyReference` but with a templated constructor that calls `AnyReference::from`. `call` and `async` call `metaCall` which is another member function which adds a layer of type-erasure. They specify if the call must be synchronous or not and give the method name and the parameters. The signature of the return type is given for the compatibility layer that libqi provides for structures described in Struct extension.

From this point on, methods return a `Future<AnyReference>` which points to the return value of the called method. It is the responsibility of the caller to free it.

This first overload of `metaCall` (called by `call` and `async`) takes a `nameWithOptionalSignature`. It will use the `MetaObject::findMethod` method, giving it that name and the arguments of the call, to resolve which overload must be called. `findMethod` then returns an integer which is the id of the method or `-1` if it couldn’t be found. In the latter case, it generates an error string with a meaningful error message. On success, it calls the other overload of `metaCall` which takes an integer and not a name. This last method just forwards the call to `ObjectTypeInterface::metaCall`.

The returned `Future<AnyReference>` may actually be a `Future<Future<T>>`, if the method returns a future and the call is made in async. As explained in About futures, a method can return a value or a future in a transparent way to the caller, so the nested future must be extracted. This is done through `extractFuture` and `adaptFutureUnwrap`, defined in futureadapter.hxx depending on the type of the call.

## Object type interface implementation

The `metaCall` method has the following signature:

    qi::Future<AnyReference> metaCall(
          void* instance,
          AnyObject context,
          unsigned int method,
          const GenericFunctionParameters& params,
          MetaCallType callType = MetaCallType_Auto,
          Signature returnSig = Signature());

The first argument is the storage, as described in Type system. The second argument is the `AnyObject` the call was made in. It is used to run the call in a specific `ExecutionContext`, associated to the `AnyObject` and to add stats and tracing to the `AnyObject`. It receives also the id of the method to be called, the arguments of the call in the form close to a `vector<AnyReference>` which must not be freed. The `callType` argument specifies if the user wanted the call to be synchronous or asynchronous. It is used only as a hint of what the user wants and it depends on the implementation of `metaCall` if the call is synchronous or not. For example, if the object has a strand, the call can not be synchronous. The last argument is the signature of the expected return value. It is used for structure compatibility.

One possible implementation is in staticobjecttype.cpp. This method checks that the method exists and that it will be able to convert the returned value to the expected value. If it can’t, it doesn’t do the call and just return an error.

The other implementation is very similar and is in dynamicobject.cpp. `DynamicObjectInterface::metaCall` actually calls `DynamicObject::metaCall` which does almost the same thing as `StaticObjectTypeBase::metaCall`.

After that, it gets the `ExecutionContext` on which to run the call. If the id of the method is small, it means the method belongs to `Manageable` which we’ll talk about later. Otherwise, the method belongs to the object.

In our case, the `metaCall` method prepends the `this` argument and calls the method `qi::metaCall`, which is the generic method which will execute the final call. It gives it the method to call as an `AnyFunction`.

## qi::metaCall

This method is defined in anyobject.cpp. It first decides if the call must be synchronous or not. If the call is direct, it bounces to the `call` method directly. If the call is asynchronous, it posts a functor on the `ExecutionContext` which will call `call` when it’s called.

`call` will handle tracing and stats if they are enabled and trigger the appropriate signals. It will do the call itself through the `AnyFunction` and set the promise to the returned `AnyReference`.

## Remote objects

Objects that reside in other processes through qimessaging are exposed through `RemoteObject` which inherits from `DynamicObject` and implements its own `metaCall`. It sends a message and returns a future that will be set when the call reply is received.

Glossary Site map Index Support Contact Legal Notices