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.
- Host: GitHub
- URL: https://github.com/darky-lucera/delegate
- Owner: Darky-Lucera
- License: bsl-1.0
- Created: 2023-12-17T17:35:31.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-12-22T18:05:49.000Z (about 1 year ago)
- Last Synced: 2025-09-14T18:42:54.491Z (6 months ago)
- Topics: callback, delegate, event-handler, listener
- Language: C++
- Homepage:
- Size: 12.7 KB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
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);
```