1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
3 * Copyright (c) 2007 INRIA, Gustavo Carneiro
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * Authors: Gustavo Carneiro <gjcarneiro@gmail.com>,
19 * Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
27 #include "trace-resolver.h"
29 #include "attribute.h"
30 #include "object-base.h"
31 #include "attribute-helper.h"
33 #define NS_OBJECT_ENSURE_REGISTERED(type) \
34 static struct X##type##RegistrationClass \
36 X##type##RegistrationClass () { \
37 ns3::TypeId tid = type::GetTypeId (); \
40 } x_##type##RegistrationVariable
48 class AttributeAccessor;
51 class TraceSourceAccessor;
54 * \brief a unique identifier for an interface.
56 * This class records a lot of meta-information about a
57 * subclass of the Object base class:
58 * - the base class of the subclass
59 * - the set of accessible constructors in the subclass
60 * - the set of 'attributes' accessible in the subclass
68 ATTR_CONSTRUCT = 1<<2,
69 ATTR_SGC = ATTR_GET | ATTR_SET | ATTR_CONSTRUCT,
73 * \param name the name of the requested interface
74 * \returns the unique id associated with the requested
77 * This method cannot fail: it will crash if the input
78 * name is not a valid interface name.
80 static TypeId LookupByName (std::string name);
83 * \returns the number of TypeId instances constructed
85 static uint32_t GetRegisteredN (void);
88 * \returns the TypeId instance whose index is \i.
90 static TypeId GetRegistered (uint32_t i);
93 * \param name the name of the interface to construct.
95 * No two instances can share the same name.
97 TypeId (const char * name);
100 * \returns the parent of this TypeId
102 * This method cannot fail. It will return itself
103 * if this TypeId has no parent. i.e., it is at the top
104 * of the TypeId hierarchy. Currently, this is the
105 * case for the TypeId associated to the Object class
108 TypeId GetParent (void) const;
111 * \returns the name of the group associated to this TypeId.
113 std::string GetGroupName (void) const;
115 * \returns the fully-qualified C++ typename of this TypeId.
117 std::string GetTypeName (void) const;
120 * \returns the name of this interface.
122 std::string GetName (void) const;
125 * \returns true if this TypeId has a constructor
127 bool HasConstructor (void) const;
130 * \returns the number of attributes associated to this TypeId
132 uint32_t GetAttributeListN (void) const;
134 * \param i index into attribute array
135 * \returns the name associated to the attribute whose
138 std::string GetAttributeName (uint32_t i) const;
140 * \param i index into attribute array
141 * \returns the full name associated to the attribute whose
144 std::string GetAttributeFullName (uint32_t i) const;
146 Attribute GetAttributeInitialValue (uint32_t i) const;
148 uint32_t GetTraceSourceN (void) const;
149 std::string GetTraceSourceName (uint32_t i) const;
150 std::string GetTraceSourceHelp (uint32_t i) const;
151 Ptr<const TraceSourceAccessor> GetTraceSourceAccessor (uint32_t i) const;
153 Ptr<Object> CreateObject (const AttributeList &attributes) const;
156 Ptr<Object> CreateObject (void) const;
157 template <typename T1>
158 Ptr<Object> CreateObject (T1 a1) const;
159 template <typename T1, typename T2>
160 Ptr<Object> CreateObject (T1 a1, T2 a2) const;
164 * \param tid the TypeId of the base class.
165 * \return this TypeId instance.
167 * Record in this TypeId which TypeId is the TypeId
168 * of the base class of the subclass.
170 TypeId SetParent (TypeId tid);
172 * \return this TypeId instance.
174 * Record in this TypeId which TypeId is the TypeId
175 * of the base class of the subclass.
177 template <typename T>
178 TypeId SetParent (void);
181 * \param groupName the name of the group this TypeId belongs to.
182 * \returns this TypeId instance.
184 * The group name is purely an advisory information used to
185 * group together types according to a user-specific grouping
188 TypeId SetGroupName (std::string groupName);
191 * \param typeName the fully-qualified C++ typename of this TypeId.
192 * \returns this TypeId instance.
194 TypeId SetTypeName (std::string typeName);
197 * \returns this TypeId instance
199 * Record in this TypeId the fact that the default constructor
202 template <typename T>
203 TypeId AddConstructor (void);
205 template <typename T, typename T1>
206 TypeId AddConstructor (void);
208 template <typename T, typename T1, typename T2>
209 TypeId AddConstructor (void);
212 * \param name the name of the new attribute
213 * \param help some help text which describes the purpose of this
215 * \param param an instance of the associated Accessor subclass
216 * \returns this TypeId instance
218 * Record in this TypeId the fact that a new attribute exists.
220 TypeId AddAttribute (std::string name,
222 Attribute initialValue,
223 Ptr<const AttributeAccessor> spec,
224 Ptr<const AttributeChecker> checker);
227 * \param name the name of the new attribute
228 * \param help some help text which describes the purpose of this
230 * \param flags flags which describe how this attribute can be read and/or written.
231 * \param param an instance of the associated Accessor subclass
232 * \returns this TypeId instance
234 * Record in this TypeId the fact that a new attribute exists.
236 TypeId AddAttribute (std::string name,
239 Attribute initialValue,
240 Ptr<const AttributeAccessor> accessor,
241 Ptr<const AttributeChecker> checker);
243 TypeId AddTraceSource (std::string name,
245 Ptr<const TraceSourceAccessor> accessor);
247 struct AttributeInfo {
248 Ptr<const AttributeAccessor> accessor;
249 Attribute initialValue;
251 Ptr<const AttributeChecker> checker;
254 * \param name the name of the requested attribute
256 bool LookupAttributeByName (std::string name, struct AttributeInfo *info) const;
259 // construct an invalid TypeId.
263 VALUE_HELPER_HEADER_1 (TypeId);
266 friend class AttributeList;
267 friend bool operator == (TypeId a, TypeId b);
268 friend bool operator != (TypeId a, TypeId b);
271 Ptr<const TraceSourceAccessor> LookupTraceSourceByName (std::string name) const;
274 * \param i the position of the requested attribute
275 * \returns the Accessor associated to the requested attribute
277 bool LookupAttributeByPosition (uint32_t i, struct AttributeInfo *info) const;
279 * \param fullName the full name of the requested attribute
280 * \returns the Accessor associated to the requested attribute
282 static bool LookupAttributeByFullName (std::string fullName, struct AttributeInfo *info);
284 explicit TypeId (uint16_t tid);
285 void DoAddConstructor (CallbackBase callback, uint32_t nArguments);
286 CallbackBase LookupConstructor (uint32_t nArguments) const;
287 Ptr<const AttributeAccessor> GetAttributeAccessor (uint32_t i) const;
288 uint32_t GetAttributeFlags (uint32_t i) const;
289 Ptr<const AttributeChecker> GetAttributeChecker (uint32_t i) const;
294 std::ostream & operator << (std::ostream &os, TypeId tid);
295 std::istream & operator >> (std::istream &is, TypeId &tid);
297 VALUE_HELPER_HEADER_2 (TypeId);
300 * \brief a container of attributes to be used during object's construction
301 * and in ns3::Object::Set.
308 AttributeList (const AttributeList &o);
309 AttributeList &operator = (const AttributeList &o);
312 * \param name the name of the attribute to set
313 * \param value the value to set
315 * This method checks that a attribute with the requested
316 * name exists and that the value specified is an acceptable
317 * value of that attribute. If any of these checks fails,
318 * the program terminates with a message.
320 bool Set (std::string name, Attribute value);
322 bool SetWithTid (TypeId tid, std::string name, Attribute value);
323 bool SetWithTid (TypeId tid, uint32_t position, Attribute value);
326 * Clear the content of this instance.
331 * \returns the global attribute container
333 * The global attribute container can be used to specify
334 * a set of attribute values without having to re-specify
335 * them for each object when it is created. This container
336 * is checked only during object construction and
337 * it is always checked last, after any per-object
338 * container is checked.
340 static AttributeList *GetGlobal (void);
342 std::string SerializeToString (void) const;
343 bool DeserializeFromString (std::string value);
347 Ptr<const AttributeChecker> checker;
350 typedef std::vector<struct Attr> Attrs;
351 typedef Attrs::iterator Iterator;
352 typedef Attrs::const_iterator CIterator;
356 bool DoSet (struct TypeId::AttributeInfo *info, Attribute param);
357 void DoSetOne (Ptr<const AttributeChecker> checker, Attribute param);
358 std::string LookupAttributeFullNameByChecker (Ptr<const AttributeChecker> checker) const;
365 * \brief a base class which provides memory management and object aggregation
368 class Object : public ObjectBase
371 static TypeId GetTypeId (void);
377 * \param name the name of the attribute to set
378 * \param value the name of the attribute to set
380 * Set a single attribute.
382 bool SetAttribute (std::string name, Attribute value);
384 * \param name the name of the attribute to read
385 * \param value a reference to the string where the value of the
386 * attribute should be stored.
387 * \returns true if the requested attribute was found, false otherwise.
389 bool GetAttribute (std::string name, std::string &value) const;
391 * \param name the name of the attribute to read
392 * \param value a reference to the object where the value of the
393 * attribute should be stored.
394 * \returns true if the requested attribute was found, false otherwise.
396 Attribute GetAttribute (std::string name) const;
398 bool TraceSourceConnect (std::string name, const CallbackBase &cb);
399 bool TraceSourceConnectWithContext (std::string name, std::string context, const CallbackBase &cb);
400 bool TraceSourceDisconnect (std::string name, const CallbackBase &cb);
402 TypeId GetRealTypeId (void) const;
405 * Increment the reference count. This method should not be called
406 * by user code. Object instances are expected to be used in conjunction
407 * of the Ptr template which would make calling Ref unecessary and
410 inline void Ref (void) const;
412 * Decrement the reference count. This method should not be called
413 * by user code. Object instances are expected to be used in conjunction
414 * of the Ptr template which would make calling Ref unecessary and
417 inline void Unref (void) const;
419 * \returns a pointer to the requested interface or zero if it could not be found.
421 template <typename T>
422 Ptr<T> GetObject (void) const;
424 * \param tid the interface id of the requested interface
425 * \returns a pointer to the requested interface or zero if it could not be found.
427 template <typename T>
428 Ptr<T> GetObject (TypeId tid) const;
430 * Run the DoDispose methods of this object and all the
431 * objects aggregated to it.
432 * After calling this method, the object is expected to be
433 * totally unusable except for the Ref and Unref methods.
434 * It is an error to call Dispose twice on the same object
439 * \param other another object pointer
441 * This method aggregates the two objects together: after this
442 * method returns, it becomes possible to call GetObject
443 * on one to get the other, and vice-versa.
445 void AggregateObject (Ptr<Object> other);
448 * \param path the path to match for the callback
449 * \param cb callback to connect
451 * Connect the input callback to all trace sources which
452 * match the input path.
455 void TraceConnect (std::string path, const CallbackBase &cb) const;
457 * \param path the path to match for the callback
458 * \param cb callback to disconnect
460 * Disconnect the input callback from all trace sources which
461 * match the input path.
463 void TraceDisconnect (std::string path, const CallbackBase &cb) const;
465 * \returns the trace resolver associated to this object.
467 * This method should be rarely called by users.
469 virtual Ptr<TraceResolver> GetTraceResolver (void) const;
472 * This method is called by Object::Dispose.
473 * Subclasses are expected to override this method and chain
474 * up to their parent's implementation once they are done.
476 virtual void DoDispose (void);
477 virtual void NotifyConstructionCompleted (void);
479 friend class TypeIdTraceResolver;
481 template <typename T>
482 friend Ptr<T> CreateObject (const AttributeList &attributes);
484 template <typename T>
485 friend Ptr<T> CreateObject (void);
486 template <typename T, typename T1>
487 friend Ptr<T> CreateObject (T1 a1);
488 template <typename T, typename T1, typename T2>
489 friend Ptr<T> CreateObject (T1 a1, T2 a2);
490 template <typename T, typename T1, typename T2, typename T3>
491 friend Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3);
492 template <typename T, typename T1, typename T2, typename T3, typename T4>
493 friend Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3, T4 a4);
494 template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
495 friend Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
496 template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
497 friend Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6);
498 template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
499 friend Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7);
502 bool DoSet (Ptr<const AttributeAccessor> spec, Attribute intialValue,
503 Ptr<const AttributeChecker> checker, Attribute value);
504 Ptr<Object> DoGetObject (TypeId tid) const;
505 void DoCollectSources (std::string path, const TraceContext &context,
506 TraceResolver::SourceCollection *collection) const;
507 void DoTraceAll (std::ostream &os, const TraceContext &context) const;
508 bool Check (void) const;
509 bool CheckLoose (void) const;
511 * Attempt to delete this object. This method iterates
512 * over all aggregated objects to check if they all
513 * have a zero refcount. If yes, the object and all
514 * its aggregates are deleted. If not, nothing is done.
516 void MaybeDelete (void) const;
518 * \param tid an TypeId
520 * Invoked from ns3::CreateObject only.
521 * Initialize the m_tid member variable to
522 * keep track of the type of this object instance.
524 void SetTypeId (TypeId tid);
526 * \param attributes the attribute values used to initialize
527 * the member variables of this object's instance.
529 * Invoked from ns3::CreateObject only.
530 * Initialize all the member variables which were
531 * registered with the associated TypeId.
533 void Construct (const AttributeList &attributes);
536 * The reference count for this object. Each aggregate
537 * has an individual reference count. When the global
538 * reference count (the sum of all reference counts)
539 * reaches zero, the object and all its aggregates is
542 mutable uint32_t m_count;
544 * Identifies the type of this object instance.
548 * Set to true when the DoDispose method of the object
549 * has run, false otherwise.
552 mutable bool m_collecting;
554 * A pointer to the next aggregate object. This is a circular
555 * linked list of aggregated objects: the last one points
556 * back to the first one. If an object is not aggregated to
557 * any other object, the value of this field is equal to the
558 * value of the 'this' pointer.
567 /*************************************************************************
568 * The TypeId implementation which depends on templates
569 *************************************************************************/
571 template <typename T>
573 TypeId::SetParent (void)
575 return SetParent (T::GetTypeId ());
578 template <typename T>
580 TypeId::AddConstructor (void)
583 static Ptr<Object> Create (const AttributeList &attributes) {
584 return ns3::CreateObject<T> (attributes);
587 CallbackBase cb = MakeCallback (&Maker::Create);
588 DoAddConstructor (cb, 0);
591 template <typename T, typename T1>
593 TypeId::AddConstructor (void)
596 static Ptr<Object> Create (T1 a1) {
597 return ns3::CreateObject<T,T1> (a1);
600 CallbackBase cb = MakeCallback (&Maker::Create);
601 DoAddConstructor (cb, 1);
604 template <typename T, typename T1, typename T2>
606 TypeId::AddConstructor (void)
609 static Ptr<Object> Create (T1 a1, T2 a2) {
610 return ns3::CreateObject<T,T1,T2> (a1, a2);
613 CallbackBase cb = MakeCallback (&Maker::Create);
614 DoAddConstructor (cb, 2);
617 template <typename T1>
619 TypeId::CreateObject (T1 a1) const
621 CallbackBase cb = LookupConstructor (1);
622 Callback<Ptr<Object>,T1> realCb;
624 Ptr<Object> object = realCb (a1);
627 template <typename T1, typename T2>
629 TypeId::CreateObject (T1 a1, T2 a2) const
631 CallbackBase cb = LookupConstructor (2);
632 Callback<Ptr<Object>,T1,T2> realCb;
634 Ptr<Object> object = realCb (a1,a2);
638 /*************************************************************************
639 * The Object implementation which depends on templates
640 *************************************************************************/
643 Object::Ref (void) const
648 Object::Unref (void) const
650 NS_ASSERT (Check ());
658 template <typename T>
660 Object::GetObject () const
662 Ptr<Object> found = DoGetObject (T::GetTypeId ());
665 return Ptr<T> (dynamic_cast<T *> (PeekPointer (found)));
670 template <typename T>
672 Object::GetObject (TypeId tid) const
674 Ptr<Object> found = DoGetObject (tid);
677 return Ptr<T> (dynamic_cast<T *> (PeekPointer (found)));
682 /*************************************************************************
683 * The helper functions which need templates.
684 *************************************************************************/
687 template <typename T>
688 Ptr<T> CreateObject (const AttributeList &attributes)
690 Ptr<T> p = Ptr<T> (new T (), false);
691 p->SetTypeId (T::GetTypeId ());
692 p->Object::Construct (attributes);
696 template <typename T>
697 Ptr<T> CreateObject (void)
699 Ptr<T> p = Ptr<T> (new T (), false);
700 p->SetTypeId (T::GetTypeId ());
701 p->Object::Construct (AttributeList ());
705 template <typename T, typename T1>
706 Ptr<T> CreateObject (T1 a1)
708 Ptr<T> p = Ptr<T> (new T (a1), false);
709 p->SetTypeId (T::GetTypeId ());
710 p->Object::Construct (AttributeList ());
714 template <typename T, typename T1, typename T2>
715 Ptr<T> CreateObject (T1 a1, T2 a2)
717 Ptr<T> p = Ptr<T> (new T (a1, a2), false);
718 p->SetTypeId (T::GetTypeId ());
719 p->Object::Construct (AttributeList ());
722 template <typename T, typename T1, typename T2, typename T3>
723 Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3)
725 Ptr<T> p = Ptr<T> (new T (a1, a2, a3), false);
726 p->SetTypeId (T::GetTypeId ());
730 template <typename T, typename T1, typename T2, typename T3, typename T4>
731 Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3, T4 a4)
733 Ptr<T> p = Ptr<T> (new T (a1, a2, a3, a4), false);
734 p->SetTypeId (T::GetTypeId ());
738 template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
739 Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
741 Ptr<T> p = Ptr<T> (new T (a1, a2, a3, a4, a5), false);
742 p->SetTypeId (T::GetTypeId ());
746 template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
747 Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
749 Ptr<T> p = Ptr<T> (new T (a1, a2, a3, a4, a5, a6), false);
750 p->SetTypeId (T::GetTypeId ());
754 template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
755 Ptr<T> CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
757 Ptr<T> p = Ptr<T> (new T (a1, a2, a3, a4, a5, a6, a7), false);
758 p->SetTypeId (T::GetTypeId ());
763 template <typename T>
765 CreateObjectWith (std::string n1 = "", Attribute v1 = Attribute (),
766 std::string n2 = "", Attribute v2 = Attribute (),
767 std::string n3 = "", Attribute v3 = Attribute (),
768 std::string n4 = "", Attribute v4 = Attribute (),
769 std::string n5 = "", Attribute v5 = Attribute (),
770 std::string n6 = "", Attribute v6 = Attribute (),
771 std::string n7 = "", Attribute v7 = Attribute (),
772 std::string n8 = "", Attribute v8 = Attribute (),
773 std::string n9 = "", Attribute v9 = Attribute ())
776 AttributeList attributes;
777 attributes.SetWithTid (T::GetTypeId (), n1, v1);
778 attributes.SetWithTid (T::GetTypeId (), n2, v2);
779 attributes.SetWithTid (T::GetTypeId (), n3, v3);
780 attributes.SetWithTid (T::GetTypeId (), n4, v4);
781 attributes.SetWithTid (T::GetTypeId (), n5, v5);
782 attributes.SetWithTid (T::GetTypeId (), n6, v6);
783 attributes.SetWithTid (T::GetTypeId (), n7, v7);
784 attributes.SetWithTid (T::GetTypeId (), n8, v8);
785 attributes.SetWithTid (T::GetTypeId (), n9, v9);
786 return CreateObject<T> (attributes);
791 #endif /* OBJECT_H */