Corrade::Interconnect::Emitter class

Emitter object.

Contains signals and manages connections between signals and slots. See Signals and slots for introduction.

Implementing signals

Signals are implemented as member functions with Signal as return type, argument count and types are not limited. The body consists of single emit() call, to which you pass pointer to the function and forward all arguments. Example signal implementations:

class Postman: public Interconnect::Emitter {
    public:
        Signal messageDelivered(const std::string& message, int price = 0) {
            return emit(&Postman::messageDelivered, message, price);
        }

        Signal paymentRequired(int amount) {
            return emit(&Postman::paymentRequired, amount);
        }
};

The implemented signal can be emitted simply by calling the function:

Postman postman;
postman.messageDelivered("hello");
postman.paymentRequired(245);

If the signal is not declared as public function, it cannot be connected or called from outside the class.

Connecting signals to slots

Signals implemented on Emitter subclasses can be connected to slots using various connect() functions. The argument count and types of slot function must be exactly the same as of the signal function. When a connection is established, returned Connection object can be used to remove or reestablish given connection using Connection::disconnect() or Connection::connect():

Connection c = Emitter::connect(...);
// ...
c.disconnect();
// ...
c.connect();
// ...

You can also call disconnectSignal() or disconnectAllSignals() on emitter to remove the connections. All emitter connections are automatically removed when emitter object is destroyed.

You can connect any signal, as long as the emitter object is of proper type:

class Base: public Interconnect::Emitter {
    public:
        Slot baseSignal();
};

class Derived: public Base {
    public:
        Slot derivedSignal();
};

Base* a = new Derived;
Derived* b = new Derived;
Interconnect::connect(*a, &Base::baseSignal, ...);       // ok
Interconnect::connect(*b, &Base::baseSignal, ...);       // ok
Interconnect::connect(*a, &Derived::derivedSignal, ...); // error, `a` is not of Derived type
Interconnect::connect(*b, &Derived::derivedSignal, ...); // ok

There are a few slot types, each type has its particular use:

Member function slots

When connecting to member function slot with connect(), receiver must be subclass of Receiver and slot must be non-constant member function with void as return type.

In addition to the cases mentioned above, the connection is automatically removed also when receiver object is destroyed. You can also use Receiver::disconnectAllSlots() to disconnect the receiver from everything.

Example usage:

class Mailbox: public Interconnect::Receiver {
    public:
        void addMessage(const std::string& message, int price);
};

Postman postman;
Mailbox mailbox;
Interconnect::connect(&postman, &Postman::messageDelivered, &mailbox, &Mailbox::addMessage);

You can connect to any member function, as long as Receiver exists somewhere in given object type hierarchy:

class Foo: public Interconnect::Emitter {
    public:
        Signal signal();
};

class Base: public Interconnect::Receiver {
    public:
        void baseSlot();
};

class Derived: public Base {
    public:
        void derivedSlot();
};

Foo foo;
Base* a = new Derived;
Derived* b = new Derived;

Interconnect::connect(&foo, &Foo::signal, a, &Base::baseSlot);       // ok
Interconnect::connect(&foo, &Foo::signal, b, &Base::baseSlot);       // ok
Interconnect::connect(&foo, &Foo::signal, a, &Derived::derivedSlot); // error, `a` is not of Derived type
Interconnect::connect(&foo, &Foo::signal, b, &Derived::derivedSlot); // ok

It is also possible to connect to member function of class which itself isn't subclass of Receiver, just add Receiver using multiple inheritance. Convoluted example:

class MyString: public std::string, public Receiver {};

std::string a;
MyString b;
Interconnect::connect(&foo, &Foo::signal, &a, &std::string::clear); // error, `a` is not of Receiver type
Interconnect::connect(&foo, &Foo::signal, &b, &std::string::clear); // ok

Derived classes

template<std::size_t states, std::size_t inputs, class State, class Input>
class StateMachine
State machine.

Public types

class Signal
Signature for signals.

Constructors, destructors, conversion operators

