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

# qi::Signal

## Summary

Global Classes

- class qi::Signal

  Functions (class qi::Signal)

  qi::SignalF<T>::signature

  qi::SignalF<T>::SignalF

  qi::SignalF<T>::connect

  qi::SignalBase::disconnectAllAsync

  qi::SignalBase::subscribers

  qi::SignalBase::setOnSubscribers

  qi::SignalBase::connect

  qi::SignalBase::asyncDisconnectAll

  qi::SignalBase::setCallType

  qi::SignalBase::trigger

  qi::SignalBase::SignalBase

  qi::SignalBase::disconnect

  qi::SignalBase::disconnectAsync

  qi::SignalBase::disconnectAll

  qi::SignalBase::~SignalBase

  qi::SignalBase::operator()

  qi::SignalBase::asyncDisconnect

  qi::SignalBase::signature

  qi::SignalBase::hasSubscribers

  qi::SignalBase::_setSignature

  qi::SignalBase::connectAsync

  qi::Signal<P>::Signal

  Members (class qi::Signal)

  qi::SignalBase::invalidSignalLink

## Detailed Description

This is an implementation of the signal/event paradigm, with some specificities:

- Thread-safe.
- Synchronous or asynchronous subscriber invocation.
- Subscriber disconnection guarantees that subscriber is not/will not be called anymore when it returns.
- Automatic subscriber disconnection when `weak_ptr` or `qi::Trackable` is used.

`qi::Signal` is non-copyable.

### Template arguments

`Signal` is templated by the argument types that must be passed when triggering, and that will be transmitted to subscribers. For instance, `Signal<int, int>` is the type of a `Signal` with two ints as payload type: `Signal::operator()` will expect two ints, and subscribers will be expected to have signature `void(int, int)`.

Note

The types used as template arguments to signal must be registered to the type system. If you fail to do that, you will get errors like:

    Cannot do 'clone' on YourType

### Connection to a signal

Use `Signal::connect` to register a subscriber that will be called each time the signal is triggered.

Arguments to `connect` can take multiple forms:

- A function or callable object (like `boost::function`). The callable object must be copyable. Beware, each time the signal is triggered, a temporary copy of the callable might be made, invoked, then thrown away.
- A function or callable, followed by arguments and placeholders that will be bound to the function.
- Another compatible `Signal`.

The variadic form of `connect` works in a similar manner to `boost::bind()`: values passed to `connect` will be passed to the function, in order, and placeholders `_1`, `_2`... will be replaced by the signal payloads.

This form will also recognize if the first argument is a `boost::weak_ptr`, or if it as pointer to a class inheriting from `qi::Trackable`. In both cases, the subscriber will be automatically disconnected if the pointer cannot be locked. See this example for a demonstration of that very same mechanism in `qi::Future`.

`Signal::connect` returns a `SignalSubscriber&`, that you can use to:

- Override the default call type for this subscriber to synchronous or asynchronous by calling `SignalSubscriber::setCallType` (see callback type).

- Obtain a subscriber identifier of type `qi::SignalLink` by casting the `SignalSubscriber`:

      qi::SignalLink link = someSignal.connect(callback1);

Unregistering a subscriber is done by invoking `Signal::disconnect` with a `SignalLink` as its sole argument. The call will block until all currently running invocations of the subscriber have finished. This gives you the strong guarantee than once `disconnect` has returned, your callback function is not being called, and will never be called again.

Warning

`disconnect` is a blocking method which will wait for the callback to finish (except if it’s called from withing the callback). The signal destruction is also blocking. These two cases may cause deadlocks in your code, be careful.

### Triggering the signal

Triggering the signal is achieved by using the `Signal::operator()`, with arguments matching the `Signal` type:

    qi::Signal<int, int> sig;
    // QI_EMIT is here for readability
    QI_EMIT sig(51, 42);

This will invoke all subscribers with given arguments.

### Signal callback type

It is possible to control how subscribers are invoked:

- `MetaCallType_Auto` is the default and means asynchronous.
- `MetaCallType_Direct` forces a synchronous call.
- `MetaCallType_Queued` forces an asynchronous call.

Note that if any subscriber is invoked asynchronously, the arguments passed to `Signal::operator()` will be copied.

You can set the call type of a signal globally with `setCallType`, but you can also set it per-callback. You can do that by calling `setCallType` on the `SignalSubscriber` returned by `connect`.

    qi::SignalLink l = someSignal
        .connect(callback2)
        .setCallType(qi::MetaCallType_Direct);

Warning

It is very dangerous to set the call type to Direct as your function may block the code that triggers the signal. This type of call is only useful for optimization purposes, only for very small and fast fuctions that do not lock.

### Signal lazy enabling

