Thu Jul 16 17:38:46 2015 +0200 1756784 Added a way to deprecate attributes and trace sources  [Natale Patriciello] diff --git a/src/core/model/attribute.cc b/src/core/model/attribute.cc index 7f42752..299f6de 100644 --- a/src/core/model/attribute.cc +++ b/src/core/model/attribute.cc @@ -108,5 +108,89 @@ EmptyAttributeValue::DeserializeFromString (std::string value, Ptr +EmptyAttributeChecker::Create (void) const +{ + static EmptyAttributeValue t; + return Ptr (&t, false); +} + +bool +EmptyAttributeChecker::Copy (const AttributeValue &source, AttributeValue &destination) const +{ + (void) source; + (void) destination; + return true; +} + } // namespace ns3 diff --git a/src/core/model/attribute.h b/src/core/model/attribute.h index 44b2f08..bc292d1 100644 --- a/src/core/model/attribute.h +++ b/src/core/model/attribute.h @@ -222,8 +222,6 @@ public: * \return true if copy was successful */ virtual bool Copy (const AttributeValue &source, AttributeValue &destination) const = 0; - - }; /** @@ -259,6 +257,53 @@ private: virtual bool DeserializeFromString (std::string value, Ptr checker); }; +/** + * \brief An accessor for EmptyAttributeValue + * + * Does nothing, since every EmptyAttributeValue is the same. + */ +class EmptyAttributeAccessor : public AttributeAccessor +{ +public: + EmptyAttributeAccessor (); + ~EmptyAttributeAccessor (); + virtual bool Set (ObjectBase * object, const AttributeValue &value) const; + virtual bool Get (const ObjectBase * object, AttributeValue &attribute) const; + virtual bool HasGetter (void) const; + virtual bool HasSetter (void) const; +}; + +static inline Ptr +MakeEmptyAttributeAccessor () +{ + return Ptr (new EmptyAttributeAccessor (), false); +} + +/** + * \brief A checker for EmptyAttributeValue + * + * Does nothing, since every EmptyAttributeValue does not contain anything and + * is, of course, valid. + */ +class EmptyAttributeChecker : public AttributeChecker +{ +public: + EmptyAttributeChecker (); + ~EmptyAttributeChecker (); + virtual bool Check (const AttributeValue &value) const; + virtual std::string GetValueTypeName (void) const; + virtual bool HasUnderlyingTypeInformation (void) const; + virtual std::string GetUnderlyingTypeInformation (void) const; + virtual Ptr Create (void) const; + virtual bool Copy (const AttributeValue &source, AttributeValue &destination) const; +}; + +static inline Ptr +MakeEmptyAttributeChecker () +{ + return Ptr (new EmptyAttributeChecker (), false); +} + } // namespace ns3 #endif /* ATTRIBUTE_H */ diff --git a/src/core/model/trace-source-accessor.h b/src/core/model/trace-source-accessor.h index c24f751..315fe30 100644 --- a/src/core/model/trace-source-accessor.h +++ b/src/core/model/trace-source-accessor.h @@ -115,6 +115,19 @@ public: template Ptr MakeTraceSourceAccessor (T a); +/** + * \ingroup tracing + * + * Create an empty TraceSourceAccessor. + * + * \returns The empty TraceSourceAccessor (runtime exception if used) + */ +static inline +Ptr MakeEmptyTraceSourceAccessor () +{ + return Ptr (0); +} + } // namespace ns3 diff --git a/src/core/model/traced-value.h b/src/core/model/traced-value.h index e477c03..499b030 100644 --- a/src/core/model/traced-value.h +++ b/src/core/model/traced-value.h @@ -240,6 +240,7 @@ public: typedef void (* Int32Callback) (const int32_t oldValue, const int32_t newValue); typedef void (* Uint32Callback)(const uint32_t oldValue, const uint32_t newValue); typedef void (* DoubleCallback)(const double oldValue, const double newValue); + typedef void (* VoidCallback) (); /**@}*/ private: diff --git a/src/core/model/type-id.cc b/src/core/model/type-id.cc index 31d4a99..3704759 100644 --- a/src/core/model/type-id.cc +++ b/src/core/model/type-id.cc @@ -101,17 +101,21 @@ public: uint32_t flags, Ptr initialValue, Ptr spec, - Ptr checker); + Ptr checker, + TypeId::SupportLevel supportLevel = TypeId::ACTIVE, + const std::string &supportMsg = ""); void SetAttributeInitialValue(uint16_t uid, uint32_t i, Ptr initialValue); uint32_t GetAttributeN (uint16_t uid) const; struct TypeId::AttributeInformation GetAttribute(uint16_t uid, uint32_t i) const; void AddTraceSource (uint16_t uid, - std::string name, + std::string name, std::string help, Ptr accessor, - std::string callback); + std::string callback, + TypeId::SupportLevel supportLevel = TypeId::ACTIVE, + const std::string &supportMsg = ""); uint32_t GetTraceSourceN (uint16_t uid) const; struct TypeId::TraceSourceInformation GetTraceSource(uint16_t uid, uint32_t i) const; bool MustHideFromDocumentation (uint16_t uid) const; @@ -411,17 +415,19 @@ IidManager::HasAttribute (uint16_t uid, } void -IidManager::AddAttribute (uint16_t uid, +IidManager::AddAttribute (uint16_t uid, std::string name, - std::string help, + std::string help, uint32_t flags, Ptr initialValue, Ptr accessor, - Ptr checker) + Ptr checker, + TypeId::SupportLevel supportLevel, + const std::string &supportMsg) { NS_LOG_FUNCTION (this << uid << name << help << flags << initialValue << accessor << checker); struct IidInformation *information = LookupInformation (uid); - if (HasAttribute (uid, name)) + if (supportLevel == TypeId::ACTIVE && HasAttribute (uid, name)) { NS_FATAL_ERROR ("Attribute \"" << name << "\" already registered on tid=\"" << information->name << "\""); @@ -434,6 +440,8 @@ IidManager::AddAttribute (uint16_t uid, info.originalInitialValue = initialValue; info.accessor = accessor; info.checker = checker; + info.supportLevel = supportLevel; + info.supportMsg = supportMsg; information->attributes.push_back (info); } void @@ -498,11 +506,13 @@ IidManager::AddTraceSource (uint16_t uid, std::string name, std::string help, Ptr accessor, - std::string callback) + std::string callback, + TypeId::SupportLevel supportLevel, + const std::string &supportMsg) { NS_LOG_FUNCTION (this << uid << name << help << accessor); struct IidInformation *information = LookupInformation (uid); - if (HasTraceSource (uid, name)) + if (supportLevel == TypeId::ACTIVE && HasTraceSource (uid, name)) { NS_FATAL_ERROR ("Trace source \"" << name << "\" already registered on tid=\"" << information->name << "\""); @@ -512,6 +522,8 @@ IidManager::AddTraceSource (uint16_t uid, source.help = help; source.accessor = accessor; source.callback = callback; + source.supportLevel = supportLevel; + source.supportMsg = supportMsg; information->traceSources.push_back (source); } uint32_t @@ -625,6 +637,17 @@ TypeId::LookupAttributeByName (std::string name, struct TypeId::AttributeInforma struct TypeId::AttributeInformation tmp = tid.GetAttribute(i); if (tmp.name == name) { + if (tmp.supportLevel == TypeId::DEPRECATED) + { + NS_LOG_UNCOND ("Attribute " << name << " is deprecated: " << + tmp.supportMsg); + /** should return true or false? */ + } + else if (tmp.supportLevel == TypeId::OBSOLETED) + { + NS_FATAL_ERROR ("Attribute " << name << + " is obsolete, with no fallback: " << tmp.supportMsg); + } *info = tmp; return true; } @@ -726,27 +749,32 @@ TypeId::DoAddConstructor (Callback cb) } TypeId -TypeId::AddAttribute (std::string name, - std::string help, +TypeId::AddAttribute (std::string name, std::string help, const AttributeValue &initialValue, Ptr accessor, - Ptr checker) + Ptr checker, + SupportLevel supportLevel, + const std::string &supportMsg) { NS_LOG_FUNCTION (this << name << help << &initialValue << accessor << checker); - Singleton::Get ()->AddAttribute (m_tid, name, help, ATTR_SGC, initialValue.Copy (), accessor, checker); + Singleton::Get ()->AddAttribute (m_tid, name, help, ATTR_SGC, + initialValue.Copy (), accessor, + checker, supportLevel, supportMsg); return *this; } TypeId -TypeId::AddAttribute (std::string name, - std::string help, - uint32_t flags, +TypeId::AddAttribute (std::string name, std::string help, uint32_t flags, const AttributeValue &initialValue, Ptr accessor, - Ptr checker) + Ptr checker, + SupportLevel supportLevel, + const std::string &supportMsg) { NS_LOG_FUNCTION (this << name << help << flags << &initialValue << accessor << checker); - Singleton::Get ()->AddAttribute (m_tid, name, help, flags, initialValue.Copy (), accessor, checker); + Singleton::Get ()->AddAttribute (m_tid, name, help, flags, + initialValue.Copy (), accessor, + checker, supportLevel, supportMsg); return *this; } @@ -822,10 +850,13 @@ TypeId TypeId::AddTraceSource (std::string name, std::string help, Ptr accessor, - std::string callback) + std::string callback, SupportLevel supportLevel, + const std::string &supportMsg) { NS_LOG_FUNCTION (this << name << help << accessor); - Singleton::Get ()->AddTraceSource (m_tid, name, help, accessor, callback); + Singleton::Get ()->AddTraceSource (m_tid, name, help, accessor, + callback, supportLevel, + supportMsg); return *this; } @@ -851,6 +882,17 @@ TypeId::LookupTraceSourceByName (std::string name) const struct TypeId::TraceSourceInformation info = tid.GetTraceSource (i); if (info.name == name) { + if (info.supportLevel == TypeId::DEPRECATED) + { + NS_LOG_UNCOND ("TraceSource " << name << " is deprecated: " << + info.supportMsg); + } + else if (info.supportLevel == TypeId::OBSOLETED) + { + NS_FATAL_ERROR ("TraceSource " << name << + " is obsolete, with no fallback: " << info.supportMsg); + } + return info.accessor; } } diff --git a/src/core/model/type-id.h b/src/core/model/type-id.h index 57de930..a1f910e 100644 --- a/src/core/model/type-id.h +++ b/src/core/model/type-id.h @@ -66,6 +66,15 @@ public: ATTR_CONSTRUCT = 1<<2, /**< The attribute can be written at construction-time */ ATTR_SGC = ATTR_GET | ATTR_SET | ATTR_CONSTRUCT, /**< The attribute can be read, and written at any time */ }; + /** + * \brief The level of deprecation of attribute or trace sources + */ + enum SupportLevel + { + ACTIVE, //!< Attribute or trace source is currently used + DEPRECATED, //!< Attribute or trace source is deprecated; user is warned + OBSOLETED //!< Attribute or trace source is not used anymore; simulation fails + }; struct AttributeInformation { std::string name; std::string help; @@ -74,12 +83,16 @@ public: Ptr initialValue; Ptr accessor; Ptr checker; + TypeId::SupportLevel supportLevel; + std::string supportMsg; }; struct TraceSourceInformation { std::string name; std::string help; std::string callback; Ptr accessor; + TypeId::SupportLevel supportLevel; + std::string supportMsg; }; /** @@ -285,6 +298,10 @@ public: * \param initialValue the initial value for this attribute. * \param accessor an instance of the associated AttributeAccessor subclass. * \param checker an instance of the associated AttributeChecker subclass. + * \param supportLevel deprecation status of the attribute + * \param supportMsg in case of deprecation, the message should indicate how + * to refactor user code to the current facilities. The name of the + * deprecated Attribute is already printed. * \returns this TypeId instance * * Record in this TypeId the fact that a new attribute exists. @@ -293,7 +310,9 @@ public: std::string help, const AttributeValue &initialValue, Ptr accessor, - Ptr checker); + Ptr checker, + SupportLevel supportLevel = ACTIVE, + const std::string &supportMsg = ""); /** * \param i the attribute to manipulate @@ -311,6 +330,11 @@ public: * \param initialValue the initial value for this attribute. * \param accessor an instance of the associated AttributeAccessor subclass. * \param checker an instance of the associated AttributeChecker subclass. + * \param supportLevel deprecation status of the attribute + * \param supportMsg if the support level of the Attribute is DEPRECATED or + * OBSOLETED, this message should indicate how + * to refactor user code to the current facilities. The name + * of the deprecated Attribute is already printed. * \returns this TypeId instance * * Record in this TypeId the fact that a new attribute exists. @@ -320,7 +344,9 @@ public: uint32_t flags, const AttributeValue &initialValue, Ptr accessor, - Ptr checker); + Ptr checker, + SupportLevel supportLevel = ACTIVE, + const std::string &supportMsg = ""); /** * \param name the name of the new trace source @@ -345,12 +371,19 @@ public: * used to connect/disconnect sinks to this trace source. * \param callback fully qualified typedef name for the callback signature. * Generally this should begin with the "ns3::" namespace qualifier. + * \param supportLevel deprecation status of the trace source + * \param supportMsg if the support level of the TraceSource is DEPRECATED or + * OBSOLETED, this message should indicate how + * to refactor user code to the current facilities. The name + * of the deprecated TraceSource is already printed. * \returns this TypeId instance. */ TypeId AddTraceSource (std::string name, std::string help, Ptr accessor, - std::string callback); + std::string callback, + SupportLevel supportLevel = ACTIVE, + const std::string &supportMsg = ""); TypeId HideFromDocumentation (void);