a first draft of a component manager

This commit is contained in:
Mathieu Lacage
2007-05-06 18:59:36 +02:00
parent 4b68e3f7fe
commit aa4cf039bf
7 changed files with 458 additions and 29 deletions

View File

@@ -26,10 +26,11 @@ core.add_sources([
'random-variable.cc',
'rng-stream.cc',
'ns-unknown.cc',
'iid-manager.cc',
'uid-manager.cc',
'default-value.cc',
'command-line.cc',
'type-name.cc',
'ns-unknown-manager.cc',
])
env = Environment()
if env['PLATFORM'] == 'posix' or env['PLATFORM'] == 'darwin' or env['PLATFORM'] == 'cygwin':
@@ -42,7 +43,8 @@ elif env['PLATFORM'] == 'win32':
'win32-system-wall-clock-ms.cc',
])
core.add_headers ([
'iid-manager.h',
'uid-manager.h',
'singleton.h',
])
core.add_inst_headers([
'system-wall-clock-ms.h',
@@ -60,6 +62,7 @@ core.add_inst_headers([
'default-value.h',
'command-line.h',
'type-name.h',
'ns-unknown-manager.h',
])
def config_core (env, config):

View File

@@ -0,0 +1,193 @@
/* -*- 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 <mathieu.lacage@sophia.inria.fr>
*/
#include "ns-unknown-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<CidManager>::Get ()->Allocate (name))
{}
bool operator == (const ClassId &a, const ClassId &b)
{
return a.m_classId == b.m_classId;
}
NsUnknown *
NsUnknownManager::Create (ClassId classId)
{
CallbackBase *callback = Lookup (classId);
if (callback == 0)
{
return 0;
}
Callback<NsUnknown *> reference;
if (reference.CheckType (*callback))
{
reference = *static_cast<Callback<NsUnknown *> *> (callback);
return reference ();
}
return 0;
}
CallbackBase *
NsUnknownManager::Lookup (ClassId classId)
{
List *list = Singleton<List>::Get ();
for (List::const_iterator i = list->begin (); i != list->end (); i++)
{
if (i->first == classId)
{
return i->second;
}
}
return 0;
}
void
NsUnknownManager::Register (ClassId classId, CallbackBase *callback)
{
List *list = Singleton<List>::Get ();
list->push_back (std::make_pair (classId, callback));
}
} // namespace ns3
#ifdef RUN_SELF_TESTS
#include "test.h"
#include "ns-unknown.h"
namespace {
class A : public ns3::NsUnknown
{
public:
static const ns3::ClassId cidZero;
static const ns3::ClassId cidOneBool;
static const ns3::ClassId cidOneInt;
static const ns3::Iid iid;
A ();
A (bool);
A (int);
bool m_zeroInvoked;
bool m_oneBoolInvoked;
bool m_oneIntInvoked;
bool m_bool;
int m_int;
};
const ns3::ClassId A::cidZero = ns3::MakeClassId <A> ("A");
const ns3::ClassId A::cidOneBool = ns3::MakeClassId <A,bool> ("ABool");
const ns3::ClassId A::cidOneInt = ns3::MakeClassId <A,int> ("AInt");
const ns3::Iid A::iid ("IA");
A::A ()
: NsUnknown (A::iid),
m_zeroInvoked (true),
m_oneBoolInvoked (false),
m_oneIntInvoked (false)
{}
A::A (bool b)
: NsUnknown (A::iid),
m_zeroInvoked (false),
m_oneBoolInvoked (true),
m_oneIntInvoked (false),
m_bool (b)
{}
A::A (int i)
: NsUnknown (A::iid),
m_zeroInvoked (false),
m_oneBoolInvoked (false),
m_oneIntInvoked (true),
m_int (i)
{}
}
namespace ns3 {
class NsUnknownManagerTest : public Test
{
public:
NsUnknownManagerTest ();
virtual bool RunTests (void);
};
NsUnknownManagerTest::NsUnknownManagerTest ()
: Test ("NsUnknownManager")
{}
bool
NsUnknownManagerTest::RunTests (void)
{
bool ok = true;
A *a = 0;
a = NsUnknownManager::Create<A> (A::cidZero, A::iid);
if (a == 0 ||
!a->m_zeroInvoked)
{
ok = false;
}
a->Unref ();
a = NsUnknownManager::Create<A> (A::cidOneBool, A::iid, true);
if (a == 0 ||
!a->m_oneBoolInvoked ||
!a->m_bool)
{
ok = false;
}
a->Unref ();
a = NsUnknownManager::Create<A> (A::cidOneBool, A::iid, false);
if (a == 0 ||
!a->m_oneBoolInvoked ||
a->m_bool)
{
ok = false;
}
a->Unref ();
return ok;
}
static NsUnknownManagerTest g_unknownManagerTest;
} // namespace ns3
#endif /* RUN_SELF_TESTS */

View File

@@ -0,0 +1,167 @@
/* -*- 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 <mathieu.lacage@sophia.inria.fr>
*/
#ifndef NS_UNKNOWN_MANAGER_H
#define NS_UNKNOWN_MANAGER_H
#include <string>
#include <vector>
#include <stdint.h>
#include "callback.h"
#include "ns-unknown.h"
namespace ns3 {
class ClassId
{
public:
ClassId (std::string name);
private:
friend bool operator == (const ClassId &a, const ClassId &b);
uint32_t m_classId;
};
template <typename T>
ClassId
MakeClassId (std::string name);
template <typename T, typename T1>
ClassId
MakeClassId (std::string name);
class NsUnknownManager
{
public:
static NsUnknown *Create (ClassId classId);
template <typename T1>
static NsUnknown *Create (ClassId classId, T1 a1);
template <typename T1, typename T2>
static NsUnknown *Create (ClassId classId, T1 a1, T2 a2);
template <typename T>
static T *Create (ClassId classId, Iid iid);
template <typename T, typename T1>
static T *Create (ClassId classId, Iid iid, T1 a1);
template <typename T, typename T1, typename T2>
static T *Create (ClassId classId, Iid iid, T1 a1, T2 a2);
static void Register (ClassId classId, CallbackBase *callback);
private:
typedef std::vector<std::pair<ClassId, CallbackBase *> > List;
static List *GetList (void);
static CallbackBase *Lookup (ClassId classId);
};
template <typename T>
NsUnknown *
MakeNsUnknownObjectZero (void)
{
return new T ();
}
template <typename T, typename T1>
NsUnknown *
MakeNsUnknownObjectOne (T1 a1)
{
return new T (a1);
}
template <typename T>
ClassId
MakeClassId (std::string name)
{
ClassId classId = ClassId (name);
static Callback<NsUnknown *> callback = MakeCallback (&MakeNsUnknownObjectZero<T>);
NsUnknownManager::Register (classId, &callback);
return classId;
}
template <typename T, typename T1>
ClassId
MakeClassId (std::string name)
{
ClassId classId = ClassId (name);
static Callback<NsUnknown *, T1> callback = MakeCallback (&MakeNsUnknownObjectOne<T,T1>);
NsUnknownManager::Register (classId, &callback);
return classId;
}
template <typename T1>
NsUnknown *
NsUnknownManager::Create (ClassId classId, T1 a1)
{
CallbackBase *callback = Lookup (classId);
if (callback == 0)
{
return 0;
}
Callback<NsUnknown *, T1> reference;
if (reference.CheckType (*callback))
{
reference = *static_cast<Callback<NsUnknown *,T1> *> (callback);
return reference (a1);
}
return 0;
}
template <typename T1, typename T2>
NsUnknown *
NsUnknownManager::Create (ClassId classId, T1 a1, T2 a2)
{
return 0;
}
template <typename T>
T *
NsUnknownManager::Create (ClassId classId, Iid iid)
{
NsUnknown *obj = Create (classId);
T *i = obj->QueryInterface<T> (iid);
return i;
}
template <typename T, typename T1>
T *
NsUnknownManager::Create (ClassId classId, Iid iid, T1 a1)
{
NsUnknown *obj = Create (classId, a1);
T *i = obj->QueryInterface<T> (iid);
return i;
}
template <typename T, typename T1, typename T2>
T *
NsUnknownManager::Create (ClassId classId, Iid iid, T1 a1, T2 a2)
{
NsUnknown *obj = Create (classId, a1, a2);
T *i = obj->QueryInterface<T> (iid);
return i;
}
} // namespace ns3
#endif /* NS_UNKNOWN_MANAGER_H */

View File

@@ -19,7 +19,8 @@
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "ns-unknown.h"
#include "iid-manager.h"
#include "singleton.h"
#include "uid-manager.h"
#include <string>
#include <list>
#include <stdint.h>
@@ -27,8 +28,11 @@
namespace ns3 {
class IidManager : public UidManager
{};
Iid::Iid (std::string name)
: m_iid (IidManager::Allocate (name))
: m_iid (Singleton<IidManager>::Get ()->Allocate (name))
{}
bool operator == (const Iid &a, const Iid &b)
@@ -218,7 +222,6 @@ NsUnknown::AddSelfInterface (Iid iid, NsUnknown *interface)
#ifdef RUN_SELF_TESTS
#include "test.h"
#include "iid-manager.h"
namespace {
@@ -292,7 +295,7 @@ public:
};
InterfaceTest::InterfaceTest ()
: Test ("Interface")
: Test ("NsUnknown")
{}
bool
InterfaceTest::RunTests (void)

View File

@@ -18,21 +18,32 @@
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef IID_MANAGER_H
#define IID_MANAGER_H
#include <stdint.h>
#include <string>
#ifndef SINGLETON_H
#define SINGLETON_H
namespace ns3 {
class IidManager
template <typename T>
class Singleton
{
public:
static uint32_t Allocate (std::string name);
static T *Get (void);
};
} // namespace ns3
namespace ns3 {
#endif /* IID_MANAGER_H */
template <typename T>
T *
Singleton<T>::Get (void)
{
static T object;
return &object;
}
} // namespace ns3
#endif /* SINGLETON_H */

View File

@@ -18,29 +18,21 @@
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "iid-manager.h"
#include "uid-manager.h"
#include "ns3/fatal-error.h"
#include <vector>
namespace ns3 {
class IidManagerPriv
{
public:
uint32_t Allocate (std::string name);
private:
typedef std::vector<std::string> NameList;
NameList m_nameList;
};
uint32_t
IidManagerPriv::Allocate (std::string name)
UidManager::Allocate (std::string name)
{
for (NameList::iterator i = m_nameList.begin (); i != m_nameList.end (); i++)
{
if ((*i) == name)
{
NS_FATAL_ERROR ("Trying to allocate twice the same iid: " << name);
NS_FATAL_ERROR ("Trying to allocate twice the same uid: " << name);
}
}
m_nameList.push_back (name);
@@ -48,10 +40,26 @@ IidManagerPriv::Allocate (std::string name)
}
uint32_t
IidManager::Allocate (std::string name)
UidManager::LookupByName (std::string name)
{
static IidManagerPriv priv;
return priv.Allocate (name);
uint32_t j = 0;
for (NameList::iterator i = m_nameList.begin (); i != m_nameList.end (); i++)
{
j++;
if ((*i) == name)
{
return j;
}
}
return 0;
}
std::string
UidManager::LookupByUid (uint32_t uid)
{
NS_ASSERT (uid > 0);
NS_ASSERT (m_nameList.size () > uid);
return m_nameList[uid-1];
}
} // namespace ns3

44
src/core/uid-manager.h Normal file
View File

@@ -0,0 +1,44 @@
/* -*- 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 <mathieu.lacage@sophia.inria.fr>
*/
#ifndef UID_MANAGER_H
#define UID_MANAGER_H
#include <stdint.h>
#include <string>
#include <vector>
namespace ns3 {
class UidManager
{
public:
uint32_t LookupByName (std::string name);
std::string LookupByUid (uint32_t uid);
uint32_t Allocate (std::string name);
private:
typedef std::vector<std::string> NameList;
NameList m_nameList;
};
} // namespace ns3
#endif /* UID_MANAGER_H */