make Disconnect work with trace contexts.
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Fri, 07 Mar 2008 12:18:34 -0800
changeset 2569 d5cff2968984
parent 2568 fe7da55d00a0
child 2570 15d5421022a1
make Disconnect work with trace contexts.
src/core/config.cc
src/core/config.h
src/core/object.cc
src/core/object.h
src/core/trace-source-accessor.h
src/core/traced-callback.h
src/core/traced-value.h
--- a/src/core/config.cc	Wed Mar 05 00:16:39 2008 +0100
+++ b/src/core/config.cc	Fri Mar 07 12:18:34 2008 -0800
@@ -269,6 +269,7 @@
   void Connect (std::string path, const CallbackBase &cb);
   void ConnectWithContext (std::string path, const CallbackBase &cb);
   void Disconnect (std::string path, const CallbackBase &cb);
+  void DisconnectWithContext (std::string path, const CallbackBase &cb);
 
   void RegisterRootNamespaceObject (Ptr<Object> obj);
   void UnregisterRootNamespaceObject (Ptr<Object> obj);
@@ -359,6 +360,26 @@
     }
 }
 void 
+ConfigImpl::DisconnectWithContext (std::string path, const CallbackBase &cb)
+{
+  class DisconnectWithContextResolver : public Resolver 
+  {
+  public:
+    DisconnectWithContextResolver (std::string path, const CallbackBase &cb)
+      : Resolver (path),
+	m_cb (cb) {}
+  private:
+    virtual void DoOne (Ptr<Object> object, std::string path, std::string name) {
+      object->TraceSourceDisconnectWithContext (name, path, m_cb);
+    }
+    CallbackBase m_cb;
+  } resolver = DisconnectWithContextResolver (path, cb);
+  for (Roots::const_iterator i = m_roots.begin (); i != m_roots.end (); i++)
+    {
+      resolver.Resolve (*i);
+    }
+}
+void 
 ConfigImpl::RegisterRootNamespaceObject (Ptr<Object> obj)
 {
   m_roots.push_back (obj);
@@ -405,6 +426,11 @@
 {
   Singleton<ConfigImpl>::Get ()->ConnectWithContext (path, cb);
 }
+void 
+DisconnectWithContext (std::string path, const CallbackBase &cb)
+{
+  Singleton<ConfigImpl>::Get ()->DisconnectWithContext (path, cb);
+}
 
 void RegisterRootNamespaceObject (Ptr<Object> obj)
 {
@@ -693,10 +719,8 @@
   d3->SetAttribute ("Source", Integer (-3));
   NS_TEST_ASSERT_EQUAL (m_traceNotification, -3);
   NS_TEST_ASSERT_EQUAL (m_tracePath, "/NodeA/NodeB/NodesB/3/Source");
-  // Yes, disconnection _cannot_ work with 'context-based connection.
-  // XXX: what do we do about this ?
-  Config::Disconnect ("/NodeA/NodeB/NodesB/[0-1]|3/Source", 
-		      MakeCallback (&ConfigTest::ChangeNotificationWithPath, this));
+  Config::DisconnectWithContext ("/NodeA/NodeB/NodesB/[0-1]|3/Source", 
+				 MakeCallback (&ConfigTest::ChangeNotificationWithPath, this));
   m_traceNotification = 0;
   // this should _not_ trigger a notification
   d1->SetAttribute ("Source", Integer (-4));
--- a/src/core/config.h	Wed Mar 05 00:16:39 2008 +0100
+++ b/src/core/config.h	Fri Mar 07 12:18:34 2008 -0800
@@ -16,6 +16,7 @@
 void Connect (std::string path, const CallbackBase &cb);
 void Disconnect (std::string path, const CallbackBase &cb);
 void ConnectWithContext (std::string path, const CallbackBase &cb);
+void DisconnectWithContext (std::string path, const CallbackBase &cb);
 
 void RegisterRootNamespaceObject (Ptr<Object> obj);
 void UnregisterRootNamespaceObject (Ptr<Object> obj);
--- a/src/core/object.cc	Wed Mar 05 00:16:39 2008 +0100
+++ b/src/core/object.cc	Fri Mar 07 12:18:34 2008 -0800
@@ -1128,6 +1128,17 @@
   bool ok = accessor->Disconnect (this, cb);
   return ok;
 }
+bool 
+Object::TraceSourceDisconnectWithContext (std::string name, std::string context, const CallbackBase &cb)
+{
+  Ptr<const TraceSourceAccessor> accessor = m_tid.LookupTraceSourceByName (name);
+  if (accessor == 0)
+    {
+      return false;
+    }
+  bool ok = accessor->DisconnectWithContext (this, context, cb);
+  return ok;
+}
 
 TypeId 
 Object::GetRealTypeId (void) const
--- a/src/core/object.h	Wed Mar 05 00:16:39 2008 +0100
+++ b/src/core/object.h	Fri Mar 07 12:18:34 2008 -0800
@@ -397,6 +397,7 @@
   bool TraceSourceConnect (std::string name, const CallbackBase &cb);
   bool TraceSourceConnectWithContext (std::string name, std::string context, const CallbackBase &cb);
   bool TraceSourceDisconnect (std::string name, const CallbackBase &cb);
+  bool TraceSourceDisconnectWithContext (std::string name, std::string context, const CallbackBase &cb);
 
   TypeId GetRealTypeId (void) const;
 
--- a/src/core/trace-source-accessor.h	Wed Mar 05 00:16:39 2008 +0100
+++ b/src/core/trace-source-accessor.h	Fri Mar 07 12:18:34 2008 -0800
@@ -19,6 +19,7 @@
   virtual bool Connect (ObjectBase *obj, const CallbackBase &cb) const = 0;
   virtual bool ConnectWithContext (ObjectBase *obj, std::string context, const CallbackBase &cb) const = 0;
   virtual bool Disconnect (ObjectBase *obj, const CallbackBase &cb) const = 0;
+  virtual bool DisconnectWithContext (ObjectBase *obj, std::string context, const CallbackBase &cb) const = 0;
 private:
   mutable uint32_t m_count;
 };
