# HG changeset patch # User Mathieu Lacage # Date 1204488037 -3600 # Node ID b451b5fc8b57044fb81f1919c61278ee307360e0 # Parent 05f9cec4462152acf24be38dbb7f896626814f1a implement context-based trace connection diff -r 05f9cec44621 -r b451b5fc8b57 src/core/callback.h --- a/src/core/callback.h Sun Mar 02 06:43:12 2008 +0100 +++ b/src/core/callback.h Sun Mar 02 21:00:37 2008 +0100 @@ -237,6 +237,52 @@ MEM_PTR m_memPtr; }; +// an impl for Bound Functors: +template +class BoundFunctorCallbackImpl : public CallbackImpl { +public: + template + BoundFunctorCallbackImpl (FUNCTOR functor, ARG a) + : m_functor (functor), m_a (a) {} + virtual ~BoundFunctorCallbackImpl () {} + R operator() (void) { + return m_functor (m_a); + } + R operator() (T1 a1) { + return m_functor (m_a,a1); + } + R operator() (T1 a1,T2 a2) { + return m_functor (m_a,a1,a2); + } + R operator() (T1 a1,T2 a2,T3 a3) { + return m_functor (m_a,a1,a2,a3); + } + R operator() (T1 a1,T2 a2,T3 a3,T4 a4) { + return m_functor (m_a,a1,a2,a3,a4); + } + R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) { + return m_functor (m_a,a1,a2,a3,a4,a5); + } + virtual bool IsEqual (Ptr other) const { + BoundFunctorCallbackImpl const *otherDerived = + dynamic_cast const *> (PeekPointer (other)); + if (otherDerived == 0) + { + return false; + } + else if (otherDerived->m_functor != m_functor || + otherDerived->m_a != m_a) + { + return false; + } + return true; + } +private: + T m_functor; + typename TypeTraits::ReferencedType m_a; +}; + + class CallbackBase { public: CallbackBase () : m_impl () {} @@ -299,6 +345,16 @@ : CallbackBase (impl) {} + template + Callback Bind (T a) { + Ptr > impl = + Ptr > ( + new BoundFunctorCallbackImpl< + Callback, + R,T1,T2,T3,T4,T5,T6> (*this, a), false); + return Callback (impl); + } + bool IsNull (void) const { return (DoPeekImpl () == 0)?true:false; } @@ -363,6 +419,15 @@ } }; + +template +bool operator != (Callback a, Callback b) +{ + return !a.IsEqual (b); +} + /** * \ingroup core * \defgroup MakeCallback MakeCallback @@ -645,50 +710,6 @@ * not yet determined whether or not it is really useful and whether * or not we really want to use it. */ -// an impl for Bound Functors: -template -class BoundFunctorCallbackImpl : public CallbackImpl { -public: - template - BoundFunctorCallbackImpl (FUNCTOR functor, ARG a) - : m_functor (functor), m_a (a) {} - virtual ~BoundFunctorCallbackImpl () {} - R operator() (void) { - return m_functor (m_a); - } - R operator() (T1 a1) { - return m_functor (m_a,a1); - } - R operator() (T1 a1,T2 a2) { - return m_functor (m_a,a1,a2); - } - R operator() (T1 a1,T2 a2,T3 a3) { - return m_functor (m_a,a1,a2,a3); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 a4) { - return m_functor (m_a,a1,a2,a3,a4); - } - R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) { - return m_functor (m_a,a1,a2,a3,a4,a5); - } - virtual bool IsEqual (Ptr other) const { - BoundFunctorCallbackImpl const *otherDerived = - dynamic_cast const *> (PeekPointer (other)); - if (otherDerived == 0) - { - return false; - } - else if (otherDerived->m_functor != m_functor || - otherDerived->m_a != m_a) - { - return false; - } - return true; - } -private: - T m_functor; - typename TypeTraits::ReferencedType m_a; -}; template Callback MakeBoundCallback (R (*fnPtr) (TX), ARG a) { diff -r 05f9cec44621 -r b451b5fc8b57 src/core/config.cc --- a/src/core/config.cc Sun Mar 02 06:43:12 2008 +0100 +++ b/src/core/config.cc Sun Mar 02 21:00:37 2008 +0100 @@ -109,7 +109,7 @@ void DoArrayResolve (std::string path, const ObjectVector &vector); void DoResolveOne (Ptr object, std::string name); std::string GetResolvedPath (std::string name) const; - virtual void DoOne (Ptr object, std::string name) = 0; + virtual void DoOne (Ptr object, std::string path, std::string name) = 0; std::vector m_workStack; std::string m_path; }; @@ -142,7 +142,7 @@ Resolver::DoResolveOne (Ptr object, std::string name) { NS_LOG_DEBUG ("resolved="<SetAttribute ("Source", Integer (-2)); + NS_TEST_ASSERT_EQUAL (m_traceNotification, 0); + m_traceNotification = 0; + m_tracePath = ""; + // this should trigger a notification + d1->SetAttribute ("Source", Integer (-3)); + NS_TEST_ASSERT_EQUAL (m_traceNotification, -3); + NS_TEST_ASSERT_EQUAL (m_tracePath, "/NodeA/NodeB/NodesB/1/Source") + m_traceNotification = 0; + m_tracePath = ""; + // this should trigger a notification + 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)); + m_traceNotification = 0; + // this should _not_ trigger a notification + d1->SetAttribute ("Source", Integer (-4)); + NS_TEST_ASSERT_EQUAL (m_traceNotification, 0); + return result; diff -r 05f9cec44621 -r b451b5fc8b57 src/core/config.h --- a/src/core/config.h Sun Mar 02 06:43:12 2008 +0100 +++ b/src/core/config.h Sun Mar 02 21:00:37 2008 +0100 @@ -15,6 +15,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 RegisterRootNamespaceObject (Ptr obj); diff -r 05f9cec44621 -r b451b5fc8b57 src/core/object.cc --- a/src/core/object.cc Sun Mar 02 06:43:12 2008 +0100 +++ b/src/core/object.cc Sun Mar 02 21:00:37 2008 +0100 @@ -1173,6 +1173,17 @@ return ok; } bool +Object::TraceSourceConnectWithContext (std::string name, std::string context, const CallbackBase &cb) +{ + Ptr accessor = m_tid.LookupTraceSourceByName (name); + if (accessor == 0) + { + return false; + } + bool ok = accessor->ConnectWithContext (this, context, cb); + return ok; +} +bool Object::TraceSourceDisconnect (std::string name, const CallbackBase &cb) { Ptr accessor = m_tid.LookupTraceSourceByName (name); diff -r 05f9cec44621 -r b451b5fc8b57 src/core/object.h --- a/src/core/object.h Sun Mar 02 06:43:12 2008 +0100 +++ b/src/core/object.h Sun Mar 02 21:00:37 2008 +0100 @@ -396,6 +396,7 @@ Attribute GetAttribute (std::string name) const; 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); TypeId GetRealTypeId (void) const; diff -r 05f9cec44621 -r b451b5fc8b57 src/core/trace-source-accessor.h --- a/src/core/trace-source-accessor.h Sun Mar 02 06:43:12 2008 +0100 +++ b/src/core/trace-source-accessor.h Sun Mar 02 21:00:37 2008 +0100 @@ -17,6 +17,7 @@ void Unref (void) const; 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; private: mutable uint32_t m_count; @@ -44,6 +45,15 @@ (p->*m_source).Connect (cb); return true; } + virtual bool ConnectWithContext (ObjectBase *obj, std::string context, const CallbackBase &cb) const { + T *p = dynamic_cast (obj); + if (p == 0) + { + return false; + } + (p->*m_source).ConnectWithContext (cb, context); + return true; + } virtual bool Disconnect (ObjectBase *obj, const CallbackBase &cb) const { T *p = dynamic_cast (obj); if (p == 0) diff -r 05f9cec44621 -r b451b5fc8b57 src/core/traced-callback.h --- a/src/core/traced-callback.h Sun Mar 02 06:43:12 2008 +0100 +++ b/src/core/traced-callback.h Sun Mar 02 21:00:37 2008 +0100 @@ -41,6 +41,7 @@ public: TracedCallback (); void Connect (const CallbackBase & callback); + void ConnectWithContext (const CallbackBase & callback, std::string path); void Disconnect (const CallbackBase & callback); void operator() (void) const; void operator() (T1 a1) const; @@ -48,7 +49,7 @@ void operator() (T1 a1, T2 a2, T3 a3) const; void operator() (T1 a1, T2 a2, T3 a3, T4 a4) const; -private: +private: typedef std::list > CallbackList; CallbackList m_callbackList; }; @@ -59,7 +60,6 @@ namespace ns3 { - template TracedCallback::TracedCallback () @@ -77,6 +77,16 @@ template void +TracedCallback::ConnectWithContext (const CallbackBase & callback, std::string path) +{ + Callback cb; + cb.Assign (callback); + Callback realCb = cb.Bind (path); + m_callbackList.push_back (realCb); +} +template +void TracedCallback::Disconnect (const CallbackBase & callback) { for (typename CallbackList::iterator i = m_callbackList.begin (); diff -r 05f9cec44621 -r b451b5fc8b57 src/core/traced-value.h --- a/src/core/traced-value.h Sun Mar 02 06:43:12 2008 +0100 +++ b/src/core/traced-value.h Sun Mar 02 21:00:37 2008 +0100 @@ -53,6 +53,9 @@ void Connect (const CallbackBase &cb) { m_cb.Connect (cb); } + void ConnectWithContext (const CallbackBase &cb, std::string path) { + m_cb.ConnectWithContext (cb, path); + } void Disconnect (const CallbackBase &cb) { m_cb.Disconnect (cb); }