give attribute power to Callback.

This commit is contained in:
Mathieu Lacage
2008-10-17 14:15:52 +02:00
parent 6f484b6ead
commit 36c0976a53
12 changed files with 188 additions and 190 deletions

View File

@@ -48,6 +48,12 @@ MakeAccessorHelper (T1 a1, T2 a2);
namespace ns3 {
template <typename T>
struct AccessorTrait
{
typedef typename TypeTraits<typename TypeTraits<T>::ReferencedType>::NonConstType Result;
};
template <typename T, typename U>
class AccessorHelper : public AttributeAccessor
{
@@ -100,7 +106,13 @@ DoMakeAccessorHelperOne (U T::*memberVariable)
{}
private:
virtual bool DoSet (T *object, const V *v) const {
(object->*m_memberVariable) = U (v->Get ());
typename AccessorTrait<U>::Result tmp;
bool ok = v->GetAccessor (tmp);
if (!ok)
{
return false;
}
(object->*m_memberVariable) = tmp;
return true;
}
virtual bool DoGet (const T *object, V *v) const {
@@ -163,7 +175,13 @@ DoMakeAccessorHelperOne (void (T::*setter) (U))
{}
private:
virtual bool DoSet (T *object, const V *v) const {
(object->*m_setter) (U (v->Get ()));
typename AccessorTrait<U>::Result tmp;
bool ok = v->GetAccessor (tmp);
if (!ok)
{
return false;
}
(object->*m_setter) (tmp);
return true;
}
virtual bool DoGet (const T *object, V *v) const {
@@ -196,7 +214,13 @@ DoMakeAccessorHelperTwo (void (T::*setter) (U),
{}
private:
virtual bool DoSet (T *object, const W *v) const {
(object->*m_setter) (v->Get ());
typename AccessorTrait<U>::Result tmp;
bool ok = v->GetAccessor (tmp);
if (!ok)
{
return false;
}
(object->*m_setter) (tmp);
return true;
}
virtual bool DoGet (const T *object, W *v) const {
@@ -239,7 +263,13 @@ DoMakeAccessorHelperTwo (bool (T::*setter) (U),
{}
private:
virtual bool DoSet (T *object, const W *v) const {
bool ok = (object->*m_setter) (v->Get ());
typename AccessorTrait<U>::Result tmp;
bool ok = v->GetAccessor (tmp);
if (!ok)
{
return false;
}
ok = (object->*m_setter) (tmp);
return ok;
}
virtual bool DoGet (const T *object, W *v) const {

View File

@@ -117,6 +117,11 @@ MakeSimpleAttributeChecker (std::string name, std::string underlying)
name##Value (const type &value); \
void Set (const type &value); \
type Get (void) const; \
template <typename T> \
bool GetAccessor (T &value) const { \
value = T (m_value); \
return true; \
} \
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); \
@@ -220,17 +225,6 @@ MakeSimpleAttributeChecker (std::string name, std::string underlying)
return MakeSimpleAttributeChecker<type##Value,type##Checker> (#type "Value", name); \
} \
/**
* \ingroup AttributeHelper
* \param type the name of the class
*
* This macro implements the conversion operators to and from
* instances of type Attribute. Typically invoked from xxx.cc.
*/
#define ATTRIBUTE_CONVERTER_IMPLEMENT(type)
/**
* \ingroup AttributeHelper
* \param type the name of the class
@@ -251,7 +245,6 @@ MakeSimpleAttributeChecker (std::string name, std::string underlying)
*/
#define ATTRIBUTE_HELPER_CPP(type) \
ATTRIBUTE_CHECKER_IMPLEMENT (type); \
ATTRIBUTE_CONVERTER_IMPLEMENT (type); \
ATTRIBUTE_VALUE_IMPLEMENT (type);

View File

@@ -29,6 +29,7 @@
#include "double.h"
#include "object-vector.h"
#include "traced-value.h"
#include "callback.h"
#include "trace-source-accessor.h"
#include "pointer.h"
@@ -71,9 +72,13 @@ private:
void NotifySourceValue (ValueClassTest old, ValueClassTest n) {
m_gotValue = n;
}
void NotifyCallbackValue (int8_t a) {
m_gotCbValue = a;
}
int64_t m_got1;
double m_got2;
ValueClassTest m_gotValue;
int16_t m_gotCbValue;
};
class Derived : public Object
@@ -171,6 +176,10 @@ public:
PointerValue (),
MakePointerAccessor (&AttributeObjectTest::m_ptr),
MakePointerChecker<Derived> ())
.AddAttribute ("Callback", "help text",
CallbackValue (),
MakeCallbackAccessor (&AttributeObjectTest::m_cbValue),
MakeCallbackChecker ())
;
return tid;
@@ -187,6 +196,13 @@ public:
m_cb (a,b,c);
}
void InvokeCbValue (int8_t a) {
if (!m_cbValue.IsNull ())
{
m_cbValue (a);
}
}
private:
void DoSetTestB (bool v) {
m_boolTestA = v;
@@ -224,6 +240,7 @@ private:
RandomVariable m_random;
std::vector<Ptr<Derived> > m_vector1;
std::vector<Ptr<Derived> > m_vector2;
Callback<void,int8_t> m_cbValue;
TracedValue<int8_t> m_intSrc1;
TracedValue<int8_t> m_intSrc2;
TracedCallback<double, int, float> m_cb;
@@ -492,6 +509,21 @@ AttributeTest::RunTests (void)
derived = ptr.Get<Derived> ();
NS_TEST_ASSERT (derived != 0);
p = CreateObject<AttributeObjectTest> ();
NS_TEST_ASSERT (p != 0);
m_gotCbValue = 1;
p->InvokeCbValue (2);
CallbackValue cbValue = MakeCallback (&AttributeTest::NotifyCallbackValue, this);
NS_TEST_ASSERT_EQUAL (m_gotCbValue, 1);
NS_TEST_ASSERT (p->SetAttributeFailSafe ("Callback",
cbValue));
p->InvokeCbValue (2);
NS_TEST_ASSERT_EQUAL (m_gotCbValue, 2);
NS_TEST_ASSERT (p->SetAttributeFailSafe ("Callback",
CallbackValue (MakeNullCallback<void,int8_t> ())));
p->InvokeCbValue (3);
NS_TEST_ASSERT_EQUAL (m_gotCbValue, 2);
return result;
}

View File

@@ -42,6 +42,8 @@ public:
BooleanValue (bool value);
void Set (bool value);
bool Get (void) const;
template <typename T>
bool GetAccessor (T &v) const;
operator bool () const;
@@ -52,6 +54,13 @@ private:
bool m_value;
};
template <typename T>
bool BooleanValue::GetAccessor (T &v) const
{
v = T (m_value);
return true;
}
std::ostream & operator << (std::ostream &os, const BooleanValue &value);
ATTRIBUTE_CHECKER_DEFINE (Boolean);

38
src/core/callback.cc Normal file
View File

@@ -0,0 +1,38 @@
#include "callback.h"
namespace ns3 {
CallbackValue::CallbackValue ()
: m_value ()
{}
CallbackValue::CallbackValue (const CallbackBase &base)
: m_value (base)
{}
CallbackValue::~CallbackValue ()
{}
void
CallbackValue::Set (CallbackBase base)
{
m_value = base;
}
Ptr<AttributeValue>
CallbackValue::Copy (void) const
{
return Create<CallbackValue> (m_value);
}
std::string
CallbackValue::SerializeToString (Ptr<const AttributeChecker> checker) const
{
std::ostringstream oss;
oss << PeekPointer (m_value.GetImpl ());
return oss.str ();
}
bool
CallbackValue::DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker)
{
return false;
}
ATTRIBUTE_CHECKER_IMPLEMENT (Callback);
} // namespace ns3

View File

@@ -25,6 +25,8 @@
#include "fatal-error.h"
#include "empty.h"
#include "type-traits.h"
#include "attribute.h"
#include "attribute-helper.h"
#include <typeinfo>
namespace ns3 {
@@ -399,7 +401,11 @@ private:
return static_cast<CallbackImpl<R,T1,T2,T3,T4,T5,T6> *> (PeekPointer (m_impl));
}
bool DoCheckType (Ptr<const CallbackImplBase> other) const {
if (dynamic_cast<const CallbackImpl<R,T1,T2,T3,T4,T5,T6> *> (PeekPointer (other)) != 0)
if (other != 0 && dynamic_cast<const CallbackImpl<R,T1,T2,T3,T4,T5,T6> *> (PeekPointer (other)) != 0)
{
return true;
}
else if (other == 0)
{
return true;
}
@@ -753,9 +759,45 @@ Callback<R,T1,T2,T3,T4,T5> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4,T5), AR
Create<BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4,T5),R,TX,T1,T2,T3,T4,T5> > (fnPtr, a);
return Callback<R,T1,T2,T3,T4,T5> (impl);
}
} // namespace ns3
namespace ns3 {
}; // namespace ns3
class CallbackValue : public AttributeValue
{
public:
CallbackValue ();
CallbackValue (const CallbackBase &base);
virtual ~CallbackValue ();
void Set (CallbackBase base);
template <typename T>
bool GetAccessor (T &value) 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:
CallbackBase m_value;
};
ATTRIBUTE_ACCESSOR_DEFINE(Callback);
ATTRIBUTE_CHECKER_DEFINE (Callback);
} // namespace ns3
namespace ns3 {
template <typename T>
bool CallbackValue::GetAccessor (T &value) const
{
if (value.CheckType (m_value))
{
value.Assign (m_value);
return true;
}
return false;
}
} // namespace ns3
#endif /* CALLBACK_H */