@@ -63,6 +64,15 @@
       (p->*m_source).Disconnect (cb);
       return true;      
     }
+    virtual bool DisconnectWithContext (ObjectBase *obj, std::string context, const CallbackBase &cb) const {
+      T *p = dynamic_cast<T*> (obj);
+      if (p == 0)
+	{
+	  return false;
+	}
+      (p->*m_source).DisconnectWithContext (cb, context);
+      return true;      
+    }
     SOURCE T::*m_source;
   } *accessor = new Accessor ();
   accessor->m_source = a;
--- a/src/core/traced-callback.h	Wed Mar 05 00:16:39 2008 +0100
+++ b/src/core/traced-callback.h	Fri Mar 07 12:18:34 2008 -0800
@@ -43,6 +43,7 @@
   void Connect (const CallbackBase & callback);
   void ConnectWithContext (const CallbackBase & callback, std::string path);
   void Disconnect (const CallbackBase & callback);
+  void DisconnectWithContext (const CallbackBase & callback, std::string path);
   void operator() (void) const;
   void operator() (T1 a1) const;
   void operator() (T1 a1, T2 a2) const;
@@ -105,6 +106,16 @@
 template<typename T1, typename T2, 
          typename T3, typename T4>
 void 
+TracedCallback<T1,T2,T3,T4>::DisconnectWithContext (const CallbackBase & callback, std::string path)
+{
+  Callback<void,std::string,T1,T2,T3,T4> cb;
+  cb.Assign (callback);
+  Callback<void,T1,T2,T3,T4> realCb = cb.Bind (path);
+  Disconnect (realCb);
+}
+template<typename T1, typename T2, 
+         typename T3, typename T4>
+void 
 TracedCallback<T1,T2,T3,T4>::operator() (void) const
 {
   for (typename CallbackList::const_iterator i = m_callbackList.begin ();
--- a/src/core/traced-value.h	Wed Mar 05 00:16:39 2008 +0100
+++ b/src/core/traced-value.h	Fri Mar 07 12:18:34 2008 -0800
@@ -59,6 +59,9 @@
   void Disconnect (const CallbackBase &cb) {
     m_cb.Disconnect (cb);
   }
+  void DisconnectWithContext (const CallbackBase &cb, std::string path) {
+    m_cb.DisconnectWithContext (cb, path);
+  }
   void Set (const T &v) {
     if (m_v != v)
       {