actually allow connection and disconnection to trace sources registered in TypeIds
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Fri, 22 Feb 2008 00:08:00 +0100
changeset 2463 c77e43117673
parent 2462 93028d4474ba
child 2464 aafe5d5c2922
actually allow connection and disconnection to trace sources registered in TypeIds
src/core/attribute-test.cc
src/core/integer-trace-source.h
src/core/object.cc
src/core/object.h
src/core/trace-source-accessor.cc
src/core/trace-source-accessor.h
src/core/wscript
--- a/src/core/attribute-test.cc	Thu Feb 21 23:15:00 2008 +0100
+++ b/src/core/attribute-test.cc	Fri Feb 22 00:08:00 2008 +0100
@@ -9,6 +9,7 @@
 #include "double.h"
 #include "object-vector.h"
 #include "integer-trace-source.h"
+#include "trace-source-accessor.h"
 
 namespace ns3 {
 
@@ -18,6 +19,10 @@
   AttributeTest ();
   virtual bool RunTests (void);
 private:
+  void NotifySource1 (int64_t old, int64_t n) {
+    m_gotNew = n;
+  }
+  int64_t m_gotNew;
 };
 
 class Derived : public Object
@@ -104,6 +109,8 @@
 		     MakeIntegerTraceSourceAccessor (&AttributeObjectTest::DoSetIntSrc,
 						     &AttributeObjectTest::DoGetIntSrc),
 		     MakeIntegerChecker<int8_t> ())
+      .AddTraceSource ("Source1", "help test",
+		       MakeTraceSourceAccessor (&AttributeObjectTest::m_intSrc1))
       ;
         
     return tid;
@@ -385,6 +392,15 @@
   NS_TEST_ASSERT (p->SetAttribute ("IntegerTraceSource2", Integer (-128)));
   NS_TEST_ASSERT (!p->SetAttribute ("IntegerTraceSource2", Integer (-129)));
 
+  m_gotNew = -2;
+  NS_TEST_ASSERT (p->SetAttribute ("IntegerTraceSource1", Integer (-1)));
+  NS_TEST_ASSERT (p->TraceSourceConnect ("Source1", MakeCallback (&AttributeTest::NotifySource1, this)));
+  NS_TEST_ASSERT (p->SetAttribute ("IntegerTraceSource1", Integer (0)));
+  NS_TEST_ASSERT_EQUAL (m_gotNew, 0);
+  NS_TEST_ASSERT (p->TraceSourceDisconnect ("Source1", MakeCallback (&AttributeTest::NotifySource1, this)));
+  NS_TEST_ASSERT (p->SetAttribute ("IntegerTraceSource1", Integer (1)));
+  NS_TEST_ASSERT_EQUAL (m_gotNew, 0);
+
   return result;
 }
 
--- a/src/core/integer-trace-source.h	Thu Feb 21 23:15:00 2008 +0100
+++ b/src/core/integer-trace-source.h	Fri Feb 22 00:08:00 2008 +0100
@@ -39,10 +39,10 @@
     return *this;
   }
 
