Last active
February 3, 2022 09:07
-
-
Save daniel5151/71d685a549365662141956aba9cc649f to your computer and use it in GitHub Desktop.
Generic Callback Manager
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <vector> | |
#include <cstddef> | |
/** | |
* Generic Callback Manager | |
* | |
* @tparam ...cb_args Types of callback arguments (aside from userdata) | |
*/ | |
template <typename ...cb_args> | |
class CallbackManager { | |
public: | |
template <typename udata_t> | |
using cb_t = void(*)(udata_t* userdata, cb_args...); | |
private: | |
struct cb_node { | |
void* userdata; | |
cb_t<void> cb; | |
}; | |
std::vector<cb_node> _cbs; | |
public: | |
/** | |
* Add a callback with specified userdata | |
* @param userdata returned as first-parameter of callback | |
* @param function callback of type void cb(void* userdata, cb_args...); | |
* @return callback successfully added | |
*/ | |
bool add(void* userdata, cb_t<void> function) { | |
_cbs.push_back(cb_node {userdata, function}); | |
return true; | |
} | |
/** | |
* Remove a userdata-callback pair from the list of callbacks | |
* @param userdata userdata to search for | |
* @param function callback to search for | |
* @return callback successfully removed | |
*/ | |
bool remove(void* userdata, cb_t<void> function) { | |
for (size_t i = 0; i < _cbs.size(); i++) { | |
if (_cbs[i].cb != function || _cbs[i].userdata != userdata) | |
continue; | |
for (size_t j = i; j < _cbs.size() - 1; j++) | |
_cbs[j] = _cbs[j + 1]; | |
_cbs.pop_back(); | |
return true; | |
} | |
return false; | |
} | |
/** | |
* @param args... execute callbacks with specified argument | |
*/ | |
void run(cb_args... args) const { | |
for (const cb_node& cb : _cbs) | |
cb.cb(cb.userdata, args...); | |
} | |
// ergonomic templates: add/remove callbacks with non void* userdata type | |
/** | |
* Add a callback with specified userdata | |
* @param userdata returned as first-parameter of callback | |
* @param function callback of type void cb(udata_t* userdata, cb_args...); | |
* @return callback successfully added | |
*/ | |
template <typename udata_t> | |
bool add(udata_t* userdata, cb_t<udata_t> function) { | |
return add(userdata, (cb_t<void>)function); | |
} | |
/** | |
* Remove a userdata-callback pair from the list of callbacks | |
* @param userdata userdata to search for | |
* @param function callback to search for | |
* @return callback successfully removed | |
*/ | |
template <typename udata_t> | |
bool remove(udata_t* userdata, cb_t<udata_t> function) { | |
return remove(userdata, (cb_t<void>)function); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example Usage: