# Signal< RT(Args...), MutexT >

<a id="signalrtargsmutext"></a>

# Signal< RT(Args...), MutexT >

```cpp
#include <icy/signal.h>

template<typename RT, typename... Args, typename MutexT>
class Signal< RT(Args...), MutexT >
```

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

Thread-safe signal and slot implementation for callback-based event dispatch.

## Public Methods

| Return | Name | Description |
|--------|------|-------------|
| `int` | [`attach`](#attach-3) `const` `inline` | Connects a `lambda` or `std::function` to the signal. |
| `int` | [`attach`](#attach-4) `const` `inline` | Connects a pre-constructed `SlotPtr` to the signal. |
| `bool` | [`detach`](#detach-2) `const` `inline` | Detaches the slot with the given ID. |
| `bool` | [`detach`](#detach-3) `const` `inline` | Detaches all slots associated with the given instance pointer. |
| `bool` | [`detach`](#detach-4) `const` `inline` | Detaches the slot whose delegate compares equal to `other->delegate`. |
| `void` | [`detachAll`](#detachall) `const` `inline` | Detaches and destroys all currently attached slots. |
| `RT` | [`emit`](#emit-6) `virtual` `inline` | Emits the signal, invoking all live attached slots in priority order. |
| std::vector< [`SlotPtr`](#slotptr) > | [`slots`](#slots) `const` `inline` | Returns a snapshot copy of the current slot list. |
| `size_t` | [`nslots`](#nslots) `const` `inline` | Returns the number of slots currently registered with this signal. |
| `int` | [`operator+=`](#operator-84) `inline` | Attaches a function; equivalent to `attach(func)`. |
| `int` | [`operator+=`](#operator-85) `inline` | Attaches a pre-constructed slot; equivalent to `attach(slot)`. |
| `bool` | [`operator-=`](#operator-86) `inline` | Detaches the slot with the given ID; equivalent to `detach(id)`. |
| `bool` | [`operator-=`](#operator-87) `inline` | Detaches all slots for the given instance; equivalent to `detach(instance)`. |
| `bool` | [`operator-=`](#operator-88) `inline` | Detaches the slot matching `slot`'s delegate; equivalent to `detach(slot)`. |
|  | [`Signal`](#signal-1)  | Defaulted constructor. |
|  | [`~Signal`](#signal-2) `inline` |  |
|  | [`Signal`](#signal-3) `inline` | Copy constructor; copies the slot list and last-assigned ID from `r`. |
| [`Signal`](https://auscaster.com/icey/docs/api-reference/icy-Signal.md#signal) & | [`operator=`](#operator-89) `inline` | Copy assignment operator; copies the slot list and last-assigned ID from `r`. |

---

<a id="attach-3"></a>

### attach

`const` `inline`

```cpp
inline int attach(Function const & func, void * instance = nullptr, int id = -1, int priority = -1) const
```

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

Connects a `lambda` or `std::function` to the signal.

#### Returns
The assigned slot ID, which can be passed to [`detach()`](#detach-2) to disconnect.

#### Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `func` | [`Function`](#function) const & | The callable to invoke when the signal is emitted. |
| `instance` | `void *` | Optional owner pointer used for instance-based detach; pass `nullptr` if not applicable. |
| `id` | `int` | Explicit slot ID to assign; pass `-1` to auto-assign. |
| `priority` | `int` | Higher values are called first; pass `-1` for default ordering. |

---

<a id="attach-4"></a>

### attach

`const` `inline`

```cpp
inline int attach(SlotPtr slot) const
```

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

Connects a pre-constructed `SlotPtr` to the signal.

Duplicate slots (matched by delegate equality) are removed before insertion. Slots are kept sorted in descending priority order after insertion.

#### Returns
The assigned slot ID, which can be passed to [`detach()`](#detach-2) to disconnect.

#### Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `slot` | [`SlotPtr`](#slotptr) | The slot to attach. Must have a valid delegate. |

#### Exceptions

| Exception | Description |
|-----------|-------------|
| `std::logic_error` | if `slot->id` is set explicitly and already in use. |

---

<a id="detach-2"></a>

### detach

`const` `inline`

```cpp
inline bool detach(int id) const
```

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

Detaches the slot with the given ID.

Safe to call from within a slot's callback (the slot is marked dead before erasure).

#### Returns
`true` if a slot was found and removed; `false` if the ID was not found.

#### Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `id` | `int` | The slot ID returned by [`attach()`](#attach-3). |

---

<a id="detach-3"></a>

### detach

`const` `inline`

```cpp
inline bool detach(const void * instance) const
```

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

Detaches all slots associated with the given instance pointer.

Useful for bulk disconnect when an object is destroyed. Matches slots by their stored `instance` pointer, not by delegate equality.

#### Returns
`true` if at least one slot was removed; `false` otherwise.

#### Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `instance` | `const void *` | The owner pointer used when the slots were attached. |

---

<a id="detach-4"></a>

### detach

`const` `inline`

```cpp
inline bool detach(SlotPtr other) const
```

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

Detaches the slot whose delegate compares equal to `other->delegate`.

Used by the [`slot()`](https://auscaster.com/icey/docs/api-reference/base.md#slot) helper overloads and `operator-=` to disconnect a specific class-member or function binding by value.

#### Returns
`true` if a matching slot was found and removed; `false` otherwise.

#### Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `other` | [`SlotPtr`](#slotptr) | A slot whose delegate is compared against attached slots. |

---

<a id="detachall"></a>

### detachAll

`const` `inline`

```cpp
inline void detachAll() const
```

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

Detaches and destroys all currently attached slots.

Each slot is marked dead before removal. After this call [`nslots()`](#nslots) returns 0.

---

<a id="emit-6"></a>

### emit

`virtual` `inline`

```cpp
virtual inline RT emit(Args... args)
```

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

Emits the signal, invoking all live attached slots in priority order.

For `Signal<bool(...)>`: iterates slots and returns `true` as soon as any slot returns `true`, stopping further propagation. Returns `false` if no slot handled the event.

For `Signal<void(...)>`: calls every live slot unconditionally.

Local `Signal<...>` traverses the stable slot list directly without any snapshot allocation. `ThreadSignal<...>` snapshots raw node pointers under a shared lock, then invokes delegates without holding the lock. Dead slots are swept after the outermost emission returns, allowing attach/detach inside callbacks without copying `shared_ptr`s on the hot path.

#### Returns
For `bool` return type: `true` if any slot handled the event, `false` otherwise. For `void` return type: nothing.

#### Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `args` | `Args...` | Arguments forwarded to each connected slot. |

---

<a id="slots"></a>

### slots

`const` `inline`

```cpp
inline std::vector< SlotPtr > slots() const
```

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

Returns a snapshot copy of the current slot list.

The copy is taken under a shared lock, so it is safe to call concurrently with attach/detach operations. Only currently live slots are returned.

#### Returns
A vector of `SlotPtr` representing all currently registered slots.

---

<a id="nslots"></a>

### nslots

`const` `inline`

```cpp
inline size_t nslots() const
```

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

Returns the number of slots currently registered with this signal.

The count is taken under a shared lock and tracks only currently live slots. Dead-but-not-yet-swept nodes are excluded.

#### Returns
The number of entries in the internal slot list.

---

<a id="operator-84"></a>

### operator+=

`inline`

```cpp
inline int operator+=(Function const & func)
```

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

Attaches a function; equivalent to `attach(func)`.

#### Returns
Assigned slot ID.

---

<a id="operator-85"></a>

### operator+=

`inline`

```cpp
inline int operator+=(SlotPtr slot)
```

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

Attaches a pre-constructed slot; equivalent to `attach(slot)`.

#### Returns
Assigned slot ID.

---

<a id="operator-86"></a>

### operator-=

`inline`

```cpp
inline bool operator-=(int id)
```

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

Detaches the slot with the given ID; equivalent to `detach(id)`.

#### Returns
`true` if removed.

---

<a id="operator-87"></a>

### operator-=

`inline`

```cpp
inline bool operator-=(const void * instance)
```

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

Detaches all slots for the given instance; equivalent to `detach(instance)`.

#### Returns
`true` if any removed.

---

<a id="operator-88"></a>

### operator-=

`inline`

```cpp
inline bool operator-=(SlotPtr slot)
```

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

Detaches the slot matching `slot`'s delegate; equivalent to `detach(slot)`.

#### Returns
`true` if removed.

---

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

### Signal

```cpp
Signal() = default
```

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

Defaulted constructor.

---

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

### ~Signal

`inline`

```cpp
inline ~Signal()
```

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

---

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

### Signal

`inline`

```cpp
inline Signal(const Signal & r)
```

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

Copy constructor; copies the slot list and last-assigned ID from `r`.

#### Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `r` | const [`Signal`](https://auscaster.com/icey/docs/api-reference/icy-Signal.md#signal) & | The signal to copy from. |

---

<a id="operator-89"></a>

### operator=

`inline`

```cpp
inline Signal & operator=(const Signal & r)
```

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

Copy assignment operator; copies the slot list and last-assigned ID from `r`. 
#### Returns
Reference to this signal.

#### Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `r` | const [`Signal`](https://auscaster.com/icey/docs/api-reference/icy-Signal.md#signal) & | The signal to copy from. |

## Public Types

| Name | Description |
|------|-------------|
| [`Function`](#function)  |  |
| [`SlotPtr`](#slotptr)  |  |
| [`Slot`](#slot-2)  |  |
| [`SlotNode`](#slotnode)  |  |

---

<a id="function"></a>

### Function

```cpp
using Function = std::function< RT(Args...)>
```

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

---

<a id="slotptr"></a>

### SlotPtr

```cpp
using SlotPtr = std::shared_ptr< internal::Slot< RT, Args... > >
```

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

---

<a id="slot-2"></a>

### Slot

```cpp
using Slot = internal::Slot< RT, Args... >
```

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

---

<a id="slotnode"></a>

### SlotNode

```cpp
using SlotNode = internal::SlotNode< RT, Args... >
```

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

## Private Attributes

| Return | Name | Description |
|--------|------|-------------|
| `MutexT` | [`_mutex`](#_mutex-5)  |  |
| [`SlotNode`](#slotnode) * | [`_head`](#_head)  |  |
| [`SlotNode`](#slotnode) * | [`_tail`](#_tail)  |  |
| `size_t` | [`_liveCount`](#_livecount)  |  |
| `int` | [`_lastId`](#_lastid)  |  |
| `EmitDepth` | [`_emitDepth`](#_emitdepth)  |  |
| `SweepFlag` | [`_needsSweep`](#_needssweep)  |  |

---

<a id="_mutex-5"></a>

### _mutex

```cpp
MutexT _mutex
```

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

---

<a id="_head"></a>

### _head

```cpp
SlotNode * _head = nullptr
```

Type: [`SlotNode`](#slotnode) *

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

---

<a id="_tail"></a>

### _tail

```cpp
SlotNode * _tail = nullptr
```

Type: [`SlotNode`](#slotnode) *

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

---

<a id="_livecount"></a>

### _liveCount

```cpp
size_t _liveCount = 0
```

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

---

<a id="_lastid"></a>

### _lastId

```cpp
int _lastId = 0
```

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

---

<a id="_emitdepth"></a>

### _emitDepth

```cpp
EmitDepth _emitDepth {}
```

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

---

<a id="_needssweep"></a>

### _needsSweep

```cpp
SweepFlag _needsSweep {}
```

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

## Private Methods

| Return | Name | Description |
|--------|------|-------------|
| `size_t` | [`killMatchingLocked`](#killmatchinglocked) `const` `inline` |  |
| `void` | [`insertSlotLocked`](#insertslotlocked) `const` `inline` |  |
| `void` | [`appendSlotLocked`](#appendslotlocked) `const` `inline` |  |
| `void` | [`eraseNodeLocked`](#erasenodelocked) `const` `inline` |  |
| `size_t` | [`emitDepthLocked`](#emitdepthlocked) `const` `inline` |  |
| `void` | [`beginEmitLocked`](#beginemitlocked) `const` `inline` |  |
| `bool` | [`endEmitLocked`](#endemitlocked) `const` `inline` |  |
| `void` | [`requestSweepLocked`](#requestsweeplocked) `const` `inline` |  |
| `bool` | [`consumeSweepRequest`](#consumesweeprequest) `const` `inline` |  |
| `void` | [`sweepLocked`](#sweeplocked) `const` `inline` |  |
| `void` | [`finishEmit`](#finishemit) `inline` |  |
| `void` | [`clearNodesLocked`](#clearnodeslocked) `const` `inline` |  |
| `void` | [`resetEmitState`](#resetemitstate) `inline` |  |
| std::pair< std::vector< [`SlotPtr`](#slotptr) >, int > | [`snapshotState`](#snapshotstate) `const` `inline` |  |
| `void` | [`restoreState`](#restorestate) `inline` |  |

---

<a id="killmatchinglocked"></a>

### killMatchingLocked

`const` `inline`

```cpp
template<typename Matcher> inline size_t killMatchingLocked(Matcher && matcher, bool removeAll) const
```

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

---

<a id="insertslotlocked"></a>

### insertSlotLocked

`const` `inline`

```cpp
inline void insertSlotLocked(SlotPtr slot) const
```

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

---

<a id="appendslotlocked"></a>

### appendSlotLocked

`const` `inline`

```cpp
inline void appendSlotLocked(SlotPtr slot) const
```

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

---

<a id="erasenodelocked"></a>

### eraseNodeLocked

`const` `inline`

```cpp
inline void eraseNodeLocked(SlotNode * node) const
```

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

---

<a id="emitdepthlocked"></a>

### emitDepthLocked

`const` `inline`

```cpp
inline size_t emitDepthLocked() const
```

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

---

<a id="beginemitlocked"></a>

### beginEmitLocked

`const` `inline`

```cpp
inline void beginEmitLocked() const
```

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

---

<a id="endemitlocked"></a>

### endEmitLocked

`const` `inline`

```cpp
inline bool endEmitLocked() const
```

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

---

<a id="requestsweeplocked"></a>

### requestSweepLocked

`const` `inline`

```cpp
inline void requestSweepLocked() const
```

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

---

<a id="consumesweeprequest"></a>

### consumeSweepRequest

`const` `inline`

```cpp
inline bool consumeSweepRequest() const
```

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

---

<a id="sweeplocked"></a>

### sweepLocked

`const` `inline`

```cpp
inline void sweepLocked() const
```

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

---

<a id="finishemit"></a>

### finishEmit

`inline`

```cpp
inline void finishEmit()
```

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

---

<a id="clearnodeslocked"></a>

### clearNodesLocked

`const` `inline`

```cpp
inline void clearNodesLocked() const
```

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

---

<a id="resetemitstate"></a>

### resetEmitState

`inline`

```cpp
inline void resetEmitState()
```

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

---

<a id="snapshotstate"></a>

### snapshotState

`const` `inline`

```cpp
inline std::pair< std::vector< SlotPtr >, int > snapshotState() const
```

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

---

<a id="restorestate"></a>

### restoreState

`inline`

```cpp
inline void restoreState(std::vector< SlotPtr > snapshot, int lastId)
```

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

## Private Static Attributes

| Return | Name | Description |
|--------|------|-------------|
| `constexpr bool` | [`threadSafe`](#threadsafe) `static` `constexpr` |  |

---

<a id="threadsafe"></a>

### threadSafe

`static` `constexpr`

```cpp
constexpr bool threadSafe = !std::is_same_v<MutexT, NullSharedMutex>
```

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