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/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