DetectorGraph  2.0
beatmachine.cpp File Reference

A Rube Goldbergesque contraption that uses TimeoutPublisherService APIs. More...

Go to the source code of this file.

Detailed Description

A Rube Goldbergesque contraption that uses TimeoutPublisherService APIs.

Introduction

Writing examples is hard - you have to be creative and stuff. So naturally stuff went wild. This one is inspired by the Na Automata [1] and the Hey Jude Flowchart [2].

Jokes aside, this example provides a useful but very basic (C++11 - only) concrete implementation for the DetectorGraph::TimeoutPublisherService class. This shows how Timers & Timeouts can be integrated with Detectors & Topics.

In the example, five detectors attempt to sing Hey Jude together in a distributed fashion - not unlike when you try to sing bits of a song in a crowded concert without knowing the song's entire lyrics or melody. Here the four 'line-singing' detectors must act in synchrony to achieve the desired output.

Implementing TimeoutPublisherService

When porting the DetectorGraph library to your environment you'll need to provide a concrete subclass of DetectorGraph::TimeoutPublisherService similar to DetectorGraph::SleepBasedTimeoutPublisherService in this example. Note that features and accuracy were sacrificed in order to keep DetectorGraph::SleepBasedTimeoutPublisherService as simple as possible.

Using the Timer APIs

The first example of using the Time APIs is on ThemeDetector where it sets up a 75 BPM Periodic Timer that publishes RhytmBeats every 0.8s and subscribes to it:

ThemeDetector(DetectorGraph::Graph* graph, TimeoutPublisherService* timeService) : DetectorGraph::Detector(graph)
{
SetupPeriodicPublishing<RhytmBeats>(RhytmBeats::kPeriod, timeService);
Subscribe<RhytmBeats>(this);
SetupPublishing<SongThemeState>(this);
}

Another example, ThenYouDetector is a DetectorGraph::TimeoutPublisher that acts in a fire and forget manner. This allows the detector to schedule the publishing of a TopicState to a Topic prompting a new graph evaluation in the future for that TopicState. The call to PublishOnTimeout basically says: "Post this data to its topic in X milliseconds".

class ThenYouDetector : public DetectorGraph::Detector
, ...
, public DetectorGraph::TimeoutPublisher<ThenYouState>
{
...
ThenYouDetector(DetectorGraph::Graph* graph, DetectorGraph::TimeoutPublisherService* timeService)
: DetectorGraph::Detector(graph)
...
{
...
SetupTimeoutPublishing<ThenYouState>(this, timeService);
}
...
PublishOnTimeout(ThenYouState(kResponses[mThenYouIndex] + " " + kResponseEnd), RhytmBeats::kPeriod);

A common DetectorGraph::TimeoutPublisher pattern is seen on DontDetector; it is both a DetectorGraph::TimeoutPublisher and a DetectorGraph::SubscriberInterface of the same Topic, DontPause. This achieves a simple timeout pattern where the detector is "called back" later.

class DontDetector : public DetectorGraph::Detector
...
{
...
{
...
Subscribe<DontPause>(this);
SetupTimeoutPublishing<DontPause>(this, timeService);
}
...
PublishOnTimeout(DontPause(), RhytmBeats::kPeriod);

Architecture

Below is the graph representation for this example.

BeatMachine

Other Notes

Note that this example in contained in a single file for the sake of unity as an example. In real-world scenarios the suggested pattern is to split the code into:

   detectorgraph/
        include/
            beatmachine.hpp (BeatMachine header)
        src/
            beatmachine.hpp (BeatMachine implementation)
        detectors/
            include/
                ThemeDetector.hpp
                DontDetector.hpp
                RememberDetector.hpp
                ThenYouDetector.hpp
                SondEndDetector.hpp
            src/
                ThemeDetector.cpp
                DontDetector.cpp
                RememberDetector.cpp
                ThenYouDetector.cpp
                SondEndDetector.cpp
        topicstates/
            include/
                RhytmBeats.hpp
                SongLine.hpp
                SongThemeState.hpp
                DontThemeState.hpp
                RememberState.hpp
                ThenYouState.hpp
                PlaybackState.hpp

References

Note that this examples take a bunch of poetic licenses to allow for more compact representation of the code (e.g. omitting namespaces)

Definition in file beatmachine.cpp.