Convert HotGoal over to event loops.

Change-Id: I43f9e4b26f89e5758cb4a18d91694cdb68186361
diff --git a/y2014/BUILD b/y2014/BUILD
index ee60c7c..f3569f0 100644
--- a/y2014/BUILD
+++ b/y2014/BUILD
@@ -62,6 +62,7 @@
     ],
     deps = [
         "//aos:init",
+        "//aos/events:shm-event-loop",
         "//aos/logging",
         "//aos/logging:queue_logging",
         "//aos/time",
diff --git a/y2014/actors/autonomous_actor.cc b/y2014/actors/autonomous_actor.cc
index b8f48af..e241d11 100644
--- a/y2014/actors/autonomous_actor.cc
+++ b/y2014/actors/autonomous_actor.cc
@@ -32,7 +32,9 @@
     ::aos::EventLoop *event_loop,
     ::frc971::autonomous::AutonomousActionQueueGroup *s)
     : frc971::autonomous::BaseAutonomousActor(
-          event_loop, s, control_loops::GetDrivetrainConfig()) {}
+          event_loop, s, control_loops::GetDrivetrainConfig()),
+      hot_goal_fetcher_(
+          event_loop->MakeFetcher<::y2014::HotGoal>(".y2014.hot_goal")) {}
 
 void AutonomousActor::PositionClawVertically(double intake_power,
                                              double centering_power) {
@@ -136,12 +138,15 @@
 
 class HotGoalDecoder {
  public:
-  HotGoalDecoder() { ResetCounts(); }
+  HotGoalDecoder(::aos::Fetcher<::y2014::HotGoal> *hot_goal_fetcher)
+      : hot_goal_fetcher_(hot_goal_fetcher) {
+    ResetCounts();
+  }
 
   void ResetCounts() {
-    hot_goal.FetchLatest();
-    if (hot_goal.get()) {
-      start_counts_ = *hot_goal;
+    hot_goal_fetcher_->Fetch();
+    if (hot_goal_fetcher_->get()) {
+      start_counts_ = *hot_goal_fetcher_->get();
       LOG_STRUCT(INFO, "counts reset to", start_counts_);
       start_counts_valid_ = true;
     } else {
@@ -150,31 +155,30 @@
     }
   }
 
-  void Update(bool block = false) {
-    if (block) {
-      hot_goal.FetchAnother();
-    } else {
-      hot_goal.FetchLatest();
-    }
-    if (hot_goal.get()) LOG_STRUCT(INFO, "new counts", *hot_goal);
+  void Update() {
+    hot_goal_fetcher_->Fetch();
+    if (hot_goal_fetcher_->get())
+      LOG_STRUCT(INFO, "new counts", *hot_goal_fetcher_->get());
   }
 
   bool left_triggered() const {
-    if (!start_counts_valid_ || !hot_goal.get()) return false;
-    return (hot_goal->left_count - start_counts_.left_count) > kThreshold;
+    if (!start_counts_valid_ || !hot_goal_fetcher_->get()) return false;
+    return (hot_goal_fetcher_->get()->left_count - start_counts_.left_count) >
+           kThreshold;
   }
 
   bool right_triggered() const {
-    if (!start_counts_valid_ || !hot_goal.get()) return false;
-    return (hot_goal->right_count - start_counts_.right_count) > kThreshold;
+    if (!start_counts_valid_ || !hot_goal_fetcher_->get()) return false;
+    return (hot_goal_fetcher_->get()->right_count - start_counts_.right_count) >
+           kThreshold;
   }
 
   bool is_left() const {
-    if (!start_counts_valid_ || !hot_goal.get()) return false;
+    if (!start_counts_valid_ || !hot_goal_fetcher_->get()) return false;
     const uint64_t left_difference =
-        hot_goal->left_count - start_counts_.left_count;
+        hot_goal_fetcher_->get()->left_count - start_counts_.left_count;
     const uint64_t right_difference =
-        hot_goal->right_count - start_counts_.right_count;
+        hot_goal_fetcher_->get()->right_count - start_counts_.right_count;
     if (left_difference > kThreshold) {
       if (right_difference > kThreshold) {
         // We've seen a lot of both, so pick the one we've seen the most of.
@@ -190,11 +194,11 @@
   }
 
   bool is_right() const {
-    if (!start_counts_valid_ || !hot_goal.get()) return false;
+    if (!start_counts_valid_ || !hot_goal_fetcher_->get()) return false;
     const uint64_t left_difference =
-        hot_goal->left_count - start_counts_.left_count;
+        hot_goal_fetcher_->get()->left_count - start_counts_.left_count;
     const uint64_t right_difference =
-        hot_goal->right_count - start_counts_.right_count;
+        hot_goal_fetcher_->get()->right_count - start_counts_.right_count;
     if (right_difference > kThreshold) {
       if (left_difference > kThreshold) {
         // We've seen a lot of both, so pick the one we've seen the most of.
@@ -214,6 +218,8 @@
 
   ::y2014::HotGoal start_counts_;
   bool start_counts_valid_;
+
+  ::aos::Fetcher<::y2014::HotGoal> *hot_goal_fetcher_;
 };
 
 bool AutonomousActor::RunAction(
@@ -258,7 +264,7 @@
       (auto_version == AutoVersion::kStraight) ? kFastWithBallDrive
                                                : kSlowWithBallDrive;
 
-  HotGoalDecoder hot_goal_decoder;
+  HotGoalDecoder hot_goal_decoder(&hot_goal_fetcher_);
   // True for left, false for right.
   bool first_shot_left, second_shot_left_default, second_shot_left;
 
@@ -309,7 +315,7 @@
     do {
       // TODO(brians): Wait for next message with timeout or something.
       this_thread::sleep_for(chrono::milliseconds(3));
-      hot_goal_decoder.Update(false);
+      hot_goal_decoder.Update();
       if (ShouldCancel()) return true;
     } while (!hot_goal_decoder.left_triggered() &&
              (monotonic_clock::now() - start_time) < chrono::seconds(9));
diff --git a/y2014/actors/autonomous_actor.h b/y2014/actors/autonomous_actor.h
index fe38a02..47195b5 100644
--- a/y2014/actors/autonomous_actor.h
+++ b/y2014/actors/autonomous_actor.h
@@ -9,6 +9,7 @@
 #include "frc971/autonomous/base_autonomous_actor.h"
 #include "frc971/control_loops/drivetrain/drivetrain.q.h"
 #include "frc971/control_loops/drivetrain/drivetrain_config.h"
+#include "y2014/queues/hot_goal.q.h"
 
 namespace y2014 {
 namespace actors {
@@ -35,6 +36,8 @@
   void Shoot();
 
   bool WaitUntilClawDone();
+
+  ::aos::Fetcher<::y2014::HotGoal> hot_goal_fetcher_;
 };
 
 }  // namespace actors
diff --git a/y2014/hot_goal_reader.cc b/y2014/hot_goal_reader.cc
index 0b99edb..a772633 100644
--- a/y2014/hot_goal_reader.cc
+++ b/y2014/hot_goal_reader.cc
@@ -6,28 +6,23 @@
 #include <arpa/inet.h>
 #include <unistd.h>
 
-#include "aos/time/time.h"
-#include "aos/logging/queue_logging.h"
-#include "aos/logging/logging.h"
-#include "aos/init.h"
 #include "aos/byteorder.h"
-
+#include "aos/events/shm-event-loop.h"
+#include "aos/init.h"
+#include "aos/logging/logging.h"
+#include "aos/logging/queue_logging.h"
+#include "aos/time/time.h"
 #include "y2014/queues/hot_goal.q.h"
 
 int main() {
   ::aos::InitNRT();
 
-  uint64_t left_count, right_count;
-  ::y2014::hot_goal.FetchLatest();
-  if (::y2014::hot_goal.get()) {
-    LOG_STRUCT(DEBUG, "starting with", *::y2014::hot_goal);
-    left_count = ::y2014::hot_goal->left_count;
-    right_count = ::y2014::hot_goal->left_count;
-  } else {
-    LOG(DEBUG, "no starting message\n");
-    left_count = right_count = 0;
-  }
+  ::aos::ShmEventLoop shm_event_loop;
 
+  ::aos::Sender<::y2014::HotGoal> hot_goal_sender =
+      shm_event_loop.MakeSender<::y2014::HotGoal>(".y2014.hot_goal");
+
+  uint64_t left_count = 0, right_count = 0;
   int my_socket = -1;
   while (true) {
     if (my_socket == -1) {
@@ -87,7 +82,7 @@
           }
           if (data & 0x01) ++right_count;
           if (data & 0x02) ++left_count;
-          auto message = ::y2014::hot_goal.MakeMessage();
+          auto message = hot_goal_sender.MakeMessage();
           message->left_count = left_count;
           message->right_count = right_count;
           LOG_STRUCT(DEBUG, "sending", *message);
diff --git a/y2014/queues/hot_goal.q b/y2014/queues/hot_goal.q
index d936968..8aabb46 100644
--- a/y2014/queues/hot_goal.q
+++ b/y2014/queues/hot_goal.q
@@ -1,7 +1,7 @@
 package y2014;
 
+// Published on ".y2014.hot_goal"
 message HotGoal {
 	uint64_t left_count;
 	uint64_t right_count;
 };
-queue HotGoal hot_goal;