summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRomain Forlot <romain.forlot@iot.bzh>2017-09-25 01:10:42 +0200
committerRomain Forlot <romain.forlot@iot.bzh>2017-12-14 11:00:25 +0100
commit1a832ce483ff8c1276bc3cd3d97e3caadb38c4df (patch)
treec0d62a2ef4aff80eebea1454124a324ca6ccc5d2
parent51ee5299a7db41e52da2cf52dd9cd9c05b76740a (diff)
Implement recursionCheck using observer pattern
Change-Id: Ic404c098f316106abe1918c3cd100ae047f4f555 Signed-off-by: Romain Forlot <romain.forlot@iot.bzh>
-rw-r--r--signal-composer-binding/observer-pattern.hpp41
-rw-r--r--signal-composer-binding/signal-composer-binding.cpp6
-rw-r--r--signal-composer-binding/signal.cpp99
-rw-r--r--signal-composer-binding/signal.hpp9
4 files changed, 47 insertions, 108 deletions
diff --git a/signal-composer-binding/observer-pattern.hpp b/signal-composer-binding/observer-pattern.hpp
index aba2847..940a80b 100644
--- a/signal-composer-binding/observer-pattern.hpp
+++ b/signal-composer-binding/observer-pattern.hpp
@@ -63,31 +63,11 @@ public:
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 T>
class Observable
{
-private:
- std::list<Observer<T>*> observerList_;
- typedef typename std::list<Observer<T>*>::iterator iterator_;
- typedef typename std::list<Observer<T>*>::const_iterator const_iterator_;
-
public:
void addObserver(Observer<T>* observer)
{
@@ -101,19 +81,10 @@ public:
if(it != observerList_.end())
{observerList_.erase(it);}
}
-/*
- int recursionCheck()
- {
- for (auto& obs: observerList_)
- {
- if( static_cast<T*>(obs) == static_cast<T*>(this))
- {return -1;}
- if( obs->recursionCheck(id_))
- {return -1;}
- }
- return 0;
- }
-*/
+
+ virtual int initialRecursionCheck() = 0;
+ virtual int recursionCheck(T* obs) = 0;
+
virtual ~Observable()
{
iterator_ itb = observerList_.begin();
@@ -126,6 +97,10 @@ public:
}
protected:
+ std::list<Observer<T>*> observerList_;
+ typedef typename std::list<Observer<T>*>::iterator iterator_;
+ typedef typename std::list<Observer<T>*>::const_iterator const_iterator_;
+
void notify()
{
iterator_ itb=observerList_.begin();
diff --git a/signal-composer-binding/signal-composer-binding.cpp b/signal-composer-binding/signal-composer-binding.cpp
index d4236a0..44b644c 100644
--- a/signal-composer-binding/signal-composer-binding.cpp
+++ b/signal-composer-binding/signal-composer-binding.cpp
@@ -217,16 +217,16 @@ int execConf()
{
sig->attachToSourceSignals(composer);
}
-/*
+
for(auto& sig: allSignals)
{
- if( (err += sig->recursionCheck()) )
+ if( (err += sig->initialRecursionCheck()) )
{
AFB_ERROR("There is an infinite recursion loop in your signals definition. Root coming from signal: %s", sig->id().c_str());
return err;
}
}
-*/
+
composer.execSignalsSubscription();
AFB_DEBUG("Signal Composer Control configuration Done.\n signals=%d", (int)sigCount);
diff --git a/signal-composer-binding/signal.cpp b/signal-composer-binding/signal.cpp
index 2dcc552..a74889d 100644
--- a/signal-composer-binding/signal.cpp
+++ b/signal-composer-binding/signal.cpp
@@ -184,52 +184,6 @@ void Signal::attachToSourceSignals(Composer& composer)
}
}
-/// @brief Call update() method on observer Signal with
-/// current Signal timestamp and value
-/*void Signal::notify() const
-{
- for (int i = 0; i < Observers_.size(); ++i)
- Observers_[i]->update(timestamp_, value_);
-}
-
-/// @brief Inner recursion check. Argument is the Signal id coming
-/// from the original Signal that made a recursion check.
-///
-/// @param[in] origId - name of the origine of the recursion check
-///
-/// @return 0 if no infinite loop detected, -1 if not.
-int Signal::recursionCheck(const std::string& origId) const
-{
- 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;
-}
-
-/// @brief Recursion check to ensure that there is no infinite loop
-/// in the Observers/Observables structure.
-/// This will check that observer signal is not the same than itself
-/// then trigger the check against the following eventuals observers
-///
-/// @return 0 if no infinite loop detected, -1 if not.
-int Signal::recursionCheck() const
-{
- for (const auto& obs: observersList_)
- {
- if( id_ == obs->id())
- {return -1;}
- if( obs->recursionCheck(id_))
- {return -1;}
- }
- return 0;
-}*/
-
/// @brief Make an average over the last X 'seconds'
///
/// @param[in] seconds - period to calculate the average
@@ -339,39 +293,40 @@ struct SignalValue Signal::last() const
return history_.rbegin()->second;
}
-/*
-template<class Signal>
-Observable<Signal>::~Observable()
-{
- iterator_ itb = observerList_.begin();
- const_iterator_ ite = observerList_.end();
-
- for(;itb!=ite;++itb)
- {
- (*itb)->delObservable(this);
- }
-}
-template <class Signal>
-Observer<Signal>::~Observer()
+/// @brief Recursion check to ensure that there is no infinite loop
+/// in the Observers/Observables structure.
+/// This will check that observer signal is not the same than itself
+/// then trigger the check against the following eventuals observers
+///
+/// @return 0 if no infinite loop detected, -1 if not.
+int Signal::initialRecursionCheck()
{
- const_iterator_ ite = observableList_.end();
-
- for(iterator_ itb=observableList_.begin();itb!=ite;++itb)
+ for (auto& obs: observerList_)
{
- (*itb)->delObserver(this);
+ if(obs == this)
+ {return -1;}
+ if(static_cast<Signal*>(obs)->recursionCheck(static_cast<Signal*>(obs)))
+ {return -1;}
}
+ return 0;
}
-template <class Signal>
-void Observable<Signal>::notify()
+/// @brief Inner recursion check. Argument is the Signal id coming
+/// from the original Signal that made a recursion check.
+///
+/// @param[in] origId - name of the origine of the recursion check
+///
+/// @return 0 if no infinite loop detected, -1 if not.
+int Signal::recursionCheck(Signal* parentSig)
{
- iterator_ itb=observerList_.begin();
- const_iterator_ ite=observerList_.end();
-
- for(;itb!=ite;++itb)
+ for (const auto& obs: observerList_)
{
- (*itb)->update(static_cast<Signal*>(this));
+ Signal* obsSig = static_cast<Signal*>(obs);
+ if(parentSig->id() == static_cast<Signal*>(obsSig)->id())
+ {return -1;}
+ if(! obsSig->recursionCheck(obsSig))
+ {return -1;}
}
+ return 0;
}
-*/
diff --git a/signal-composer-binding/signal.hpp b/signal-composer-binding/signal.hpp
index 8d0d1ab..46caa23 100644
--- a/signal-composer-binding/signal.hpp
+++ b/signal-composer-binding/signal.hpp
@@ -40,6 +40,12 @@ struct SignalValue {
std::string strVal;
};
+/// @brief Holds a signal (raw or virtual) definition. Value could be of
+/// different types, so an intermediate structure is use to store them.
+/// A signal could also be a subject or an observer at the same time, this
+/// is the behavior retained to compose virtual signals based on raw signals.
+/// And this is the way that is used to update and reacts to an underlaying
+/// signal change.
class Signal: public Observable<Signal>, public Observer<Signal>
{
private:
@@ -76,4 +82,7 @@ public:
double maximum(int seconds = 0) const;
struct SignalValue last() const;
//int recursionCheck() const;
+
+ int initialRecursionCheck();
+ int recursionCheck(Signal* obs);
};