#pragma once #include #include #include #include namespace ddkit { namespace utils { namespace callback { template class Wrapper; class Base { public: virtual ~Base(){} template void tryToInvoke(void (Actor::*func)(Args...), Args&&... args) { auto cb = dynamic_cast*>(this); if(cb && cb->isFunction(func)){ cb->invoke(args...); } } }; template class Wrapper : public Base { public: using ActorType = Actor; using CallbackType = std::function; using ActorFunctionType = void (Actor::*)(Args...); Wrapper() = delete; virtual ~Wrapper(){} Wrapper(ActorFunctionType func, CallbackType cb) : m_actorFunction(func) , m_callback(cb) { } bool isFunction(ActorFunctionType func){ return m_actorFunction == func; } void invoke(Args... args){ m_callback(args...); } private: friend class Base; ActorFunctionType m_actorFunction; CallbackType m_callback; }; template Wrapper* Callback(void (Actor::*pm)(Args...), std::function cb){ return new Wrapper(pm, cb); } template Wrapper* Callback(void (Actor::*pm)(Args...), const Fn& callback){ return new Wrapper(pm, std::function(callback)); } } // callback } // utils namespace callback = ddkit::utils::callback; } // ddkit