Emitter(const Emitter&) deleted
Copying is not allowed.
Emitter(Emitter&&) deleted
Moving is not allowed.

Public functions

auto operator=(const Emitter&) -> Emitter& deleted
Copying is not allowed.
auto operator=(Emitter&&) -> Emitter& deleted
Moving is not allowed.
auto hasSignalConnections() const -> bool
Whether the emitter is connected to any slot.
template<class Emitter, class ... Args>
auto hasSignalConnections(Signal(Emitter::*)(Args...) signal) const -> bool
Whether given signal is connected to any slot.
auto signalConnectionCount() const -> std::size_t
Count of connections to this emitter signals.
template<class Emitter, class ... Args>
auto signalConnectionCount(Signal(Emitter::*)(Args...) signal) const -> std::size_t
Count of slots connected to given signal.
template<class Emitter, class ... Args>
void disconnectSignal(Signal(Emitter::*)(Args...) signal)
Disconnect signal.
void disconnectAllSignals()
Disconnect everything from this emitter signals.

Protected functions

template<class Emitter, class ... Args>
auto emit(Signal(Emitter::*)(Args...) signal, typename std::common_type<Args>::type... args) -> Signal
Emit signal.

Function documentation

bool Corrade::Interconnect::Emitter::hasSignalConnections() const

Whether the emitter is connected to any slot.

template<class Emitter, class ... Args>
bool Corrade::Interconnect::Emitter::hasSignalConnections(Signal(Emitter::*)(Args...) signal) const

Whether given signal is connected to any slot.

std::size_t Corrade::Interconnect::Emitter::signalConnectionCount() const

Count of connections to this emitter signals.

template<class Emitter, class ... Args>
std::size_t Corrade::Interconnect::Emitter::signalConnectionCount(Signal(Emitter::*)(Args...) signal) const

Count of slots connected to given signal.

template<class Emitter, class ... Args>
void Corrade::Interconnect::Emitter::disconnectSignal(Signal(Emitter::*)(Args...) signal)

Disconnect signal.

Disconnects all slots connected to given signal.

Example usage:

Postman postman;
postman.disconnect(&postman, &Postman::messageDelivered);

void Corrade::Interconnect::Emitter::disconnectAllSignals()

Disconnect everything from this emitter signals.

template<class Emitter, class ... Args>
Signal Corrade::Interconnect::Emitter::emit(Signal(Emitter::*)(Args...) signal, typename std::common_type<Args>::type... args) protected

Emit signal.

Parameters
signal Signal
args Arguments

See class documentation for more information about implementing signals.

template<class EmitterObject, class Emitter, class ... Args>
Connection connect(EmitterObject& emitter, Interconnect::Emitter::Signal(Emitter::*)(Args...) signal, void(*)(Args...) slot)

Connect signal to function slot.

Parameters
emitter Emitter
signal Signal
slot Slot

Connects given signal to compatible slot. emitter must be subclass of Emitter, signal must be implemented signal and slot must be non-member function or non-capturing lambda with void as return type. The argument count and types must be exactly the same.

See Emitter class documentation for more information about connections.

template<class EmitterObject, class Emitter, class Lambda, class ... Args>
Connection connect(EmitterObject& emitter, Interconnect::Emitter::Signal(Emitter::*)(Args...) signal, Lambda slot)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

template<class EmitterObject, class Emitter, class Receiver, class ReceiverObject, class ... Args>
Connection connect(EmitterObject& emitter, Interconnect::Emitter::Signal(Emitter::*)(Args...) signal, ReceiverObject& receiver, void(Receiver::*)(Args...) slot)

Connect signal to member function slot.

Parameters
emitter Emitter
signal Signal
receiver Receiver
slot Slot

Connects given signal to compatible slot in receiver object. emitter must be subclass of Emitter, signal must be implemented signal, receiver must be subclass of Receiver and slot must be non-constant member function with void as return type. The argument count and types must be exactly the same.

See Emitter class documentation for more information about connections.