Sometimes, mainly for performance reasons, it is useful to only enable some code if a `Signal` has at least one subscriber. For example, if you have a signal `humanDetected`, you may want to enable the image processing code only if there is at least one subscriber to the signal to save CPU cycles.

This can be achieved by passing a callback to the `Signal` constructor, of signature `void(bool)`. This function will be called synchronously each time the number of subscribers switches between 0 and 1.

    void onConnect(bool c)
    {
      if (c)
        std::cout << "First connection";
      else
        std::cout << "No more connections";
    }

    qi::Signal<int> sig(onConnect);
    qi::SignalLink l1 = sig.connect(mycallback); // calls onConnect(true)
    qi::SignalLink l2 = sig.connect(mycallback); // nothing happens
    sig.disconnect(l1); // nothing happens
    sig.disconnect(l2); // calls onConnect(false);

### Example

Here is a simple example, demonstrating how you can connect a callback, then disconnect it before it gets destroyed.

    class MyClass
    {
    public:
      void myCallback(const std::string& str, int value)
      {
        // ...
      }
    };

    void main()
    {
      qi::Signal<int> someSignal;
      {
        MyClass myInstance;
        qi::SignalLink link = someSignal.connect(
            std::bind(&MyClass::myCallback, &myInstance,
                      "this connection", std::placeholders::_1));
        someSignal(42);
        someSignal(43);
        someSignal.disconnect(link);
      }
      someSignal(44);
    }

### Overriding signal triggering behavior (advanced)

Sometimes, mainly when bridging `Signal` with another signal implementation, one needs to override the action performed when the signal is triggered (which is by default to invoke all subscribers).

This can be achieved by inheriting from `Signal`, and then either overriding the `trigger` virtual function, or by calling `setTriggerOverride` with a functor that will replace the original trigger. You can then call `callSubscribers` to invoke the subscribers, which `trigger` would do by default.

## Reference

### qi::Signal Class Reference

#### Introduction

`More...`

    #include <qi/signal.hpp>

- Inherits: `qi::SignalF< void(P...)>`

#### Public Members

const SignalLink ``invalidSignalLink``

#### Public Functions

``Signal``(OnSubscribers onSubscribers)
``Signal``(ExecutionContext* execContext, OnSubscribers onSubscribers)

``SignalF``(OnSubscribers onSubscribers)
``SignalF``(ExecutionContext* execContext, OnSubscribers onSubscribers)
qi::Signature ``signature``() const
SignalSubscriber ``connect``(...)

``SignalBase``(const Signature& signature, OnSubscribers onSubscribers)
``SignalBase``(const Signature& signature, ExecutionContext* execContext, OnSubscribers onSubscribers)
``SignalBase``(OnSubscribers onSubscribers)
``SignalBase``(ExecutionContext* execContext, OnSubscribers onSubscribers)
````()
````()
``~SignalBase``()
qi::Signature ``signature``() const
template<typename F>
SignalSubscriber ``connect``(boost::function<F> func)
SignalSubscriber ``connect``(AnyObject object, unsigned int slot)
SignalSubscriber ``connect``(AnyObject object, const std::string& slot)
SignalSubscriber ``connect``(const SignalSubscriber& s)
Future<SignalSubscriber> ``connectAsync``(const SignalSubscriber&)
bool ``disconnectAll``()
Future<bool> ``disconnectAllAsync``()
bool ``asyncDisconnectAll``()
bool ``disconnect``(const SignalLink& link)
Future<bool> ``disconnectAsync``(const SignalLink& link)
bool ``asyncDisconnect``(const SignalLink& link)
void ``trigger``(const GenericFunctionParameters& params, MetaCallType callType)
void ``setCallType``(MetaCallType callType)
void ``operator()``(qi::AutoAnyReference p1)
std::vector<SignalSubscriber> ``subscribers``()
bool ``hasSubscribers``()
void ``setOnSubscribers``(OnSubscribers onSubscribers)
void ``_setSignature``(const Signature& s)

#### Types

typedef void(FunctionType)(P...)
typedef SignalF< FunctionType > ParentType
typedef typename ParentType::OnSubscribers OnSubscribers

typedef T FunctionType

typedef boost::function< Future< void >(bool)> OnSubscribers
typedef boost::function< void(const GenericFunctionParameters &params, MetaCallType callType)> Trigger

#### Detailed Description

Class that represent an event to which function can subscribe.

#### Members Documentation

const SignalLink `qi::SignalBase::``invalidSignalLink`

#### Functions Documentation

