add 'factory' support to InterfaceId
This commit is contained in:
@@ -38,13 +38,20 @@ class IidManager
|
||||
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 @@ IidManager::SetParent (uint16_t uid, uint16_t parent)
|
||||
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 @@ IidManager::GetParent (uint16_t uid) const
|
||||
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 @@ InterfaceIdTraceResolver::TraceAll (std::ostream &os, const TraceContext &contex
|
||||
* 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 @@ InterfaceId::LookupByName (std::string name)
|
||||
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 @@ InterfaceId::GetName (void) const
|
||||
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 @@ class BaseA : public ns3::Object
|
||||
{
|
||||
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 @@ class DerivedA : public BaseA
|
||||
{
|
||||
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 @@ class BaseB : public ns3::Object
|
||||
{
|
||||
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 @@ class DerivedB : public BaseB
|
||||
{
|
||||
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 @@ ObjectTest::RunTests (void)
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 @@ public:
|
||||
* \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 @@ Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7);
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user