DetectorGraph  2.0
trivialvendingmachine.cpp File Reference

Vending Machine with Named TopicStates and GraphAnalyzer. More...

Go to the source code of this file.

Detailed Description

Vending Machine with Named TopicStates and GraphAnalyzer.

Introduction

This example gives a single-detector solution for a hypothetical one-item, one-coin vending machine. It shows how a single detector can be used to synchronize combine signals - coins being inserted and the "Buy" button being clicked - to produce a third - SaleCompleted. It also introduces the concepts of Trivial TopicStates, Named TopicStates and using GraphAnalyzer.

Trivial TopicStates

A Trivial TopicState has no data fields:

101 struct CoinInserted : public DetectorGraph::TopicState
102 {
103 };
Base struct for topic data types.
Definition: topicstate.hpp:52

These are sometimes useful to represent parameter-less signals, timeouts etc.

Named TopicStates

Named TopicStates, as opposed to Anonymous ones, are TopicStates that override the TopicState::GetId method. This allows for code that deals with sequences of different TopicStates in a general way. This is used primarily outside (or at the boundary) of the DetectorGraph portion of the application in applications that necessitate any need of generic/transparent treatment of TopicStates. An example of this is GraphStateStore & StateSnapshot. They are often also called Public TopicStates as they're what's exposed to the outside world from the point of view of a DetectorGraph graph.

TopicState "names" come from an application-specific enumeration value for your named TopicStates - values must be cast-able to TopicStateIdType and be different than TopicState::kAnonymousTopicState (-1). An example would be:

111 enum class VendingMachineTopicStateIds{
112  kSaleCompleted = 0,
113  kBalance
114 };

(C++03 enums are fine too)

Which then can be used in the overriding of TopicState::GetId for the desired named TopicState:

118 struct SaleCompleted : public DetectorGraph::TopicState
119 {
121  {
122  return static_cast<DetectorGraph::TopicStateIdType>(
123  VendingMachineTopicStateIds::kSaleCompleted);
124  }
125 };
virtual TopicStateIdType GetId() const
Returns the TopicStateId for this TopicState - to be implemented.
Definition: topicstate.hpp:90
Base struct for topic data types.
Definition: topicstate.hpp:52
int TopicStateIdType
Definition: topicstate.hpp:27

That then enables things like:

200  void ProcessOutput()
201  {
202  // Now we can iterate exclusively through newly updated TopicStates
203  // instead of checking through every Topic of interest.
204  for (const auto topicState : mGraph.GetOutputList())
205  {
206  switch(static_cast<VendingMachineTopicStateIds>(
207  topicState->GetId()))
208  {
209  case VendingMachineTopicStateIds::kSaleCompleted:
210  cout << "Sale Made" << endl;
211  break;
212 
213  case VendingMachineTopicStateIds::kBalance:
214  {
215  const std::shared_ptr<const Balance> balance =
216  std::static_pointer_cast<const Balance>(topicState);
217 
218  cout << "Balance: " << balance->numberOfCoins;
219  cout << " coins" << endl;
220  }
221  break;
222  }
223  }
224 
225  // Or update a GraphStateStore that can be used for persistence or for
226  // a State querying API to be used from outside of the graph.
227  mStateStore.TakeNewSnapshot(mGraph.GetOutputList());
228  }

GraphAnalyzer

Finally, this example also shows how to use DetectorGraph::GraphAnalyzer to generate a GraphViz-compatible .dot representation of the graph:

248  DetectorGraph::GraphAnalyzer analyzer(vendingMachine.mGraph);
249  analyzer.GenerateDotFile("trivial_vending_machine.dot");
Class that provides debugging/diagnostics to a DetectorGraph detector graph.

That .dot file when rendered generates the following graph:

Trivial Vending Machine

Note that the Named TopicStates are represented by outlined rectangles.

For a more sophisticated solution to a similar problem, see fancyvendingmachine.cpp .

Definition in file trivialvendingmachine.cpp.