rework and document API

Mathieu Lacage 2007-05-07 13:21:29 +02:00
parent aa4cf039bf
commit 658cc9cd23
2 changed files with 210 additions and 67 deletions

View File

@ -34,6 +34,16 @@ ClassId::ClassId (std::string name)
: m_classId (Singleton<CidManager>::Get ()->Allocate (name)) : m_classId (Singleton<CidManager>::Get ()->Allocate (name))
{} {}
ClassId::ClassId (uint32_t classId)
: m_classId (classId)
{}
std::string
ClassId::GetName (void)
{
return Singleton<CidManager>::Get ()->LookupByUid (m_classId);
}
bool operator == (const ClassId &a, const ClassId &b) bool operator == (const ClassId &a, const ClassId &b)
{ {
return a.m_classId == b.m_classId; return a.m_classId == b.m_classId;
@ -42,18 +52,8 @@ bool operator == (const ClassId &a, const ClassId &b)
NsUnknown * NsUnknown *
NsUnknownManager::Create (ClassId classId) NsUnknownManager::Create (ClassId classId)
{ {
CallbackBase *callback = Lookup (classId); Callback<NsUnknown *> callback = DoGetCallback<empty,empty,empty,empty,empty> (classId);
if (callback == 0) return callback ();
{
return 0;
}
Callback<NsUnknown *> reference;
if (reference.CheckType (*callback))
{
reference = *static_cast<Callback<NsUnknown *> *> (callback);
return reference ();
}
return 0;
} }
CallbackBase * CallbackBase *
@ -70,6 +70,12 @@ NsUnknownManager::Lookup (ClassId classId)
return 0; return 0;
} }
ClassId
NsUnknownManager::LookupByName (std::string name)
{
return ClassId (Singleton<CidManager>::Get ()->LookupByName (name));
}
void void
NsUnknownManager::Register (ClassId classId, CallbackBase *callback) NsUnknownManager::Register (ClassId classId, CallbackBase *callback)
{ {
@ -78,7 +84,6 @@ NsUnknownManager::Register (ClassId classId, CallbackBase *callback)
} }
} // namespace ns3 } // namespace ns3
#ifdef RUN_SELF_TESTS #ifdef RUN_SELF_TESTS
@ -108,9 +113,9 @@ public:
int m_int; int m_int;
}; };
const ns3::ClassId A::cidZero = ns3::MakeClassId <A> ("A"); const ns3::ClassId A::cidZero = ns3::NsUnknownManager::RegisterConstructor <A> ("A");
const ns3::ClassId A::cidOneBool = ns3::MakeClassId <A,bool> ("ABool"); const ns3::ClassId A::cidOneBool = ns3::NsUnknownManager::RegisterConstructor <A,bool> ("ABool");
const ns3::ClassId A::cidOneInt = ns3::MakeClassId <A,int> ("AInt"); const ns3::ClassId A::cidOneInt = ns3::NsUnknownManager::RegisterConstructor <A,int> ("AInt");
const ns3::Iid A::iid ("IA"); const ns3::Iid A::iid ("IA");
A::A () A::A ()

View File

