Skip to content

Instantly share code, notes, and snippets.

@sasq64
Last active April 5, 2021 14:27
Show Gist options
  • Save sasq64/2027955e1afe9fb6b35704eb1aed207f to your computer and use it in GitHub Desktop.
Save sasq64/2027955e1afe9fb6b35704eb1aed207f to your computer and use it in GitHub Desktop.
C++ Callbacks
#include <functional>
#include <vector>
#include <memory>
template<typename... X> struct Callback;
template <typename R, typename ...ARGS> struct Callback<R(ARGS...)>
{
struct BaseFx
{
virtual R call(ARGS...) = 0;
};
template <typename FX> struct Fx : public BaseFx
{
Fx(FX f) : f(f) {}
virtual R call(ARGS... args)
{
return f(args...);
};
FX f;
};
using Holder = std::shared_ptr<std::function<void(std::nullptr_t)>>;
template <typename FX> Holder add(FX f)
{
callbacks.push_back(std::make_shared<Fx<FX>>(f));
auto cb = callbacks.back();
return Holder(nullptr, [=](std::nullptr_t) {
callbacks.erase(remove(callbacks.begin(), callbacks.end(), cb));
});
};
void call(ARGS... args)
{
for(auto &cb : callbacks)
cb->call(args...);
}
std::vector<std::shared_ptr<BaseFx>> callbacks;
};
int main()
{
// Outputs 5.0
Callback<void(float, float)> test;
{
auto holder = test.add([](float x, float y) {
printf("%.1f\n", x+y);
});
test.call(3.0f, 2.0f);
}
test.call(1.0f, 5.0f);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment