From 5f92c76c31eb93bd86780f1d70db2081f19dac1e Mon Sep 17 00:00:00 2001 From: Lars Melchior Date: Mon, 22 Apr 2019 21:34:39 +0200 Subject: [PATCH] Data handling (#11) * move data into shared_ptr * v2.0.2 * remove default constructor * fix move constructor * reset when observing new event --- CMakeLists.txt | 2 +- README.md | 2 +- include/lars/event.h | 80 +++++++++++++++++++------------------------- 3 files changed, 36 insertions(+), 48 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ded2841..52c8721 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.5 FATAL_ERROR) # ---- Project ---- project(LarsEvent - VERSION 2.0.1 + VERSION 2.0.2 LANGUAGES CXX ) diff --git a/README.md b/README.md index 72d566e..afbe130 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ With [CPM](https://github.com/TheLartians/CPM), lars::Event can be added to your ```cmake CPMAddPackage( NAME LarsEvent - VERSION 2.0.1 + VERSION 2.0.2 GIT_REPOSITORY https://github.com/TheLartians/Event.git ) diff --git a/include/lars/event.h b/include/lars/event.h index 85e90a0..2484ea6 100644 --- a/include/lars/event.h +++ b/include/lars/event.h @@ -49,35 +49,29 @@ namespace lars{ }; using HandlerList = std::vector; - using EventPointer = std::shared_ptr; - using WeakEventPointer = std::weak_ptr; - mutable HandlerID IDCounter = 0; - mutable HandlerList observers; - mutable std::mutex observerMutex; - EventPointer self; + struct Data { + HandlerID IDCounter = 0; + HandlerList observers; + std::mutex observerMutex; + }; + + std::shared_ptr data; HandlerID addHandler(Handler h)const{ - std::lock_guard lock(observerMutex); - observers.emplace_back(StoredHandler{IDCounter,h}); - return IDCounter++; - } - - void eraseHandler(const HandlerID &id)const{ - std::lock_guard lock(observerMutex); - auto it = std::find_if(observers.begin(), observers.end(), [&](auto &o){ return o.id == id; }); - if (it != observers.end()) { observers.erase(it); } + std::lock_guard lock(data->observerMutex); + data->observers.emplace_back(StoredHandler{data->IDCounter,h}); + return data->IDCounter++; } - + public: struct Observer:public lars::Observer::Base{ - WeakEventPointer parent; + std::weak_ptr data; HandlerID id; Observer(){} - Observer(const EventPointer & _parent, HandlerID _id):parent(_parent), id(_id){ - } + Observer(const std::weak_ptr &_data, HandlerID _id):data(_data), id(_id){} Observer(Observer &&other) = default; Observer(const Observer &other) = delete; @@ -86,50 +80,44 @@ namespace lars{ Observer & operator=(Observer &&other)=default; void observe(const Event &event, const Handler &handler){ + reset(); *this = event.createObserver(handler); } void reset(){ - if(auto p = parent.lock()){ - (*p)->eraseHandler(id); + if(auto d = data.lock()){ + std::lock_guard lock(d->observerMutex); + auto it = std::find_if(d->observers.begin(), d->observers.end(), [&](auto &o){ return o.id == id; }); + if (it != d->observers.end()) { d->observers.erase(it); } } - parent.reset(); + data.reset(); } ~Observer(){ reset(); } }; - Event():self(std::make_shared(this)){ - + Event():data(std::make_shared()){ } - - Event(const Event &) = delete; - - Event(Event &&other){ - *this = std::move(other); - } - - Event & operator=(const Event &) = delete; - Event & operator=(Event &&other){ - self = std::move(other.self); - *self = this; - observers = std::move(other.observers); - IDCounter = other.IDCounter; + Event(const Event &) = delete; + Event(Event &&other):Event(){ *this = std::move(other); } + Event &operator=(const Event &) = delete; + Event &operator=(Event &&other){ + std::swap(data, other.data); return *this; } - + void emit(Args ... args) const { - observerMutex.lock(); - auto tmpObservers = observers; - observerMutex.unlock(); + data->observerMutex.lock(); + auto tmpObservers = data->observers; + data->observerMutex.unlock(); for(auto &observer: tmpObservers){ observer.callback(args...); } } Observer createObserver(const Handler &h)const{ - return Observer(self, addHandler(h)); + return Observer(data, addHandler(h)); } void connect(const Handler &h)const{ @@ -137,13 +125,13 @@ namespace lars{ } void clearObservers(){ - std::lock_guard lock(observerMutex); - observers.clear(); + std::lock_guard lock(data->observerMutex); + data->observers.clear(); } size_t observerCount() const { - std::lock_guard lock(observerMutex); - return observers.size(); + std::lock_guard lock(data->observerMutex); + return data->observers.size(); } };