@ -26,37 +26,99 @@
#include <stdint.h> #include <stdint.h>
#include "callback.h" #include "callback.h"
#include "ns-unknown.h" #include "ns-unknown.h"
#include "fatal-error.h"
namespace ns3 { namespace ns3 {
/**
* \brief Unique Identifier for class constructors.
*
* Instances of this type must be allocated through
* the ns3::Ns3UnknownManager::RegisterConstructor methods
*/
class ClassId class ClassId
{ {
public: public:
ClassId (std::string name); /**
* \returns the symbolic name associated to this class id
*
* This name is the name which was associated to this class id
* by the ns3::Ns3UnknownManager::RegisterConstructor methods.
* This name is also the name which is expected to be input
* to ns3::UnknownManager::LookupByName.
*/
std::string GetName (void);
private: private:
ClassId (std::string name);
ClassId (uint32_t classId);
friend class NsUnknownManager;
friend bool operator == (const ClassId &a, const ClassId &b); friend bool operator == (const ClassId &a, const ClassId &b);
uint32_t m_classId; uint32_t m_classId;
}; };
template <typename T> /**
ClassId * \brief Create any NsUnknown
MakeClassId (std::string name); *
* This class keeps track of a set of ClassId, each
template <typename T, typename T1> * of which uniquely identifies the constructor of an
ClassId * object which derives from the NsUnknown base class.
MakeClassId (std::string name); * This class can also create an instance of any of
* the objects tracked through any of their tracked
* constructor/ClassId.
*/
class NsUnknownManager class NsUnknownManager
{ {
public: public:
/**
* \param name the symbolic name to lookup
* \returns the ClassId associated to the input name.
*/
static ClassId LookupByName (std::string name);
/**
* \param classId class id of the constructor to invoke.
* \return a pointer to the instance created.
*
* Create an instance of the object identified by its
* ClassId. This method invokes the default constructor.
*/
static NsUnknown *Create (ClassId classId); static NsUnknown *Create (ClassId classId);
/**
* \param classId class id of the constructor to invoke.
* \param a1 argument to pass to the constructor.
* \return a pointer to the instance created.
* \overload NsUnknown *Create (ClassId)
*
* Create an instance of the object identified by its
* ClassId.
*/
template <typename T1> template <typename T1>
static NsUnknown *Create (ClassId classId, T1 a1); static NsUnknown *Create (ClassId classId, T1 a1);
/**
* \param classId class id of the constructor to invoke.
* \param a1 first argument to pass to the constructor.
* \param a2 second argument to pass to the constructor.
* \return a pointer to the instance created.
* \overload NsUnknown *Create (ClassId)
*
* Create an instance of the object identified by its
* ClassId.
*/
template <typename T1, typename T2> template <typename T1, typename T2>
static NsUnknown *Create (ClassId classId, T1 a1, T2 a2); static NsUnknown *Create (ClassId classId, T1 a1, T2 a2);
/**
* \param classId class id of the constructor to invoke.
* \param iid interface id to query for
* \return a pointer to the instance created.
* \overload NsUnknown *Create (ClassId)
*
* Create an instance of the object identified by its
* ClassId, call QueryInterface on it, and return the
* result.
*/
template <typename T> template <typename T>
static T *Create (ClassId classId, Iid iid); static T *Create (ClassId classId, Iid iid);
@ -66,45 +128,76 @@ public:
template <typename T, typename T1, typename T2> template <typename T, typename T1, typename T2>
static T *Create (ClassId classId, Iid iid, T1 a1, T2 a2); static T *Create (ClassId classId, Iid iid, T1 a1, T2 a2);
static void Register (ClassId classId, CallbackBase *callback); /**
* \param name the symbolic name to associate to this
* constructor
* \returns a ClassId which uniquely identifies this constructor.
*/
template <typename T>
static ClassId RegisterConstructor (std::string name);
/**
* \param name the symbolic name to associate to this
* constructor
* \returns a ClassId which uniquely identifies this constructor.
* \overload ClassIdRegisterConstructor (std::string)
*/
template <typename T, typename T1>
static ClassId RegisterConstructor (std::string name);
/**
* \param name the symbolic name to associate to this
* constructor
* \returns a ClassId which uniquely identifies this constructor.
* \overload ClassIdRegisterConstructor (std::string)
*/
template <typename T, typename T1, typename T2>
static ClassId RegisterConstructor (std::string name);
private: private:
static void Register (ClassId classId, CallbackBase *callback);
template <typename T1, typename T2,
typename T3, typename T4,
typename T5>
static Callback<NsUnknown *,T1,T2,T3,T4,T5> DoGetCallback (ClassId classId);
template <typename T>
static NsUnknown *MakeObjectZero (void);
template <typename T, typename T1>
static NsUnknown *MakeObjectOne (T1 a1);
template <typename T, typename T1, typename T2>
static NsUnknown *MakeObjectTwo (T1 a1, T2 a2);
typedef std::vector<std::pair<ClassId, CallbackBase *> > List; typedef std::vector<std::pair<ClassId, CallbackBase *> > List;
static List *GetList (void); static List *GetList (void);
static CallbackBase *Lookup (ClassId classId); static CallbackBase *Lookup (ClassId classId);
}; };
template <typename T> } // namespace ns3
NsUnknown *
MakeNsUnknownObjectZero (void)
{
return new T ();
}
template <typename T, typename T1>
NsUnknown *
MakeNsUnknownObjectOne (T1 a1)
{
return new T (a1);
}
template <typename T> namespace ns3 {
ClassId
MakeClassId (std::string name)
{
ClassId classId = ClassId (name);
static Callback<NsUnknown *> callback = MakeCallback (&MakeNsUnknownObjectZero<T>);
NsUnknownManager::Register (classId, &callback);
return classId;
}
template <typename T, typename T1> template <typename T1, typename T2,
ClassId typename T3, typename T4,
MakeClassId (std::string name) typename T5>
Callback<NsUnknown *,T1,T2,T3,T4,T5>
NsUnknownManager::DoGetCallback (ClassId classId)
{ {
ClassId classId = ClassId (name); CallbackBase *callback = Lookup (classId);
static Callback<NsUnknown *, T1> callback = MakeCallback (&MakeNsUnknownObjectOne<T,T1>); if (callback == 0)
NsUnknownManager::Register (classId, &callback); {
return classId; NS_FATAL_ERROR ("Invalid Class Id.");
}
Callback<NsUnknown *, T1,T2,T3,T4,T5> reference;
if (!reference.CheckType (*callback))
{
NS_FATAL_ERROR ("Incompatible types.");
}
reference = *static_cast<Callback<NsUnknown *,T1,T2,T3,T4,T5> *> (callback);
return reference;
} }
@ -112,25 +205,16 @@ template <typename T1>
NsUnknown * NsUnknown *
NsUnknownManager::Create (ClassId classId, T1 a1) NsUnknownManager::Create (ClassId classId, T1 a1)
{ {
CallbackBase *callback = Lookup (classId); Callback<NsUnknown *, T1> callback = DoGetCallback<T1,empty,empty,empty,empty> (classId);
if (callback == 0) return callback (a1);
{
return 0;
}
Callback<NsUnknown *, T1> reference;
if (reference.CheckType (*callback))
{
reference = *static_cast<Callback<NsUnknown *,T1> *> (callback);
return reference (a1);
}
return 0;
} }
template <typename T1, typename T2> template <typename T1, typename T2>
NsUnknown * NsUnknown *
NsUnknownManager::Create (ClassId classId, T1 a1, T2 a2) NsUnknownManager::Create (ClassId classId, T1 a1, T2 a2)
{ {
return 0; Callback<NsUnknown *, T1,T2> callback = DoGetCallback<T1,T2,empty,empty,empty> (classId);
return callback (a1, a2);
} }
template <typename T> template <typename T>
@ -139,6 +223,7 @@ NsUnknownManager::Create (ClassId classId, Iid iid)
{ {
NsUnknown *obj = Create (classId); NsUnknown *obj = Create (classId);
T *i = obj->QueryInterface<T> (iid); T *i = obj->QueryInterface<T> (iid);
obj->Unref ();
return i; return i;
} }
@ -148,6 +233,7 @@ NsUnknownManager::Create (ClassId classId, Iid iid, T1 a1)
{ {
NsUnknown *obj = Create (classId, a1); NsUnknown *obj = Create (classId, a1);
T *i = obj->QueryInterface<T> (iid); T *i = obj->QueryInterface<T> (iid);
obj->Unref ();
return i; return i;
} }
@ -157,10 +243,62 @@ NsUnknownManager::Create (ClassId classId, Iid iid, T1 a1, T2 a2)
{ {
NsUnknown *obj = Create (classId, a1, a2); NsUnknown *obj = Create (classId, a1, a2);
T *i = obj->QueryInterface<T> (iid); T *i = obj->QueryInterface<T> (iid);
obj->Unref ();
return i; return i;
} }
template <typename T>
NsUnknown *
NsUnknownManager::MakeObjectZero (void)
{
return new T ();
}
template <typename T, typename T1>
NsUnknown *
NsUnknownManager::MakeObjectOne (T1 a1)
{
return new T (a1);
}
template <typename T, typename T1, typename T2>
NsUnknown *
NsUnknownManager::MakeObjectTwo (T1 a1, T2 a2)
{
return new T (a1, a2);
}
template <typename T>
ClassId
NsUnknownManager::RegisterConstructor (std::string name)
{
ClassId classId = ClassId (name);
static Callback<NsUnknown *> callback = MakeCallback (&NsUnknownManager::MakeObjectZero<T>);
NsUnknownManager::Register (classId, &callback);
return classId;
}
template <typename T, typename T1>
ClassId
NsUnknownManager::RegisterConstructor (std::string name)
{
ClassId classId = ClassId (name);
static Callback<NsUnknown *,T1> callback = MakeCallback (&NsUnknownManager::MakeObjectOne<T,T1>);
NsUnknownManager::Register (classId, &callback);
return classId;
}
template <typename T, typename T1, typename T2>
ClassId
NsUnknownManager::RegisterConstructor (std::string name)
{
ClassId classId = ClassId (name);
static Callback<NsUnknown *,T1, T2> callback = MakeCallback (&NsUnknownManager::MakeObjectTwo<T,T1, T2>);
NsUnknownManager::Register (classId, &callback);
return classId;
}
} // namespace ns3 } // namespace ns3