--- a/src/core/object.h Tue Feb 26 01:39:59 2008 +0100
+++ b/src/core/object.h Wed Feb 27 22:19:39 2008 +0100
@@ -26,13 +26,15 @@
#include "ptr.h"
#include "trace-resolver.h"
#include "callback.h"
-#include "empty.h"
+#include "attribute.h"
+#include "object-base.h"
+#include "attribute-helper.h"
#define NS_OBJECT_ENSURE_REGISTERED(type) \
static struct X##type##RegistrationClass \
{ \
X##type##RegistrationClass () { \
- ns3::TypeId tid = type::GetTypeId (); \
+ ns3::TypeId tid = type::GetTypeId (); \
tid.GetParent (); \
} \
} x_##type##RegistrationVariable
@@ -43,14 +45,30 @@
class TraceContext;
class CallbackBase;
class Object;
+class AttributeAccessor;
+class AttributeValue;
+class AttributeList;
+class TraceSourceAccessor;
/**
* \brief a unique identifier for an interface.
*
+ * This class records a lot of meta-information about a
+ * subclass of the Object base class:
+ * - the base class of the subclass
+ * - the set of accessible constructors in the subclass
+ * - the set of 'attributes' accessible in the subclass
*/
class TypeId
{
public:
+ enum {
+ ATTR_GET = 1<<0,
+ ATTR_SET = 1<<1,
+ ATTR_CONSTRUCT = 1<<2,
+ ATTR_SGC = ATTR_GET | ATTR_SET | ATTR_CONSTRUCT,
+ };
+
/**
* \param name the name of the requested interface
* \returns the unique id associated with the requested
@@ -60,8 +78,24 @@
* name is not a valid interface name.
*/
static TypeId LookupByName (std::string name);
+
+ /**
+ * \returns the number of TypeId instances constructed
+ */
static uint32_t GetRegisteredN (void);
+ /**
+ * \param i index
+ * \returns the TypeId instance whose index is \i.
+ */
static TypeId GetRegistered (uint32_t i);
+
+ /**
+ * \param name the name of the interface to construct.
+ *
+ * No two instances can share the same name.
+ */
+ TypeId (const char * name);
+
/**
* \returns the parent of this TypeId
*
@@ -74,6 +108,15 @@
TypeId GetParent (void) const;
/**
+ * \returns the name of the group associated to this TypeId.
+ */
+ std::string GetGroupName (void) const;
+ /**
+ * \returns the fully-qualified C++ typename of this TypeId.
+ */
+ std::string GetTypeName (void) const;
+
+ /**
* \returns the name of this interface.
*/
std::string GetName (void) const;
@@ -83,64 +126,280 @@
*/
bool HasConstructor (void) const;
- TypeId (std::string);
+ /**
+ * \returns the number of attributes associated to this TypeId
+ */
+ uint32_t GetAttributeListN (void) const;
+ /**
+ * \param i index into attribute array
+ * \returns the name associated to the attribute whose
+ * index is \i i.
+ */
+ std::string GetAttributeName (uint32_t i) const;
+ /**
+ * \param i index into attribute array
+ * \returns the full name associated to the attribute whose
+ * index is \i i.
+ */
+ std::string GetAttributeFullName (uint32_t i) const;
+
+ 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<const TraceSourceAccessor> GetTraceSourceAccessor (uint32_t i) const;
+ Ptr<Object> CreateObject (const AttributeList &attributes) const;
+
+
+ Ptr<Object> CreateObject (void) const;
+ template <typename T1>
+ Ptr<Object> CreateObject (T1 a1) const;
+ template <typename T1, typename T2>
+ Ptr<Object> CreateObject (T1 a1, T2 a2) const;
+
+
+ /**
+ * \param tid the TypeId of the base class.
+ * \return this TypeId instance.
+ *
+ * Record in this TypeId which TypeId is the TypeId
+ * of the base class of the subclass.
+ */
TypeId SetParent (TypeId tid);
+ /**
+ * \return this TypeId instance.
+ *
+ * Record in this TypeId which TypeId is the TypeId
+ * of the base class of the subclass.
+ */
template <typename T>
TypeId SetParent (void);
+ /**
+ * \param groupName the name of the group this TypeId belongs to.
+ * \returns this TypeId instance.
+ *
+ * The group name is purely an advisory information used to
+ * group together types according to a user-specific grouping
+ * scheme.
+ */
+ TypeId SetGroupName (std::string groupName);
+
+ /**
+ * \param typeName the fully-qualified C++ typename of this TypeId.
+ * \returns this TypeId instance.
+ */
+ TypeId SetTypeName (std::string typeName);
+
+ /**
+ * \returns this TypeId instance
+ *
+ * Record in this TypeId the fact that the default constructor
+ * is accessible.
+ */
template <typename T>
TypeId AddConstructor (void);
+
template <typename T, typename T1>
TypeId AddConstructor (void);
+
template <typename T, typename T1, typename T2>
TypeId AddConstructor (void);
- template <typename T, typename T1, typename T2, typename T3>
- TypeId AddConstructor (void);
- template <typename T, typename T1, typename T2, typename T3, typename T4>
- TypeId AddConstructor (void);
- template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
- TypeId AddConstructor (void);
+
+ /**
+ * \param name the name of the new attribute
+ * \param help some help text which describes the purpose of this
+ * attribute
+ * \param param an instance of the associated Accessor subclass
+ * \returns this TypeId instance
+ *
+ * Record in this TypeId the fact that a new attribute exists.
+ */
+ TypeId AddAttribute (std::string name,
+ std::string help,
+ Attribute initialValue,
+ Ptr<const AttributeAccessor> spec,
+ Ptr<const AttributeChecker> checker);
+
+ /**
+ * \param name the name of the new attribute
+ * \param help some help text which describes the purpose of this
+ * attribute
+ * \param flags flags which describe how this attribute can be read and/or written.
+ * \param param an instance of the associated Accessor subclass
+ * \returns this TypeId instance
+ *
+ * Record in this TypeId the fact that a new attribute exists.
+ */
+ TypeId AddAttribute (std::string name,
+ std::string help,
+ uint32_t flags,
+ Attribute initialValue,
+ Ptr<const AttributeAccessor> accessor,
+ Ptr<const AttributeChecker> checker);
+
+ TypeId AddTraceSource (std::string name,
+ std::string help,
+ Ptr<const TraceSourceAccessor> accessor);
+
+ struct AttributeInfo {
+ Ptr<const AttributeAccessor> accessor;
+ Attribute initialValue;
+ uint32_t flags;
+ Ptr<const AttributeChecker> checker;
+ };
+ /**
+ * \param name the name of the requested attribute
+ */
+ bool LookupAttributeByName (std::string name, struct AttributeInfo *info) const;
- 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);
+ // construct an invalid TypeId.
+ TypeId ();
+ ~TypeId ();
- ~TypeId ();
+ VALUE_HELPER_HEADER_1 (TypeId);
private:
+ friend class Object;
+ friend class AttributeList;
friend bool operator == (TypeId a, TypeId b);
friend bool operator != (TypeId a, TypeId b);
+
+ Ptr<const TraceSourceAccessor> LookupTraceSourceByName (std::string name) const;
+
+ /**
+ * \param i the position of the requested attribute
+ * \returns the Accessor associated to the requested attribute
+ */
+ bool LookupAttributeByPosition (uint32_t i, struct AttributeInfo *info) const;
+ /**
+ * \param fullName the full name of the requested attribute
+ * \returns the Accessor associated to the requested attribute
+ */
+ static bool LookupAttributeByFullName (std::string fullName, struct AttributeInfo *info);
+
explicit TypeId (uint16_t tid);
void DoAddConstructor (CallbackBase callback, uint32_t nArguments);
- CallbackBase LookupConstructor (uint32_t nArguments);
+ CallbackBase LookupConstructor (uint32_t nArguments) const;
+ Ptr<const AttributeAccessor> GetAttributeAccessor (uint32_t i) const;
+ uint32_t GetAttributeFlags (uint32_t i) const;
+ Ptr<const AttributeChecker> GetAttributeChecker (uint32_t i) const;
uint16_t m_tid;
};
+std::ostream & operator << (std::ostream &os, TypeId tid);
+std::istream & operator >> (std::istream &is, TypeId &tid);
+
+VALUE_HELPER_HEADER_2 (TypeId);
+
+/**
+ * \brief a container of attributes to be used during object's construction
+ * and in ns3::Object::Set.
+ *
+ */
+class AttributeList
+{
+public:
+ AttributeList ();
+ AttributeList (const AttributeList &o);
+ AttributeList &operator = (const AttributeList &o);
+ ~AttributeList ();
+ /**
+ * \param name the name of the attribute to set
+ * \param value the value to set
+ *
+ * This method checks that a attribute with the requested
+ * name exists and that the value specified is an acceptable
+ * value of that attribute. If any of these checks fails,
+ * the program terminates with a message.
+ */
+ bool Set (std::string name, Attribute value);
+
+ void SetWithTid (TypeId tid, std::string name, Attribute value);
+ void SetWithTid (TypeId tid, uint32_t position, Attribute value);
+
+ /**
+ * Clear the content of this instance.
+ */
+ void Reset (void);
+
+ /**
+ * \returns the global attribute container
+ *
+ * The global attribute container can be used to specify
+ * a set of attribute values without having to re-specify
+ * them for each object when it is created. This container
+ * is checked only during object construction and
+ * it is always checked last, after any per-object
+ * container is checked.
+ */
+ static AttributeList *GetGlobal (void);
+
+ std::string SerializeToString (void) const;
+ bool DeserializeFromString (std::string value);
+private:
+ friend class Object;
+ struct Attr {
+ Ptr<const AttributeChecker> checker;
+ Attribute value;
+ };
+ typedef std::vector<struct Attr> Attrs;
+ typedef Attrs::iterator Iterator;
+ typedef Attrs::const_iterator CIterator;
+
+
+
+ bool DoSet (struct TypeId::AttributeInfo *info, Attribute param);
+ void DoSetOne (Ptr<const AttributeChecker> checker, Attribute param);
+ std::string LookupAttributeFullNameByChecker (Ptr<const AttributeChecker> checker) const;
+
+ Attrs m_attributes;
+};
+
+
/**
* \brief a base class which provides memory management and object aggregation
*
- * Note: This base class is quite similar in spirit to IUnknown in COM or
- * BonoboObject in Bonobo: it provides three main methods: Ref, Unref and
- * GetObject.
*/
-class Object
+class Object : public ObjectBase
{
public:
static TypeId GetTypeId (void);
Object ();
virtual ~Object ();
+
+ /**
+ * \param name the name of the attribute to set
+ * \param value the name of the attribute to set
+ *
+ * Set a single attribute.
+ */
+ bool SetAttribute (std::string name, Attribute value);
+ /**
+ * \param name the name of the attribute to read
+ * \param value a reference to the string where the value of the
+ * attribute should be stored.
+ * \returns true if the requested attribute was found, false otherwise.
+ */
+ bool GetAttribute (std::string name, std::string &value) const;
+ /**
+ * \param name the name of the attribute to read
+ * \param value a reference to the object where the value of the
+ * attribute should be stored.
+ * \returns true if the requested attribute was found, false otherwise.
+ */
+ Attribute GetAttribute (std::string name) const;
+
+ bool TraceSourceConnect (std::string name, const CallbackBase &cb);
+ bool TraceSourceDisconnect (std::string name, const CallbackBase &cb);
+
+ TypeId GetRealTypeId (void) const;
+
/**
* Increment the reference count. This method should not be called
* by user code. Object instances are expected to be used in conjunction
@@ -214,8 +473,13 @@
* up to their parent's implementation once they are done.
*/
virtual void DoDispose (void);
+ virtual void NotifyConstructionCompleted (void);
private:
friend class TypeIdTraceResolver;
+
+ template <typename T>
+ friend Ptr<T> CreateObject (const AttributeList &attributes);
+
template <typename T>
friend Ptr<T> CreateObject (void);
template <typename T, typename T1>
@@ -233,57 +497,76 @@
template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
friend Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7);
+
+ bool DoSet (Ptr<const AttributeAccessor> spec, Attribute intialValue,
+ Ptr<const AttributeChecker> checker, Attribute value);
Ptr<Object> DoGetObject (TypeId tid) const;
void DoCollectSources (std::string path, const TraceContext &context,
TraceResolver::SourceCollection *collection) const;
void DoTraceAll (std::ostream &os, const TraceContext &context) const;
bool Check (void) const;
bool CheckLoose (void) const;
+ /**
+ * Attempt to delete this object. This method iterates
+ * over all aggregated objects to check if they all
+ * have a zero refcount. If yes, the object and all
+ * its aggregates are deleted. If not, nothing is done.
+ */
void MaybeDelete (void) const;
/**
* \param tid an TypeId
*
- * Every subclass which defines a new TypeId for itself
- * should register this TypeId by calling this method
- * from its constructor.
+ * Invoked from ns3::CreateObject only.
+ * Initialize the m_tid member variable to
+ * keep track of the type of this object instance.
*/
void SetTypeId (TypeId tid);
+ /**
+ * \param attributes the attribute values used to initialize
+ * the member variables of this object's instance.
+ *
+ * Invoked from ns3::CreateObject only.
+ * Initialize all the member variables which were
+ * registered with the associated TypeId.
+ */
+ void Construct (const AttributeList &attributes);
+ /**
+ * The reference count for this object. Each aggregate
+ * has an individual reference count. When the global
+ * reference count (the sum of all reference counts)
+ * reaches zero, the object and all its aggregates is
+ * deleted.
+ */
mutable uint32_t m_count;
+ /**
+ * Identifies the type of this object instance.
+ */
TypeId m_tid;
+ /**
+ * Set to true when the DoDispose method of the object
+ * has run, false otherwise.
+ */
bool m_disposed;
mutable bool m_collecting;
+ /**
+ * A pointer to the next aggregate object. This is a circular
+ * linked list of aggregated objects: the last one points
+ * back to the first one. If an object is not aggregated to
+ * any other object, the value of this field is equal to the
+ * value of the 'this' pointer.
+ */
Object *m_next;
};
-template <typename T>
-Ptr<T> CreateObject (void);
-
-template <typename T, typename T1>
-Ptr<T> CreateObject (T1 a1);
-
-template <typename T, typename T1, typename T2>
-Ptr<T> CreateObject (T1 a1, T2 a2);
-
-template <typename T, typename T1, typename T2, typename T3>
-Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3);
-
-template <typename T, typename T1, typename T2, typename T3, typename T4>
-Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3, T4 a4);
-
-template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
-Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
-
-template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
-Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6);
-
-template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
-Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7);
-
} // namespace ns3
namespace ns3 {
+/*************************************************************************
+ * The TypeId implementation which depends on templates
+ *************************************************************************/
+
template <typename T>
TypeId
TypeId::SetParent (void)
@@ -296,8 +579,8 @@
TypeId::AddConstructor (void)
{
struct Maker {
- static Ptr<Object> Create (void) {
- return ns3::CreateObject<T> ();
+ static Ptr<Object> Create (const AttributeList &attributes) {
+ return ns3::CreateObject<T> (attributes);
}
};
CallbackBase cb = MakeCallback (&Maker::Create);
@@ -330,49 +613,9 @@
DoAddConstructor (cb, 2);
return *this;
}
-template <typename T, typename T1, typename T2, typename T3>
-TypeId
-TypeId::AddConstructor (void)
-{
- struct Maker {
- static Ptr<Object> Create (T1 a1, T2 a2, T3 a3) {
- return ns3::CreateObject<T,T1,T2,T3> (a1, a2, a3);
- }
- };
- CallbackBase cb = MakeCallback (&Maker::Create);
- DoAddConstructor (cb, 3);
- return *this;
-}
-template <typename T, typename T1, typename T2, typename T3, typename T4>
-TypeId
-TypeId::AddConstructor (void)
-{
- struct Maker {
- static Ptr<Object> Create (T1 a1, T2 a2, T3 a3, T4 a4) {
- return ns3::CreateObject<T,T1,T2,T3,T4> (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>
-TypeId
-TypeId::AddConstructor (void)
-{
- struct Maker {
- static Ptr<Object> Create (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) {
- return ns3::CreateObject<T,T1,T2,T3,T4,T5> (a1, a2, a3, a4, a5);
- }
- };
- CallbackBase cb = MakeCallback (&Maker::Create);
- DoAddConstructor (cb, 5);
- return *this;
-}
-
template <typename T1>
Ptr<Object>
-TypeId::CreateObject (T1 a1)
+TypeId::CreateObject (T1 a1) const
{
CallbackBase cb = LookupConstructor (1);
Callback<Ptr<Object>,T1> realCb;
@@ -382,7 +625,7 @@
}
template <typename T1, typename T2>
Ptr<Object>
-TypeId::CreateObject (T1 a1, T2 a2)
+TypeId::CreateObject (T1 a1, T2 a2) const
{
CallbackBase cb = LookupConstructor (2);
Callback<Ptr<Object>,T1,T2> realCb;
@@ -390,38 +633,10 @@
Ptr<Object> object = realCb (a1,a2);
return object;
}
-template <typename T1, typename T2, typename T3>
-Ptr<Object>
-TypeId::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>
-TypeId::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>
-TypeId::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;
-}
-
+/*************************************************************************
+ * The Object implementation which depends on templates
+ *************************************************************************/
void
Object::Ref (void) const
@@ -463,11 +678,26 @@
return 0;
}
+/*************************************************************************
+ * The helper functions which need templates.
+ *************************************************************************/
+
+
+template <typename T>
+Ptr<T> CreateObject (const AttributeList &attributes)
+{
+ Ptr<T> p = Ptr<T> (new T (), false);
+ p->SetTypeId (T::GetTypeId ());
+ p->Object::Construct (attributes);
+ return p;
+}
+
template <typename T>
Ptr<T> CreateObject (void)
{
Ptr<T> p = Ptr<T> (new T (), false);
p->SetTypeId (T::GetTypeId ());
+ p->Object::Construct (AttributeList ());
return p;
}
@@ -476,6 +706,7 @@
{
Ptr<T> p = Ptr<T> (new T (a1), false);
p->SetTypeId (T::GetTypeId ());
+ p->Object::Construct (AttributeList ());
return p;
}
@@ -484,9 +715,9 @@
{
Ptr<T> p = Ptr<T> (new T (a1, a2), false);
p->SetTypeId (T::GetTypeId ());
+ p->Object::Construct (AttributeList ());
return p;
}
-
template <typename T, typename T1, typename T2, typename T3>
Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3)
{
@@ -528,6 +759,32 @@
}
+template <typename T>
+Ptr<T>
+CreateObjectWith (std::string n1 = "", Attribute v1 = Attribute (),
+ std::string n2 = "", Attribute v2 = Attribute (),
+ std::string n3 = "", Attribute v3 = Attribute (),
+ std::string n4 = "", Attribute v4 = Attribute (),
+ std::string n5 = "", Attribute v5 = Attribute (),
+ std::string n6 = "", Attribute v6 = Attribute (),
+ std::string n7 = "", Attribute v7 = Attribute (),
+ std::string n8 = "", Attribute v8 = Attribute (),
+ std::string n9 = "", Attribute v9 = Attribute ())
+
+{
+ AttributeList attributes;
+ attributes.SetWithTid (T::GetTypeId (), n1, v1);
+ attributes.SetWithTid (T::GetTypeId (), n2, v2);
+ attributes.SetWithTid (T::GetTypeId (), n3, v3);
+ attributes.SetWithTid (T::GetTypeId (), n4, v4);
+ attributes.SetWithTid (T::GetTypeId (), n5, v5);
+ attributes.SetWithTid (T::GetTypeId (), n6, v6);
+ attributes.SetWithTid (T::GetTypeId (), n7, v7);
+ attributes.SetWithTid (T::GetTypeId (), n8, v8);
+ attributes.SetWithTid (T::GetTypeId (), n9, v9);
+ return CreateObject<T> (attributes);
+}
+
} // namespace ns3
#endif /* OBJECT_H */