This commit is contained in:
Matthias Janetschek
2015-05-22 16:40:23 +02:00
parent feff4efc35
commit 3626b45dfc
23 changed files with 491 additions and 395 deletions
@@ -34,6 +34,14 @@ struct ServiceInfo {
/**
* Implementation of interface::Object.
*/
class Object
: public virtual interface::Object {};
/**
* Implementation of interface::Service.
*/
@@ -48,7 +56,7 @@ public:
*
* \return service name.
**/
virtual const char* getServiceName() {
virtual const char* getServiceName() noexcept override {
return ServiceInfo<_Service>::name;
};
@@ -58,7 +66,7 @@ public:
* \param[out] major version major number.
* \param[out] minor version minor number.
*/
virtual void getServiceVersion(int& major, int& minor) override {
virtual void getServiceVersion(int& major, int& minor) noexcept override {
major = ServiceInfo<_Service>::major;
minor = ServiceInfo<_Service>::minor;
}
@@ -76,6 +84,15 @@ template <class... _Args> class Observable {};
/**
* Convenience template merging the Object class and the Observable template into a single template.
*/
template<class... _Args> class ObservableObject
: public virtual Object,
public virtual Observable<_Args...> {};
/**
* Convenience template merging the Service class and the Observable template into a single template.
*/
@@ -98,7 +115,7 @@ protected:
typedef std::unordered_set<typename interface::Observable<_Event>::observer_type*> observers_type;
std::mutex _observersMutex;
std::recursive_mutex _observersMutex;
observers_type _observers;
@@ -111,14 +128,16 @@ public:
*
* \param[in] o observer to be registered.
*/
virtual void addObserver(typename interface::Observable<_Event>::observer_type* o) override {
std::lock_guard<std::mutex> lock(_observersMutex);
virtual bool addObserver(typename interface::Observable<_Event>::observer_type* o) noexcept override {
std::lock_guard<std::recursive_mutex> lock(_observersMutex);
if (o != nullptr) {
auto elem = _observers.find(o);
if (elem == _observers.end()) {
_observers.insert(o);
return true;
}
}
return false;
}
/**
@@ -126,21 +145,23 @@ public:
*
* \param[in] o observer to be unregistered.
*/
virtual void deleteObserver(typename interface::Observable<_Event>::observer_type* o) override {
std::lock_guard<std::mutex> lock(_observersMutex);
virtual bool deleteObserver(typename interface::Observable<_Event>::observer_type* o) noexcept override {
std::lock_guard<std::recursive_mutex> lock(_observersMutex);
if (o != nullptr) {
auto elem = _observers.find(o);
if (elem != _observers.end()) {
_observers.erase(elem);
return true;
}
}
return false;
}
/**
* Unregisters all observers.
*/
virtual void deleteObservers() override {
std::lock_guard<std::mutex> lock(_observersMutex);
virtual void deleteObservers() noexcept override {
std::lock_guard<std::recursive_mutex> lock(_observersMutex);
_observers.clear();
};
@@ -149,8 +170,8 @@ public:
*
* \return number of registered observers.
*/
virtual size_t countObservers() override {
std::lock_guard<std::mutex> lock(_observersMutex);
virtual size_t countObservers() noexcept override {
std::lock_guard<std::recursive_mutex> lock(_observersMutex);
return _observers.size();
}
@@ -158,12 +179,18 @@ public:
* Notify observers of a new event.
*
* \param[in] e event.
* \return notified observer count.
*/
virtual void notifyObservers(const _Event* e) override {
std::lock_guard<std::mutex> lock(_observersMutex);
for (auto l : _observers) {
virtual size_t notifyObservers(const _Event* e) noexcept override {
std::lock_guard<std::recursive_mutex> lock(_observersMutex);
size_t retval = 0;
// We work with a copy so that we can insert/remove observers within a callback.
observers_type tmp = _observers;
for (auto l : tmp) {
l->notificationReceived(this, e);
retval++;
}
return retval;
}
};
@@ -183,7 +210,7 @@ protected:
typedef std::unordered_multimap<_Key, typename interface::Observable<_Key, _Event>::observer_type*> observers_type;
std::mutex _observersMutex;
std::recursive_mutex _observersMutex;
observers_type _observers;
@@ -197,21 +224,23 @@ public:
* \param[in] k filter key.
* \param[in] o observer to be registered.
*/
virtual void addObserver(_Key k, typename interface::Observable<_Key, _Event>::observer_type* o) override {
std::lock_guard<std::mutex> lock(_observersMutex);
virtual bool addObserver(const _Key& k, typename interface::Observable<_Key, _Event>::observer_type* o) noexcept override {
std::lock_guard<std::recursive_mutex> lock(_observersMutex);
if (o != nullptr) {
bool _found = false;
auto range = _observers.equal_range(k);
for (auto i = range.first; i != range.second; i++) {
if (i.second == o) {
if (i->second == o) {
_found = true;
break;
}
}
if (!_found) {
_observers.insert({k, o});
return true;
}
}
return false;
}
/**
@@ -220,25 +249,50 @@ public:
* \param[in] k filter key.
* \param[in] o observer to be unregistered.
*/
virtual void deleteObserver(_Key k, typename interface::Observable<_Key, _Event>::observer_type* o) override {
std::lock_guard<std::mutex> lock(_observersMutex);
virtual bool deleteObserver(const _Key& k, typename interface::Observable<_Key, _Event>::observer_type* o) noexcept override {
std::lock_guard<std::recursive_mutex> lock(_observersMutex);
if (o != nullptr) {
bool _found = false;
auto range = _observers.equal_range(k);
for (auto i = range.first; i != range.second; i++) {
if (i.second == o) {
if (i->second == o) {
_observers.erase(i);
break;
return true;
}
}
}
return false;
}
/**
* Unregisters an observer from all filter keys.
*
* \param[in] o observer to be unregistered.
*/
virtual bool deleteObserver(typename interface::Observable<_Key, _Event>::observer_type* o) noexcept override {
std::lock_guard<std::recursive_mutex> lock(_observersMutex);
bool retval = false;
if (o != nullptr) {
// Quick and dirty, needs to be replaced with a proper implementation
auto found = std::find_if(_observers.begin(), _observers.end(), [=](const typename Observable<_Key, _Event>::observers_type::value_type& v)->bool {
return v.second == o;
});
while ( found != _observers.end()) {
_observers.erase(found);
retval = true;
found = std::find_if(_observers.begin(), _observers.end(), [=](const typename Observable<_Key, _Event>::observers_type::value_type& v)->bool {
return v.second == o;
});
}
}
return retval;
}
/**
* Unregisters all observers.
*/
virtual void deleteObservers() override {
std::lock_guard<std::mutex> lock(_observersMutex);
virtual void deleteObservers() noexcept override {
std::lock_guard<std::recursive_mutex> lock(_observersMutex);
_observers.clear();
}
@@ -247,8 +301,8 @@ public:
*
* \return number of registered observers.
*/
virtual size_t countObservers() override {
std::lock_guard<std::mutex> lock(_observersMutex);
virtual size_t countObservers() noexcept override {
std::lock_guard<std::recursive_mutex> lock(_observersMutex);
return _observers.size();
}
@@ -257,13 +311,19 @@ public:
*
* \param[in] k observer filter key.
* \param[in] e event.
* \return notified observer count.
*/
void notifyObservers(_Key k, const _Event* e) override {
std::lock_guard<std::mutex> lock(_observersMutex);
auto ol = _observers.equal_range(k);
std::for_each(ol.first, ol.second, [&](const typename interface::Observable<_Key, _Event>::observer_type::value_type& o) {
o.second->notificationReceived(this, k, e);
});
size_t notifyObservers(const _Key& k, const _Event* e) noexcept override {
std::lock_guard<std::recursive_mutex> lock(_observersMutex);
size_t retval = 0;
// We work with a copy so that we can insert/remove observers within a callback.
observers_type tmp = _observers;
auto ol = tmp.equal_range(k);
for (auto i = ol.first; i != ol.second; i++) {
i->second->notificationReceived(this, k, e);
retval++;
}
return retval;
}
};
@@ -46,7 +46,7 @@ public:
*
* \return service name.
**/
virtual const char* getServiceName() = 0;
virtual const char* getServiceName() noexcept = 0 ;
/**
* Returns the version of the service.
@@ -58,7 +58,7 @@ public:
* \param[out] major version major number.
* \param[out] minor version minor number.
*/
virtual void getServiceVersion(int& major, int& minor) = 0;
virtual void getServiceVersion(int& major, int& minor) noexcept = 0;
};
@@ -120,7 +120,7 @@ public:
* \param[in] o observable object emitting the event.
* \param[in] e the event (can be null).
*/
virtual void notificationReceived(observable_type* o, const _Event* e) = 0;
virtual void notificationReceived(observable_type* o, const _Event* e) noexcept = 0;
};
@@ -148,7 +148,7 @@ public:
* \param[in] key the filter key.
* \param[in] e the event (can be null).
*/
virtual void notificationReceived(observable_type* o, const _Key& key, const _Event* e) = 0;
virtual void notificationReceived(observable_type* o, const _Key& key, const _Event* e) noexcept = 0;
};
@@ -175,33 +175,34 @@ public:
*
* \param[in] o observer to be registered.
*/
virtual void addObserver(observer_type* o) = 0;
virtual bool addObserver(observer_type* o) noexcept = 0;
/**
* Unregisters an observer.
*
* \param[in] o observer to be unregistered.
*/
virtual void deleteObserver(observer_type* o) = 0;
virtual bool deleteObserver(observer_type* o) noexcept = 0;
/**
* Unregisters all observers.
*/
virtual void deleteObservers() = 0;
virtual void deleteObservers() noexcept = 0;
/**
* Returns the number of registered observers.
*
* \return number of registered observers.
*/
virtual size_t countObservers() = 0;
virtual size_t countObservers() noexcept = 0;
/**
* Notify observers of a new event.
*
* \param[in] e event.
* \return notified observer count.
*/
virtual void notifyObservers(const _Event* e) = 0;
virtual size_t notifyObservers(const _Event* e) noexcept = 0;
};
@@ -230,7 +231,7 @@ public:
* \param[in] key filter key.
* \param[in] o observer to be registered.
*/
virtual void addObserver(_Key& key, observer_type* o) = 0;
virtual bool addObserver(const _Key& key, observer_type* o) noexcept = 0;
/**
* Unregisters an observer.
@@ -238,27 +239,35 @@ public:
* \param[in] key filter key.
* \param[in] o observer to be unregistered.
*/
virtual void deleteObserver(_Key& key, observer_type* o) = 0;
virtual bool deleteObserver(const _Key& key, observer_type* o) noexcept = 0;
/**
* Unregisters an observer from all filter keys.
*
* \param[in] o observer to be unregistered.
*/
virtual bool deleteObserver(observer_type* o) noexcept = 0;
/**
* Unregisters all observers.
*/
virtual void deleteObservers() = 0;
virtual void deleteObservers() noexcept = 0;
/**
* Returns the number of registered observers.
*
* \return number of registered observers.
*/
virtual size_t countObservers() = 0;
virtual size_t countObservers() noexcept = 0;
/**
* Notify observers of a new event.
*
* \param[in] key observer filter key.
* \param[in] e event.
* \return notified observer count.
*/
virtual void notifyObservers(const _Key& key, const _Event* e) = 0;
virtual size_t notifyObservers(const _Key& key, const _Event* e) noexcept = 0;
};
@@ -28,7 +28,9 @@ namespace core {
class CoreServiceEvent {
public:
typedef std::chrono::system_clock::time_point timestamp_t;
enum class EventType : int { STARTUP_FINISHED = 1, SHUTDOWN = 2 };
const EventType eventType;
const timestamp_t timestamp;