Fix bug with getUniqueId

Improve API
Update old code
This commit is contained in:
Dawid Drozd 2016-09-04 17:10:46 +02:00
parent e40d1a3674
commit d6a0b8c8e5
3 changed files with 76 additions and 41 deletions

7
src/Notification.cpp Normal file
View File

@ -0,0 +1,7 @@
//
// Created by Dawid Drozd aka Gelldur on 9/4/16.
//
#include "Notification.h"
int Dexode::_::_BaseNotification::_idGenerator = 0;

View File

@ -11,56 +11,53 @@ enum NotificationConst
UNUSED_TAG = 0 UNUSED_TAG = 0
}; };
inline int getUniqueId() namespace _ //Hide from autocomplete
{ {
static int id = NotificationConst::UNUSED_TAG + 1; class _BaseNotification
return ++id; {
} public:
_BaseNotification()
: tag(++_idGenerator)
{
}
inline int getToken() virtual ~_BaseNotification() = default;
{ _BaseNotification& operator=(const _BaseNotification&) = delete;
return getUniqueId();
}
template<typename Type> _BaseNotification& operator=(_BaseNotification&& notification)
inline int getTokenForType() {
{ tag = notification.tag;
static int id_for_type = getUniqueId(); return *this;
return id_for_type; }
_BaseNotification(const _BaseNotification& notification)
: tag(notification.tag)
{
}
_BaseNotification(_BaseNotification&& notification)
: tag(notification.tag)
{
}
int tag = NotificationConst::UNUSED_TAG;
private:
static int _idGenerator;
};
} }
template<typename ... Args> template<typename ... Args>
class Notification class Notification : public _::_BaseNotification
{ {
public: public:
using Callback = std::function<void(Args...)>; using Callback = std::function<void(Args...)>;
//dummyInt used only for prevent creating unused notifications you should use MAKE_NOTIFICATION //dummyInt used only for prevent creating unused notifications you should use MAKE_NOTIFICATION
Notification(int dummyInt) Notification(int dummyInt)
: tag(getUniqueId())
{ {
assert(dummyInt == 691283); assert(dummyInt == 691283);
} }
Notification& operator=(const Notification&) = delete;
Notification& operator=(Notification&& notification)
{
tag = notification.tag;
return *this;
}
Notification(const Notification& notification)
: tag(notification.tag)
{
}
Notification(Notification&& notification)
: tag(notification.tag)
{
}
int tag = NotificationConst::UNUSED_TAG;
}; };
template<typename NotificationType> template<typename NotificationType>

View File

@ -9,12 +9,16 @@
namespace Dexode namespace Dexode
{ {
template<typename T>
struct notifier_traits
{
typedef T type;
};
class Notifier class Notifier
{ {
public: public:
Notifier() Notifier() = default;
{
}
virtual ~Notifier() virtual ~Notifier()
{ {
@ -38,10 +42,31 @@ public:
return globalNotifier; return globalNotifier;
} }
/**
* Register listener for notification. Returns token used to unregister
*
* @param notification - pass notification like "getNotificationXYZ()"
* @param callback - your callback to handle notification
* @return token used to unregister
*/
template<typename ... Args>
int listen(const Notification<Args...>& notification
, typename notifier_traits<const std::function<void(Args...)>&>::type callback)
{
const int token = ++_tokener;
listen(token, notification, callback);
return token;
}
/**
* @param token - unique token for identification receiver. Simply pass token from @see Notifier::listen
* @param notification - pass notification like "getNotificationXYZ()"
* @param callback - your callback to handle notification
*/
template<typename ... Args> template<typename ... Args>
void listen(const int token void listen(const int token
, const Notification<Args...>& notification , const Notification<Args...>& notification
, const std::function<void(Args...)>& callback) , typename notifier_traits<const std::function<void(Args...)>&>::type callback)
{ {
using CallbackType = std::function<void(Args...)>; using CallbackType = std::function<void(Args...)>;
@ -60,6 +85,9 @@ public:
pVector->container.emplace_back(std::make_pair(callback, token)); pVector->container.emplace_back(std::make_pair(callback, token));
} }
/**
* @param token - token from Notifier::listen
*/
void unlistenAll(const int token) void unlistenAll(const int token)
{ {
for (auto&& element : _callbacks) for (auto&& element : _callbacks)
@ -68,6 +96,10 @@ public:
} }
} }
/**
* @param token - token from Notifier::listen
* @param notification - notification you wan't to unlisten. @see Notiier::listen
*/
template<typename NotificationType, typename ... Args> template<typename NotificationType, typename ... Args>
void unlisten(const int token, const NotificationType& notification) void unlisten(const int token, const NotificationType& notification)
{ {
@ -103,9 +135,7 @@ public:
} }
} }
////////////////////////////////////////////////////////////////////////////////////////////////////
private: private:
struct VectorInterface struct VectorInterface
{ {
virtual ~VectorInterface() virtual ~VectorInterface()
@ -143,6 +173,7 @@ private:
} }
}; };
int _tokener = 0;
std::map<int, VectorInterface*> _callbacks; std::map<int, VectorInterface*> _callbacks;
}; };