--- a/src/core/object.cc Wed Jan 02 13:40:37 2008 +0100
+++ b/src/core/object.cc Wed Jan 02 15:54:53 2008 +0100
@@ -38,13 +38,20 @@
public:
uint16_t AllocateUid (std::string name);
void SetParent (uint16_t uid, uint16_t parent);
+ void AddConstructor (uint16_t uid, ns3::CallbackBase callback, uint32_t nArguments);
uint16_t GetUid (std::string name) const;
std::string GetName (uint16_t uid) const;
uint16_t GetParent (uint16_t uid) const;
+ ns3::CallbackBase GetConstructor (uint16_t uid, uint32_t nArguments);
private:
+ struct ConstructorInformation {
+ ns3::CallbackBase cb;
+ uint32_t nArguments;
+ };
struct IidInformation {
std::string name;
uint16_t parent;
+ std::vector<struct ConstructorInformation> constructors;
};
typedef std::vector<struct IidInformation>::const_iterator Iterator;
@@ -89,6 +96,24 @@
struct IidInformation *information = LookupInformation (uid);
information->parent = parent;
}
+void
+IidManager::AddConstructor (uint16_t uid, ns3::CallbackBase callback, uint32_t nArguments)
+{
+ struct IidInformation *information = LookupInformation (uid);
+ struct ConstructorInformation constructor;
+ constructor.cb = callback;
+ constructor.nArguments = nArguments;
+ for (std::vector<struct ConstructorInformation>::const_iterator i = information->constructors.begin ();
+ i != information->constructors.end (); i++)
+ {
+ if (i->nArguments == nArguments)
+ {
+ NS_FATAL_ERROR ("registered two constructors on the same type with the same number of arguments.");
+ break;
+ }
+ }
+ information->constructors.push_back (constructor);
+}
uint16_t
IidManager::GetUid (std::string name) const
@@ -117,6 +142,21 @@
struct IidInformation *information = LookupInformation (uid);
return information->parent;
}
+ns3::CallbackBase
+IidManager::GetConstructor (uint16_t uid, uint32_t nArguments)
+{
+ struct IidInformation *information = LookupInformation (uid);
+ for (std::vector<struct ConstructorInformation>::const_iterator i = information->constructors.begin ();
+ i != information->constructors.end (); i++)
+ {
+ if (i->nArguments == nArguments)
+ {
+ return i->cb;
+ }
+ }
+ NS_FATAL_ERROR ("Requested constructor with "<<nArguments<<" arguments not found");
+ return ns3::CallbackBase ();
+}
} // anonymous namespace
@@ -191,6 +231,13 @@
* The InterfaceId class
*********************************************************************/
+InterfaceId::InterfaceId (std::string name)
+{
+ uint16_t uid = Singleton<IidManager>::Get ()->AllocateUid (name);
+ NS_ASSERT (uid != 0);
+ m_iid = uid;
+}
+
InterfaceId::InterfaceId (uint16_t iid)
: m_iid (iid)
@@ -205,6 +252,12 @@
return InterfaceId (uid);
}
InterfaceId
+InterfaceId::SetParent (InterfaceId iid)
+{
+ Singleton<IidManager>::Get ()->SetParent (m_iid, iid.m_iid);
+ return *this;
+}
+InterfaceId
InterfaceId::GetParent (void) const
{
uint16_t parent = Singleton<IidManager>::Get ()->GetParent (m_iid);
@@ -217,6 +270,29 @@
return name;
}
+void
+InterfaceId::DoAddConstructor (CallbackBase cb, uint32_t nArguments)
+{
+ Singleton<IidManager>::Get ()->AddConstructor (m_iid, cb, nArguments);
+}
+
+CallbackBase
+InterfaceId::LookupConstructor (uint32_t nArguments)
+{
+ CallbackBase constructor = Singleton<IidManager>::Get ()->GetConstructor (m_iid, nArguments);
+ return constructor;
+}
+
+Ptr<Object>
+InterfaceId::CreateObject (void)
+{
+ CallbackBase cb = LookupConstructor (0);
+ Callback<Ptr<Object> > realCb;
+ realCb.Assign (cb);
+ Ptr<Object> object = realCb ();
+ return object;
+}
+
bool operator == (InterfaceId a, InterfaceId b)
{
return a.m_iid == b.m_iid;
@@ -486,7 +562,9 @@
{
public:
static ns3::InterfaceId iid (void) {
- static ns3::InterfaceId iid = ns3::MakeInterfaceId ("BaseA", Object::iid ());
+ static ns3::InterfaceId iid = ns3::InterfaceId ("BaseA")
+ .SetParent (Object::iid ())
+ .AddConstructor<BaseA> ();
return iid;
}
BaseA ()
@@ -509,7 +587,9 @@
{
public:
static ns3::InterfaceId iid (void) {
- static ns3::InterfaceId iid = ns3::MakeInterfaceId ("DerivedA", BaseA::iid ());
+ static ns3::InterfaceId iid = ns3::InterfaceId ("DerivedA")
+ .SetParent (BaseA::iid ())
+ .AddConstructor<DerivedA,int> ();
return iid;
}
DerivedA (int v)
@@ -534,7 +614,9 @@
{
public:
static ns3::InterfaceId iid (void) {
- static ns3::InterfaceId iid = ns3::MakeInterfaceId ("BaseB", Object::iid ());
+ static ns3::InterfaceId iid = ns3::InterfaceId ("BaseB")
+ .SetParent (Object::iid ())
+ .AddConstructor<BaseB> ();
return iid;
}
BaseB ()
@@ -557,7 +639,9 @@
{
public:
static ns3::InterfaceId iid (void) {
- static ns3::InterfaceId iid = ns3::MakeInterfaceId ("DerivedB", BaseB::iid ());
+ static ns3::InterfaceId iid = ns3::InterfaceId ("DerivedB")
+ .SetParent (BaseB::iid ())
+ .AddConstructor<DerivedB,int> ();
return iid;
}
DerivedB (int v)
@@ -739,6 +823,17 @@
NS_TEST_ASSERT (m_derivedATrace);
baseB->TraceDisconnect ("/$DerivedA/*", MakeCallback (&ObjectTest::BaseATrace, this));
+ // Test the object creation code of InterfaceId
+ Ptr<Object> a = BaseA::iid ().CreateObject ();
+ NS_TEST_ASSERT_EQUAL (a->QueryInterface<BaseA> (), a);
+ NS_TEST_ASSERT_EQUAL (a->QueryInterface<BaseA> (DerivedA::iid ()), 0);
+ NS_TEST_ASSERT_EQUAL (a->QueryInterface<DerivedA> (), 0);
+ a = DerivedA::iid ().CreateObject (10);
+ NS_TEST_ASSERT_EQUAL (a->QueryInterface<BaseA> (), a);
+ NS_TEST_ASSERT_EQUAL (a->QueryInterface<BaseA> (DerivedA::iid ()), a);
+ NS_TEST_ASSERT_UNEQUAL (a->QueryInterface<DerivedA> (), 0);
+
+
return result;
}
--- a/src/core/object.h Wed Jan 02 13:40:37 2008 +0100
+++ b/src/core/object.h Wed Jan 02 15:54:53 2008 +0100
@@ -25,11 +25,14 @@
#include <string>
#include "ptr.h"
#include "trace-resolver.h"
+#include "callback.h"
+#include "empty.h"
namespace ns3 {
class TraceContext;
class CallbackBase;
+class Object;
/**
* \brief a unique identifier for an interface.
@@ -65,13 +68,47 @@
* \returns the name of this interface.
*/
std::string GetName (void) const;
+
+ InterfaceId (std::string);
+
+ InterfaceId SetParent (InterfaceId iid);
+ template <typename T>
+ InterfaceId AddConstructor (void);
+ template <typename T, typename T1>
+ InterfaceId AddConstructor (void);
+ template <typename T, typename T1, typename T2>
+ InterfaceId AddConstructor (void);
+ template <typename T, typename T1, typename T2, typename T3>
+ InterfaceId AddConstructor (void);
+ template <typename T, typename T1, typename T2, typename T3, typename T4>
+ InterfaceId AddConstructor (void);
+ template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
+ InterfaceId AddConstructor (void);
+
+
+ Ptr<Object> CreateObject (void);
+ template <typename T1>
+ Ptr<Object> CreateObject (T1 a1);
+ template <typename T1, typename T2>
+ Ptr<Object> CreateObject (T1 a1, T2 a2);
+ template <typename T1, typename T2, typename T3>
+ Ptr<Object> CreateObject (T1 a1, T2 a2, T3 a3);
+ template <typename T1, typename T2, typename T3, typename T4>
+ Ptr<Object> CreateObject (T1 a1, T2 a2, T3 a3, T4 a4);
+ template <typename T1, typename T2, typename T3, typename T4, typename T5>
+ Ptr<Object> CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
+
~InterfaceId ();
private:
- InterfaceId (uint16_t iid);
friend InterfaceId MakeInterfaceId (std::string name, InterfaceId parent);
friend InterfaceId MakeObjectInterfaceId (void);
friend bool operator == (InterfaceId a, InterfaceId b);
friend bool operator != (InterfaceId a, InterfaceId b);
+
+ InterfaceId (uint16_t iid);
+ void DoAddConstructor (CallbackBase callback, uint32_t nArguments);
+ CallbackBase LookupConstructor (uint32_t nArguments);
+
uint16_t m_iid;
};
@@ -245,6 +282,139 @@
namespace ns3 {
+
+template <typename T>
+InterfaceId
+InterfaceId::AddConstructor (void)
+{
+ struct Maker {
+ static Ptr<Object> Create (void) {
+ return ns3::CreateObject<T> ();
+ }
+ };
+ CallbackBase cb = MakeCallback (&Maker::Create);
+ DoAddConstructor (cb, 0);
+ return *this;
+}
+template <typename T, typename T1>
+InterfaceId
+InterfaceId::AddConstructor (void)
+{
+ struct Maker {
+ static Ptr<Object> Create (T1 a1) {
+ return ns3::CreateObject<T> (a1);
+ }
+ };
+ CallbackBase cb = MakeCallback (&Maker::Create);
+ DoAddConstructor (cb, 1);
+ return *this;
+}
+template <typename T, typename T1, typename T2>
+InterfaceId
+InterfaceId::AddConstructor (void)
+{
+ struct Maker {
+ static Ptr<Object> Create (T1 a1, T2 a2) {
+ return ns3::CreateObject<T> (a1, a2);
+ }
+ };
+ CallbackBase cb = MakeCallback (&Maker::Create);
+ DoAddConstructor (cb, 2);
+ return *this;
+}
+template <typename T, typename T1, typename T2, typename T3>
+InterfaceId
+InterfaceId::AddConstructor (void)
+{
+ struct Maker {
+ static Ptr<Object> Create (T1 a1, T2 a2, T3 a3) {
+ return ns3::CreateObject<T> (a1, a2, a3);
+ }
+ };
+ CallbackBase cb = MakeCallback (&Maker::Create);
+ DoAddConstructor (cb, 3);
+ return *this;
+}
+template <typename T, typename T1, typename T2, typename T3, typename T4>
+InterfaceId
+InterfaceId::AddConstructor (void)
+{
+ struct Maker {
+ static Ptr<Object> Create (T1 a1, T2 a2, T3 a3, T4 a4) {
+ return ns3::CreateObject<T> (a1, a2, a3, a4);
+ }
+ };
+ CallbackBase cb = MakeCallback (&Maker::Create);
+ DoAddConstructor (cb, 4);
+ return *this;
+}
+template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
+InterfaceId
+InterfaceId::AddConstructor (void)
+{
+ struct Maker {
+ static Ptr<Object> Create (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) {
+ return ns3::CreateObject<T> (a1, a2, a3, a4, a5);
+ }
+ };
+ CallbackBase cb = MakeCallback (&Maker::Create);
+ DoAddConstructor (cb, 5);
+ return *this;
+}
+
+template <typename T1>
+Ptr<Object>
+InterfaceId::CreateObject (T1 a1)
+{
+ CallbackBase cb = LookupConstructor (1);
+ Callback<Ptr<Object>,T1> realCb;
+ realCb.Assign (cb);
+ Ptr<Object> object = realCb (a1);
+ return object;
+}
+template <typename T1, typename T2>
+Ptr<Object>
+InterfaceId::CreateObject (T1 a1, T2 a2)
+{
+ CallbackBase cb = LookupConstructor (2);
+ Callback<Ptr<Object>,T1,T2> realCb;
+ realCb.Assign (cb);
+ Ptr<Object> object = realCb (a1,a2);
+ return object;
+}
+template <typename T1, typename T2, typename T3>
+Ptr<Object>
+InterfaceId::CreateObject (T1 a1, T2 a2, T3 a3)
+{
+ CallbackBase cb = LookupConstructor (3);
+ Callback<Ptr<Object>,T1,T2,T3> realCb;
+ realCb.Assign (cb);
+ Ptr<Object> object = realCb (a1,a2,a3);
+ return object;
+}
+template <typename T1, typename T2, typename T3, typename T4>
+Ptr<Object>
+InterfaceId::CreateObject (T1 a1, T2 a2, T3 a3, T4 a4)
+{
+ CallbackBase cb = LookupConstructor (4);
+ Callback<Ptr<Object>,T1,T2,T3,T4> realCb;
+ realCb.Assign (cb);
+ Ptr<Object> object = realCb (a1,a2,a3,a4);
+ return object;
+}
+ template <typename T1, typename T2, typename T3, typename T4, typename T5>
+Ptr<Object>
+InterfaceId::CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
+{
+ CallbackBase cb = LookupConstructor (5);
+ Callback<Ptr<Object>,T1,T2,T3,T4,T5> realCb;
+ realCb.Assign (cb);
+ Ptr<Object> object = realCb (a1,a2,a3,a4,a5);
+ return object;
+}
+
+
+
void
Object::Ref (void) const
{