Added support for map objects in the attribute system.
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/pointer.h"
|
||||
#include "ns3/object-vector.h"
|
||||
#include "ns3/object-map.h"
|
||||
#include "ns3/string.h"
|
||||
#include <fstream>
|
||||
|
||||
@@ -125,6 +126,28 @@ AttributeIterator::DoEndVisitArrayItem (void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AttributeIterator::DoStartVisitMapAttribute (Ptr<Object> object, std::string name, const ObjectMapValue &map)
|
||||
{
|
||||
|
||||
}
|
||||
void
|
||||
AttributeIterator::DoEndVisitMapAttribute (void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
AttributeIterator::DoStartVisitMapItem (const ObjectMapValue &vector, uint32_t index, Ptr<Object> item)
|
||||
{
|
||||
|
||||
}
|
||||
void
|
||||
AttributeIterator::DoEndVisitMapItem (void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
AttributeIterator::VisitAttribute (Ptr<Object> object, std::string name)
|
||||
{
|
||||
@@ -189,6 +212,37 @@ AttributeIterator::EndVisitArrayItem (void)
|
||||
DoEndVisitArrayItem ();
|
||||
}
|
||||
|
||||
void
|
||||
AttributeIterator::StartVisitMapAttribute (Ptr<Object> object, std::string name, const ObjectMapValue &map)
|
||||
{
|
||||
m_currentPath.push_back (name);
|
||||
DoStartVisitMapAttribute (object, name, map);
|
||||
}
|
||||
|
||||
void
|
||||
AttributeIterator::EndVisitMapAttribute (void)
|
||||
{
|
||||
m_currentPath.pop_back ();
|
||||
DoEndVisitArrayAttribute ();
|
||||
}
|
||||
|
||||
void
|
||||
AttributeIterator::StartVisitMapItem (const ObjectMapValue &map, uint32_t index, Ptr<Object> item)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << index;
|
||||
m_currentPath.push_back (oss.str ());
|
||||
m_currentPath.push_back ("$" + item->GetInstanceTypeId ().GetName ());
|
||||
DoStartVisitMapItem (map, index, item);
|
||||
}
|
||||
|
||||
void
|
||||
AttributeIterator::EndVisitMapItem (void)
|
||||
{
|
||||
m_currentPath.pop_back ();
|
||||
m_currentPath.pop_back ();
|
||||
DoEndVisitMapItem ();
|
||||
}
|
||||
|
||||
void
|
||||
AttributeIterator::DoIterate (Ptr<Object> object)
|
||||
@@ -243,6 +297,27 @@ AttributeIterator::DoIterate (Ptr<Object> object)
|
||||
EndVisitArrayAttribute ();
|
||||
continue;
|
||||
}
|
||||
// attempt to cast to an object map.
|
||||
const ObjectMapChecker *mapChecker = dynamic_cast<const ObjectMapChecker *> (PeekPointer (checker));
|
||||
if (mapChecker != 0)
|
||||
{
|
||||
NS_LOG_DEBUG ("map attribute " << tid.GetAttributeName (i));
|
||||
ObjectMapValue map;
|
||||
object->GetAttribute (tid.GetAttributeName (i), map);
|
||||
// JNG Fix this
|
||||
StartVisitMapAttribute (object, tid.GetAttributeName (i), map);
|
||||
for (ObjectMapValue::Iterator it = map.Begin () ; it != map.End(); it++ )
|
||||
{
|
||||
NS_LOG_DEBUG ("map attribute item " << (*it).first << (*it).second );
|
||||
StartVisitMapItem (map, (*it).first, (*it).second);
|
||||
m_examined.push_back (object);
|
||||
DoIterate ((*it).second);
|
||||
m_examined.pop_back ();
|
||||
EndVisitMapItem ();
|
||||
}
|
||||
EndVisitMapAttribute ();
|
||||
continue;
|
||||
}
|
||||
uint32_t flags = tid.GetAttributeFlags (i);
|
||||
Ptr<const AttributeAccessor> accessor = tid.GetAttributeAccessor (i);
|
||||
if ((flags & TypeId::ATTR_GET) && accessor->HasGetter () &&
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
namespace ns3 {
|
||||
|
||||
class ObjectVectorValue;
|
||||
class ObjectMapValue;
|
||||
|
||||
// This class is used internally by ConfigStore and GtkConfigStore.
|
||||
class AttributeIterator
|
||||
@@ -48,6 +49,11 @@ private:
|
||||
virtual void DoStartVisitArrayItem (const ObjectVectorValue &vector, uint32_t index, Ptr<Object> item);
|
||||
virtual void DoEndVisitArrayItem (void);
|
||||
|
||||
virtual void DoStartVisitMapAttribute (Ptr<Object> object, std::string name, const ObjectMapValue &map);
|
||||
virtual void DoEndVisitMapAttribute (void);
|
||||
virtual void DoStartVisitMapItem (const ObjectMapValue &vector, uint32_t index, Ptr<Object> item);
|
||||
virtual void DoEndVisitMapItem (void);
|
||||
|
||||
void DoIterate (Ptr<Object> object);
|
||||
bool IsExamined (Ptr<const Object> object);
|
||||
std::string GetCurrentPath (std::string attr) const;
|
||||
@@ -62,6 +68,10 @@ private:
|
||||
void StartVisitArrayItem (const ObjectVectorValue &vector, uint32_t index, Ptr<Object> item);
|
||||
void EndVisitArrayItem (void);
|
||||
|
||||
void StartVisitMapAttribute (Ptr<Object> object, std::string name, const ObjectMapValue &map);
|
||||
void EndVisitMapAttribute (void);
|
||||
void StartVisitMapItem (const ObjectMapValue &vector, uint32_t index, Ptr<Object> item);
|
||||
void EndVisitMapItem (void);
|
||||
|
||||
std::vector<Ptr<Object> > m_examined;
|
||||
std::vector<std::string> m_currentPath;
|
||||
|
||||
109
src/core/model/object-map.cc
Normal file
109
src/core/model/object-map.cc
Normal file
@@ -0,0 +1,109 @@
|
||||
#include "object-map.h"
|
||||
#include <ns3/log.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("ObjectMapValue");
|
||||
|
||||
ObjectMapValue::ObjectMapValue ()
|
||||
{}
|
||||
|
||||
ObjectMapValue::Iterator
|
||||
ObjectMapValue::Begin (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return m_objects.begin ();
|
||||
}
|
||||
ObjectMapValue::Iterator
|
||||
ObjectMapValue::End (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return m_objects.end ();
|
||||
}
|
||||
uint32_t
|
||||
ObjectMapValue::GetN (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return m_objects.size ();
|
||||
}
|
||||
Ptr<Object>
|
||||
ObjectMapValue::Get (uint32_t i) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return m_objects.find(i)->second;
|
||||
}
|
||||
|
||||
Ptr<AttributeValue>
|
||||
ObjectMapValue::Copy (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return ns3::Create<ObjectMapValue> (*this);
|
||||
}
|
||||
std::string
|
||||
ObjectMapValue::SerializeToString (Ptr<const AttributeChecker> checker) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
std::ostringstream oss;
|
||||
for (ObjectMapValue::Iterator it = Begin () ; it != End(); it++ )
|
||||
{
|
||||
oss << (*it).first << "-" << (*it).second;
|
||||
if (it != End () )
|
||||
{
|
||||
oss << " ";
|
||||
}
|
||||
}
|
||||
return oss.str ();
|
||||
}
|
||||
|
||||
bool
|
||||
ObjectMapValue::DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker)
|
||||
{
|
||||
NS_FATAL_ERROR ("cannot deserialize a map of object pointers.");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ObjectMapAccessor::Set (ObjectBase * object, const AttributeValue & value) const
|
||||
{
|
||||
// not allowed.
|
||||
return false;
|
||||
}
|
||||
bool
|
||||
ObjectMapAccessor::Get (const ObjectBase * object, AttributeValue &value) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
ObjectMapValue *v = dynamic_cast<ObjectMapValue *> (&value);
|
||||
if (v == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
v->m_objects.clear ();
|
||||
uint32_t n;
|
||||
bool ok = DoGetN (object, &n);
|
||||
if (!ok)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (uint32_t i = 0; i < n; i++)
|
||||
{
|
||||
|
||||
std::pair<uint32_t, Ptr<Object> > element = DoGet (object, i);
|
||||
NS_LOG_FUNCTION(i << object << element.first << element.second);
|
||||
|
||||
v->m_objects.insert ( DoGet (object, i));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
bool
|
||||
ObjectMapAccessor::HasGetter (void) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool
|
||||
ObjectMapAccessor::HasSetter (void) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
} // name
|
||||
217
src/core/model/object-map.h
Normal file
217
src/core/model/object-map.h
Normal file
@@ -0,0 +1,217 @@
|
||||
#ifndef OBJECT_MAP_H
|
||||
#define OBJECT_MAP_H
|
||||
|
||||
#include "object.h"
|
||||
#include "ptr.h"
|
||||
#include "attribute.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* \ingroup object
|
||||
*
|
||||
* \brief contain a map of ns3::Object pointers.
|
||||
*
|
||||
* This class it used to get attribute access to an array of
|
||||
* ns3::Object pointers.
|
||||
*/
|
||||
class ObjectMapValue : public AttributeValue
|
||||
{
|
||||
|
||||
|
||||
public:
|
||||
typedef std::map<uint32_t, Ptr<Object> >::const_iterator Iterator;
|
||||
|
||||
ObjectMapValue ();
|
||||
|
||||
/**
|
||||
* \returns an iterator to the first object contained in this map
|
||||
*/
|
||||
Iterator Begin (void) const;
|
||||
/**
|
||||
* \returns an iterator to the last object contained in this map
|
||||
*/
|
||||
Iterator End (void) const;
|
||||
/**
|
||||
* \returns the number of objects contained in this map.
|
||||
*/
|
||||
uint32_t GetN (void) const;
|
||||
/**
|
||||
* \param i the index of the requested object.
|
||||
* \returns the requested object
|
||||
*/
|
||||
Ptr<Object> Get (uint32_t i) const;
|
||||
|
||||
virtual Ptr<AttributeValue> Copy (void) const;
|
||||
virtual std::string SerializeToString (Ptr<const AttributeChecker> checker) const;
|
||||
virtual bool DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker);
|
||||
|
||||
private:
|
||||
friend class ObjectMapAccessor;
|
||||
std::map<uint32_t, Ptr<Object> > m_objects;
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
Ptr<const AttributeAccessor>
|
||||
MakeObjectMapAccessor (U T::*memberMap);
|
||||
|
||||
template <typename T, typename U, typename INDEX>
|
||||
Ptr<const AttributeAccessor>
|
||||
MakeObjectMapAccessor (Ptr<U> (T::*get) (INDEX) const,
|
||||
INDEX (T::*getN) (void) const);
|
||||
|
||||
template <typename T, typename U, typename INDEX>
|
||||
Ptr<const AttributeAccessor>
|
||||
MakeObjectMapAccessor (INDEX (T::*getN) (void) const,
|
||||
Ptr<U> (T::*get) (INDEX) const);
|
||||
|
||||
class ObjectMapChecker : public AttributeChecker
|
||||
{
|
||||
public:
|
||||
virtual TypeId GetItemTypeId (void) const = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
Ptr<const AttributeChecker> MakeObjectMapChecker (void);
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <typename T>
|
||||
class AnObjectMapChecker : public ObjectMapChecker
|
||||
{
|
||||
public:
|
||||
virtual TypeId GetItemTypeId (void) const {
|
||||
return T::GetTypeId ();
|
||||
}
|
||||
virtual bool Check (const AttributeValue &value) const {
|
||||
return dynamic_cast<const ObjectMapValue *> (&value) != 0;
|
||||
}
|
||||
virtual std::string GetValueTypeName (void) const {
|
||||
return "ns3::ObjectMapValue";
|
||||
}
|
||||
virtual bool HasUnderlyingTypeInformation (void) const {
|
||||
return true;
|
||||
}
|
||||
virtual std::string GetUnderlyingTypeInformation (void) const {
|
||||
return "ns3::Ptr< " + T::GetTypeId ().GetName () + " >";
|
||||
}
|
||||
virtual Ptr<AttributeValue> Create (void) const {
|
||||
return ns3::Create<ObjectMapValue> ();
|
||||
}
|
||||
virtual bool Copy (const AttributeValue &source, AttributeValue &destination) const {
|
||||
const ObjectMapValue *src = dynamic_cast<const ObjectMapValue *> (&source);
|
||||
ObjectMapValue *dst = dynamic_cast<ObjectMapValue *> (&destination);
|
||||
if (src == 0 || dst == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*dst = *src;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
class ObjectMapAccessor : public AttributeAccessor
|
||||
{
|
||||
public:
|
||||
virtual bool Set (ObjectBase * object, const AttributeValue &value) const;
|
||||
virtual bool Get (const ObjectBase * object, AttributeValue &value) const;
|
||||
virtual bool HasGetter (void) const;
|
||||
virtual bool HasSetter (void) const;
|
||||
private:
|
||||
virtual bool DoGetN (const ObjectBase *object, uint32_t *n) const = 0;
|
||||
virtual std::pair<uint32_t, Ptr<Object> > DoGet (const ObjectBase *object, uint32_t i) const = 0;
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
Ptr<const AttributeAccessor>
|
||||
MakeObjectMapAccessor (U T::*memberMap)
|
||||
{
|
||||
struct MemberStdContainer : public ObjectMapAccessor
|
||||
{
|
||||
virtual bool DoGetN (const ObjectBase *object, uint32_t *n) const {
|
||||
const T *obj = dynamic_cast<const T *> (object);
|
||||
if (obj == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*n = (obj->*m_memberMap).size ();
|
||||
return true;
|
||||
}
|
||||
virtual std::pair<uint32_t, Ptr<Object> > DoGet (const ObjectBase *object, uint32_t i) const {
|
||||
const T *obj = static_cast<const T *> (object);
|
||||
typename U::const_iterator begin = (obj->*m_memberMap).begin ();
|
||||
typename U::const_iterator end = (obj->*m_memberMap).end ();
|
||||
uint32_t k = 0;
|
||||
for (typename U::const_iterator j = begin; j != end; j++, k++)
|
||||
{
|
||||
if (k == i)
|
||||
{
|
||||
return std::pair<uint32_t, Ptr<Object> > ( k, (*j).second);
|
||||
break;
|
||||
}
|
||||
}
|
||||
NS_ASSERT (false);
|
||||
// quiet compiler.
|
||||
std::pair<uint32_t, Ptr<Object> > empty;
|
||||
return empty;
|
||||
}
|
||||
U T::*m_memberMap;
|
||||
} *spec = new MemberStdContainer ();
|
||||
spec->m_memberMap = memberMap;
|
||||
return Ptr<const AttributeAccessor> (spec, false);
|
||||
}
|
||||
|
||||
template <typename T, typename U, typename INDEX>
|
||||
Ptr<const AttributeAccessor>
|
||||
MakeObjectMapAccessor (Ptr<U> (T::*get) (INDEX) const,
|
||||
INDEX (T::*getN) (void) const)
|
||||
{
|
||||
struct MemberGetters : public ObjectMapAccessor
|
||||
{
|
||||
virtual bool DoGetN (const ObjectBase *object, uint32_t *n) const {
|
||||
const T *obj = dynamic_cast<const T *> (object);
|
||||
if (obj == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*n = (obj->*m_getN) ();
|
||||
return true;
|
||||
}
|
||||
virtual Ptr<Object> DoGet (const ObjectBase *object, uint32_t i) const {
|
||||
const T *obj = static_cast<const T *> (object);
|
||||
return (obj->*m_get) (i);
|
||||
}
|
||||
Ptr<U> (T::*m_get) (INDEX) const;
|
||||
INDEX (T::*m_getN) (void) const;
|
||||
} *spec = new MemberGetters ();
|
||||
spec->m_get = get;
|
||||
spec->m_getN = getN;
|
||||
return Ptr<const AttributeAccessor> (spec, false);
|
||||
}
|
||||
|
||||
template <typename T, typename U, typename INDEX>
|
||||
Ptr<const AttributeAccessor>
|
||||
MakeObjectMapAccessor (INDEX (T::*getN) (void) const,
|
||||
Ptr<U> (T::*get) (INDEX) const)
|
||||
{
|
||||
return MakeObjectMapAccessor (get, getN);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Ptr<const AttributeChecker> MakeObjectMapChecker (void)
|
||||
{
|
||||
return Create<internal::AnObjectMapChecker<T> > ();
|
||||
}
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* OBJECT_MAP_H */
|
||||
@@ -130,6 +130,7 @@ def build(bld):
|
||||
'model/string.cc',
|
||||
'model/pointer.cc',
|
||||
'model/object-vector.cc',
|
||||
'model/object-map.cc',
|
||||
'model/object-factory.cc',
|
||||
'model/global-value.cc',
|
||||
'model/trace-source-accessor.cc',
|
||||
@@ -207,6 +208,7 @@ def build(bld):
|
||||
'model/trace-source-accessor.h',
|
||||
'model/config.h',
|
||||
'model/object-vector.h',
|
||||
'model/object-map.h',
|
||||
'model/deprecated.h',
|
||||
'model/abort.h',
|
||||
'model/names.h',
|
||||
|
||||
Reference in New Issue
Block a user