DetectorGraph  2.0
detector.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_DETECTOR_HPP_
16 #define DETECTORGRAPH_INCLUDE_DETECTOR_HPP_
17 
18 #include "vertex.hpp"
19 #include "subscriberinterface.hpp"
22 #include "topicregistry.hpp"
23 #include "graph.hpp"
24 #include "publisher.hpp"
25 #include "futurepublisher.hpp"
26 #include "timeoutpublisher.hpp"
27 
28 namespace DetectorGraph
29 {
30 
31 /**
32  * @brief A unit of logic in a DetectorGraph
33  *
34  * Detectors are compartmentalized algorithm with clear inputs & outputs.
35  * It has fixed input types (Subscriptions) and fixed output types
36  * (Publishing).
37  *
38  * A new detector is implemented by a new class that:
39  * - Sub-classes Detector
40  * - Sub-classes [SubscriberInterface<TopicStateX>](@ref SubscriberInterface)
41  * for each TopicState it subscribes to.
42  * - Sub-classes [Publisher<TopicStateY>](@ref Publisher) for each TopicState
43  * it publishes.
44  * - Calls to [Subscribe<TopicStateX>(this)](@ref Detector::Subscribe) in
45  * the constructor for each TopicState it subscribes to.
46  * - Calls to [SetupPublishing<TopicStateY>(this)](@ref Detector::SetupPublishing)
47  * (or variants) in constructor for each TopicState it publishes to (see
48  * Detector::Detector for more info).
49  *
50  * Detectors should be designed to be modular & finely grained. Note that
51  * there's a trade-off between granularity & practicality/overhead and
52  * sometimes it's easier to find the sweet spot by designing TopicStates
53  * that provide intuitive intermediary state representations and then design
54  * the detectors afterwards.
55  *
56  * For example, a trivial 'temperature threshold' detector could be:
57  * @snippet helloworld.cpp Detector
58  * For a complete example, go to [Hello World](@ref helloworld.cpp)
59  *
60  * More complex Detectors will subscribe & publish to multiple different
61  * topics.
62  *
63  * Detectors can also implement BeginEvaluation() and CompleteEvaluation()
64  * methods if performing a summary across multiple Evaluate() calls - with
65  * calls to Publish() from within CompleteEvaluation().
66  *
67  */
68 class Detector : public Vertex
69 {
70  Graph* mGraph;
71 public:
72  /**
73  * @brief Constructor
74  *
75  * A Detector is always created within a @ref Graph.
76  * The detector is "attached" to the graph during construction.
77  * Also, during construction a subclass must make the necessary
78  * calls to:
79  * - [Subscribe(this)](@ref Detector::Subscribe)
80  * - [SetupPublishing(this)](@ref Detector::SetupPublishing)
81  * - [SetupFuturePublishing(this)](@ref Detector::SetupFuturePublishing)
82  * - [SetupTimeoutPublishing(this, TimeoutPublisherService*)](@ref Detector::SetupTimeoutPublishing)
83  * - [SetupPeriodicPublishing(aPeriodInMilliseconds, TimeoutPublisherService*)](@ref Detector::SetupPeriodicPublishing)
84  */
85  Detector(Graph* graph);
86 
87  /**
88  * @brief Destructor
89  *
90  * Destruction of a Detector removes it from the graph it's contained.
91  * It also removes it's own subscription dispatchers and the 'out' edges
92  * pointing to this detector owned by the topics it subscribes to.
93  */
94  virtual ~Detector();
95 
96  /**
97  * @brief Returns kDetectorVertex to identify this subclass of @ref Vertex
98  */
99  virtual VertexType GetVertexType() const { return Vertex::kDetectorVertex; }
100 
101  /**
102  * @brief Consume data in the topics.
103  *
104  * Executes the evaluation of this detector. This entails:
105  * - Calling @ref BeginEvaluation()
106  * - Iterating through all the subscription dispatchers firing only the ones
107  * with new data. Firing causes the correct SubscriptionInterface::Evaluate method
108  * to be called with the new data.
109  * - Calling @ref CompleteEvaluation()
110  */
111  void ProcessVertex();
112 
113 protected:
114  /**
115  * @brief Setup an subscription on a specific topic
116  *
117  * This method must be called at the constructor of a detector;
118  * once per `SubscriberInterface<T>` interfaces it implements.
119  */
120  template<class TTopicState> void Subscribe(SubscriberInterface<TTopicState>* aSubscriber)
121  {
122  Topic<TTopicState>* topic = mGraph->ResolveTopic<TTopicState>();
123  mDispatchersContainer.CreateDispatcher(topic, aSubscriber);
124 
125  // Keep track of all edges
126  topic->InsertEdge(this);
127  }
128 
129  /**
130  * @brief Setup an advertisement on a specific topic
131  *
132  * This method must be called at the constructor of a detector;
133  * once per `Publisher<T>` implementation it contains.
134  */
135  template<class TTopic> void SetupPublishing(Publisher<TTopic>* aPublisher)
136  {
137  aPublisher->SetGraph(mGraph);
138  Vertex* topic = mGraph->ResolveTopic<TTopic>();
139  InsertEdge(topic);
140  }
141 
142  /**
143  * @brief Setup an future advertisement on a specific topic
144  *
145  * This method must be called at the constructor of a detector;
146  * once per `FuturePublisher<T>` implementation it contains.
147  */
148  template<class TTopic> void SetupFuturePublishing(FuturePublisher<TTopic>* aFuturePublisher)
149  {
150  aFuturePublisher->SetGraph(mGraph);
151  Vertex* topic = mGraph->ResolveTopic<TTopic>();
152  MarkFutureEdge(topic);
153  }
154 
155  /**
156  * @brief Setup an timeout advertisement on a specific topic
157  *
158  * This method must be called at the constructor of a detector;
159  * once per `TimeoutPublisher<T>` implementation it contains.
160  */
161  template<class TTopic> void SetupTimeoutPublishing(TimeoutPublisher<TTopic>* aTimeoutPublisher, TimeoutPublisherService* aTimeoutPublisherService)
162  {
163  aTimeoutPublisher->SetTimeoutService(aTimeoutPublisherService);
164  Vertex* topic = mGraph->ResolveTopic<TTopic>();
165  MarkFutureEdge(topic);
166  }
167 
168  /**
169  * @brief Setup an periodic advertisement on a specific topic
170  *
171  * This method must be called at the constructor of a detector;
172  */
173  template<class TTopic> void SetupPeriodicPublishing(const uint64_t aPeriodInMilliseconds, TimeoutPublisherService* aTimeoutPublisherService)
174  {
175  aTimeoutPublisherService->SchedulePeriodicPublishing<TTopic>(aPeriodInMilliseconds);
176  Vertex* topic = mGraph->ResolveTopic<TTopic>();
177  MarkFutureEdge(topic);
178  }
179 
180  /**
181  * @brief Called before any calls to SubscriberInterface::Evaluate
182  *
183  * See more at @ref ProcessVertex()
184  */
185  virtual void BeginEvaluation();
186 
187  /**
188  * @brief Called after all calls to SubscriberInterface::Evaluate
189  *
190  * See more at @ref ProcessVertex()
191  */
192  virtual void CompleteEvaluation();
193 
194 private:
195  /**
196  * @brief Contain dispatchers to manage subscription interfaces
197  */
198  SubscriptionDispatchersContainer mDispatchersContainer;
199 };
200 
201 } // namespace DetectorGraph
202 
203 #endif // DETECTORGRAPH_INCLUDE_DETECTOR_HPP_
Push data to a topic when timer expires.
void ProcessVertex()
Consume data in the topics.
Definition: detector.cpp:38
void InsertEdge(Vertex *aVertex)
Definition: vertex.hpp:81
void SetupFuturePublishing(FuturePublisher< TTopic > *aFuturePublisher)
Setup an future advertisement on a specific topic.
Definition: detector.hpp:148
void SchedulePeriodicPublishing(const TimeOffset aPeriodInMilliseconds)
Schedules a TopicState for publishing periodically.
Implements a graph of Topics & Detectors with Input/Output APIs.
Definition: graph.hpp:127
Internal - Manages a fixed number of SubscriptionDispatchers.
Publish data to the graph for future evaluation.
void MarkFutureEdge(Vertex *aVertex)
Definition: vertex.hpp:105
Manage data and its handler.
Definition: topic.hpp:84
A service that provides Timer function to DetectorGraph Detectors.
virtual VertexType GetVertexType() const
Returns kDetectorVertex to identify this subclass of Vertex.
Definition: detector.hpp:99
virtual void BeginEvaluation()
Called before any calls to SubscriberInterface::Evaluate.
Definition: detector.cpp:53
void SetGraph(Graph *aGraph)
Definition: publisher.hpp:77
void SetTimeoutService(TimeoutPublisherService *apTimeoutPublisherService)
Sets the timeout service and acquires a TimerHandle to be used by the default/simple API...
Topic< TTopicState > * ResolveTopic()
Find/add a topic in the detector graph.
Definition: graph.hpp:160
virtual void CompleteEvaluation()
Called after all calls to SubscriberInterface::Evaluate.
Definition: detector.cpp:58
void SetupPublishing(Publisher< TTopic > *aPublisher)
Setup an advertisement on a specific topic.
Definition: detector.hpp:135
Detector(Graph *graph)
Constructor.
Definition: detector.cpp:20
void CreateDispatcher(Topic< TTopicState > *topic, SubscriberInterface< TTopicState > *subscriber)
Base class that implements a Publisher behavior.
Definition: publisher.hpp:66
A unit of logic in a DetectorGraph.
Definition: detector.hpp:68
A Pure interface that declares the Subscriber behavior.
void SetupPeriodicPublishing(const uint64_t aPeriodInMilliseconds, TimeoutPublisherService *aTimeoutPublisherService)
Setup an periodic advertisement on a specific topic.
Definition: detector.hpp:173
void SetupTimeoutPublishing(TimeoutPublisher< TTopic > *aTimeoutPublisher, TimeoutPublisherService *aTimeoutPublisherService)
Setup an timeout advertisement on a specific topic.
Definition: detector.hpp:161
virtual ~Detector()
Destructor.
Definition: detector.cpp:25
Define behaviors of a vertex in a graph.
Definition: vertex.hpp:37
void Subscribe(SubscriberInterface< TTopicState > *aSubscriber)
Setup an subscription on a specific topic.
Definition: detector.hpp:120