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

View File

@ -9,12 +9,16 @@
namespace Dexode
{
template<typename T>
struct notifier_traits
{
typedef T type;
};
class Notifier
{
public:
Notifier()
{
}
Notifier() = default;
virtual ~Notifier()
{
@ -38,10 +42,31 @@ public:
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>
void listen(const int token
, const Notification<Args...>& notification
, const std::function<void(Args...)>& callback)
, const Notification<Args...>& notification
, typename notifier_traits<const std::function<void(Args...)>&>::type callback)
{
using CallbackType = std::function<void(Args...)>;
@ -60,6 +85,9 @@ public:
pVector->container.emplace_back(std::make_pair(callback, token));
}
/**
* @param token - token from Notifier::listen
*/
void unlistenAll(const int token)
{
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>
void unlisten(const int token, const NotificationType& notification)
{
@ -103,9 +135,7 @@ public:
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
private:
struct VectorInterface
{
virtual ~VectorInterface()
@ -143,6 +173,7 @@ private:
}
};
int _tokener = 0;
std::map<int, VectorInterface*> _callbacks;
};