-  void AddCallback (const CallbackBase & callback) {
+  void Connect (const CallbackBase & callback) {
     m_callback.AddCallback (callback);
   }
-  void RemoveCallback (const CallbackBase & callback) {
+  void Disconnect (const CallbackBase & callback) {
     m_callback.RemoveCallback (callback);
   }
 protected:
--- a/src/core/object.cc	Thu Feb 21 23:15:00 2008 +0100
+++ b/src/core/object.cc	Fri Feb 22 00:08:00 2008 +0100
@@ -23,6 +23,7 @@
 #include "singleton.h"
 #include "trace-resolver.h"
 #include "attribute.h"
+#include "trace-source-accessor.h"
 #include "log.h"
 #include <vector>
 #include <sstream>
@@ -66,6 +67,15 @@
   ns3::Attribute GetAttributeInitialValue (uint16_t uid, uint32_t i) const;
   ns3::Ptr<const ns3::AttributeAccessor> GetAttributeAccessor (uint16_t uid, uint32_t i) const;
   ns3::Ptr<const ns3::AttributeChecker> GetAttributeChecker (uint16_t uid, uint32_t i) const;
+  void AddTraceSource (uint16_t uid,
+                       std::string name, 
+                       std::string help,
+                       ns3::Ptr<const ns3::TraceSourceAccessor> accessor);
+  uint32_t GetTraceSourceN (uint16_t uid) const;
+  std::string GetTraceSourceName (uint16_t uid, uint32_t i) const;
+  std::string GetTraceSourceHelp (uint16_t uid, uint32_t i) const;
+  ns3::Ptr<const ns3::TraceSourceAccessor> GetTraceSourceAccessor (uint16_t uid, uint32_t i) const;
+
 private:
   struct ConstructorInformation {
     ns3::CallbackBase cb;
@@ -79,6 +89,11 @@
     ns3::Ptr<const ns3::AttributeAccessor> param;
     ns3::Ptr<const ns3::AttributeChecker> checker;
   };
+  struct TraceSourceInformation {
+    std::string name;
+    std::string help;
+    ns3::Ptr<const ns3::TraceSourceAccessor> accessor;
+  };
   struct IidInformation {
     std::string name;
     uint16_t parent;
@@ -86,6 +101,7 @@
     std::string groupName;
     std::vector<struct ConstructorInformation> constructors;
     std::vector<struct AttributeInformation> attributes;
+    std::vector<struct TraceSourceInformation> traceSources;
   };
   typedef std::vector<struct IidInformation>::const_iterator Iterator;
 
@@ -313,6 +329,47 @@
   return information->attributes[i].checker;
 }
 
+void 
+IidManager::AddTraceSource (uint16_t uid,
+                            std::string name, 
+                            std::string help,
+                            ns3::Ptr<const ns3::TraceSourceAccessor> accessor)
+{
+  struct IidInformation *information  = LookupInformation (uid);
+  struct TraceSourceInformation source;
+  source.name = name;
+  source.help = help;
+  source.accessor = accessor;
+  information->traceSources.push_back (source);
+}
+uint32_t 
+IidManager::GetTraceSourceN (uint16_t uid) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  return information->traceSources.size ();
+}
+std::string 
+IidManager::GetTraceSourceName (uint16_t uid, uint32_t i) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  NS_ASSERT (i < information->traceSources.size ());
+  return information->traceSources[i].name;
+}
+std::string 
+IidManager::GetTraceSourceHelp (uint16_t uid, uint32_t i) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  NS_ASSERT (i < information->traceSources.size ());
+  return information->traceSources[i].help;
+}
+ns3::Ptr<const ns3::TraceSourceAccessor> 
+IidManager::GetTraceSourceAccessor (uint16_t uid, uint32_t i) const
+{
+  struct IidInformation *information = LookupInformation (uid);
+  NS_ASSERT (i < information->traceSources.size ());
+  return information->traceSources[i].accessor;
+}
+
 } // anonymous namespace
 
 /*********************************************************************
@@ -631,6 +688,56 @@
   return checker;
 }
 
+uint32_t 
+TypeId::GetTraceSourceN (void) const
+{
+  return Singleton<IidManager>::Get ()->GetTraceSourceN (m_tid);
+}
+std::string 
+TypeId::GetTraceSourceName (uint32_t i) const
+{
+  return Singleton<IidManager>::Get ()->GetTraceSourceName (m_tid, i);
+}
+std::string 
+TypeId::GetTraceSourceHelp (uint32_t i) const
+{
+  return Singleton<IidManager>::Get ()->GetTraceSourceHelp (m_tid, i);
+}
+Ptr<const TraceSourceAccessor> 
+TypeId::GetTraceSourceAccessor (uint32_t i) const
+{
+  return Singleton<IidManager>::Get ()->GetTraceSourceAccessor (m_tid, i);
+}
+
+TypeId 
+TypeId::AddTraceSource (std::string name,
+                        std::string help,
+                        Ptr<const TraceSourceAccessor> accessor)
+{
+  Singleton<IidManager>::Get ()->AddTraceSource (m_tid, name, help, accessor);
+  return *this;
+}
+
+
+Ptr<const TraceSourceAccessor> 
+TypeId::LookupTraceSourceByName (std::string name) const
+{
+  TypeId tid = TypeId (0);
+  TypeId nextTid = *this;
+  do {
+    tid = nextTid;
+    for (uint32_t i = 0; i < tid.GetTraceSourceN (); i++)
+      {
+        std::string srcName = tid.GetTraceSourceName (i);
+        if (srcName == name)
+          {
+            return tid.GetTraceSourceAccessor (i);
+          }
+      }
+    nextTid = tid.GetParent ();
+  } while (nextTid != tid);
+  return 0;
+}
 
 bool operator == (TypeId a, TypeId b)
 {
@@ -1035,6 +1142,30 @@
   return value;
 }
 
+bool 
+Object::TraceSourceConnect (std::string name, const CallbackBase &cb)
+{
+  Ptr<const TraceSourceAccessor> accessor = m_tid.LookupTraceSourceByName (name);
+  if (accessor == 0)
+    {
+      return false;
+    }
+  bool ok = accessor->Connect (this, cb);
+  return ok;
+}
+bool 
+Object::TraceSourceDisconnect (std::string name, const CallbackBase &cb)
+{
+  Ptr<const TraceSourceAccessor> accessor = m_tid.LookupTraceSourceByName (name);
+  if (accessor == 0)
+    {
+      return false;
+    }
+  bool ok = accessor->Disconnect (this, cb);
+  return ok;
+}
+
+
 Ptr<Object>
 Object::DoGetObject (TypeId tid) const
 {
--- a/src/core/object.h	Thu Feb 21 23:15:00 2008 +0100
+++ b/src/core/object.h	Fri Feb 22 00:08:00 2008 +0100
@@ -47,6 +47,7 @@
 class AttributeAccessor;
 class AttributeValue;
 class AttributeList;
+class TraceSourceAccessor;
 
 /**
  * \brief a unique identifier for an interface.
@@ -140,6 +141,11 @@
 
   Attribute GetAttributeInitialValue (uint32_t i) const;
 
+  uint32_t GetTraceSourceN (void) const;
+  std::string GetTraceSourceName (uint32_t i) const;
+  std::string GetTraceSourceHelp (uint32_t i) const;
+  Ptr<const TraceSourceAccessor> GetTraceSourceAccessor (uint32_t i) const;
+
   Ptr<Object> CreateObject (const AttributeList &attributes) const;
 
 
@@ -227,9 +233,13 @@
                        std::string help, 
                        uint32_t flags,
                        Attribute initialValue,
-                       Ptr<const AttributeAccessor> spec,
+                       Ptr<const AttributeAccessor> accessor,
                        Ptr<const AttributeChecker> checker);
 
+  TypeId AddTraceSource (std::string name,
+                         std::string help,
+                         Ptr<const TraceSourceAccessor> accessor);
+
   // construct an invalid TypeId.
   TypeId ();
   ~TypeId ();
@@ -246,6 +256,8 @@
     Ptr<const AttributeChecker> checker;
   };
 
+  Ptr<const TraceSourceAccessor> LookupTraceSourceByName (std::string name) const;
+
   /**
    * \param name the name of the requested attribute
    * \returns the Accessor associated to the requested attribute
@@ -372,6 +384,9 @@
    */
   Attribute GetAttribute (std::string name) const;
 
