helper: Fix NDN stack initialization when using VisualSimulatorImpl

Change-Id: Ide284d87a0d06c11a7191fdea5b58169392281a2
diff --git a/examples/ndn-simple.cpp b/examples/ndn-simple.cpp
index 913c16f..0e84b4d 100644
--- a/examples/ndn-simple.cpp
+++ b/examples/ndn-simple.cpp
@@ -82,7 +82,8 @@
   // Consumer will request /prefix/0, /prefix/1, ...
   consumerHelper.SetPrefix("/prefix");
   consumerHelper.SetAttribute("Frequency", StringValue("10")); // 10 interests a second
-  consumerHelper.Install(nodes.Get(0));                        // first node
+  auto apps = consumerHelper.Install(nodes.Get(0));                        // first node
+  apps.Stop(Seconds(10.0)); // stop the consumer app at 10 seconds mark
 
   // Producer
   ndn::AppHelper producerHelper("ns3::ndn::Producer");
diff --git a/helper/ndn-app-helper.cpp b/helper/ndn-app-helper.cpp
index 0fe7f5c..fef02c8 100644
--- a/helper/ndn-app-helper.cpp
+++ b/helper/ndn-app-helper.cpp
@@ -23,6 +23,7 @@
 #include "ns3/names.h"
 
 #include "apps/ndn-app.hpp"
+#include "ndn-stack-helper.hpp"
 
 #ifdef NS3_MPI
 #include "ns3/mpi-interface.h"
@@ -96,8 +97,7 @@
         app = m_factory.Create<Application>();
         node->AddApplication(app);
       }));
-  Simulator::Stop(Seconds(0));
-  Simulator::Run();
+  StackHelper::ProcessWarmupEvents();
 
   return app;
 }
diff --git a/helper/ndn-stack-helper.cpp b/helper/ndn-stack-helper.cpp
index d2b8abb..863b191 100644
--- a/helper/ndn-stack-helper.cpp
+++ b/helper/ndn-stack-helper.cpp
@@ -27,6 +27,10 @@
 #include "ns3/node-list.h"
 #include "ns3/simulator.h"
 
+#if HAVE_NS3_VISUALIZER
+#include "../../visualizer/model/visual-simulator-impl.h"
+#endif // HAVE_NS3_VISUALIZER
+
 #include "model/ndn-l3-protocol.hpp"
 #include "model/ndn-net-device-transport.hpp"
 #include "utils/ndn-time.hpp"
@@ -174,8 +178,7 @@
     return;
   }
   Simulator::ScheduleWithContext(node->GetId(), Seconds(0), &StackHelper::doInstall, this, node);
-  Simulator::Stop(Seconds(0));
-  Simulator::Run(); // to automatically dispatch events on proper nodes
+  ProcessWarmupEvents();
 }
 
 void
@@ -393,9 +396,7 @@
 
   if (m_needSetDefaultRoutes) {
     // default route with lowest priority possible
-    Simulator::ScheduleWithContext(node->GetId(), Seconds(0), MakeEvent([=] {
-          FibHelper::AddRoute(node, "/", face, std::numeric_limits<int32_t>::max());
-        }));
+    FibHelper::AddRoute(node, "/", face, std::numeric_limits<int32_t>::max());
   }
   return face;
 }
@@ -435,5 +436,23 @@
   }
 }
 
+void
+StackHelper::ProcessWarmupEvents()
+{
+  Simulator::Stop(Seconds(0));
+#if HAVE_NS3_VISUALIZER
+  auto impl = DynamicCast<VisualSimulatorImpl>(Simulator::GetImplementation());
+  if (impl != nullptr) {
+    impl->RunRealSimulator();
+  }
+  else {
+    Simulator::Run();
+  }
+#else
+  Simulator::Run();
+#endif // HAVE_NS3_VISUALIZER
+}
+
+
 } // namespace ndn
 } // namespace ns3
diff --git a/helper/ndn-stack-helper.hpp b/helper/ndn-stack-helper.hpp
index 18ce308..1237a15 100644
--- a/helper/ndn-stack-helper.hpp
+++ b/helper/ndn-stack-helper.hpp
@@ -240,6 +240,9 @@
   static void
   SetLinkDelayAsFaceMetric();
 
+  static void
+  ProcessWarmupEvents();
+
 private:
   void
   doInstall(Ptr<Node> node) const;
diff --git a/helper/ndn-strategy-choice-helper.cpp b/helper/ndn-strategy-choice-helper.cpp
index 215d34b..43cd9fd 100644
--- a/helper/ndn-strategy-choice-helper.cpp
+++ b/helper/ndn-strategy-choice-helper.cpp
@@ -64,8 +64,7 @@
 
   Simulator::ScheduleWithContext(node->GetId(), Seconds(0),
                                  &StrategyChoiceHelper::sendCommand, parameters, node);
-  Simulator::Stop(Seconds(0));
-  Simulator::Run();
+  StackHelper::ProcessWarmupEvents();
 }
 
 void
diff --git a/wscript b/wscript
index 973165e..0601bdc 100644
--- a/wscript
+++ b/wscript
@@ -126,6 +126,8 @@
     module.use += ['version-ndn-cxx', 'version-NFD', 'BOOST', 'SQLITE3', 'RT', 'PTHREAD', 'OPENSSL']
     module.includes = ['../..', '../../ns3/ndnSIM/NFD', './NFD/core', './NFD/daemon', './NFD/rib', '../../ns3/ndnSIM', '../../ns3/ndnSIM/ndn-cxx']
     module.export_includes = ['../../ns3/ndnSIM/NFD', './NFD/core', './NFD/daemon', './NFD/rib', '../../ns3/ndnSIM']
+    if 'ns3-visualizer' in bld.env['NS3_ENABLED_MODULES']:
+        module.defines = ['HAVE_NS3_VISUALIZER=1']
 
     headers = bld(features='ns3header')
     headers.module = 'ndnSIM'