From a758f4a632adc7fff4769d97379264de6c68685d Mon Sep 17 00:00:00 2001 From: Romain Forlot Date: Fri, 22 Sep 2017 18:15:33 +0200 Subject: Migrating to real Observer design pattern usage Change-Id: I2fa4e1dc81f5dff852e619a425b8caf26b94b55a Signed-off-by: Romain Forlot --- signal-composer-binding/observer-pattern.hpp | 139 +++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 signal-composer-binding/observer-pattern.hpp (limited to 'signal-composer-binding/observer-pattern.hpp') diff --git a/signal-composer-binding/observer-pattern.hpp b/signal-composer-binding/observer-pattern.hpp new file mode 100644 index 0000000..aba2847 --- /dev/null +++ b/signal-composer-binding/observer-pattern.hpp @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2015, 2016 "IoT.bzh" + * Author "Romain Forlot" + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/* This is a classic observer design pattern a bit enhanced to be + able to pull and push info in 2 ways */ + + + #include + #include + +template +class Observable; + +template +class Observer +{ +protected: + virtual ~Observer() + { + const_iterator_ ite = observableList_.end(); + + for(iterator_ itb=observableList_.begin();itb!=ite;++itb) + { + (*itb)->delObserver(this); + } + } + + std::list*> observableList_; + typedef typename std::list*>::iterator iterator_; + typedef typename std::list*>::const_iterator const_iterator_; + +public: + virtual void update(T* observable) = 0; + + void addObservable(Observable* observable) + { + for (auto& obs : observableList_) + { + if (obs == observable) + {return;} + } + + observableList_.push_back(observable); + } + + void delObservable(Observable* observable) + { + const_iterator_ it = std::find(observableList_.begin(), observableList_.end(), observable); + if(it != observableList_.end()) + {observableList_.erase(it);} + } +/* + void recursionCheck(T* obs) + { + for (const auto& obs: observersList_) + { + if( id_ == obs->id()) + {return -1;} + if( origId == obs->id()) + {return -1;} + if(! obs->recursionCheck(origId)) + {return -1;} + } + return 0; + } +*/ +}; + +template +class Observable +{ +private: + std::list*> observerList_; + typedef typename std::list*>::iterator iterator_; + typedef typename std::list*>::const_iterator const_iterator_; + +public: + void addObserver(Observer* observer) + { + observerList_.push_back(observer); + observer->addObservable(this); + } + + void delObserver(Observer* observer) + { + const_iterator_ it = find(observerList_.begin(), observerList_.end(), observer); + if(it != observerList_.end()) + {observerList_.erase(it);} + } +/* + int recursionCheck() + { + for (auto& obs: observerList_) + { + if( static_cast(obs) == static_cast(this)) + {return -1;} + if( obs->recursionCheck(id_)) + {return -1;} + } + return 0; + } +*/ + virtual ~Observable() + { + iterator_ itb = observerList_.begin(); + const_iterator_ ite = observerList_.end(); + + for(;itb!=ite;++itb) + { + (*itb)->delObservable(this); + } + } + +protected: + void notify() + { + iterator_ itb=observerList_.begin(); + const_iterator_ ite=observerList_.end(); + + for(;itb!=ite;++itb) + { + (*itb)->update(static_cast(this)); + } + } +}; -- cgit 1.2.3-korg