From 658cc9cd2333d825701978fd351ee00b70f53213 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Mon, 7 May 2007 13:21:29 +0200 Subject: [PATCH] rework and document API --- src/core/ns-unknown-manager.cc | 37 ++--- src/core/ns-unknown-manager.h | 240 ++++++++++++++++++++++++++------- 2 files changed, 210 insertions(+), 67 deletions(-) diff --git a/src/core/ns-unknown-manager.cc b/src/core/ns-unknown-manager.cc index 2142dbb97..6b18a5389 100644 --- a/src/core/ns-unknown-manager.cc +++ b/src/core/ns-unknown-manager.cc @@ -34,6 +34,16 @@ ClassId::ClassId (std::string name) : m_classId (Singleton::Get ()->Allocate (name)) {} +ClassId::ClassId (uint32_t classId) + : m_classId (classId) +{} + +std::string +ClassId::GetName (void) +{ + return Singleton::Get ()->LookupByUid (m_classId); +} + bool operator == (const ClassId &a, const ClassId &b) { return a.m_classId == b.m_classId; @@ -42,18 +52,8 @@ bool operator == (const ClassId &a, const ClassId &b) NsUnknown * NsUnknownManager::Create (ClassId classId) { - CallbackBase *callback = Lookup (classId); - if (callback == 0) - { - return 0; - } - Callback reference; - if (reference.CheckType (*callback)) - { - reference = *static_cast *> (callback); - return reference (); - } - return 0; + Callback callback = DoGetCallback (classId); + return callback (); } CallbackBase * @@ -70,6 +70,12 @@ NsUnknownManager::Lookup (ClassId classId) return 0; } +ClassId +NsUnknownManager::LookupByName (std::string name) +{ + return ClassId (Singleton::Get ()->LookupByName (name)); +} + void NsUnknownManager::Register (ClassId classId, CallbackBase *callback) { @@ -78,7 +84,6 @@ NsUnknownManager::Register (ClassId classId, CallbackBase *callback) } - } // namespace ns3 #ifdef RUN_SELF_TESTS @@ -108,9 +113,9 @@ public: int m_int; }; -const ns3::ClassId A::cidZero = ns3::MakeClassId ("A"); -const ns3::ClassId A::cidOneBool = ns3::MakeClassId ("ABool"); -const ns3::ClassId A::cidOneInt = ns3::MakeClassId ("AInt"); +const ns3::ClassId A::cidZero = ns3::NsUnknownManager::RegisterConstructor ("A"); +const ns3::ClassId A::cidOneBool = ns3::NsUnknownManager::RegisterConstructor ("ABool"); +const ns3::ClassId A::cidOneInt = ns3::NsUnknownManager::RegisterConstructor ("AInt"); const ns3::Iid A::iid ("IA"); A::A () diff --git a/src/core/ns-unknown-manager.h b/src/core/ns-unknown-manager.h index 20def8860..e2eb11b3d 100644 --- a/src/core/ns-unknown-manager.h +++ b/src/core/ns-unknown-manager.h @@ -26,37 +26,99 @@ #include #include "callback.h" #include "ns-unknown.h" +#include "fatal-error.h" namespace ns3 { +/** + * \brief Unique Identifier for class constructors. + * + * Instances of this type must be allocated through + * the ns3::Ns3UnknownManager::RegisterConstructor methods + */ class ClassId { 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: + ClassId (std::string name); + ClassId (uint32_t classId); + friend class NsUnknownManager; friend bool operator == (const ClassId &a, const ClassId &b); uint32_t m_classId; }; -template -ClassId -MakeClassId (std::string name); - -template -ClassId -MakeClassId (std::string name); - +/** + * \brief Create any NsUnknown + * + * This class keeps track of a set of ClassId, each + * of which uniquely identifies the constructor of an + * object which derives from the NsUnknown base class. + * This class can also create an instance of any of + * the objects tracked through any of their tracked + * constructor/ClassId. + */ class NsUnknownManager { 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); + /** + * \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 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 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 static T *Create (ClassId classId, Iid iid); @@ -66,45 +128,76 @@ public: template 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 + 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 + 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 + static ClassId RegisterConstructor (std::string name); private: + static void Register (ClassId classId, CallbackBase *callback); + + template + static Callback DoGetCallback (ClassId classId); + + template + static NsUnknown *MakeObjectZero (void); + + template + static NsUnknown *MakeObjectOne (T1 a1); + + template + static NsUnknown *MakeObjectTwo (T1 a1, T2 a2); + typedef std::vector > List; static List *GetList (void); static CallbackBase *Lookup (ClassId classId); }; -template -NsUnknown * -MakeNsUnknownObjectZero (void) -{ - return new T (); -} -template -NsUnknown * -MakeNsUnknownObjectOne (T1 a1) -{ - return new T (a1); -} +} // namespace ns3 -template -ClassId -MakeClassId (std::string name) -{ - ClassId classId = ClassId (name); - static Callback callback = MakeCallback (&MakeNsUnknownObjectZero); - NsUnknownManager::Register (classId, &callback); - return classId; -} +namespace ns3 { -template -ClassId -MakeClassId (std::string name) +template +Callback +NsUnknownManager::DoGetCallback (ClassId classId) { - ClassId classId = ClassId (name); - static Callback callback = MakeCallback (&MakeNsUnknownObjectOne); - NsUnknownManager::Register (classId, &callback); - return classId; + CallbackBase *callback = Lookup (classId); + if (callback == 0) + { + NS_FATAL_ERROR ("Invalid Class Id."); + } + Callback reference; + if (!reference.CheckType (*callback)) + { + NS_FATAL_ERROR ("Incompatible types."); + } + reference = *static_cast *> (callback); + return reference; } @@ -112,25 +205,16 @@ template NsUnknown * NsUnknownManager::Create (ClassId classId, T1 a1) { - CallbackBase *callback = Lookup (classId); - if (callback == 0) - { - return 0; - } - Callback reference; - if (reference.CheckType (*callback)) - { - reference = *static_cast *> (callback); - return reference (a1); - } - return 0; + Callback callback = DoGetCallback (classId); + return callback (a1); } template NsUnknown * NsUnknownManager::Create (ClassId classId, T1 a1, T2 a2) { - return 0; + Callback callback = DoGetCallback (classId); + return callback (a1, a2); } template @@ -139,6 +223,7 @@ NsUnknownManager::Create (ClassId classId, Iid iid) { NsUnknown *obj = Create (classId); T *i = obj->QueryInterface (iid); + obj->Unref (); return i; } @@ -148,6 +233,7 @@ NsUnknownManager::Create (ClassId classId, Iid iid, T1 a1) { NsUnknown *obj = Create (classId, a1); T *i = obj->QueryInterface (iid); + obj->Unref (); return i; } @@ -157,10 +243,62 @@ NsUnknownManager::Create (ClassId classId, Iid iid, T1 a1, T2 a2) { NsUnknown *obj = Create (classId, a1, a2); T *i = obj->QueryInterface (iid); + obj->Unref (); return i; } +template +NsUnknown * +NsUnknownManager::MakeObjectZero (void) +{ + return new T (); +} +template +NsUnknown * +NsUnknownManager::MakeObjectOne (T1 a1) +{ + return new T (a1); +} +template +NsUnknown * +NsUnknownManager::MakeObjectTwo (T1 a1, T2 a2) +{ + return new T (a1, a2); +} + + +template +ClassId +NsUnknownManager::RegisterConstructor (std::string name) +{ + ClassId classId = ClassId (name); + static Callback callback = MakeCallback (&NsUnknownManager::MakeObjectZero); + NsUnknownManager::Register (classId, &callback); + return classId; +} + +template +ClassId +NsUnknownManager::RegisterConstructor (std::string name) +{ + ClassId classId = ClassId (name); + static Callback callback = MakeCallback (&NsUnknownManager::MakeObjectOne); + NsUnknownManager::Register (classId, &callback); + return classId; +} + +template +ClassId +NsUnknownManager::RegisterConstructor (std::string name) +{ + ClassId classId = ClassId (name); + static Callback callback = MakeCallback (&NsUnknownManager::MakeObjectTwo); + NsUnknownManager::Register (classId, &callback); + return classId; +} + + } // namespace ns3