Split function scheduler out

I'd like to use it in more tests.

Change-Id: I17d591a525dd25b5f4061d92791159af9a0b08e8
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/events/BUILD b/aos/events/BUILD
index 926d0c5..7f9c008 100644
--- a/aos/events/BUILD
+++ b/aos/events/BUILD
@@ -513,6 +513,7 @@
     target_compatible_with = ["@platforms//os:linux"],
     deps = [
         ":event_loop_param_test",
+        ":function_scheduler",
         ":message_counter",
         ":ping_lib",
         ":pong_lib",
@@ -744,6 +745,17 @@
     ],
 )
 
+cc_library(
+    name = "function_scheduler",
+    srcs = [
+        "function_scheduler.cc",
+    ],
+    hdrs = [
+        "function_scheduler.h",
+    ],
+    deps = [":event_loop"],
+)
+
 cc_binary(
     name = "aos_timing_report_streamer",
     srcs = ["aos_timing_report_streamer.cc"],
diff --git a/aos/events/function_scheduler.cc b/aos/events/function_scheduler.cc
new file mode 100644
index 0000000..94cb90d
--- /dev/null
+++ b/aos/events/function_scheduler.cc
@@ -0,0 +1,34 @@
+#include "aos/events/function_scheduler.h"
+
+namespace aos {
+
+FunctionScheduler::FunctionScheduler(aos::EventLoop *event_loop)
+    : event_loop_(event_loop), timer_(event_loop_->AddTimer([this]() {
+        RunFunctions(event_loop_->context().monotonic_event_time);
+      })) {
+  timer_->set_name("function_timer");
+  event_loop_->OnRun(
+      [this]() { RunFunctions(event_loop_->context().monotonic_event_time); });
+}
+
+void FunctionScheduler::ScheduleAt(std::function<void()> &&function,
+                                   aos::monotonic_clock::time_point time) {
+  functions_.insert(std::make_pair(time, std::move(function)));
+  timer_->Schedule(functions_.begin()->first);
+}
+
+void FunctionScheduler::RunFunctions(aos::monotonic_clock::time_point now) {
+  while (true) {
+    if (functions_.empty()) return;
+    if (functions_.begin()->first > now) {
+      break;
+    }
+    CHECK_EQ(functions_.begin()->first, now);
+
+    functions_.begin()->second();
+    functions_.erase(functions_.begin());
+  }
+  timer_->Schedule(functions_.begin()->first);
+}
+
+}  // namespace aos
diff --git a/aos/events/function_scheduler.h b/aos/events/function_scheduler.h
new file mode 100644
index 0000000..7a846c6
--- /dev/null
+++ b/aos/events/function_scheduler.h
@@ -0,0 +1,33 @@
+#ifndef AOS_EVENTS_FUNCTION_SCHEDULER_H_
+#define AOS_EVENTS_FUNCTION_SCHEDULER_H_
+
+#include <functional>
+#include <map>
+
+#include "aos/events/event_loop.h"
+#include "aos/time/time.h"
+
+namespace aos {
+
+// Simple class to call a function at a time with a timer.
+class FunctionScheduler {
+ public:
+  FunctionScheduler(aos::EventLoop *event_loop);
+
+  // Schedules the function to be run at the provided time.
+  void ScheduleAt(std::function<void()> &&function,
+                  aos::monotonic_clock::time_point time);
+
+ private:
+  void RunFunctions(aos::monotonic_clock::time_point now);
+
+  aos::EventLoop *event_loop_;
+  aos::TimerHandler *timer_;
+
+  std::multimap<aos::monotonic_clock::time_point, std::function<void()>>
+      functions_;
+};
+
+}  // namespace aos
+
+#endif  // AOS_EVENTS_FUNCTION_SCHEDULER_H_
diff --git a/aos/events/simulated_event_loop_test.cc b/aos/events/simulated_event_loop_test.cc
index 7a910b9..f929165 100644
--- a/aos/events/simulated_event_loop_test.cc
+++ b/aos/events/simulated_event_loop_test.cc
@@ -7,6 +7,7 @@
 #include "gtest/gtest.h"
 
 #include "aos/events/event_loop_param_test.h"
+#include "aos/events/function_scheduler.h"
 #include "aos/events/logging/logger_generated.h"
 #include "aos/events/message_counter.h"
 #include "aos/events/ping_lib.h"
@@ -2495,48 +2496,6 @@
   }
 }
 
-// Simple class to call a function at a time with a timer.
-class FunctionScheduler {
- public:
-  FunctionScheduler(aos::EventLoop *event_loop)
-      : event_loop_(event_loop), timer_(event_loop_->AddTimer([this]() {
-          IncrementTestTimer(event_loop_->context().monotonic_event_time);
-        })) {
-    timer_->set_name("function_timer");
-    event_loop_->OnRun([this]() {
-      IncrementTestTimer(event_loop_->context().monotonic_event_time);
-    });
-  }
-
-  // Schedules the function to be run at the provided time.
-  void ScheduleAt(std::function<void()> &&function,
-                  aos::monotonic_clock::time_point time) {
-    functions_.insert(std::make_pair(time, std::move(function)));
-    timer_->Schedule(functions_.begin()->first);
-  }
-
- private:
-  void IncrementTestTimer(aos::monotonic_clock::time_point now) {
-    while (true) {
-      if (functions_.empty()) return;
-      if (functions_.begin()->first > now) {
-        break;
-      }
-      CHECK_EQ(functions_.begin()->first, now);
-
-      functions_.begin()->second();
-      functions_.erase(functions_.begin());
-    }
-    timer_->Schedule(functions_.begin()->first);
-  }
-
-  aos::EventLoop *event_loop_;
-  aos::TimerHandler *timer_;
-
-  std::multimap<aos::monotonic_clock::time_point, std::function<void()>>
-      functions_;
-};
-
 // Struct to capture the expected time a message should be received (and it's
 // value).  This is from the perspective of the node receiving the message.
 struct ExpectedTimestamps {