Make logger work again with an external SimulatedEventLoopFactory

The only way to get a node, and therefore a remapped_configuration_ and
therefore be able to call Register(SimulatedEventLoopFactory *factory)
is to be able to get the remapped config at all times.  This makes that
work again.

Change-Id: I1be0e751f4b92d3712f73fdff2b5edee4d453a40
diff --git a/aos/events/logging/logger.cc b/aos/events/logging/logger.cc
index 23dc802..d5626a9 100644
--- a/aos/events/logging/logger.cc
+++ b/aos/events/logging/logger.cc
@@ -224,6 +224,7 @@
     : sorted_message_reader_(filename),
       replay_configuration_(replay_configuration) {
   channels_.resize(logged_configuration()->channels()->size());
+  MakeRemappedConfig();
 }
 
 LogReader::~LogReader() {
@@ -235,9 +236,6 @@
 }
 
 const Configuration *LogReader::configuration() const {
-  CHECK(remapped_configuration_ != nullptr)
-      << ": Need to call Register() before the remapped config will be "
-         "generated.";
   return remapped_configuration_;
 }
 
@@ -263,7 +261,6 @@
 }
 
 void LogReader::Register() {
-  MakeRemappedConfig();
   event_loop_factory_unique_ptr_ =
       std::make_unique<SimulatedEventLoopFactory>(configuration(), node());
   Register(event_loop_factory_unique_ptr_.get());
@@ -300,10 +297,18 @@
               << configuration::CleanedChannelToString(original_channel);
       channel_name = remapped_channels_[i];
     }
+
     VLOG(1) << "Going to remap channel " << channel_name << " " << channel_type;
-    channels_[i] = event_loop_->MakeRawSender(CHECK_NOTNULL(
-        configuration::GetChannel(event_loop_->configuration(), channel_name,
-                                  channel_type, "", nullptr)));
+    const Channel *channel = configuration::GetChannel(
+        event_loop_->configuration(), channel_name, channel_type,
+        event_loop_->name(), event_loop_->node());
+
+    CHECK(channel != nullptr)
+        << ": Unable to send {\"name\": \"" << channel_name
+        << "\", \"type\": \"" << channel_type
+        << "\"} because it is not in the provided configuration.";
+
+    channels_[i] = event_loop_->MakeRawSender(channel);
   }
 
   timer_handler_ = event_loop_->AddTimer([this]() {
@@ -392,8 +397,6 @@
 
 void LogReader::RemapLoggedChannel(std::string_view name, std::string_view type,
                                    std::string_view add_prefix) {
-  CHECK(remapped_configuration_ == nullptr)
-      << "Must call RemapLoggedChannel before calling Register().";
   for (size_t ii = 0; ii < logged_configuration()->channels()->size(); ++ii) {
     const Channel *const channel = logged_configuration()->channels()->Get(ii);
     if (channel->name()->str() == name &&
@@ -405,6 +408,7 @@
       VLOG(1) << "Remapping channel "
               << configuration::CleanedChannelToString(channel)
               << " to have name " << remapped_channels_[ii];
+      MakeRemappedConfig();
       return;
     }
   }
diff --git a/aos/events/logging/logger.h b/aos/events/logging/logger.h
index 1740b1f..be9ea36 100644
--- a/aos/events/logging/logger.h
+++ b/aos/events/logging/logger.h
@@ -67,18 +67,20 @@
             const Configuration *replay_configuration = nullptr);
   ~LogReader();
 
-  // Registers everything, but also updates the real time time in sync.  Runs
-  // until the log file starts.
-  // Note that if you use any call other than the Register() call with no
-  // arguments, the user is responsible for making sure that the config of the
-  // supplied event loop (factory) provides any necessary remapped configs.
-  void Register();
-  // Does the same as Register(), except it uses a pre-provided event loop
-  // factory.
+  // Registers all the callbacks to send the log file data out on an event loop
+  // created in event_loop_factory.  This also updates time to be at the start
+  // of the log file by running until the log file starts.
+  // Note: the configuration used in the factory should be configuration()
+  // below, but can be anything as long as the locations needed to send
+  // everything are available.
   void Register(SimulatedEventLoopFactory *event_loop_factory);
-  // Registers the timer and senders used to resend the messages from the log
-  // file.
+  // Creates an SimulatedEventLoopFactory accessible via event_loop_factory(),
+  // and then calls Register.
+  void Register();
+  // Registers callbacks for all the events after the log file starts.  This is
+  // only useful when replaying live.
   void Register(EventLoop *event_loop);
+
   // Unregisters the senders. You only need to call this if you separately
   // supplied an event loop or event loop factory and the lifetimes are such
   // that they need to be explicitly destroyed before the LogReader destructor
@@ -90,7 +92,12 @@
   // Returns the configuration being used for replay.
   const Configuration *configuration() const;
 
-  // Returns the node that this log file was created on.
+  const LogFileHeader *log_file_header() const {
+    return sorted_message_reader_.log_file_header();
+  }
+
+  // Returns the node that this log file was created on.  This is a pointer to a
+  // node in the nodes() list inside configuration().
   const Node *node() const;
 
   // Returns the starting timestamp for the log file.
diff --git a/aos/events/logging/logger_test.cc b/aos/events/logging/logger_test.cc
index 98f6a74..4fff962 100644
--- a/aos/events/logging/logger_test.cc
+++ b/aos/events/logging/logger_test.cc
@@ -72,8 +72,6 @@
 
   EXPECT_EQ(reader.node(), nullptr);
 
-  EXPECT_EQ(reader.event_loop_factory()->node(), nullptr);
-
   std::unique_ptr<EventLoop> test_event_loop =
       reader.event_loop_factory()->MakeEventLoop("log_reader");
 
@@ -213,10 +211,12 @@
   // TODO(austin): Also replay as pi2 or pi3 and make sure we see the pong
   // messages.  This won't work today yet until the log reading code gets
   // significantly better.
+  SimulatedEventLoopFactory log_reader_factory(reader.logged_configuration(), reader.node());
+  log_reader_factory.set_send_delay(chrono::microseconds(0));
 
   // This sends out the fetched messages and advances time to the start of the
   // log file.
-  reader.Register();
+  reader.Register(&log_reader_factory);
 
   ASSERT_NE(reader.node(), nullptr);
   EXPECT_EQ(reader.node()->name()->string_view(), "pi1");
@@ -224,7 +224,7 @@
   reader.event_loop_factory()->set_send_delay(chrono::microseconds(0));
 
   std::unique_ptr<EventLoop> test_event_loop =
-      reader.event_loop_factory()->MakeEventLoop("test");
+      log_reader_factory.MakeEventLoop("test");
 
   int ping_count = 10;
   int pong_count = 10;
@@ -252,9 +252,11 @@
         EXPECT_EQ(ping_count, pong_count);
       });
 
-  reader.event_loop_factory()->RunFor(std::chrono::seconds(100));
+  log_reader_factory.RunFor(std::chrono::seconds(100));
   EXPECT_EQ(ping_count, 2010);
   EXPECT_EQ(pong_count, 2010);
+
+  reader.Deregister();
 }
 
 }  // namespace testing