View File

@@ -17,8 +17,8 @@
*
* Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef NS3_CONFIG_H
#define NS3_CONFIG_H
#ifndef CONFIG_H
#define CONFIG_H
#include "ptr.h"
#include <string>
@@ -139,4 +139,4 @@ Ptr<Object> GetRootNamespaceObject (uint32_t i);
} // namespace ns3
#endif /* NS3_CONFIG_H */
#endif /* CONFIG_H */

View File

@@ -39,7 +39,6 @@ EnumValue::Get (void) const
{
return m_v;
}
Ptr<AttributeValue>
EnumValue::Copy (void) const
{

View File

@@ -41,6 +41,8 @@ public:
EnumValue (int v);
void Set (int v);
int Get (void) const;
template <typename T>
bool GetAccessor (T &v) const;
virtual Ptr<AttributeValue> Copy (void) const;
virtual std::string SerializeToString (Ptr<const AttributeChecker> checker) const;
@@ -50,6 +52,13 @@ private:
int m_v;
};
template <typename T>
bool EnumValue::GetAccessor (T &v) const
{
v = T (m_v);
return true;
}
class EnumChecker : public AttributeChecker
{
public:

View File

@@ -50,6 +50,9 @@ public:
template <typename T>
Ptr<T> Get (void) const;
template <typename T>
bool GetAccessor (Ptr<T> &v) const;
template <typename T>
operator Ptr<T> () const;
@@ -61,23 +64,6 @@ private:
Ptr<Object> m_value;
};
template <typename T, typename U>
Ptr<const AttributeAccessor>
MakePointerAccessor (Ptr<U> T::*memberVariable);
template <typename T, typename U>
Ptr<const AttributeAccessor>
MakePointerAccessor (void (T::*setter) (Ptr<U>));
template <typename T, typename U>
Ptr<const AttributeAccessor>
MakePointerAccessor (Ptr<U> (T::*getter) (void) const);
template <typename T, typename U>
Ptr<const AttributeAccessor>
MakePointerAccessor (void (T::*setter) (Ptr<U>),
Ptr<U> (T::*getter) (void) const);
template <typename T, typename U>
Ptr<const AttributeAccessor>
MakePointerAccessor (Ptr<U> (T::*getter) (void) const,
void (T::*setter) (Ptr<U>));
class PointerChecker : public AttributeChecker
{
@@ -142,57 +128,8 @@ class APointerChecker : public PointerChecker
}
};
/********************************************************
* The Accessor associated to
* PointerValue
********************************************************/
template <typename T, typename U>
class PointerAccessor : public AttributeAccessor
{
public:
virtual ~PointerAccessor () {}
virtual bool Set (ObjectBase * object, const AttributeValue &val) const {
T *obj = dynamic_cast<T *> (object);
if (obj == 0)
{
return false;
}
const PointerValue *value = dynamic_cast<const PointerValue *> (&val);
if (value == 0)
{
return false;
}
Ptr<U> ptr = dynamic_cast<U*> (PeekPointer (value->GetObject ()));
if (ptr == 0)
{
return false;
}
DoSet (obj, ptr);
return true;
}
virtual bool Get (const ObjectBase * object, AttributeValue &val) const {
const T *obj = dynamic_cast<const T *> (object);
if (obj == 0)
{
return false;
}
PointerValue *value = dynamic_cast<PointerValue *> (&val);
if (value == 0)
{
return false;
}
value->Set (DoGet (obj));
return true;
}
private:
virtual void DoSet (T *object, Ptr<U> value) const = 0;
virtual Ptr<U> DoGet (const T *object) const = 0;
};
} // namespace internal
template <typename T>
PointerValue::PointerValue (const Ptr<T> &object)
{
@@ -220,112 +157,21 @@ PointerValue::operator Ptr<T> () const
return Get<T> ();
}
template <typename T, typename U>
Ptr<const AttributeAccessor>
MakePointerAccessor (Ptr<U> T::*memberVariable)
template <typename T>
bool
PointerValue::GetAccessor (Ptr<T> &v) const
{
struct MemberVariable : public internal::PointerAccessor<T,U>
{
Ptr<U> T::*m_memberVariable;
virtual void DoSet (T *object, Ptr<U> value) const {
(object->*m_memberVariable) = value;
}
virtual Ptr<U> DoGet (const T *object) const {
return object->*m_memberVariable;
}
virtual bool HasGetter (void) const {
return true;
}
virtual bool HasSetter (void) const {
return true;
}
} *spec = new MemberVariable ();
spec->m_memberVariable = memberVariable;
return Ptr<const AttributeAccessor> (spec, false);
}
template <typename T, typename U>
Ptr<const AttributeAccessor>
MakePointerAccessor (void (T::*setter) (Ptr<U>))
{
struct MemberMethod : public internal::PointerAccessor<T,U>
{
void (T::*m_setter) (Ptr<U>);
virtual void DoSet (T *object, Ptr<U> value) const {
(object->*m_setter) (value);
}
virtual Ptr<U> DoGet (const T *object) const {
return 0;
//return (object->*m_getter) ();
}
virtual bool HasGetter (void) const {
Ptr<T> ptr = dynamic_cast<T*> (PeekPointer (m_value));
if (ptr == 0)
{
return false;
}
virtual bool HasSetter (void) const {
return true;
}
} *spec = new MemberMethod ();
spec->m_setter = setter;
return Ptr<const AttributeAccessor> (spec, false);
v = ptr;
return true;
}
template <typename T, typename U>
Ptr<const AttributeAccessor>
MakePointerAccessor (Ptr<U> (T::*getter) (void) const)
{
struct MemberMethod : public internal::PointerAccessor<T,U>
{
Ptr<U> (T::*m_getter) (void) const;
virtual void DoSet (T *object, Ptr<U> value) const {
//(object->*m_setter) (value);
}
virtual Ptr<U> DoGet (const T *object) const {
return (object->*m_getter) ();
}
virtual bool HasGetter (void) const {
return true;
}
virtual bool HasSetter (void) const {
return false;
}
} *spec = new MemberMethod ();
spec->m_getter = getter;
return Ptr<const AttributeAccessor> (spec, false);
}
template <typename T, typename U>
Ptr<const AttributeAccessor>
MakePointerAccessor (void (T::*setter) (Ptr<U>),
Ptr<U> (T::*getter) (void) const)
{
return MakePointerAccessor (getter, setter);
}
template <typename T, typename U>
Ptr<const AttributeAccessor>
MakePointerAccessor (Ptr<U> (T::*getter) (void) const,
void (T::*setter) (Ptr<U>))
{
struct MemberMethod : public internal::PointerAccessor<T,U>
{
void (T::*m_setter) (Ptr<U>);
Ptr<U> (T::*m_getter) (void) const;
virtual void DoSet (T *object, Ptr<U> value) const {
(object->*m_setter) (value);
}
virtual Ptr<U> DoGet (const T *object) const {
return (object->*m_getter) ();
}
virtual bool HasGetter (void) const {
return true;
}
virtual bool HasSetter (void) const {
return true;
}
} *spec = new MemberMethod ();
spec->m_setter = setter;
spec->m_getter = getter;
return Ptr<const AttributeAccessor> (spec, false);
}
ATTRIBUTE_ACCESSOR_DEFINE (Pointer);
template <typename T>
Ptr<AttributeChecker>

View File

@@ -3,7 +3,6 @@
namespace ns3 {
ATTRIBUTE_CHECKER_IMPLEMENT_WITH_NAME (String, "std::string");
ATTRIBUTE_CONVERTER_IMPLEMENT (String);
ATTRIBUTE_VALUE_IMPLEMENT_WITH_NAME (std::string, String);
} // namespace ns3

View File

@@ -72,6 +72,7 @@ def build(bld):
'traced-callback.cc',
'trace-source-accessor.cc',
'config.cc',
'callback.cc',
]
core.uselib = 'RT'