diff --git a/src/media/video/video_base.h b/src/media/video/video_base.h index 8babcad8e41426091f64fdacc6853f294970793d..6954d1aac704f0b69df4a00bfa0ec295da0f687c 100644 --- a/src/media/video/video_base.h +++ b/src/media/video/video_base.h @@ -22,6 +22,7 @@ #pragma once #include "noncopyable.h" +#include "observer.h" #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" @@ -57,70 +58,6 @@ using VideoFrame = DRing::VideoFrame; namespace ring { namespace video { -template <typename T> class Observer; -template <typename T> class Observable; - -/*=== Observable =============================================================*/ - -template <typename T> -class Observable -{ -public: - Observable() : observers_(), mutex_() {} - virtual ~Observable() { - std::lock_guard<std::mutex> lk(mutex_); - for (auto& o : observers_) - o->detached(this); - }; - - bool attach(Observer<T>* o) { - std::lock_guard<std::mutex> lk(mutex_); - if (o and observers_.insert(o).second) { - o->attached(this); - return true; - } - return false; - } - - bool detach(Observer<T>* o) { - std::lock_guard<std::mutex> lk(mutex_); - if (o and observers_.erase(o)) { - o->detached(this); - return true; - } - return false; - } - - void notify(T data) { - std::lock_guard<std::mutex> lk(mutex_); - for (auto observer : observers_) - observer->update(this, data); - } - - int getObserversCount() { - std::lock_guard<std::mutex> lk(mutex_); - return observers_.size(); - } - -private: - NON_COPYABLE(Observable<T>); - - std::set<Observer<T>*> observers_; - std::mutex mutex_; // lock observers_ -}; - -/*=== Observer =============================================================*/ - -template <typename T> -class Observer -{ -public: - virtual ~Observer() {}; - virtual void update(Observable<T>*, const T&) = 0; - virtual void attached(Observable<T>*) {}; - virtual void detached(Observable<T>*) {}; -}; - struct VideoFrameActiveWriter: Observable<std::shared_ptr<VideoFrame>> {}; struct VideoFramePassiveReader: Observer<std::shared_ptr<VideoFrame>> {}; diff --git a/src/observer.h b/src/observer.h new file mode 100644 index 0000000000000000000000000000000000000000..1ff089dd82fd19d69ebd63e1abfc6ac50d448bc0 --- /dev/null +++ b/src/observer.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2013-2018 Savoir-faire Linux Inc. + * + * Author: Guillaume Roguez <Guillaume.Roguez@savoirfairelinux.com> + * Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#pragma once + +#include "noncopyable.h" + +#include <cstdlib> +#include <cstdint> +#include <memory> +#include <set> +#include <mutex> +#include <ciso646> // fix windows compiler bug + +namespace ring { + +template <typename T> class Observer; +template <typename T> class Observable; + +/*=== Observable =============================================================*/ + +template <typename T> +class Observable +{ +public: + Observable() : observers_(), mutex_() {} + virtual ~Observable() { + std::lock_guard<std::mutex> lk(mutex_); + for (auto& o : observers_) + o->detached(this); + }; + + bool attach(Observer<T>* o) { + std::lock_guard<std::mutex> lk(mutex_); + if (o and observers_.insert(o).second) { + o->attached(this); + return true; + } + return false; + } + + bool detach(Observer<T>* o) { + std::lock_guard<std::mutex> lk(mutex_); + if (o and observers_.erase(o)) { + o->detached(this); + return true; + } + return false; + } + + void notify(T data) { + std::lock_guard<std::mutex> lk(mutex_); + for (auto observer : observers_) + observer->update(this, data); + } + + int getObserversCount() { + std::lock_guard<std::mutex> lk(mutex_); + return observers_.size(); + } + +private: + NON_COPYABLE(Observable<T>); + + std::set<Observer<T>*> observers_; + std::mutex mutex_; // lock observers_ +}; + +/*=== Observer =============================================================*/ + +template <typename T> +class Observer +{ +public: + virtual ~Observer() {}; + virtual void update(Observable<T>*, const T&) = 0; + virtual void attached(Observable<T>*) {}; + virtual void detached(Observable<T>*) {}; +}; + +}; // namespace ring