[ndnSIM] core: Make use of scheduler redirection from ndn-cxx library (avoid code duplication)

Change-Id: I238dff4f25f07cdd05f96714c3dbeca01327c26d
diff --git a/core/global-io.cpp b/core/global-io.cpp
new file mode 100644
index 0000000..7eb6a56
--- /dev/null
+++ b/core/global-io.cpp
@@ -0,0 +1,54 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "global-io.hpp"
+#include "scheduler.hpp"
+
+namespace nfd {
+
+namespace detail {
+
+void
+SimulatorIo::post(const std::function<void()>& callback)
+{
+  scheduler::schedule(time::seconds(0), callback);
+}
+
+void
+SimulatorIodispatch(const std::function<void()>& callback)
+{
+  scheduler::schedule(time::seconds(0), callback);
+}
+
+} // namespace detail
+
+detail::SimulatorIo&
+getGlobalIoService()
+{
+  static detail::SimulatorIo io;
+  return io;
+}
+
+} // namespace nfd
diff --git a/core/global-io.hpp b/core/global-io.hpp
index ef90b18..6a76c57 100644
--- a/core/global-io.hpp
+++ b/core/global-io.hpp
@@ -29,25 +29,27 @@
 
 namespace nfd {
 
-/** \return *nullptr (kept for interface compatibility)
- */
-inline boost::asio::io_service&
-getGlobalIoService()
-{
-  return *static_cast<boost::asio::io_service*>(nullptr);
-}
+namespace detail {
 
-#ifdef WITH_TESTS
-/** \brief delete the global io_service instance
- *
- *  It will be recreated at the next invocation of getGlobalIoService.
+/**
+ * @brief Simulator-based IO that implements a few interfaces from boost::asio::io_service
  */
-inline void
-resetGlobalIoService()
+class SimulatorIo
 {
-  // noop
-}
-#endif
+public:
+  void
+  post(const std::function<void()>& callback);
+
+  void
+  dispatch(const std::function<void()>& callback);
+};
+
+} // namespace detail
+
+/** \return Simulator-based IO object
+ */
+detail::SimulatorIo&
+getGlobalIoService();
 
 } // namespace nfd
 
diff --git a/core/scheduler.cpp b/core/scheduler.cpp
index 504a53c..725f81a 100644
--- a/core/scheduler.cpp
+++ b/core/scheduler.cpp
@@ -24,43 +24,41 @@
  */
 
 #include "scheduler.hpp"
+#include "global-io.hpp"
 
-namespace ns3 {
-
-/// @cond include_hidden
-
-template<>
-struct EventMemberImplObjTraits<std::function<void()>> {
-  typedef std::function<void()> T;
-  static T&
-  GetReference(T& p)
-  {
-    return p;
-  }
-};
-
-/// @endcond
-
-} // namespace ns3
+#include <boost/thread/tss.hpp>
 
 namespace nfd {
 namespace scheduler {
 
-EventId
-schedule(const time::nanoseconds& after, const std::function<void()>& event)
+static boost::thread_specific_ptr<Scheduler> g_scheduler;
+
+Scheduler&
+getGlobalScheduler()
 {
-  ns3::EventId id = ns3::Simulator::Schedule(ns3::NanoSeconds(after.count()),
-                                             &std::function<void()>::operator(), event);
-  return std::make_shared<ns3::EventId>(id);
+  if (g_scheduler.get() == nullptr) {
+    g_scheduler.reset(new Scheduler(*static_cast<boost::asio::io_service*>(nullptr)));
+  }
+
+  return *g_scheduler;
+}
+
+EventId
+schedule(const time::nanoseconds& after, const Scheduler::Event& event)
+{
+  return getGlobalScheduler().scheduleEvent(after, event);
 }
 
 void
 cancel(const EventId& eventId)
 {
-  if (eventId != nullptr) {
-    ns3::Simulator::Remove(*eventId);
-    const_cast<EventId&>(eventId).reset();
-  }
+  getGlobalScheduler().cancelEvent(eventId);
+}
+
+void
+resetGlobalScheduler()
+{
+  g_scheduler.reset();
 }
 
 ScopedEventId::ScopedEventId()
diff --git a/core/scheduler.hpp b/core/scheduler.hpp
index 8c9db68..6e87199 100644
--- a/core/scheduler.hpp
+++ b/core/scheduler.hpp
@@ -27,27 +27,31 @@
 #define NFD_CORE_SCHEDULER_HPP
 
 #include "common.hpp"
-
-#include "ns3/simulator.h"
+#include <ndn-cxx/util/scheduler.hpp>
 
 namespace nfd {
 namespace scheduler {
 
+using ndn::Scheduler;
+
 /** \class EventId
  *  \brief Opaque type (shared_ptr) representing ID of a scheduled event
  */
-typedef std::shared_ptr<ns3::EventId> EventId;
+using ndn::EventId;
 
 /** \brief schedule an event
  */
 EventId
-schedule(const time::nanoseconds& after, const std::function<void()>& event);
+schedule(const time::nanoseconds& after, const Scheduler::Event& event);
 
 /** \brief cancel a scheduled event
  */
 void
 cancel(const EventId& eventId);
 
+Scheduler&
+getGlobalScheduler();
+
 /** \brief cancels an event automatically upon destruction
  */
 class ScopedEventId : noncopyable