+  bool TraceSourceConnect (std::string name, const CallbackBase &cb);
+  bool TraceSourceDisconnect (std::string name, const CallbackBase &cb);
+
   /**
    * Increment the reference count. This method should not be called
    * by user code. Object instances are expected to be used in conjunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-source-accessor.cc	Fri Feb 22 00:08:00 2008 +0100
@@ -0,0 +1,25 @@
+#include "trace-source-accessor.h"
+
+namespace ns3 {
+
+TraceSourceAccessor::TraceSourceAccessor ()
+  : m_count (1)
+{}
+TraceSourceAccessor::~TraceSourceAccessor ()
+{}
+void 
+TraceSourceAccessor::Ref (void) const
+{
+  m_count++;
+}
+void 
+TraceSourceAccessor::Unref (void) const
+{
+  m_count--;
+  if (m_count == 0)
+    {
+      delete this;
+    }
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/trace-source-accessor.h	Fri Feb 22 00:08:00 2008 +0100
@@ -0,0 +1,71 @@
+#ifndef TRACE_SOURCE_ACCESSOR_H
+#define TRACE_SOURCE_ACCESSOR_H
+
+#include <stdint.h>
+#include "object-base.h"
+#include "callback.h"
+#include "ptr.h"
+
+namespace ns3 {
+
+class TraceSourceAccessor : public ObjectBase
+{
+public:
+  TraceSourceAccessor ();
+  virtual ~TraceSourceAccessor ();
+  void Ref (void) const;
+  void Unref (void) const;
+
+  virtual bool Connect (ObjectBase *obj, const CallbackBase &cb) const = 0;
+  virtual bool Disconnect (ObjectBase *obj, const CallbackBase &cb) const = 0;
+private:
+  mutable uint32_t m_count;
+};
+
+template <typename T>
+Ptr<const TraceSourceAccessor> MakeTraceSourceAccessor (T a);
+
+} // namespace ns3
+
+namespace ns3 {
+
+template <typename T, typename SOURCE>
+Ptr<const TraceSourceAccessor> 
+DoMakeTraceSourceAccessor (SOURCE T::*a)
+{
+  struct Accessor : public TraceSourceAccessor
+  {
+    virtual bool Connect (ObjectBase *obj, const CallbackBase &cb) const {
+      T *p = dynamic_cast<T*> (obj);
+      if (p == 0)
+	{
+	  return false;
+	}
+      (p->*m_source).Connect (cb);
+      return true;
+    }
+    virtual bool Disconnect (ObjectBase *obj, const CallbackBase &cb) const {
+      T *p = dynamic_cast<T*> (obj);
+      if (p == 0)
+	{
+	  return false;
+	}
+      (p->*m_source).Disconnect (cb);
+      return true;      
+    }
+    SOURCE T::*m_source;
+  } *accessor = new Accessor ();
+  accessor->m_source = a;
+  return Ptr<const TraceSourceAccessor> (accessor, false);
+}
+
+template <typename T>
+Ptr<const TraceSourceAccessor> MakeTraceSourceAccessor (T a)
+{
+  return DoMakeTraceSourceAccessor (a);
+}
+
+} // namespace ns3
+
+
+#endif /* TRACE_SOURCE_ACCESSOR_H */
--- a/src/core/wscript	Thu Feb 21 23:15:00 2008 +0100
+++ b/src/core/wscript	Fri Feb 22 00:08:00 2008 +0100
@@ -64,6 +64,7 @@
         'object-vector.cc',
         'initial-value.cc',
         'event-trace-source.cc',
+        'trace-source-accessor.cc',
         ]
 
     if sys.platform == 'win32':
@@ -119,5 +120,7 @@
         'attribute-helper.h',
         'initial-value.h',
         'event-trace-source.h',
+        'integer-trace-source.h',
+        'trace-source-accessor.h',
         ]