fw: decouple Forwarder and FaceTable

refs #3679

Change-Id: I449e20e58a0a67a7172bdf3ab02b0d655149690f
diff --git a/daemon/fw/face-table.cpp b/daemon/fw/face-table.cpp
index ef5b916..ed082bf 100644
--- a/daemon/fw/face-table.cpp
+++ b/daemon/fw/face-table.cpp
@@ -33,17 +33,11 @@
 
 NFD_LOG_INIT("FaceTable");
 
-FaceTable::FaceTable(Forwarder& forwarder)
-  : m_forwarder(forwarder)
-  , m_lastFaceId(face::FACEID_RESERVED_MAX)
+FaceTable::FaceTable()
+  : m_lastFaceId(face::FACEID_RESERVED_MAX)
 {
 }
 
-FaceTable::~FaceTable()
-{
-
-}
-
 Face*
 FaceTable::get(FaceId id) const
 {
@@ -90,9 +84,6 @@
   NFD_LOG_INFO("Added face id=" << faceId << " remote=" << face->getRemoteUri()
                                           << " local=" << face->getLocalUri());
 
-  face->afterReceiveInterest.connect(bind(&Forwarder::startProcessInterest, &m_forwarder, ref(*face), _1));
-  face->afterReceiveData.connect(bind(&Forwarder::startProcessData, &m_forwarder, ref(*face), _1));
-  face->afterReceiveNack.connect(bind(&Forwarder::startProcessNack, &m_forwarder, ref(*face), _1));
   connectFaceClosedSignal(*face, bind(&FaceTable::remove, this, faceId));
 
   this->afterAdd(*face);
@@ -107,8 +98,6 @@
 
   this->beforeRemove(*face);
 
-  m_forwarder.getFib().removeNextHopFromAllEntries(*face);
-
   m_faces.erase(i);
   face->setId(face::INVALID_FACEID);
 
diff --git a/daemon/fw/face-table.hpp b/daemon/fw/face-table.hpp
index 7da4aff..508db4a 100644
--- a/daemon/fw/face-table.hpp
+++ b/daemon/fw/face-table.hpp
@@ -32,37 +32,31 @@
 
 namespace nfd {
 
-class Forwarder;
-
 /** \brief container of all faces
  */
 class FaceTable : noncopyable
 {
 public:
-  explicit
-  FaceTable(Forwarder& forwarder);
-
-  VIRTUAL_WITH_TESTS
-  ~FaceTable();
+  FaceTable();
 
   /** \brief add a face
    *
    *  FaceTable obtains shared ownership of the face.
    *  The channel or protocol factory that creates the face may retain ownership.
    */
-  VIRTUAL_WITH_TESTS void
+  void
   add(shared_ptr<Face> face);
 
   /** \brief add a special face with a reserved FaceId
    */
-  VIRTUAL_WITH_TESTS void
+  void
   addReserved(shared_ptr<Face> face, FaceId faceId);
 
   /** \brief get face by FaceId
    *  \return a face if found, nullptr if not found;
    *          face->shared_from_this() can be used if shared_ptr<Face> is desired
    */
-  VIRTUAL_WITH_TESTS Face*
+  Face*
   get(FaceId id) const;
 
   /** \return count of faces
@@ -107,7 +101,6 @@
   getForwardRange() const;
 
 private:
-  Forwarder& m_forwarder;
   FaceId m_lastFaceId;
   FaceMap m_faces;
 };
diff --git a/daemon/fw/forwarder.cpp b/daemon/fw/forwarder.cpp
index 0b4c653..1bb2ebe 100644
--- a/daemon/fw/forwarder.cpp
+++ b/daemon/fw/forwarder.cpp
@@ -37,18 +37,34 @@
 using fw::Strategy;
 
 Forwarder::Forwarder()
-  : m_faceTable(*this)
-  , m_fib(m_nameTree)
+  : m_fib(m_nameTree)
   , m_pit(m_nameTree)
   , m_measurements(m_nameTree)
   , m_strategyChoice(m_nameTree, fw::makeDefaultStrategy(*this))
 {
   fw::installStrategies(*this);
+
+  m_faceTable.afterAdd.connect([this] (Face& face) {
+    face.afterReceiveInterest.connect(
+      [this, &face] (const Interest& interest) {
+        this->startProcessInterest(face, interest);
+      });
+    face.afterReceiveData.connect(
+      [this, &face] (const Data& data) {
+        this->startProcessData(face, data);
+      });
+    face.afterReceiveNack.connect(
+      [this, &face] (const lp::Nack& nack) {
+        this->startProcessNack(face, nack);
+      });
+  });
+
+  m_faceTable.beforeRemove.connect([this] (Face& face) {
+    m_fib.removeNextHopFromAllEntries(face);
+  });
 }
 
-Forwarder::~Forwarder()
-{
-}
+Forwarder::~Forwarder() = default;
 
 void
 Forwarder::startProcessInterest(Face& face, const Interest& interest)