`qi::Signal<P>::``Signal`(OnSubscribers onSubscribers = OnSubscribers()

`qi::Signal<P>::``Signal`(ExecutionContext* execContext, OnSubscribers onSubscribers = OnSubscribers()

`qi::SignalF<T>::``SignalF`(OnSubscribers onSubscribers = OnSubscribers()

  Brief:

  Parameters: | onSubscribers – invoked each time number of subscribers switch between 0 and 1, with argument ‘!subscribers.empty()’ Will not be called when destructor is invoked and all subscribers are removed

  Signal constructor

`qi::SignalF<T>::``SignalF`(ExecutionContext* execContext, OnSubscribers onSubscribers)

qi::Signature `qi::SignalF<T>::``signature`()`const`

SignalSubscriber `qi::SignalF<T>::``connect`(...)

  Brief:

  Returns: | a SignalSubscriber object. This object can be implicitly converted to a SignalLink.

  Connect a subscriber to this signal.

  Multiple forms can be used: connect(function, argOrPlaceholder1, argOrPlaceholder2, ...) Where function is a function or callable object (such as a boost::function). If the first argument is a weak ptr or inherits qi::Trackable, the slot will automatically disconnect if object is no longuer available.connect(AnyObject target, unsigned int slot)connect(AnyObject target, const std::string& slotName)connect(AnyFunction func)connect(const SignalSubscriber&)connect(qi::Signal<U>& otherSignal)

`qi::SignalBase::``SignalBase`(const Signature& signature, OnSubscribers onSubscribers = OnSubscribers()

`qi::SignalBase::``SignalBase`(const Signature& signature, ExecutionContext* execContext, OnSubscribers onSubscribers = OnSubscribers()

`qi::SignalBase::``SignalBase`(OnSubscribers onSubscribers = OnSubscribers()

`qi::SignalBase::``SignalBase`(ExecutionContext* execContext, OnSubscribers onSubscribers = OnSubscribers()

`()`

`()`

`qi::SignalBase::``~SignalBase`()

qi::Signature `qi::SignalBase::``signature`()`const`

template<typename F>
SignalSubscriber `qi::SignalBase::``connect`(boost::function<F> func)

SignalSubscriber `qi::SignalBase::``connect`(AnyObject object, unsigned int slot)

SignalSubscriber `qi::SignalBase::``connect`(AnyObject object, const std::string& slot)

SignalSubscriber `qi::SignalBase::``connect`(const SignalSubscriber& s)

  The following overloads are the lowest-level.

Future<SignalSubscriber> `qi::SignalBase::``connectAsync`(const SignalSubscriber&)

  Connect asynchronously. This is recommended since derived classes may provide asynchronous customizations for dealing with subscribers. The callbacks are guaranteed to be called only after the returned future is set.

bool `qi::SignalBase::``disconnectAll`()

  Brief:

  Returns: | Returns true on success.

  Disconnect all callbacks from signal.

  This function will block until all callbacks are finished.

Future<bool> `qi::SignalBase::``disconnectAllAsync`()

  Brief:

  Returns: | A future set to true on success.

  Disconnect all callbacks from signal without waiting for them.

  This function does not block.

bool `qi::SignalBase::``asyncDisconnectAll`()

bool `qi::SignalBase::``disconnect`(const SignalLink& link)

  Brief:

  Returns: | Returns true on success.

  Disconnect a SignalHandler.

  The associated callback will not be called anymore as soon as this function returns.

  This method blocks until all the already running callbacks are finished.

Future<bool> `qi::SignalBase::``disconnectAsync`(const SignalLink& link)

  Brief:

  Returns: | A future set to true on success.

  Disconnect a SignalHandler without waiting for it.

  Same as disconnect, but this method does not block. Though this is async, you are guaranteed that once the function returns the future, your callback will not be called anymore.

bool `qi::SignalBase::``asyncDisconnect`(const SignalLink& link)

void `qi::SignalBase::``trigger`(const GenericFunctionParameters& params, MetaCallType callType = MetaCallType_Auto)

  Brief:

  Parameters: | params – the signal arguments callType – specify how to invoke subscribers. Used in combination with each subscriber’s MetaCallType to chose between synchronous and asynchronous call. The combination rule is to honor subscriber’s override, then callType, then signal’s callType and default to asynchronous

  Trigger the signal with given type-erased parameters.

void `qi::SignalBase::``setCallType`(MetaCallType callType)

  Set the MetaCallType used by operator()().

void `qi::SignalBase::``operator`(qi::AutoAnyReference p1 = qi::AutoAnyReference()

  Trigger the signal with given arguments, and call type set by setCallType()

std::vector<SignalSubscriber> `qi::SignalBase::``subscribers`()

bool `qi::SignalBase::``hasSubscribers`()

void `qi::SignalBase::``setOnSubscribers`(OnSubscribers onSubscribers)

  Set a function to call when the number of subscribers go between 1 and 0. You can use this to avoid computing if no one has subscribed to the signal.

void `qi::SignalBase::``_setSignature`(const Signature& s)

### qi::SignalSubscriber Class Reference

Unknow Class.

Glossary Site map Index Support Contact Legal Notices