remove Interface

This commit is contained in:
Mathieu Lacage
2007-05-25 10:04:38 +02:00
parent f86cf8b9c3
commit 6c6a0073bf
3 changed files with 0 additions and 528 deletions

View File

@@ -39,7 +39,6 @@ core.add_sources([
'test.cc',
'random-variable.cc',
'rng-stream.cc',
'interface.cc',
'uid-manager.cc',
'default-value.cc',
'command-line.cc',
@@ -71,7 +70,6 @@ core.add_inst_headers([
'test.h',
'random-variable.h',
'rng-stream.h',
'interface.h',
'default-value.h',
'command-line.h',
'type-name.h',

View File

@@ -1,396 +0,0 @@
/* -*- 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 "interface.h"
#include "singleton.h"
#include "uid-manager.h"
#include <string>
#include <list>
#include <stdint.h>
#include "assert.h"
#include "debug.h"
NS_DEBUG_COMPONENT_DEFINE ("Interface");
namespace ns3 {
class IidManager : public UidManager
{};
InterfaceId::InterfaceId (std::string name)
: m_iid (Singleton<IidManager>::Get ()->Allocate (name))
{}
InterfaceId::InterfaceId (uint32_t iid)
: m_iid (iid)
{}
InterfaceId
InterfaceId::LookupByName (std::string name)
{
return InterfaceId (Singleton<IidManager>::Get ()->LookupByName (name));
}
bool operator == (const InterfaceId &a, const InterfaceId &b)
{
return a.m_iid == b.m_iid;
}
class InterfaceImpl
{
public:
InterfaceImpl (InterfaceId iid, Interface *interface);
~InterfaceImpl ();
void Ref (void);
void RefAll (InterfaceImpl *other);
void Unref (void);
void UnrefAll (void);
Interface *PeekQueryInterface (InterfaceId iid) const;
void DoDisposeAll (void);
void AddInterface (Interface * interface);
void AddSelfInterface (InterfaceId iid, Interface *interface);
private:
typedef std::list<std::pair<InterfaceId,Interface *> > List;
uint32_t m_ref;
List m_list;
bool m_disposed;
};
InterfaceImpl::InterfaceImpl (InterfaceId iid, Interface * interface)
: m_ref (1),
m_disposed (false)
{
NS_DEBUG ("new " << this << " ref=" << m_ref);
m_list.push_back (std::make_pair (iid, interface));
}
InterfaceImpl::~InterfaceImpl ()
{
for (List::const_iterator i = m_list.begin ();
i != m_list.end (); i++)
{
i->second->UnrefInternal ();
}
m_list.clear ();
}
void
InterfaceImpl::Ref (void)
{
m_ref++;
NS_DEBUG ("inc " << this << " ref=" << m_ref);
}
void
InterfaceImpl::RefAll (InterfaceImpl *other)
{
m_ref += other->m_ref;
NS_DEBUG ("inc all " << this << " o=" << other->m_ref << " ref=" << m_ref);
}
void
InterfaceImpl::Unref (void)
{
NS_ASSERT (m_ref > 0);
m_ref--;
NS_DEBUG ("dec " << this << " ref=" << m_ref);
if (m_ref == 0)
{
delete this;
}
}
void
InterfaceImpl::UnrefAll (void)
{
NS_ASSERT (m_ref > 0);
m_ref = 0;
delete this;
NS_DEBUG ("dec all " << this);
}
void
InterfaceImpl::DoDisposeAll (void)
{
NS_ASSERT (!m_disposed);
for (List::const_iterator i = m_list.begin ();
i != m_list.end (); i++)
{
Interface *interface = i->second;
interface->DoDispose ();
}
m_disposed = true;
}
Interface *
InterfaceImpl::PeekQueryInterface (InterfaceId iid) const
{
for (List::const_iterator i = m_list.begin ();
i != m_list.end (); i++)
{
if (i->first == iid)
{
return i->second;
}
}
return 0;
}
void
InterfaceImpl::AddInterface (Interface *interface)
{
for (List::const_iterator i = interface->m_impl->m_list.begin ();
i != interface->m_impl->m_list.end (); i++)
{
// XXX here, we should check that we have only one
// instance of each interface
i->second->RefInternal ();
m_list.push_back (std::make_pair (i->first, i->second));
}
}
void
InterfaceImpl::AddSelfInterface (InterfaceId iid, Interface *interface)
{
interface->RefInternal ();
m_list.push_back (std::make_pair (iid, interface));
}
Interface::Interface (InterfaceId iid)
: m_impl (new InterfaceImpl (iid, this)),
m_ref (1)
{}
Interface::~Interface ()
{
m_impl = 0;
m_ref = 0xffffffff;
}
void
Interface::Ref (void) const
{
m_impl->Ref ();
}
void
Interface::Unref (void) const
{
m_impl->Unref ();
}
void
Interface::Dispose (void)
{
m_impl->DoDisposeAll ();
}
void
Interface::DoDispose (void)
{
// we do not do anything by default.
}
void
Interface::RefInternal (void)
{
m_ref++;
}
void
Interface::UnrefInternal (void)
{
NS_ASSERT (m_ref != 0);
m_ref--;
if (m_ref == 0)
{
delete this;
}
}
Ptr<Interface>
Interface::DoQueryInterface (InterfaceId iid) const
{
return m_impl->PeekQueryInterface (iid);
}
void
Interface::AddInterface (Ptr<Interface> interface)
{
Interface *p = PeekPointer (interface);
m_impl->AddInterface (p);
m_impl->RefAll (p->m_impl);
p->m_impl->UnrefAll ();
p->m_impl = m_impl;
}
void
Interface::AddSelfInterface (InterfaceId iid, Ptr<Interface> interface)
{
m_impl->AddSelfInterface (iid, PeekPointer (interface));
}
}//namespace ns3
#ifdef RUN_SELF_TESTS
#include "test.h"
namespace {
class A : public ns3::Interface
{
public:
static const ns3::InterfaceId iid;
A ()
: Interface (A::iid)
{}
};
class B : public ns3::Interface
{
public:
static const ns3::InterfaceId iid;
B ()
: Interface (B::iid)
{}
};
class BaseA : public ns3::Interface
{
public:
static const ns3::InterfaceId iid;
BaseA ()
: Interface (BaseA::iid)
{}
};
class BaseB : public ns3::Interface
{
public:
static const ns3::InterfaceId iid;
BaseB ()
: Interface (BaseB::iid)
{}
};
class Base : public ns3::Interface
{
public:
static const ns3::InterfaceId iid;
Base ()
: Interface (Base::iid)
{}
};
class Derived : public Base
{
public:
static const ns3::InterfaceId iid;
Derived ()
{
AddSelfInterface (Derived::iid, this);
}
};
const ns3::InterfaceId A::iid ("A");
const ns3::InterfaceId B::iid ("B");
const ns3::InterfaceId BaseA::iid ("BaseA");
const ns3::InterfaceId BaseB::iid ("BaseB");
const ns3::InterfaceId Base::iid ("Base");
const ns3::InterfaceId Derived::iid ("Derived");
}//namespace
namespace ns3 {
class InterfaceTest : public Test
{
public:
InterfaceTest ();
virtual bool RunTests (void);
};
InterfaceTest::InterfaceTest ()
: Test ("Interface")
{}
bool
InterfaceTest::RunTests (void)
{
bool ok = true;
//DerivedAB *derivedAB;
Ptr<A> a = MakeNewObject<A> ();
a = MakeNewObject<A> ();
Ptr<A> a1 = a->QueryInterface<A> (A::iid);
if (a1 == 0 || a1 != a)
{
ok = false;
}
a1 = a->QueryInterface<A> (A::iid);
if (a1 == 0 || a1 != a)
{
ok = false;
}
Ptr<B> b = MakeNewObject<B> ();
Ptr<B> b1 = b->QueryInterface<B> (B::iid);
if (b1 == 0 || b1 != b)
{
ok = false;
}
a = MakeNewObject<A> ();
a->AddInterface (b);
b1 = b->QueryInterface<B> (B::iid);
if (b1 == 0 || b1 != b)
{
ok = false;
}
a1 = b->QueryInterface<A> (A::iid);
if (a1 == 0 || a1 != a)
{
ok = false;
}
a1 = a->QueryInterface<A> (A::iid);
if (a1 == 0 || a1 != a)
{
ok = false;
}
b1 = a->QueryInterface<B> (B::iid);
if (b1 == 0 || b1 != b)
{
ok = false;
}
Ptr<Derived> derived = MakeNewObject<Derived> ();
Ptr<Base> base = derived->QueryInterface<Base> (Base::iid);
if (base == 0)
{
ok = false;
}
Ptr<Derived> derived1 = base->QueryInterface<Derived> (Derived::iid);
if (derived1 == 0 || derived1 != derived)
{
ok = false;
}
// the following cannot work and it is on purpose
// delete derived;
return ok;
}
static InterfaceTest g_interface_test;
}// namespace ns3
#endif /* RUN_SELF_TESTS */

View File

@@ -1,130 +0,0 @@
/* -*- 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 INTERFACE_H
#define INTERFACE_H
#include <string>
#include "ptr.h"
namespace ns3 {
class InterfaceImpl;
class InterfaceId
{
public:
InterfaceId (std::string name);
static InterfaceId LookupByName (std::string);
private:
InterfaceId (uint32_t iid);
friend bool operator == (const InterfaceId &a, const InterfaceId &b);
uint32_t m_iid;
};
/**
* \brief COM-like IUnknown
*
* This class should be used as a base class for every object which
* wishes to provide a COM-like QueryInterface API. Multiple
* inheritance where this base class is at the top of the dreaded
* "diamond" shape is not allowed.
*/
class Interface
{
public:
virtual ~Interface ();
void Ref (void) const;
void Unref (void) const;
/**
* \param iid the Interface id of the requested interface
*/
template <typename T>
Ptr<T> QueryInterface (InterfaceId iid) const;
/**
* \param interface another interface
*
* Aggregate together the two interfaces. After this call,
* the two interface objects are tied together: each of them
* will be able to perform QI on each other and their lifetimes
* will be found by the same reference count.
*/
void AddInterface (Ptr<Interface> interface);
void Dispose (void);
protected:
/**
* \param iid the Interface Id of the interface defined by a direct subclass
* of this base class
*
* If you are a direct subclass of this class, you _must_ register
* the name of your interface with this constructor.
*/
Interface (InterfaceId iid);
/**
* \param iid the Interface id of the interface
* \param interface a pointer to the interface object
*
* If you are not a direct subclass of the ns3::Interface base class,
* and if you want to register yourself as another accessible interface
* (typically, your subclass has added API), you need to call
* this method to associate an interface id to your interface.
*/
void AddSelfInterface (InterfaceId iid, Ptr<Interface> interface);
protected:
/**
* Subclasses who want to handle the "dispose" event should
* override this method. They are also responsible for
* "chaining up" to their parent class' DoDispose method
* once they have done their own "dispose".
*/
virtual void DoDispose (void);
private:
friend class InterfaceImpl;
Interface ();
Ptr<Interface> DoQueryInterface (InterfaceId iid) const;
void RefInternal (void);
void UnrefInternal (void);
InterfaceImpl *m_impl;
uint32_t m_ref;
};
}//namespace ns3
namespace ns3 {
template <typename T>
Ptr<T>
Interface::QueryInterface (InterfaceId iid) const
{
Ptr<Interface> found = DoQueryInterface (iid);
if (found != 0)
{
return Ptr<T> (dynamic_cast<T *> (PeekPointer (found)));
}
return 0;
}
}//namespace ns3
#endif /* INTERFACE_H */