DetectorGraph  2.0
topic.hpp
Go to the documentation of this file.
1 // Copyright 2017 Nest Labs, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef DETECTORGRAPH_INCLUDE_TOPIC_HPP_
16 #define DETECTORGRAPH_INCLUDE_TOPIC_HPP_
17 
18 #include "vertex.hpp"
19 #include "subscriberinterface.hpp"
20 #include "topicstate.hpp"
21 #include "dgassert.hpp"
22 
23 #if defined(BUILD_FEATURE_DETECTORGRAPH_CONFIG_LITE)
24 // LITE_BEGIN
25 #include "detectorgraphliteconfig.hpp"
27 // LITE_END
28 #else
29 // FULL_BEGIN
30 #include "sharedptr.hpp"
31 #include <vector>
32 #include <typeinfo>
33 // FULL_END
34 #endif
35 
36 #include "dgstdincludes.hpp"
37 
38 namespace DetectorGraph
39 {
40 
41 class Graph;
42 
43 /**
44  * @brief Provide interface for a topic
45  */
46 class BaseTopic : public Vertex
47 {
48 public:
49 #if !defined(BUILD_FEATURE_DETECTORGRAPH_CONFIG_LITE)
50  virtual std::list< ptr::shared_ptr<const TopicState> > GetCurrentTopicStates() const = 0;
51  virtual TopicStateIdType GetId() const = 0;
52 #endif
53 
54  virtual VertexType GetVertexType() const { return Vertex::kTopicVertex; }
55 
56 protected:
58  {
59  for (VertexPtrContainer::iterator vIt = GetOutEdges().begin();
60  vIt != GetOutEdges().end();
61  ++vIt)
62  {
63  (*vIt)->SetState(aNewState);
64  }
65  }
66 };
67 /**
68  * @brief Manage data and its handler
69  *
70  * It is a data transport system with publish / subscribe semantics.
71  *
72  * # Internals #
73  * `std::vector<T> mCurrentValues` is the holder for current values in the topic.
74  *
75  * This vector is cleared once per evaluation at either:
76  * - The first Publish call during an evaluation pass (cleared
77  * before adding new value)
78  * - Topic is processed, and no further data will be Published to it
79  *
80  * The intended behavior is to have this vector always contain all the
81  * data for a single evaluation pass - or nothing if that's the case.
82  */
83 template<class T>
84 class Topic : public BaseTopic
85 {
86  // Post-C++11 type checking
87 #if defined(BUILD_FEATURE_DETECTORGRAPH_CONFIG_STATIC_ASSERTS)
88  static_assert(std::is_base_of<TopicState, T>::value, "T must inherit from TopicState");
89 #endif
90 
91 public:
92 
93 #if defined(BUILD_FEATURE_DETECTORGRAPH_CONFIG_LITE)
95 #else
96  typedef std::vector<T> ValuesContainer;
97 #endif
98 
100  {
101  // Pre-C++11 type checking.
102 #if __cplusplus < 201103L
103  (void)static_cast<TopicState*>((T*)0);
104 #endif
105  }
106 
107  /**
108  * @brief Append data to its vector
109  */
110  void Publish(const T& arPayload)
111  {
113  {
114  mCurrentValues.clear();
116  }
117 
118  mCurrentValues.push_back(arPayload);
119  }
120 
121  virtual void ProcessVertex()
122  {
123  // TODO(DGRAPH-5): This maintains the old detector graph state style
124  // if we want to preserve topic states until they're touched we can
125  // remove this clearing here.
127  {
128  mCurrentValues.clear();
129  }
130 
132  {
135  }
136  }
137 
138  /**
139  * @brief Pass pending data to its handler
140  */
142  {
143  if (Vertex::GetState() == kVertexDone)
144  {
145  // TODO(DGRAPH-35): Both implementations below work fine. Sometimes
146  // the iterator generates smaller code, sometimes not. Sort this out.
147  for (typename ValuesContainer::const_iterator valueIt = mCurrentValues.begin();
148  valueIt != mCurrentValues.end();
149  ++valueIt)
150  {
151  aSubscriber->Evaluate(*valueIt);
152  }
153  // for (unsigned valueIdx = 0; valueIdx < mCurrentValues.size(); ++valueIdx)
154  // {
155  // aSubscriber->Evaluate(mCurrentValues[valueIdx]);
156  // }
157  }
158  }
159 
160  /**
161  * @brief Returns true if the new Data is available.
162  *
163  * New data is signaled by the Topic having been Processed and containing
164  * in storage.
165  */
166  inline bool HasNewValue() const
167  {
169  }
170 
171  /**
172  * @brief Returns reference to the new/latest value in the topic.
173  *
174  * This method is a direct forwarding of the internal STL container and as
175  * such, calling GetNewValue on an empty Topic is undefined.
176  *
177  * On debug builds, a DG_ASSERT will check that the Topic contains a value.
178  */
179  inline const T& GetNewValue() const
180  {
181  DG_ASSERT(HasNewValue());
182  return mCurrentValues.back();
183  }
184 
185  const ValuesContainer& GetCurrentValues() const
186  {
187  return mCurrentValues;
188  }
189 
190  virtual ~Topic()
191  {}
192 
193 #if !defined(BUILD_FEATURE_DETECTORGRAPH_CONFIG_LITE)
194 // FULL_BEGIN
195  virtual TopicStateIdType GetId() const
196  {
197  return TopicState::GetId<T>();
198  }
199 
200  virtual std::list<ptr::shared_ptr<const TopicState> > GetCurrentTopicStates() const
201  {
202  std::list<ptr::shared_ptr<const TopicState> > tCurrentTopicStates;
203 
204  for (typename std::vector<T>::const_iterator valueIt = mCurrentValues.begin();
205  valueIt != mCurrentValues.end();
206  ++valueIt)
207  {
208  tCurrentTopicStates.push_back(ptr::shared_ptr<TopicState>(new T(*valueIt)));
209  }
210 
211  return tCurrentTopicStates;
212  }
213 // FULL_END
214 #endif
215 
216 private:
217  /*
218  * @brief List of current data in topic. @sa Topic.
219  */
220  ValuesContainer mCurrentValues;
221 };
222 
223 } // namespace DetectorGraph
224 
225 #endif // DETECTORGRAPH_INCLUDE_TOPIC_HPP_
void MarkChildrenState(VertexSearchState aNewState)
Definition: topic.hpp:57
virtual TopicStateIdType GetId() const
Definition: topic.hpp:195
const ValuesContainer & GetCurrentValues() const
Definition: topic.hpp:185
void DispatchIntoSubscriber(SubscriberInterface< T > *aSubscriber)
Pass pending data to its handler.
Definition: topic.hpp:141
VertexSearchState
Enum used for topological sort & traverse context keeping.
Definition: vertex.hpp:52
void Publish(const T &arPayload)
Append data to its vector.
Definition: topic.hpp:110
virtual void Evaluate(const T &)=0
Pure-virtual method that should Evaluate a piece of input data.
bool HasNewValue() const
Returns true if the new Data is available.
Definition: topic.hpp:166
virtual ~Topic()
Definition: topic.hpp:190
Manage data and its handler.
Definition: topic.hpp:84
virtual TopicStateIdType GetId() const =0
VertexPtrContainer & GetOutEdges()
Definition: vertex.hpp:100
VertexSearchState GetState() const
Definition: vertex.hpp:71
Provide interface for a topic.
Definition: topic.hpp:46
virtual VertexType GetVertexType() const
Definition: topic.hpp:54
std::vector< T > ValuesContainer
Definition: topic.hpp:96
const T & GetNewValue() const
Returns reference to the new/latest value in the topic.
Definition: topic.hpp:179
void SetState(VertexSearchState aNewState)
Definition: vertex.hpp:76
A Pure interface that declares the Subscriber behavior.
int TopicStateIdType
Definition: topicstate.hpp:27
virtual void ProcessVertex()
Definition: topic.hpp:121
virtual std::list< ptr::shared_ptr< const TopicState > > GetCurrentTopicStates() const
Definition: topic.hpp:200
#define DG_ASSERT(condition)
Definition: dgassert.hpp:20
virtual std::list< ptr::shared_ptr< const TopicState > > GetCurrentTopicStates() const =0
Define behaviors of a vertex in a graph.
Definition: vertex.hpp:37