00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "object.h"
00022 #include "assert.h"
00023 #include "singleton.h"
00024 #include "attribute.h"
00025 #include "log.h"
00026 #include "string.h"
00027 #include <vector>
00028 #include <sstream>
00029
00030 NS_LOG_COMPONENT_DEFINE ("Object");
00031
00032 namespace ns3 {
00033
00034
00035
00036
00037
00038 NS_OBJECT_ENSURE_REGISTERED (Object);
00039
00040 Object::AggregateIterator::AggregateIterator ()
00041 : m_first (0),
00042 m_current (0)
00043 {}
00044
00045 bool
00046 Object::AggregateIterator::HasNext (void) const
00047 {
00048 if (m_current != 0 && m_current->m_next != PeekPointer (m_first))
00049 {
00050 return true;
00051 }
00052 return false;
00053 }
00054 Ptr<const Object>
00055 Object::AggregateIterator::Next (void)
00056 {
00057 m_current = m_current->m_next;
00058 return m_current;
00059 }
00060 Object::AggregateIterator::AggregateIterator (Ptr<const Object> first)
00061 : m_first (first),
00062 m_current (first)
00063 {}
00064
00065
00066 TypeId
00067 Object::GetInstanceTypeId (void) const
00068 {
00069 return m_tid;
00070 }
00071
00072 TypeId
00073 Object::GetTypeId (void)
00074 {
00075 static TypeId tid = TypeId ("ns3::Object")
00076 .SetParent<ObjectBase> ()
00077 ;
00078 return tid;
00079 }
00080
00081
00082 Object::Object ()
00083 : m_count (1),
00084 m_tid (Object::GetTypeId ()),
00085 m_disposed (false),
00086 m_next (this)
00087 {}
00088 Object::~Object ()
00089 {
00090 m_next = 0;
00091 }
00092 Object::Object (const Object &o)
00093 : m_count (1),
00094 m_tid (o.m_tid),
00095 m_disposed (false),
00096 m_next (this)
00097 {}
00098 uint32_t
00099 Object::GetReferenceCount (void) const
00100 {
00101 return m_count;
00102 }
00103 void
00104 Object::Construct (const AttributeList &attributes)
00105 {
00106 ConstructSelf (attributes);
00107 }
00108
00109 Ptr<Object>
00110 Object::DoGetObject (TypeId tid) const
00111 {
00112 NS_ASSERT (CheckLoose ());
00113 const Object *currentObject = this;
00114 TypeId objectTid = Object::GetTypeId ();
00115 do {
00116 NS_ASSERT (currentObject != 0);
00117 TypeId cur = currentObject->GetInstanceTypeId ();
00118 while (cur != tid && cur != objectTid)
00119 {
00120 cur = cur.GetParent ();
00121 }
00122 if (cur == tid)
00123 {
00124 return const_cast<Object *> (currentObject);
00125 }
00126 currentObject = currentObject->m_next;
00127 } while (currentObject != this);
00128 return 0;
00129 }
00130 void
00131 Object::Dispose (void)
00132 {
00133 Object *current = this;
00134 do {
00135 NS_ASSERT (current != 0);
00136 NS_ASSERT (!current->m_disposed);
00137 current->DoDispose ();
00138 current->m_disposed = true;
00139 current = current->m_next;
00140 } while (current != this);
00141 }
00142 void
00143 Object::AggregateObject (Ptr<Object> o)
00144 {
00145 NS_ASSERT (!m_disposed);
00146 NS_ASSERT (!o->m_disposed);
00147 NS_ASSERT (CheckLoose ());
00148 NS_ASSERT (o->CheckLoose ());
00149
00150 if (DoGetObject (o->GetInstanceTypeId ()))
00151 {
00152 NS_FATAL_ERROR ("Object::AggregateObject(): "
00153 "Multiple aggregation of objects of type " <<
00154 o->GetInstanceTypeId ().GetName ());
00155 }
00156
00157 Object *other = PeekPointer (o);
00158 Object *next = m_next;
00159 m_next = other->m_next;
00160 other->m_next = next;
00161 NS_ASSERT (CheckLoose ());
00162 NS_ASSERT (o->CheckLoose ());
00163 }
00164
00165 Object::AggregateIterator
00166 Object::GetAggregateIterator (void) const
00167 {
00168 return AggregateIterator (this);
00169 }
00170
00171 void
00172 Object::SetTypeId (TypeId tid)
00173 {
00174 NS_ASSERT (Check ());
00175 m_tid = tid;
00176 }
00177
00178 void
00179 Object::DoDispose (void)
00180 {
00181 NS_ASSERT (!m_disposed);
00182 }
00183
00184
00185 bool
00186 Object::Check (void) const
00187 {
00188 return (m_count > 0);
00189 }
00190
00191
00192
00193
00194
00195
00196
00197
00198 bool
00199 Object::CheckLoose (void) const
00200 {
00201 uint32_t refcount = 0;
00202 const Object *current = this;
00203 do
00204 {
00205 refcount += current->m_count;
00206 current = current->m_next;
00207 }
00208 while (current != this);
00209
00210 return (refcount > 0);
00211 }
00212
00213 void
00214 Object::MaybeDelete (void) const
00215 {
00216
00217
00218 const Object *current = this;
00219 do {
00220 NS_ASSERT (current != 0);
00221 if (current->m_count != 0)
00222 {
00223 return;
00224 }
00225 current = current->m_next;
00226 } while (current != this);
00227
00228
00229 Object *tmp = const_cast<Object *> (this);
00230 const Object *end = this;
00231 do {
00232 NS_ASSERT (current != 0);
00233 Object *next = tmp->m_next;
00234 if (!tmp->m_disposed)
00235 {
00236 tmp->DoDispose ();
00237 }
00238 tmp = next;
00239 } while (tmp != end);
00240
00241
00242
00243 current = this;
00244 do {
00245 NS_ASSERT (current != 0);
00246 Object *next = current->m_next;
00247 delete current;
00248 current = next;
00249 } while (current != end);
00250 }
00251
00252 }
00253
00254
00255 #ifdef RUN_SELF_TESTS
00256
00257 #include "test.h"
00258 #include "object-factory.h"
00259
00260 namespace {
00261
00262 class BaseA : public ns3::Object
00263 {
00264 public:
00265 static ns3::TypeId GetTypeId (void) {
00266 static ns3::TypeId tid = ns3::TypeId ("BaseA")
00267 .SetParent (Object::GetTypeId ())
00268 .HideFromDocumentation ()
00269 .AddConstructor<BaseA> ();
00270 return tid;
00271 }
00272 BaseA ()
00273 {}
00274 virtual void Dispose (void) {}
00275 };
00276
00277 class DerivedA : public BaseA
00278 {
00279 public:
00280 static ns3::TypeId GetTypeId (void) {
00281 static ns3::TypeId tid = ns3::TypeId ("DerivedA")
00282 .SetParent (BaseA::GetTypeId ())
00283 .HideFromDocumentation ()
00284 .AddConstructor<DerivedA> ();
00285 return tid;
00286 }
00287 DerivedA ()
00288 {}
00289 virtual void Dispose (void) {
00290 BaseA::Dispose ();
00291 }
00292 };
00293
00294 class BaseB : public ns3::Object
00295 {
00296 public:
00297 static ns3::TypeId GetTypeId (void) {
00298 static ns3::TypeId tid = ns3::TypeId ("BaseB")
00299 .SetParent (Object::GetTypeId ())
00300 .HideFromDocumentation ()
00301 .AddConstructor<BaseB> ();
00302 return tid;
00303 }
00304 BaseB ()
00305 {}
00306 virtual void Dispose (void) {}
00307 };
00308
00309 class DerivedB : public BaseB
00310 {
00311 public:
00312 static ns3::TypeId GetTypeId (void) {
00313 static ns3::TypeId tid = ns3::TypeId ("DerivedB")
00314 .SetParent (BaseB::GetTypeId ())
00315 .HideFromDocumentation ()
00316 .AddConstructor<DerivedB> ();
00317 return tid;
00318 }
00319 DerivedB ()
00320 {}
00321 virtual void Dispose (void) {
00322 BaseB::Dispose ();
00323 }
00324 };
00325
00326 NS_OBJECT_ENSURE_REGISTERED (BaseA);
00327 NS_OBJECT_ENSURE_REGISTERED (DerivedA);
00328 NS_OBJECT_ENSURE_REGISTERED (BaseB);
00329 NS_OBJECT_ENSURE_REGISTERED (DerivedB);
00330
00331 }
00332
00333 namespace ns3 {
00334
00335 class ObjectTest : public Test
00336 {
00337 public:
00338 ObjectTest ();
00339 virtual bool RunTests (void);
00340 };
00341
00342 ObjectTest::ObjectTest ()
00343 : Test ("Object")
00344 {}
00345
00346 bool
00347 ObjectTest::RunTests (void)
00348 {
00349 bool result = true;
00350
00351 Ptr<BaseA> baseA = CreateObject<BaseA> ();
00352 NS_TEST_ASSERT_EQUAL (baseA->GetObject<BaseA> (), baseA);
00353 NS_TEST_ASSERT_EQUAL (baseA->GetObject<BaseA> (DerivedA::GetTypeId ()), 0);
00354 NS_TEST_ASSERT_EQUAL (baseA->GetObject<DerivedA> (), 0);
00355 baseA = CreateObject<DerivedA> ();
00356 NS_TEST_ASSERT_EQUAL (baseA->GetObject<BaseA> (), baseA);
00357 NS_TEST_ASSERT_EQUAL (baseA->GetObject<BaseA> (DerivedA::GetTypeId ()), baseA);
00358 NS_TEST_ASSERT_UNEQUAL (baseA->GetObject<DerivedA> (), 0);
00359
00360 baseA = CreateObject<BaseA> ();
00361 Ptr<BaseB> baseB = CreateObject<BaseB> ();
00362 Ptr<BaseB> baseBCopy = baseB;
00363 baseA->AggregateObject (baseB);
00364 NS_TEST_ASSERT_UNEQUAL (baseA->GetObject<BaseA> (), 0);
00365 NS_TEST_ASSERT_EQUAL (baseA->GetObject<DerivedA> (), 0);
00366 NS_TEST_ASSERT_UNEQUAL (baseA->GetObject<BaseB> (), 0);
00367 NS_TEST_ASSERT_EQUAL (baseA->GetObject<DerivedB> (), 0);
00368 NS_TEST_ASSERT_UNEQUAL (baseB->GetObject<BaseB> (), 0);
00369 NS_TEST_ASSERT_EQUAL (baseB->GetObject<DerivedB> (), 0);
00370 NS_TEST_ASSERT_UNEQUAL (baseB->GetObject<BaseA> (), 0);
00371 NS_TEST_ASSERT_EQUAL (baseB->GetObject<DerivedA> (), 0);
00372 NS_TEST_ASSERT_UNEQUAL (baseBCopy->GetObject<BaseA> (), 0);
00373
00374 baseA = CreateObject<DerivedA> ();
00375 baseB = CreateObject<DerivedB> ();
00376 baseBCopy = baseB;
00377 baseA->AggregateObject (baseB);
00378 NS_TEST_ASSERT_UNEQUAL (baseA->GetObject<DerivedB> (), 0);
00379 NS_TEST_ASSERT_UNEQUAL (baseA->GetObject<BaseB> (), 0);
00380 NS_TEST_ASSERT_UNEQUAL (baseB->GetObject<DerivedA> (), 0);
00381 NS_TEST_ASSERT_UNEQUAL (baseB->GetObject<BaseA> (), 0);
00382 NS_TEST_ASSERT_UNEQUAL (baseBCopy->GetObject<DerivedA> (), 0);
00383 NS_TEST_ASSERT_UNEQUAL (baseBCopy->GetObject<BaseA> (), 0);
00384 NS_TEST_ASSERT_UNEQUAL (baseB->GetObject<DerivedB> (), 0);
00385 NS_TEST_ASSERT_UNEQUAL (baseB->GetObject<BaseB> (), 0);
00386
00387 baseA = CreateObject<BaseA> ();
00388 baseB = CreateObject<BaseB> ();
00389 baseA->AggregateObject (baseB);
00390 baseA = 0;
00391 baseA = baseB->GetObject<BaseA> ();
00392
00393
00394
00395 ObjectFactory factory;
00396 factory.SetTypeId (BaseA::GetTypeId ());
00397 Ptr<Object> a = factory.Create ();
00398 NS_TEST_ASSERT_EQUAL (a->GetObject<BaseA> (), a);
00399 NS_TEST_ASSERT_EQUAL (a->GetObject<BaseA> (DerivedA::GetTypeId ()), 0);
00400 NS_TEST_ASSERT_EQUAL (a->GetObject<DerivedA> (), 0);
00401 factory.SetTypeId (DerivedA::GetTypeId ());
00402 a = factory.Create ();
00403 NS_TEST_ASSERT_EQUAL (a->GetObject<BaseA> (), a);
00404 NS_TEST_ASSERT_EQUAL (a->GetObject<BaseA> (DerivedA::GetTypeId ()), a);
00405 NS_TEST_ASSERT_UNEQUAL (a->GetObject<DerivedA> (), 0);
00406
00407
00408 return result;
00409 }
00410
00411 static ObjectTest g_interfaceObjectTests;
00412
00413
00414 }
00415
00416 #endif
00417
00418