mirror of
https://github.com/gelldur/EventBus.git
synced 2024-12-27 12:21:02 +08:00
Secure EventBus from wrong usage
For example user previously could do such thing: bus.listen<const MyEvent>(...) bus.listen<MyEvent>(...) Those we 2 different events :/
This commit is contained in:
parent
f9195316d3
commit
63395f5a7e
@ -12,13 +12,21 @@ namespace Dexode
|
|||||||
|
|
||||||
template <typename>
|
template <typename>
|
||||||
void type_id() // Helper for getting "type id"
|
void type_id() // Helper for getting "type id"
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
using type_id_t = void (*)(); // Function pointer
|
using type_id_t = void (*)(); // Function pointer
|
||||||
|
|
||||||
class EventBus
|
class EventBus
|
||||||
{
|
{
|
||||||
|
template <class Event>
|
||||||
|
constexpr void validateEvent()
|
||||||
|
{
|
||||||
|
static_assert(std::is_const<Event>::value == false, "Struct must be without const");
|
||||||
|
static_assert(std::is_volatile<Event>::value == false, "Struct must be without volatile");
|
||||||
|
static_assert(std::is_reference<Event>::value == false, "Struct must be without reference");
|
||||||
|
static_assert(std::is_pointer<Event>::value == false, "Struct must be without pointer");
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EventBus() = default;
|
EventBus() = default;
|
||||||
|
|
||||||
@ -43,6 +51,8 @@ public:
|
|||||||
template <typename Event>
|
template <typename Event>
|
||||||
int listen(const std::function<void(const Event&)>& callback)
|
int listen(const std::function<void(const Event&)>& callback)
|
||||||
{
|
{
|
||||||
|
validateEvent<Event>();
|
||||||
|
|
||||||
const int token = ++_tokener;
|
const int token = ++_tokener;
|
||||||
listen<Event>(token, callback);
|
listen<Event>(token, callback);
|
||||||
return token;
|
return token;
|
||||||
@ -56,6 +66,8 @@ public:
|
|||||||
template <typename Event>
|
template <typename Event>
|
||||||
void listen(const int token, const std::function<void(const Event&)>& callback)
|
void listen(const int token, const std::function<void(const Event&)>& callback)
|
||||||
{
|
{
|
||||||
|
validateEvent<Event>();
|
||||||
|
|
||||||
using Vector = VectorImpl<Event>;
|
using Vector = VectorImpl<Event>;
|
||||||
|
|
||||||
assert(callback && "callback should be valid"); //Check for valid object
|
assert(callback && "callback should be valid"); //Check for valid object
|
||||||
@ -88,6 +100,8 @@ public:
|
|||||||
template <typename Event>
|
template <typename Event>
|
||||||
void unlisten(const int token)
|
void unlisten(const int token)
|
||||||
{
|
{
|
||||||
|
validateEvent<Event>();
|
||||||
|
|
||||||
auto found = _callbacks.find(type_id<Event>);
|
auto found = _callbacks.find(type_id<Event>);
|
||||||
if(found != _callbacks.end())
|
if(found != _callbacks.end())
|
||||||
{
|
{
|
||||||
@ -103,8 +117,11 @@ public:
|
|||||||
template <typename Event>
|
template <typename Event>
|
||||||
void notify(const Event& event)
|
void notify(const Event& event)
|
||||||
{
|
{
|
||||||
using Vector = VectorImpl<Event>;
|
using CleanEventType = typename std::remove_const<Event>::type;
|
||||||
auto found = _callbacks.find(type_id<Event>);
|
validateEvent<CleanEventType>();
|
||||||
|
|
||||||
|
using Vector = VectorImpl<CleanEventType>;
|
||||||
|
auto found = _callbacks.find(type_id<CleanEventType>);
|
||||||
if(found == _callbacks.end())
|
if(found == _callbacks.end())
|
||||||
{
|
{
|
||||||
return; // no such notifications
|
return; // no such notifications
|
||||||
@ -151,9 +168,9 @@ private:
|
|||||||
|
|
||||||
//Invalidation rules: https://stackoverflow.com/questions/6438086/iterator-invalidation-rules
|
//Invalidation rules: https://stackoverflow.com/questions/6438086/iterator-invalidation-rules
|
||||||
auto removeFrom = std::remove_if(
|
auto removeFrom = std::remove_if(
|
||||||
container.begin(), container.end(), [token](const ContainerElement& element) {
|
container.begin(), container.end(), [token](const ContainerElement& element) {
|
||||||
return element.first == token;
|
return element.first == token;
|
||||||
});
|
});
|
||||||
if(removeFrom != container.end())
|
if(removeFrom != container.end())
|
||||||
{
|
{
|
||||||
container.erase(removeFrom, container.end());
|
container.erase(removeFrom, container.end());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user