# Signal

<a id="signal"></a>

# Signal

```cpp
template<typename RT, typename MutexT = NullSharedMutex>
class Signal
```

[Defined in src/base/include/icy/signal.h:139](https://github.com/auscaster/icey/blob/main/src/base/include/icy/signal.h#L139)

[Signal](#signal) and slots implementation.

To create a signal, declare member variables of type `Signal<...>` in your class. The template parameter is the argument types that will be passed to the callback functions.

Here's a simple example with a class `MyClass` that has a single signal `my_signal` which takes a single `int` argument: 
```
class MyClass
{
public:
    Signal<int> my_signal;
    ...
};
```
 To connect to a signal, call its `attach()` member function, passing a function (in the `std::function` sense) as the argument. The function can be a function pointer, a functor object, or an anonymous lambda function.

Here's an example connecting to the above signal to a lambda function: 
```
MyClass my_class;
my_class.my_signal.attach([](int x) {
    cout << "value: " << x << endl;
});
```
 The `attach()` function returns a unique ID of type `int` which can be used later to disconnect the callback function.

Here's an example using the above code to then immediately disconnect the signal connection with the `detach()` member function: 
```
MyClass my_class;
auto id = my_class.my_signal.attach([](int x) {
    cout << "value: " << x << endl;
});
my_class.my_signal.detach(id);
```
 The `detach()` function is passed the callback ID and will return `true` if a callback was disconnected or `false` if the ID wasn't found. Note that `detach()` can be safely called from within the callback scope.

In the case of class members there is a [`slot()`](https://auscaster.com/icey/docs/api-reference/base.md#slot) helper that can be used to bind the signal like so: 
```
class TargetClass
{
public:
    Signal<int> my_signal;

    int print(int x)
    {
        cout << "say: " << x << endl;
    }
};

MyClass my_class;

TargetClass target_class;
my_class.my_signal += slot(&target_class, &TargetClass::print)
```
 The [`slot()`](https://auscaster.com/icey/docs/api-reference/base.md#slot) helper can also be used to disconnect class member callbacks like so: 
```
my_class.my_signal -= slot(&target_class, &TargetClass::print)
```
 To emit the signal, call its `emit()` member function passing arguments matching the types of those in the signal variable declaration.

Using the above example code, here's an example showing how to emit `my_signal`: 
```
my_class.my_signal.emit(42);
```
 Since the signal was declared to take a single `int` argument, this will cause any callbacks connected to the signal to be called, passing the integer `42` as the only argument.

`Signal<...>` is the single-threaded fast-path implementation and is intended for the common libuv event-loop case. Use `ThreadSignal<...>` when a signal may be emitted, attached, or detached from multiple threads.
