/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2007 INRIA * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation; * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: Mathieu Lacage */ #include "component-manager.h" #include "uid-manager.h" #include "singleton.h" namespace ns3 { // we redefine a UidManager type for the class id singleton below. // otherwise, we would have to share the same id singleton instance // with the Iids. class CidManager : public UidManager {}; ClassId::ClassId (std::string name) : m_classId (Singleton::Get ()->Allocate (name)) {} ClassId::ClassId (uint32_t classId) : m_classId (classId) {} std::string ClassId::GetName (void) const { return Singleton::Get ()->LookupByUid (m_classId); } bool operator == (const ClassId &a, const ClassId &b) { return a.m_classId == b.m_classId; } ComponentManager::ClassIdEntry::ClassIdEntry (ClassId classId) : m_classId (classId) {} Ptr ComponentManager::Create (ClassId classId) { Callback > callback = DoGetCallback (classId); return callback (); } CallbackBase * ComponentManager::Lookup (ClassId classId) { List *list = Singleton::Get (); for (List::const_iterator i = list->begin (); i != list->end (); i++) { if (i->m_classId == classId) { return i->m_callback; } } return 0; } ClassId ComponentManager::LookupByName (std::string name) { return ClassId (Singleton::Get ()->LookupByName (name)); } ClassId ComponentManager::LookupByName (std::string name, bool *ok) { uint32_t cid = Singleton::Get ()->LookupByName (name); if (cid == 0) { *ok = false; } else { *ok = true; } return ClassId (cid); } std::vector ComponentManager::LookupByInterfaceId (InterfaceId iid) { std::vector classIdList; List *list = Singleton::Get (); for (List::const_iterator i = list->begin (); i != list->end (); i++) { for (std::vector::const_iterator j = i->m_supportedInterfaces.begin (); j != i->m_supportedInterfaces.end (); j++) { if (*j == iid) { classIdList.push_back (i->m_classId); break; } } } unique (classIdList.begin (), classIdList.end ()); return classIdList; } void ComponentManager::Register (ClassId classId, CallbackBase *callback, std::vector supportedInterfaces) { List *list = Singleton::Get (); struct ClassIdEntry entry = ClassIdEntry (classId); entry.m_callback = callback; bool foundObject = false; for (std::vector::iterator i = supportedInterfaces.begin (); i != supportedInterfaces.end (); i++) { if (*i == Object::iid ()) { foundObject = true; } } if (!foundObject) { supportedInterfaces.push_back (Object::iid ()); } entry.m_supportedInterfaces = supportedInterfaces; list->push_back (entry); } void RegisterCallback (ClassId classId, CallbackBase *callback, std::vector supportedInterfaces) { return ComponentManager::Register (classId, callback, supportedInterfaces); } ClassIdDefaultValue::ClassIdDefaultValue (std::string name, std::string help, InterfaceId iid, std::string defaultValue) : DefaultValueBase (name, help), m_defaultName (defaultValue), m_name (defaultValue), m_interfaceId (iid) { DefaultValueList::Add (this); } ClassId ClassIdDefaultValue::GetValue (void) const { return ComponentManager::LookupByName (m_name); } void ClassIdDefaultValue::SetValue (ClassId classId) { m_name = classId.GetName (); } void ClassIdDefaultValue::SetValue (std::string name) { m_name = name; } bool ClassIdDefaultValue::DoParseValue (const std::string &value) { bool ok; ClassId classId = ComponentManager::LookupByName (value, &ok); if (!ok) { return false; } std::vector classIdList = ComponentManager::LookupByInterfaceId (m_interfaceId); for (std::vector::const_iterator i = classIdList.begin (); i != classIdList.end (); i++) { if (*i == classId) { m_name = value; return true; } } return false; } std::string ClassIdDefaultValue::DoGetType (void) const { std::vector classIdList = ComponentManager::LookupByInterfaceId (m_interfaceId); std::ostringstream oss; oss << "("; for (std::vector::const_iterator i = classIdList.begin (); i != classIdList.end (); i++) { if (i != classIdList.begin ()) { oss << "|"; } oss << i->GetName (); } oss << ")"; return oss.str (); } std::string ClassIdDefaultValue::DoGetDefaultValue (void) const { return m_name; } } // namespace ns3 #ifdef RUN_SELF_TESTS #include "test.h" #include "object.h" namespace { class B : public ns3::Object { public: static ns3::InterfaceId iid (void) { static ns3::InterfaceId iid = ns3::MakeInterfaceId ("B", Object::iid ()); return iid; } B (); }; B::B () {} class A : public ns3::Object { public: static const ns3::ClassId cidZero; static const ns3::ClassId cidOneBool; static const ns3::ClassId cidOneUi32; static const ns3::ClassId cidOther; static ns3::InterfaceId iid (void) { static ns3::InterfaceId iid = ns3::MakeInterfaceId ("A", Object::iid ()); return iid; } A (); A (bool); A (uint32_t); bool m_zeroInvoked; bool m_oneBoolInvoked; bool m_oneUi32Invoked; bool m_bool; int m_ui32; }; const ns3::ClassId A::cidZero = ns3::MakeClassId ("A", A::iid ()); const ns3::ClassId A::cidOneBool = ns3::MakeClassId ("ABool", A::iid ()); const ns3::ClassId A::cidOneUi32 = ns3::MakeClassId ("AUi32", A::iid ()); A::A () : m_zeroInvoked (true), m_oneBoolInvoked (false), m_oneUi32Invoked (false) { ns3::Ptr b = ns3::CreateObject (); AddInterface (b); } A::A (bool bo) : m_zeroInvoked (false), m_oneBoolInvoked (true), m_oneUi32Invoked (false), m_bool (bo) { ns3::Ptr b = ns3::CreateObject (); AddInterface (b); } A::A (uint32_t i) : m_zeroInvoked (false), m_oneBoolInvoked (false), m_oneUi32Invoked (true), m_ui32 (i) { ns3::Ptr b = ns3::CreateObject (); AddInterface (b); } class X : public A { public: static ns3::InterfaceId iid (void) { static ns3::InterfaceId iid = ns3::MakeInterfaceId ("X", A::iid ()); return iid; } }; class C : public X { public: static ns3::InterfaceId iid (void) { static ns3::InterfaceId iid = ns3::MakeInterfaceId ("C", X::iid ()); return iid; } }; class D : public C { public: static ns3::InterfaceId iid (void) { static ns3::InterfaceId iid = ns3::MakeInterfaceId ("D", C::iid ()); return iid; } static const ns3::ClassId cid; }; const ns3::ClassId D::cid = ns3::MakeClassId ("D", A::iid (), X::iid (), C::iid (), D::iid ()); } namespace ns3 { class ComponentManagerTest : public Test { public: ComponentManagerTest (); virtual bool RunTests (void); }; ComponentManagerTest::ComponentManagerTest () : Test ("ComponentManager") {} bool ComponentManagerTest::RunTests (void) { bool ok = true; Ptr a = 0; a = ComponentManager::Create (A::cidZero); if (a == 0 || !a->m_zeroInvoked) { ok = false; } a = ComponentManager::Create (A::cidOneBool, true); if (a == 0 || !a->m_oneBoolInvoked || !a->m_bool) { ok = false; } a = ComponentManager::Create (A::cidOneBool, false); if (a == 0 || !a->m_oneBoolInvoked || a->m_bool) { ok = false; } a = ComponentManager::Create (A::cidOneUi32, 10); if (a == 0 || !a->m_oneUi32Invoked || a->m_ui32 != 10) { ok = false; } a = ComponentManager::Create (A::cidOneUi32, (uint32_t)10); if (a == 0 || !a->m_oneUi32Invoked || a->m_ui32 != 10) { ok = false; } Ptr b = ComponentManager::Create (A::cidOneUi32, 10); if (b == 0) { ok = false; } return ok; } static ComponentManagerTest g_unknownManagerTest; } // namespace ns3 #endif /* RUN_SELF_TESTS */