#pragma once #include #include #include template class Handler; template class Notification { friend class Handler; public: typedef std::function HandlerTy; typedef int HandlerID; Notification() { mIdMaker = 0; }; void notify(notifyData... notifySendData); protected: HandlerID onNotify(HandlerTy aHandler); void unregister(HandlerID aHandler); private: std::map mFunctionHandlers; HandlerID mIdMaker; }; template int Notification::onNotify(HandlerTy aHandler) { if (aHandler) { mFunctionHandlers[++mIdMaker] = std::move(aHandler); return mIdMaker; } else { return -1; } } template void Notification::notify(outboundData... notifySendData) { for (auto handler : mFunctionHandlers) { handler.second(notifySendData...); } } template void Notification::unregister(HandlerID aHandlerId) { auto handlerToUnRegister = std::find_if(mFunctionHandlers.begin(), mFunctionHandlers.end(), [aHandlerId](auto registeredHandler) { return aHandlerId == registeredHandler.first; }); if (handlerToUnRegister != mFunctionHandlers.end()) { mFunctionHandlers.erase(handlerToUnRegister); } } template class Handler { public: typedef std::function callableTy; void operator=(Handler &other) = delete; Handler() = default; Handler(std::shared_ptr> aNotification, callableTy aCallable = nullptr) : mNotification(aNotification), mHandlerId(aNotification->onNotify(aCallable)) {} virtual ~Handler() { if (mHandlerId >= 0) { mNotification->unregister(mHandlerId); } } void operator=(callableTy aHandler) { if (mHandlerId >= 0) { mNotification->unregister(mHandlerId); mHandlerId = -1; } if (aHandler) { mHandlerId = mNotification->onNotify(aHandler); } } void SetNotification(std::shared_ptr> aNotification) { mNotification = aNotification; } private: std::shared_ptr> mNotification = nullptr; int mHandlerId = -1; };