An open API service indexing awesome lists of open source software.

https://github.com/darky-lucera/delegate

Versatile, easy-to-use and header-only implementation for delegates.
https://github.com/darky-lucera/delegate

callback delegate event-handler listener

Last synced: 16 days ago
JSON representation

Versatile, easy-to-use and header-only implementation for delegates.

Awesome Lists containing this project

README

          

# Delegate Class

The Delegate class in C++ is a versatile, easy-to-use, type-safe and header-only implementation for delegates. It empowers you to craft delegate / callback / listener / event-handler objects capable of holding multiple references to a variety of entities:

- Free functions
- Static member functions
- Functors
- Non-static member functions (const or non-const)
- Lambda functions (with and without captures)
- std::function
- std::bind

This utility is derived from an earlier version employed in the **MindShake** video game engine from **Lucera Project**. While I can't recall the precise inception date of the initial class, I developed it prior to the establishment of Lucera in 2009, utilizing C++98. Subsequently, I enhanced it to leverage the features introduced in C++11, a transformation that took place several years ago.

**Note:** In all my tests, the Delegate has demonstrated comparable speed to std::function and, in some cases, even faster performance (depending on the specific scenario and compiler flags). Additionally, it is capable of holding multiple functions at the same time.

## Usage

Just drop the class into your code folder and include it.

**Note:** We now capture exceptions on every call and show information using fprintf. Change it by your own logger.

## Interface

**Note:** The interface has been changed and the flag lazy for removing a function it is not needed anymore.

- `id Add(function)`: Adds a function.
- `bool Remove(function)`: If the delegate is not being executed the function is removed. If it is being executed the function will be disabled and removed when the execution will finish.
- `bool RemoveById(id)`: Removes a funtion given its id.
- `void Clear()`: Removes all functions.
- `void operator(...) const`: Runs all the functions added.
- `size_t GetNumDelegates() const`: Get the number of delegates added.

## Examples

The main.cpp contains an exhaustive example of how to use this class.

## Snippets

Here are some basic examples of how to use the `Delegate` class:

```cpp
#include "Delegate.h"

void mousePosition(int x, int y) {
// ...
}

class MyClass {
public:
void mousePosition(int x, int y) {
// ...
}
};

int main() {
MindShake::Delegate delegate;

delegate.Add(mousePosition);

MyClass myObject;
delegate.Add(&myObject, &MyClass::mousePosition);

delegate.Add([](int x, int y) {
// ...
});

delegate(2, 3);

// ...
}
```

If you find yourself needing to distinguish between calling a const or a non-const function, you can employ the helper functions: `getNonConstMethod` and `getConstMethod`:

```cpp

class MyClass {
public:
void memberFunction() {
// ...
}

void memberFunction() const {
// ...
}
};

int kk() {
MindShake::Delegate delegate;

MyClass myObject;
delegate.Add(&myObject, MindShake::getNonConstMethod(&MyClass::memberFunction));

delegate.Add(&myObject, MindShake::getConstMethod(&MyClass::memberFunction));

// ...
}

```

If you no longer wish to receive additional events, or if you are in the process of destroying the class that holds the delegate, it is advisable to remove it:

```cpp
struct Holder {
static MindShake::Delegate delegate;
};

class MyClass {
public:
MyClass() {
Holder::delegate.Add(this, &MyClass::memberFunction);
}

virtual ~MyClass() {
Holder::delegate.Remove(this, &MyClass::memberFunction);
}

void memberFunction(int value) {
// ...
}
};

int main() {
MyClass myObject;
// ...
Holder::delegate(123);
// ...
}
```

If you wish to cease receiving further events for a lambda function, take note that the Add function returns an ID, facilitating the straightforward identification of the delegate to be removed:

```cpp
Delegate delegate;

auto lambdaId = delegate.Add([]() {
// ...
});

// ...
delegate.RemoveById(lambdaId);
```