diff --git a/src/core/attribute-test.cc b/src/core/attribute-test.cc index 976b8e64d..00345046d 100644 --- a/src/core/attribute-test.cc +++ b/src/core/attribute-test.cc @@ -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 @@ public: 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 @@ public: MakeIntegerTraceSourceAccessor (&AttributeObjectTest::DoSetIntSrc, &AttributeObjectTest::DoGetIntSrc), MakeIntegerChecker ()) + .AddTraceSource ("Source1", "help test", + MakeTraceSourceAccessor (&AttributeObjectTest::m_intSrc1)) ; return tid; @@ -385,6 +392,15 @@ AttributeTest::RunTests (void) 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; } diff --git a/src/core/integer-trace-source.h b/src/core/integer-trace-source.h index ae5d622c3..467b4b121 100644 --- a/src/core/integer-trace-source.h +++ b/src/core/integer-trace-source.h @@ -39,10 +39,10 @@ public: 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: diff --git a/src/core/object.cc b/src/core/object.cc index 3137d334e..901abe640 100644 --- a/src/core/object.cc +++ b/src/core/object.cc @@ -23,6 +23,7 @@ #include "singleton.h" #include "trace-resolver.h" #include "attribute.h" +#include "trace-source-accessor.h" #include "log.h" #include #include @@ -66,6 +67,15 @@ public: ns3::Attribute GetAttributeInitialValue (uint16_t uid, uint32_t i) const; ns3::Ptr GetAttributeAccessor (uint16_t uid, uint32_t i) const; ns3::Ptr GetAttributeChecker (uint16_t uid, uint32_t i) const; + void AddTraceSource (uint16_t uid, + std::string name, + std::string help, + ns3::Ptr 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 GetTraceSourceAccessor (uint16_t uid, uint32_t i) const; + private: struct ConstructorInformation { ns3::CallbackBase cb; @@ -79,6 +89,11 @@ private: ns3::Ptr param; ns3::Ptr checker; }; + struct TraceSourceInformation { + std::string name; + std::string help; + ns3::Ptr accessor; + }; struct IidInformation { std::string name; uint16_t parent; @@ -86,6 +101,7 @@ private: std::string groupName; std::vector constructors; std::vector attributes; + std::vector traceSources; }; typedef std::vector::const_iterator Iterator; @@ -313,6 +329,47 @@ IidManager::GetAttributeChecker (uint16_t uid, uint32_t i) const return information->attributes[i].checker; } +void +IidManager::AddTraceSource (uint16_t uid, + std::string name, + std::string help, + ns3::Ptr 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 +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 @@ TypeId::GetAttributeChecker (uint32_t i) const return checker; } +uint32_t +TypeId::GetTraceSourceN (void) const +{ + return Singleton::Get ()->GetTraceSourceN (m_tid); +} +std::string +TypeId::GetTraceSourceName (uint32_t i) const +{ + return Singleton::Get ()->GetTraceSourceName (m_tid, i); +} +std::string +TypeId::GetTraceSourceHelp (uint32_t i) const +{ + return Singleton::Get ()->GetTraceSourceHelp (m_tid, i); +} +Ptr +TypeId::GetTraceSourceAccessor (uint32_t i) const +{ + return Singleton::Get ()->GetTraceSourceAccessor (m_tid, i); +} + +TypeId +TypeId::AddTraceSource (std::string name, + std::string help, + Ptr accessor) +{ + Singleton::Get ()->AddTraceSource (m_tid, name, help, accessor); + return *this; +} + + +Ptr +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 @@ Object::GetAttribute (std::string name) const return value; } +bool +Object::TraceSourceConnect (std::string name, const CallbackBase &cb) +{ + Ptr 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 accessor = m_tid.LookupTraceSourceByName (name); + if (accessor == 0) + { + return false; + } + bool ok = accessor->Disconnect (this, cb); + return ok; +} + + Ptr Object::DoGetObject (TypeId tid) const { diff --git a/src/core/object.h b/src/core/object.h index f3ba1a1ca..795fd2197 100644 --- a/src/core/object.h +++ b/src/core/object.h @@ -47,6 +47,7 @@ class Object; class AttributeAccessor; class AttributeValue; class AttributeList; +class TraceSourceAccessor; /** * \brief a unique identifier for an interface. @@ -140,6 +141,11 @@ public: 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 GetTraceSourceAccessor (uint32_t i) const; + Ptr CreateObject (const AttributeList &attributes) const; @@ -227,9 +233,13 @@ public: std::string help, uint32_t flags, Attribute initialValue, - Ptr spec, + Ptr accessor, Ptr checker); + TypeId AddTraceSource (std::string name, + std::string help, + Ptr accessor); + // construct an invalid TypeId. TypeId (); ~TypeId (); @@ -246,6 +256,8 @@ private: Ptr checker; }; + Ptr 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 @@ public: */ 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 diff --git a/src/core/trace-source-accessor.cc b/src/core/trace-source-accessor.cc new file mode 100644 index 000000000..42c03d50a --- /dev/null +++ b/src/core/trace-source-accessor.cc @@ -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 diff --git a/src/core/trace-source-accessor.h b/src/core/trace-source-accessor.h new file mode 100644 index 000000000..a8e1a8464 --- /dev/null +++ b/src/core/trace-source-accessor.h @@ -0,0 +1,71 @@ +#ifndef TRACE_SOURCE_ACCESSOR_H +#define TRACE_SOURCE_ACCESSOR_H + +#include +#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 +Ptr MakeTraceSourceAccessor (T a); + +} // namespace ns3 + +namespace ns3 { + +template +Ptr +DoMakeTraceSourceAccessor (SOURCE T::*a) +{ + struct Accessor : public TraceSourceAccessor + { + virtual bool Connect (ObjectBase *obj, const CallbackBase &cb) const { + T *p = dynamic_cast (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 (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 (accessor, false); +} + +template +Ptr MakeTraceSourceAccessor (T a) +{ + return DoMakeTraceSourceAccessor (a); +} + +} // namespace ns3 + + +#endif /* TRACE_SOURCE_ACCESSOR_H */ diff --git a/src/core/wscript b/src/core/wscript index 57146e5ff..bb9099b72 100644 --- a/src/core/wscript +++ b/src/core/wscript @@ -64,6 +64,7 @@ def build(bld): 'object-vector.cc', 'initial-value.cc', 'event-trace-source.cc', + 'trace-source-accessor.cc', ] if sys.platform == 'win32': @@ -119,5 +120,7 @@ def build(bld): 'attribute-helper.h', 'initial-value.h', 'event-trace-source.h', + 'integer-trace-source.h', + 'trace-source-accessor.h', ]