Add a simulated message bridge

This gives us multi-node simulations!

Change-Id: I10fa955653766a26e4d11471a6dae5b47ea5cd1c
diff --git a/aos/events/simulated_event_loop.h b/aos/events/simulated_event_loop.h
index 019172b..8cff0d7 100644
--- a/aos/events/simulated_event_loop.h
+++ b/aos/events/simulated_event_loop.h
@@ -24,6 +24,9 @@
 class SimulatedChannel;
 
 class NodeEventLoopFactory;
+namespace message_bridge {
+class SimulatedMessageBridge;
+}
 
 // There are 2 concepts needed to support multi-node simulations.
 //  1) The node.  This is implemented with NodeEventLoopFactory.
@@ -110,6 +113,8 @@
   std::vector<std::unique_ptr<NodeEventLoopFactory>> node_factories_;
 
   std::vector<const Node *> nodes_;
+
+  std::unique_ptr<message_bridge::SimulatedMessageBridge> bridge_;
 };
 
 // This class holds all the state required to be a single node.
@@ -132,6 +137,14 @@
   inline monotonic_clock::time_point monotonic_now() const;
   inline realtime_clock::time_point realtime_now() const;
 
+  // Returns the simulated network delay for messages forwarded between nodes.
+  std::chrono::nanoseconds network_delay() const {
+    return factory_->network_delay();
+  }
+  // Returns the simulated send delay for all messages sent within a single
+  // node.
+  std::chrono::nanoseconds send_delay() const { return factory_->send_delay(); }
+
   // Converts a time to the distributed clock for scheduling and cross-node time
   // measurement.
   inline distributed_clock::time_point ToDistributedClock(