From 5ed6f37ad99fc3579528e5ea52bb7d6983e8f204 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 7 Mar 2008 12:18:34 -0800 Subject: [PATCH] make Disconnect work with trace contexts. --- src/core/config.cc | 32 ++++++++++++++++++++++++++++---- src/core/config.h | 1 + src/core/object.cc | 11 +++++++++++ src/core/object.h | 1 + src/core/trace-source-accessor.h | 10 ++++++++++ src/core/traced-callback.h | 11 +++++++++++ src/core/traced-value.h | 3 +++ 7 files changed, 65 insertions(+), 4 deletions(-) diff --git a/src/core/config.cc b/src/core/config.cc index 71a382c00..b3a20c673 100644 --- a/src/core/config.cc +++ b/src/core/config.cc @@ -269,6 +269,7 @@ public: 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 obj); void UnregisterRootNamespaceObject (Ptr obj); @@ -359,6 +360,26 @@ ConfigImpl::ConnectWithContext (std::string path, const CallbackBase &cb) } } 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, 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 obj) { m_roots.push_back (obj); @@ -405,6 +426,11 @@ ConnectWithContext (std::string path, const CallbackBase &cb) { Singleton::Get ()->ConnectWithContext (path, cb); } +void +DisconnectWithContext (std::string path, const CallbackBase &cb) +{ + Singleton::Get ()->DisconnectWithContext (path, cb); +} void RegisterRootNamespaceObject (Ptr obj) { @@ -693,10 +719,8 @@ ConfigTest::RunTests (void) 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)); diff --git a/src/core/config.h b/src/core/config.h index 0032dff47..511db8249 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -16,6 +16,7 @@ void SetGlobal (std::string name, Attribute value); 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 obj); void UnregisterRootNamespaceObject (Ptr obj); diff --git a/src/core/object.cc b/src/core/object.cc index 8eec87aee..633fb5c8f 100644 --- a/src/core/object.cc +++ b/src/core/object.cc @@ -1128,6 +1128,17 @@ Object::TraceSourceDisconnect (std::string name, const CallbackBase &cb) bool ok = accessor->Disconnect (this, cb); return ok; } +bool +Object::TraceSourceDisconnectWithContext (std::string name, std::string context, const CallbackBase &cb) +{ + Ptr accessor = m_tid.LookupTraceSourceByName (name); + if (accessor == 0) + { + return false; + } + bool ok = accessor->DisconnectWithContext (this, context, cb); + return ok; +} TypeId Object::GetRealTypeId (void) const diff --git a/src/core/object.h b/src/core/object.h index 95123dac4..749719deb 100644 --- a/src/core/object.h +++ b/src/core/object.h @@ -397,6 +397,7 @@ public: 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; diff --git a/src/core/trace-source-accessor.h b/src/core/trace-source-accessor.h index f606b46f4..741464f57 100644 --- a/src/core/trace-source-accessor.h +++ b/src/core/trace-source-accessor.h @@ -19,6 +19,7 @@ public: 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 @@ DoMakeTraceSourceAccessor (SOURCE T::*a) (p->*m_source).Disconnect (cb); return true; } + virtual bool DisconnectWithContext (ObjectBase *obj, std::string context, const CallbackBase &cb) const { + T *p = dynamic_cast (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; diff --git a/src/core/traced-callback.h b/src/core/traced-callback.h index 87eeae907..fd0bef9cd 100644 --- a/src/core/traced-callback.h +++ b/src/core/traced-callback.h @@ -43,6 +43,7 @@ public: 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 @@ TracedCallback::Disconnect (const CallbackBase & callback) template void +TracedCallback::DisconnectWithContext (const CallbackBase & callback, std::string path) +{ + Callback cb; + cb.Assign (callback); + Callback realCb = cb.Bind (path); + Disconnect (realCb); +} +template +void TracedCallback::operator() (void) const { for (typename CallbackList::const_iterator i = m_callbackList.begin (); diff --git a/src/core/traced-value.h b/src/core/traced-value.h index 6a29ba4af..bd507126a 100644 --- a/src/core/traced-value.h +++ b/src/core/traced-value.h @@ -59,6 +59,9 @@ public: 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) {