diff --git a/dart/common/Addon.cpp b/dart/common/Addon.cpp index c201ba973029f..f6a1226f50aaa 100644 --- a/dart/common/Addon.cpp +++ b/dart/common/Addon.cpp @@ -68,12 +68,6 @@ const Addon::Properties* Addon::getAddonProperties() const return nullptr; } -//============================================================================== -bool Addon::isOptional(AddonManager* /*oldManager*/) -{ - return true; -} - //============================================================================== Addon::Addon(AddonManager* manager) { diff --git a/dart/common/Addon.h b/dart/common/Addon.h index cf5b8f4750d66..658cb408219a9 100644 --- a/dart/common/Addon.h +++ b/dart/common/Addon.h @@ -111,19 +111,6 @@ class Addon /// which implies that the Addon has no properties. virtual const Properties* getAddonProperties() const; - /// This function will be called if the user is attempting to delete the Addon - /// but not immediately replacing it with another Addon of the same type. The - /// incoming argument will point to the AddonManager that had been holding - /// this Addon. - /// - /// If your Addon is mandatory for the AddonManager type that is passed in - /// here, then you should perform error handling in this function, and you - /// should return false to indicate that the operation is not permitted. If - /// you return false, then the Addon will NOT be removed from its Manager. - /// - /// By default, this simply returns true. - virtual bool isOptional(AddonManager* oldManager); - protected: /// Constructor diff --git a/dart/common/AddonManager.h b/dart/common/AddonManager.h index 9ebe37b80ed92..b5a6674f5d695 100644 --- a/dart/common/AddonManager.h +++ b/dart/common/AddonManager.h @@ -38,6 +38,7 @@ #define DART_COMMON_ADDONMANAGER_H_ #include +#include #include #include @@ -54,27 +55,8 @@ namespace common { /// on average in log(N) time. Most often, a class that accepts Addons will have /// certain Addon types that it will need to access frequently, and it would be /// beneficial to have constant-time access to those Addon types. To get -/// constant-time access to specific Addon types, there are FOUR macros that you -/// should use in your derived class: -/// -/// DART_ENABLE_ADDON_SPECIALIZATION() must be declared once in the derived -/// class's definition, under a 'public:' declaration range. -/// -/// DART_SPECIALIZE_ADDON_INTERNAL( AddonType ) must be declared once for each -/// AddonType that you want to specialize. It should be placed in the derived -/// class's definition, under a 'public:' declaration range. -/// -/// DART_SPECIALIZE_ADDON_EXTERNAL( Derived, AddonType ) must be declared once -/// for each AddonType that you want to specialize. It should be placed -/// immediately after the class's definition in the same header file as the -/// derived class, inside of the same namespace as the derived class. This macro -/// defines a series of templated functions, so it should go in a header, and -/// not in a source file. -/// -/// DART_INSTANTIATE_SPECIALIZED_ADDON( AddonType ) must be declared once for -/// each AddonType that you want to specialize. It should be placed inside the -/// constructor of the derived class, preferably before anything else is done -/// inside the body of the constructor. +/// constant-time access to specific Addon types, you can use the templated +/// class SpecializedForAddon. class AddonManager { public: @@ -86,10 +68,21 @@ class AddonManager using Properties = ExtensibleMapHolder; using AddonMap = std::map< std::type_index, std::unique_ptr >; + using RequiredAddonSet = std::unordered_set; /// Virtual destructor virtual ~AddonManager() = default; + /// Default constructor + AddonManager() = default; + + /// It is currently unsafe to copy an AddonManager + // TODO(MXG): Consider making this safe by cloning Addons into the new copy + AddonManager(const AddonManager&) = delete; + + /// It is currently unsafe to move an AddonManager + AddonManager(AddonManager&&) = delete; + /// Check if this AddonManager currently has a certain type of Addon template bool has() const; @@ -134,6 +127,10 @@ class AddonManager template static constexpr bool isSpecializedFor(); + /// Check if this Manager requires this specific type of Addon + template + bool requires() const; + /// Set the states of the addons in this AddonManager based on the given /// AddonManager::State. The states of any Addon types that do not exist /// within this manager will be ignored. @@ -175,6 +172,10 @@ class AddonManager /// A map that relates the type of Addon to its pointer AddonMap mAddonMap; + + /// A set containing type information for Addons which are not allowed to + /// leave this manager. + RequiredAddonSet mRequiredAddons; }; } // namespace common diff --git a/dart/common/AddonManagerJoiner.h b/dart/common/AddonManagerJoiner.h index b01aa4ca548e0..5ac57d06a31e2 100644 --- a/dart/common/AddonManagerJoiner.h +++ b/dart/common/AddonManagerJoiner.h @@ -52,9 +52,9 @@ template class AddonManagerJoiner : public Base1 { }; /// AddonManagerJoiner allows classes that inherit from various -/// SpecializedAddonManager types to be inherited by a single derived class. +/// SpecializedForAddon types to be inherited by a single derived class. /// This class solves the diamond-of-death problem for multiple -/// SpecializedAddonManager inheritance. +/// SpecializedForAddon inheritance. template class AddonManagerJoiner : public Base1, public Base2 { diff --git a/dart/common/RequiresAddon.h b/dart/common/RequiresAddon.h new file mode 100644 index 0000000000000..15b58a772d980 --- /dev/null +++ b/dart/common/RequiresAddon.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2016, Georgia Tech Research Corporation + * All rights reserved. + * + * Author(s): Michael X. Grey + * + * Georgia Tech Graphics Lab and Humanoid Robotics Lab + * + * Directed by Prof. C. Karen Liu and Prof. Mike Stilman + * + * + * This file is provided under the following "BSD-style" License: + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DART_COMMON_REQUIRESADDON_H_ +#define DART_COMMON_REQUIRESADDON_H_ + +#include "dart/common/SpecializedForAddon.h" + +namespace dart { +namespace common { + +//============================================================================== +/// RequiresAddon allows classes that inherit AddonManager to know which Addons +/// are required for their operation. This guarantees that there is no way for +/// a required Addon do not get unexpectedly removed from their manager. +/// +/// Required Addons are also automatically specialized for. +template +class RequiresAddon { }; + +//============================================================================== +template +class RequiresAddon : public virtual SpecializedForAddon +{ +public: + + /// Default constructor. This is where the base AddonManager is informed that + /// the Addon type is required. + RequiresAddon(); + +}; + +//============================================================================== +template +class RequiresAddon : + public AddonManagerJoiner< Virtual< RequiresAddon >, + Virtual< RequiresAddon > > { }; + +} // namespace common +} // namespace dart + +#include "dart/common/detail/RequiresAddon.h" + +#endif // DART_COMMON_REQUIRESADDON_H_ diff --git a/dart/common/SpecializedAddonManager.h b/dart/common/SpecializedForAddon.h similarity index 90% rename from dart/common/SpecializedAddonManager.h rename to dart/common/SpecializedForAddon.h index 62dd5acb8a4e5..d998eed0f9686 100644 --- a/dart/common/SpecializedAddonManager.h +++ b/dart/common/SpecializedForAddon.h @@ -46,18 +46,18 @@ namespace common { /// Declaration of the variadic template template -class SpecializedAddonManager { }; +class SpecializedForAddon { }; //============================================================================== -/// SpecializedAddonManager allows classes that inherit AddonManager to have +/// SpecializedForAddon allows classes that inherit AddonManager to have /// constant-time access to a specific type of Addon template -class SpecializedAddonManager : public virtual AddonManager +class SpecializedForAddon : public virtual AddonManager { public: /// Default Constructor - SpecializedAddonManager(); + SpecializedForAddon(); /// Check if this AddonManager currently has a certain type of Addon template @@ -173,23 +173,23 @@ class SpecializedAddonManager : public virtual AddonManager /// Return true static constexpr bool _isSpecializedFor(type); - /// Iterator that points to the Addon of this SpecializedAddonManager + /// Iterator that points to the Addon of this SpecializedForAddon AddonManager::AddonMap::iterator mSpecAddonIterator; }; //============================================================================== -/// This is the variadic version of the SpecializedAddonManager class which +/// This is the variadic version of the SpecializedForAddon class which /// allows you to include arbitrarily many specialized types in the /// specialization. template -class SpecializedAddonManager : - public AddonManagerJoiner< Virtual< SpecializedAddonManager >, - Virtual< SpecializedAddonManager > > { }; +class SpecializedForAddon : + public AddonManagerJoiner< Virtual< SpecializedForAddon >, + Virtual< SpecializedForAddon > > { }; } // namespace common } // namespace dart -#include "dart/common/detail/SpecializedAddonManager.h" +#include "dart/common/detail/SpecializedForAddon.h" #endif // DART_COMMON_SPECIALIZEDADDONMANAGER_H_ diff --git a/dart/common/detail/AddonManager.h b/dart/common/detail/AddonManager.h index 4e185babbf79a..993534b7b9057 100644 --- a/dart/common/detail/AddonManager.h +++ b/dart/common/detail/AddonManager.h @@ -39,10 +39,11 @@ #include "dart/common/AddonManager.h" -#define DART_COMMON_CHECK_ILLEGAL_ADDON_ERASE( Func, it, ReturnType )\ - if(it ->second && !it ->second->isOptional(this))\ +#define DART_COMMON_CHECK_ILLEGAL_ADDON_ERASE( Func, T, ReturnType )\ + if(requires< T >())\ {\ - dterr << "[AddonManager::" #Func << "] Illegal request to remove Addon!\n";\ + dterr << "[AddonManager::" #Func << "] Illegal request to remove required "\ + << "Addon [" << typeid(T).name() << "]!\n";\ assert(false);\ return ReturnType ;\ } @@ -114,7 +115,7 @@ template void AddonManager::erase() { AddonMap::iterator it = mAddonMap.find( typeid(T) ); - DART_COMMON_CHECK_ILLEGAL_ADDON_ERASE(erase, it, DART_BLANK) + DART_COMMON_CHECK_ILLEGAL_ADDON_ERASE(erase, T, DART_BLANK) if(mAddonMap.end() != it) it->second = nullptr; } @@ -125,7 +126,7 @@ std::unique_ptr AddonManager::release() { std::unique_ptr extraction = nullptr; AddonMap::iterator it = mAddonMap.find( typeid(T) ); - DART_COMMON_CHECK_ILLEGAL_ADDON_ERASE(release, it, nullptr) + DART_COMMON_CHECK_ILLEGAL_ADDON_ERASE(release, T, nullptr) if(mAddonMap.end() != it) extraction = std::unique_ptr(static_cast(it->second.release())); @@ -139,6 +140,13 @@ constexpr bool AddonManager::isSpecializedFor() return false; } +//============================================================================== +template +bool AddonManager::requires() const +{ + return (mRequiredAddons.find(typeid(T)) != mRequiredAddons.end()); +} + } // namespace common } // namespace dart @@ -146,22 +154,22 @@ constexpr bool AddonManager::isSpecializedFor() // Create non-template alternatives to AddonManager functions #define DART_BAKE_SPECIALIZED_ADDON_IRREGULAR( TypeName, AddonName )\ inline bool has ## AddonName () const\ - { return has(); }\ + { return this->template has(); }\ inline TypeName * get ## AddonName ()\ - { return get(); }\ + { return this->template get(); }\ inline const TypeName* get ## AddonName () const\ - { return get(); }\ + { return this->template get(); }\ inline void set ## AddonName (const TypeName * addon)\ - { set(addon); }\ + { this->template set(addon); }\ inline void set ## AddonName (std::unique_ptr< TypeName >&& addon)\ - { set(std::move(addon)); }\ + { this->template set(std::move(addon)); }\ template \ inline TypeName * create ## AddonName (Args&&... args)\ - { return create(std::forward(args)...); }\ + { return this->template create(std::forward(args)...); }\ inline void erase ## AddonName ()\ - { erase(); }\ + { this->template erase(); }\ inline std::unique_ptr< TypeName > release ## AddonName ()\ - { return release(); } + { return this->template release(); } //============================================================================== #define DART_BAKE_SPECIALIZED_ADDON(AddonName)\ diff --git a/dart/common/detail/RequiresAddon.h b/dart/common/detail/RequiresAddon.h new file mode 100644 index 0000000000000..ed319a7c16995 --- /dev/null +++ b/dart/common/detail/RequiresAddon.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016, Georgia Tech Research Corporation + * All rights reserved. + * + * Author(s): Michael X. Grey + * + * Georgia Tech Graphics Lab and Humanoid Robotics Lab + * + * Directed by Prof. C. Karen Liu and Prof. Mike Stilman + * + * + * This file is provided under the following "BSD-style" License: + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DART_COMMON_DETAIL_REQUIRESADDON_H_ +#define DART_COMMON_DETAIL_REQUIRESADDON_H_ + +#include "dart/common/RequiresAddon.h" + +namespace dart { +namespace common { + +//============================================================================== +template +RequiresAddon::RequiresAddon() +{ + AddonManager::mRequiredAddons.insert(typeid(ReqAddon)); +} + +} // namespace common +} // namespace dart + +#endif // DART_COMMON_DETAIL_REQUIRESADDON_H_ diff --git a/dart/common/detail/SpecializedAddonManager.h b/dart/common/detail/SpecializedForAddon.h similarity index 81% rename from dart/common/detail/SpecializedAddonManager.h rename to dart/common/detail/SpecializedForAddon.h index e125a6ec1aa2c..c83cd4ed00571 100644 --- a/dart/common/detail/SpecializedAddonManager.h +++ b/dart/common/detail/SpecializedForAddon.h @@ -37,7 +37,7 @@ #ifndef DART_COMMON_DETAIL_SPECIALIZEDADDONMANAGER_H_ #define DART_COMMON_DETAIL_SPECIALIZEDADDONMANAGER_H_ -#include "dart/common/SpecializedAddonManager.h" +#include "dart/common/SpecializedForAddon.h" // This preprocessor token should only be used by the unittest that is // responsible for checking that the specialized routines are being used to @@ -51,7 +51,7 @@ namespace common { //============================================================================== template -SpecializedAddonManager::SpecializedAddonManager() +SpecializedForAddon::SpecializedForAddon() { mAddonMap[typeid( SpecAddon )] = nullptr; mSpecAddonIterator = mAddonMap.find(typeid( SpecAddon )); @@ -60,7 +60,7 @@ SpecializedAddonManager::SpecializedAddonManager() //============================================================================== template template -bool SpecializedAddonManager::has() const +bool SpecializedForAddon::has() const { return _has(type()); } @@ -68,7 +68,7 @@ bool SpecializedAddonManager::has() const //============================================================================== template template -T* SpecializedAddonManager::get() +T* SpecializedForAddon::get() { return _get(type()); } @@ -76,7 +76,7 @@ T* SpecializedAddonManager::get() //============================================================================== template template -const T* SpecializedAddonManager::get() const +const T* SpecializedForAddon::get() const { return _get(type()); } @@ -84,7 +84,7 @@ const T* SpecializedAddonManager::get() const //============================================================================== template template -void SpecializedAddonManager::set(const T* addon) +void SpecializedForAddon::set(const T* addon) { _set(type(), addon); } @@ -92,7 +92,7 @@ void SpecializedAddonManager::set(const T* addon) //============================================================================== template template -void SpecializedAddonManager::set(std::unique_ptr&& addon) +void SpecializedForAddon::set(std::unique_ptr&& addon) { _set(type(), std::move(addon)); } @@ -100,7 +100,7 @@ void SpecializedAddonManager::set(std::unique_ptr&& addon) //============================================================================== template template -T* SpecializedAddonManager::create(Args&&... args) +T* SpecializedForAddon::create(Args&&... args) { return _create(type(), std::forward(args)...); } @@ -108,7 +108,7 @@ T* SpecializedAddonManager::create(Args&&... args) //============================================================================== template template -void SpecializedAddonManager::erase() +void SpecializedForAddon::erase() { _erase(type()); } @@ -116,7 +116,7 @@ void SpecializedAddonManager::erase() //============================================================================== template template -std::unique_ptr SpecializedAddonManager::release() +std::unique_ptr SpecializedForAddon::release() { return _release(type()); } @@ -124,7 +124,7 @@ std::unique_ptr SpecializedAddonManager::release() //============================================================================== template template -constexpr bool SpecializedAddonManager::isSpecializedFor() +constexpr bool SpecializedForAddon::isSpecializedFor() { return _isSpecializedFor(type()); } @@ -132,7 +132,7 @@ constexpr bool SpecializedAddonManager::isSpecializedFor() //============================================================================== template template -bool SpecializedAddonManager::_has(type) const +bool SpecializedForAddon::_has(type) const { #ifdef DART_UNITTEST_SPECIALIZED_ADDON_ACCESS usedSpecializedAddonAccess = true; @@ -143,7 +143,7 @@ bool SpecializedAddonManager::_has(type) const //============================================================================== template -bool SpecializedAddonManager::_has(type) const +bool SpecializedForAddon::_has(type) const { #ifdef DART_UNITTEST_SPECIALIZED_ADDON_ACCESS usedSpecializedAddonAccess = true; @@ -155,14 +155,14 @@ bool SpecializedAddonManager::_has(type) const //============================================================================== template template -T* SpecializedAddonManager::_get(type) +T* SpecializedForAddon::_get(type) { return AddonManager::get(); } //============================================================================== template -SpecAddon* SpecializedAddonManager::_get(type) +SpecAddon* SpecializedForAddon::_get(type) { #ifdef DART_UNITTEST_SPECIALIZED_ADDON_ACCESS usedSpecializedAddonAccess = true; @@ -174,14 +174,14 @@ SpecAddon* SpecializedAddonManager::_get(type) //============================================================================== template template -const T* SpecializedAddonManager::_get(type) const +const T* SpecializedForAddon::_get(type) const { return AddonManager::get(); } //============================================================================== template -const SpecAddon* SpecializedAddonManager::_get(type) const +const SpecAddon* SpecializedForAddon::_get(type) const { #ifdef DART_UNITTEST_SPECIALIZED_ADDON_ACCESS usedSpecializedAddonAccess = true; @@ -193,14 +193,14 @@ const SpecAddon* SpecializedAddonManager::_get(type) const //============================================================================== template template -void SpecializedAddonManager::_set(type, const T* addon) +void SpecializedForAddon::_set(type, const T* addon) { AddonManager::set(addon); } //============================================================================== template -void SpecializedAddonManager::_set( +void SpecializedForAddon::_set( type, const SpecAddon* addon) { #ifdef DART_UNITTEST_SPECIALIZED_ADDON_ACCESS @@ -221,14 +221,14 @@ void SpecializedAddonManager::_set( //============================================================================== template template -void SpecializedAddonManager::_set(type, std::unique_ptr&& addon) +void SpecializedForAddon::_set(type, std::unique_ptr&& addon) { AddonManager::set(std::move(addon)); } //============================================================================== template -void SpecializedAddonManager::_set( +void SpecializedForAddon::_set( type, std::unique_ptr&& addon) { #ifdef DART_UNITTEST_SPECIALIZED_ADDON_ACCESS @@ -242,7 +242,7 @@ void SpecializedAddonManager::_set( //============================================================================== template template -T* SpecializedAddonManager::_create(type, Args&&... args) +T* SpecializedForAddon::_create(type, Args&&... args) { return AddonManager::create(std::forward(args)...); } @@ -250,7 +250,7 @@ T* SpecializedAddonManager::_create(type, Args&&... args) //============================================================================== template template -SpecAddon* SpecializedAddonManager::_create( +SpecAddon* SpecializedForAddon::_create( type, Args&&... args) { #ifdef DART_UNITTEST_SPECIALIZED_ADDON_ACCESS @@ -267,41 +267,41 @@ SpecAddon* SpecializedAddonManager::_create( //============================================================================== template template -void SpecializedAddonManager::_erase(type) +void SpecializedForAddon::_erase(type) { AddonManager::erase(); } //============================================================================== template -void SpecializedAddonManager::_erase(type) +void SpecializedForAddon::_erase(type) { #ifdef DART_UNITTEST_SPECIALIZED_ADDON_ACCESS usedSpecializedAddonAccess = true; #endif // DART_UNITTEST_SPECIALIZED_ADDON_ACCESS - DART_COMMON_CHECK_ILLEGAL_ADDON_ERASE(erase, mSpecAddonIterator, DART_BLANK); + DART_COMMON_CHECK_ILLEGAL_ADDON_ERASE(erase, SpecAddon, DART_BLANK); mSpecAddonIterator->second = nullptr; } //============================================================================== template template -std::unique_ptr SpecializedAddonManager::_release(type) +std::unique_ptr SpecializedForAddon::_release(type) { return AddonManager::release(); } //============================================================================== template -std::unique_ptr SpecializedAddonManager::_release( +std::unique_ptr SpecializedForAddon::_release( type) { #ifdef DART_UNITTEST_SPECIALIZED_ADDON_ACCESS usedSpecializedAddonAccess = true; #endif // DART_UNITTEST_SPECIALIZED_ADDON_ACCESS - DART_COMMON_CHECK_ILLEGAL_ADDON_ERASE(release, mSpecAddonIterator, nullptr); + DART_COMMON_CHECK_ILLEGAL_ADDON_ERASE(release, SpecAddon, nullptr); std::unique_ptr extraction( static_cast(mSpecAddonIterator->second.release())); @@ -311,14 +311,14 @@ std::unique_ptr SpecializedAddonManager::_release( //============================================================================== template template -constexpr bool SpecializedAddonManager::_isSpecializedFor(type) +constexpr bool SpecializedForAddon::_isSpecializedFor(type) { return false; } //============================================================================== template -constexpr bool SpecializedAddonManager::_isSpecializedFor(type) +constexpr bool SpecializedForAddon::_isSpecializedFor(type) { return true; } diff --git a/dart/dynamics/Addon.h b/dart/dynamics/Addon.h index 4c4b84aa3950a..96045d0e81607 100644 --- a/dart/dynamics/Addon.h +++ b/dart/dynamics/Addon.h @@ -50,8 +50,7 @@ namespace dynamics { /// Node class). This will increment the version count any time the /// Addon::setProperties function is called. template , - bool OptionalT = true> + void (*updateProperties)(BaseT*) = common::detail::NoOp > class AddonWithProtectedPropertiesInSkeleton : public common::Addon { public: @@ -61,10 +60,9 @@ class AddonWithProtectedPropertiesInSkeleton : public common::Addon using ManagerType = ManagerT; using Properties = common::Addon::PropertiesMixer; constexpr static void (*UpdateProperties)(Base*) = updateProperties; - constexpr static bool Optional = OptionalT; using Implementation = AddonWithProtectedPropertiesInSkeleton< - BaseT, PropertiesDataT, ManagerT, updateProperties, OptionalT>; + BaseT, PropertiesDataT, ManagerT, updateProperties>; AddonWithProtectedPropertiesInSkeleton() = delete; AddonWithProtectedPropertiesInSkeleton( @@ -91,9 +89,6 @@ class AddonWithProtectedPropertiesInSkeleton : public common::Addon /// Get the Properties of this Addon const Properties& getProperties() const; - // Documentation inherited - bool isOptional(common::AddonManager* oldManager) override final; - /// Get the Skeleton that this Addon is embedded in SkeletonPtr getSkeleton(); @@ -131,8 +126,7 @@ class AddonWithProtectedPropertiesInSkeleton : public common::Addon template , - void (*updateProperties)(BaseT*) = updateState, - bool OptionalT = true> + void (*updateProperties)(BaseT*) = updateState> class AddonWithProtectedStateAndPropertiesInSkeleton : public common::Addon { public: @@ -145,7 +139,6 @@ class AddonWithProtectedStateAndPropertiesInSkeleton : public common::Addon using Properties = common::Addon::PropertiesMixer; constexpr static void (*UpdateState)(Base*) = updateState; constexpr static void (*UpdateProperties)(Base*) = updateProperties; - constexpr static bool Optional = OptionalT; AddonWithProtectedStateAndPropertiesInSkeleton() = delete; AddonWithProtectedStateAndPropertiesInSkeleton( @@ -191,9 +184,6 @@ class AddonWithProtectedStateAndPropertiesInSkeleton : public common::Addon /// Get the Properties of this Addon const Properties& getProperties() const; - // Documentation inherited - bool isOptional(common::AddonManager* oldManager) override final; - /// Get the Skeleton that this Addon is embedded in SkeletonPtr getSkeleton(); @@ -232,7 +222,7 @@ class AddonWithProtectedStateAndPropertiesInSkeleton : public common::Addon #define DART_DYNAMICS_ADDON_PROPERTY_CONSTRUCTOR( ClassName, UpdatePropertiesMacro )\ ClassName (const ClassName &) = delete;\ inline ClassName (dart::common::AddonManager* mgr, const PropertiesData& properties)\ - : AddonWithProtectedPropertiesInSkeleton< Base, PropertiesData, ManagerType, UpdatePropertiesMacro, Optional>(mgr, properties) { } + : AddonWithProtectedPropertiesInSkeleton< Base, PropertiesData, ManagerType, UpdatePropertiesMacro>(mgr, properties) { } //============================================================================== #define DART_DYNAMICS_JOINT_ADDON_CONSTRUCTOR( ClassName )\ @@ -242,9 +232,9 @@ class AddonWithProtectedStateAndPropertiesInSkeleton : public common::Addon #define DART_DYNAMICS_ADDON_STATE_PROPERTY_CONSTRUCTORS( ClassName, UpdateStateMacro, UpdatePropertiesMacro )\ ClassName (const ClassName &) = delete;\ inline ClassName (dart::common::AddonManager* mgr, const StateData& state = StateData(), const PropertiesData& properties = PropertiesData())\ - : AddonWithProtectedStateAndPropertiesInSkeleton< Base, StateData, PropertiesData, ManagerType, UpdateStateMacro, UpdatePropertiesMacro, Optional >(mgr, state, properties) { }\ + : AddonWithProtectedStateAndPropertiesInSkeleton< Base, StateData, PropertiesData, ManagerType, UpdateStateMacro, UpdatePropertiesMacro >(mgr, state, properties) { }\ inline ClassName (dart::common::AddonManager* mgr, const PropertiesData& properties, const StateData state = StateData())\ - : AddonWithProtectedStateAndPropertiesInSkeleton< Base, StateData, PropertiesData, ManagerType, UpdateStateMacro, UpdatePropertiesMacro, Optional >(mgr, properties, state) { } + : AddonWithProtectedStateAndPropertiesInSkeleton< Base, StateData, PropertiesData, ManagerType, UpdateStateMacro, UpdatePropertiesMacro >(mgr, properties, state) { } //============================================================================== #define DART_DYNAMICS_SET_ADDON_PROPERTY_CUSTOM( Type, Name, Update )\ @@ -320,52 +310,6 @@ class AddonWithProtectedStateAndPropertiesInSkeleton : public common::Addon #define DART_DYNAMICS_SET_GET_MULTIDOF_ADDON( SingleType, VectorType, SingleName )\ DART_DYNAMICS_IRREGULAR_SET_GET_MULTIDOF_ADDON( SingleType, VectorType, SingleName, SingleName ## s ) -//============================================================================== -#define DETAIL_DART_ADDON_PROPERTIES_UPDATE( AddonName, GetAddon )\ - AddonName :: UpdateProperties( GetAddon () );\ - GetAddon ()->incrementSkeletonVersion(); - -//============================================================================== -#define DETAIL_DART_ADDON_STATE_PROPERTIES_UPDATE( AddonName, GetAddon )\ - AddonName :: UpdateState( GetAddon () );\ - DETAIL_DART_ADDON_PROPERTIES_UPDATE( AddonName, GetAddon ); - -//============================================================================== -// Used for Addons that have Properties (but no State) inside of a Skeleton -#define DART_DYNAMICS_SKEL_PROPERTIES_ADDON_INLINE( AddonName )\ - DETAIL_DART_SPECIALIZED_ADDON_INLINE( AddonName,\ - DETAIL_DART_ADDON_PROPERTIES_UPDATE( AddonName, get ## AddonName ) ) - -//============================================================================== -// Used for Addons that have both State and Properties inside of a Skeleton -#define DART_DYNAMICS_SKEL_ADDON_INLINE( AddonName )\ - DETAIL_DART_SPECIALIZED_ADDON_INLINE( AddonName,\ - DETAIL_DART_ADDON_STATE_PROPERTIES_UPDATE( AddonName, get ## AddonName ) ) - -//============================================================================== -// Used for edge cases, such as nested template classes, that have Properties -// (but no State) inside of a Skeleton -#define DART_DYNAMICS_IRREGULAR_SKEL_PROPERTIES_ADDON_INLINE( TypeName, HomogenizedName )\ - DETAIL_DART_IRREGULAR_SPECIALIZED_ADDON_INLINE( TypeName, HomogenizedName,\ - DETAIL_DART_ADDON_PROPERTIES_UPDATE( TypeName, get ## HomogenizedName ) ) - -//============================================================================== -// Used for edge cases, such as nested template classes, that have both State -// and Properties inside of a Skeleton -#define DART_DYNAMICS_IRREGULAR_SKEL_ADDON_INLINE( TypeName, HomogenizedName )\ - DETAIL_DART_IRREGULAR_SPECIALIZED_ADDON_INLINE( TypeName, HomogenizedName,\ - DETAIL_DART_ADDON_STATE_PROPERTIES_UPDATE( TypeName, get ## HomogenizedName ) ) - -//============================================================================== -// Used for nested-class Addons that have Properties (but no State) inside of a Skeleton -#define DART_DYNAMICS_NESTED_SKEL_PROPERTIES_ADDON_INLINE( ParentName, AddonName )\ - DART_DYNAMICS_IRREGULAR_SKEL_PROPERTIES_ADDON_INLINE( ParentName :: AddonName, ParentName ## AddonName ) - -//============================================================================== -// Used for nested-class Addons that have both State and Properties inside of a Skeleton -#define DART_DYNAMICS_NESTED_SKEL_ADDON_INLINE( ParentName, AddonName )\ - DART_DYNAMICS_IRREGULAR_SKEL_ADDON_INLINE( ParentName :: AddonName, ParentName ## AddonName ) - #include "dart/dynamics/Skeleton.h" #include "dart/dynamics/detail/Addon.h" diff --git a/dart/dynamics/BodyNode.h b/dart/dynamics/BodyNode.h index 4b7d8df8f340d..b97c740426ef6 100644 --- a/dart/dynamics/BodyNode.h +++ b/dart/dynamics/BodyNode.h @@ -84,7 +84,7 @@ class Marker; /// BodyNode of the BodyNode. class BodyNode : public virtual common::AddonManager, - public virtual SpecializedNodeManagerForBodyNode, + public virtual BodyNodeSpecializedFor, public SkeletonRefCountingBase, public TemplatedJacobianNode { diff --git a/dart/dynamics/EndEffector.h b/dart/dynamics/EndEffector.h index 5c0e5ace58893..08abcf755292b 100644 --- a/dart/dynamics/EndEffector.h +++ b/dart/dynamics/EndEffector.h @@ -40,7 +40,7 @@ #include "dart/dynamics/FixedFrame.h" #include "dart/dynamics/TemplatedJacobianNode.h" #include "dart/dynamics/Addon.h" -#include "dart/common/SpecializedAddonManager.h" +#include "dart/common/SpecializedForAddon.h" namespace dart { namespace dynamics { @@ -98,7 +98,7 @@ class Support final : }; class EndEffector final : - public virtual common::SpecializedAddonManager, + public virtual common::SpecializedForAddon, public FixedFrame, public AccessoryNode, public TemplatedJacobianNode diff --git a/dart/dynamics/MultiDofJoint.h b/dart/dynamics/MultiDofJoint.h index 20a001a964697..ca3b8edb868bb 100644 --- a/dart/dynamics/MultiDofJoint.h +++ b/dart/dynamics/MultiDofJoint.h @@ -47,7 +47,7 @@ #include "dart/dynamics/Joint.h" #include "dart/dynamics/Skeleton.h" #include "dart/dynamics/DegreeOfFreedom.h" -#include "dart/common/SpecializedAddonManager.h" +#include "dart/common/RequiresAddon.h" #include "dart/dynamics/detail/MultiDofJointProperties.h" namespace dart { @@ -60,7 +60,7 @@ class Skeleton; template class MultiDofJoint : public Joint, - public virtual common::SpecializedAddonManager< detail::MultiDofJointAddon > + public virtual common::RequiresAddon< detail::MultiDofJointAddon > { public: diff --git a/dart/dynamics/SingleDofJoint.cpp b/dart/dynamics/SingleDofJoint.cpp index b7713c6cc3f3d..4d33acd88627c 100644 --- a/dart/dynamics/SingleDofJoint.cpp +++ b/dart/dynamics/SingleDofJoint.cpp @@ -1145,7 +1145,7 @@ double SingleDofJoint::getPotentialEnergy() const //============================================================================== SingleDofJoint::SingleDofJoint(const Properties& _properties) - : Joint(_properties), + : detail::SingleDofJointBase(_properties, common::NoArg), mDof(createDofPointer(0)), mCommand(0.0), mPosition(0.0), diff --git a/dart/dynamics/SingleDofJoint.h b/dart/dynamics/SingleDofJoint.h index cf56d9d393e2f..af14fe6c4c811 100644 --- a/dart/dynamics/SingleDofJoint.h +++ b/dart/dynamics/SingleDofJoint.h @@ -40,7 +40,6 @@ #include #include "dart/dynamics/Joint.h" -#include "dart/common/SpecializedAddonManager.h" #include "dart/dynamics/detail/SingleDofJointProperties.h" namespace dart { @@ -51,7 +50,7 @@ class Skeleton; class DegreeOfFreedom; /// class SingleDofJoint -class SingleDofJoint : public Joint +class SingleDofJoint : public detail::SingleDofJointBase { public: diff --git a/dart/dynamics/Skeleton.h b/dart/dynamics/Skeleton.h index 6ebc3c1f1f68a..56917914761ac 100644 --- a/dart/dynamics/Skeleton.h +++ b/dart/dynamics/Skeleton.h @@ -58,7 +58,7 @@ namespace dynamics { /// class Skeleton class Skeleton : public virtual common::AddonManager, public MetaSkeleton, - public virtual SpecializedNodeManagerForSkeleton + public virtual SkeletonSpecializedFor { public: diff --git a/dart/dynamics/SpecializedNodeManager.h b/dart/dynamics/SpecializedNodeManager.h index f3d89913da64a..b31ed402bc8c0 100644 --- a/dart/dynamics/SpecializedNodeManager.h +++ b/dart/dynamics/SpecializedNodeManager.h @@ -50,19 +50,19 @@ class Skeleton; //============================================================================== /// Declaration of the variadic template template -class SpecializedNodeManagerForBodyNode { }; +class BodyNodeSpecializedFor { }; //============================================================================== -/// SpecializedNodeManagerForBodyNode allows classes that inherit BodyNode to +/// BodyNodeSpecializedFor allows classes that inherit BodyNode to /// have constant-time access to a specific type of Node template -class SpecializedNodeManagerForBodyNode : +class BodyNodeSpecializedFor : public virtual detail::BasicNodeManagerForBodyNode { public: /// Default constructor - SpecializedNodeManagerForBodyNode(); + BodyNodeSpecializedFor(); /// Get the number of Nodes corresponding to the specified type template @@ -109,35 +109,35 @@ class SpecializedNodeManagerForBodyNode : }; //============================================================================== -/// This is the variadic version of the SpecializedNodeManagerForBodyNode class +/// This is the variadic version of the BodyNodeSpecializedFor class /// which allows you to include arbitrarily many specialized types in the /// specialization. template -class SpecializedNodeManagerForBodyNode : +class BodyNodeSpecializedFor : public NodeManagerJoinerForBodyNode< - common::Virtual< SpecializedNodeManagerForBodyNode >, - common::Virtual< SpecializedNodeManagerForBodyNode > > { }; + common::Virtual< BodyNodeSpecializedFor >, + common::Virtual< BodyNodeSpecializedFor > > { }; //============================================================================== /// Declaration of the variadic template template -class SpecializedNodeManagerForSkeleton { }; +class SkeletonSpecializedFor { }; //============================================================================== -/// SpecializedNodeManagerForSkeleton allows classes that inherit Skeleton to +/// SkeletonSpecializedForNode allows classes that inherit Skeleton to /// have constant-time access to a specific type of Node template -class SpecializedNodeManagerForSkeleton : +class SkeletonSpecializedFor : public virtual detail::BasicNodeManagerForSkeleton, - public virtual SpecializedNodeManagerForBodyNode + public virtual BodyNodeSpecializedFor { public: - using SpecializedNodeManagerForBodyNode::getNode; - using SpecializedNodeManagerForBodyNode::getNumNodes; - using SpecializedNodeManagerForBodyNode::isSpecializedForNode; + using BodyNodeSpecializedFor::getNode; + using BodyNodeSpecializedFor::getNumNodes; + using BodyNodeSpecializedFor::isSpecializedForNode; - SpecializedNodeManagerForSkeleton(); + SkeletonSpecializedFor(); /// Get the number of Nodes of the specified type that are in the treeIndexth /// tree of this Skeleton @@ -196,14 +196,14 @@ class SpecializedNodeManagerForSkeleton : }; //============================================================================== -/// This is the variadic version of the SpecializedNodeManagerForSkeleton class +/// This is the variadic version of the SkeletonSpecializedForNode class /// which allows you to include arbitrarily many specialized types in the /// specialization. template -class SpecializedNodeManagerForSkeleton : +class SkeletonSpecializedFor : public NodeManagerJoinerForSkeleton< - common::Virtual< SpecializedNodeManagerForSkeleton >, - common::Virtual< SpecializedNodeManagerForSkeleton > > { }; + common::Virtual< SkeletonSpecializedFor >, + common::Virtual< SkeletonSpecializedFor > > { }; } // namespace dynamics } // namespace dart diff --git a/dart/dynamics/detail/Addon.h b/dart/dynamics/detail/Addon.h index 9a965936353e1..f9e0d73a2bafb 100644 --- a/dart/dynamics/detail/Addon.h +++ b/dart/dynamics/detail/Addon.h @@ -44,9 +44,9 @@ namespace dynamics { //============================================================================== template + class ManagerT, void (*updateProperties)(BaseT*)> AddonWithProtectedPropertiesInSkeleton< - BaseT, PropertiesDataT, ManagerT, updateProperties, OptionalT>:: + BaseT, PropertiesDataT, ManagerT, updateProperties>:: AddonWithProtectedPropertiesInSkeleton( common::AddonManager* mgr, const PropertiesData& properties) : Addon(mgr), @@ -59,9 +59,9 @@ AddonWithProtectedPropertiesInSkeleton( //============================================================================== template + class ManagerT, void (*updateProperties)(BaseT*)> std::unique_ptr AddonWithProtectedPropertiesInSkeleton< - BaseT, PropertiesDataT, ManagerT, updateProperties, OptionalT>:: + BaseT, PropertiesDataT, ManagerT, updateProperties>:: cloneAddon(common::AddonManager* newManager) const { DART_COMMON_CAST_NEW_MANAGER_TYPE_AND_RETURN_NULL_IF_BAD( @@ -71,9 +71,9 @@ cloneAddon(common::AddonManager* newManager) const //============================================================================== template + class ManagerT, void (*updateProperties)(BaseT*)> void AddonWithProtectedPropertiesInSkeleton< - BaseT, PropertiesDataT, ManagerT, updateProperties, OptionalT>:: + BaseT, PropertiesDataT, ManagerT, updateProperties>:: setAddonProperties(const Addon::Properties& someProperties) { setProperties(static_cast(someProperties)); @@ -81,9 +81,9 @@ setAddonProperties(const Addon::Properties& someProperties) //============================================================================== template + class ManagerT, void (*updateProperties)(BaseT*)> const common::Addon::Properties* AddonWithProtectedPropertiesInSkeleton< - BaseT, PropertiesDataT, ManagerT, updateProperties, OptionalT>:: + BaseT, PropertiesDataT, ManagerT, updateProperties>:: getAddonProperties() const { return &mProperties; @@ -91,9 +91,9 @@ getAddonProperties() const //============================================================================== template + class ManagerT, void (*updateProperties)(BaseT*)> void AddonWithProtectedPropertiesInSkeleton< - BaseT, PropertiesDataT, ManagerT, updateProperties, OptionalT>:: + BaseT, PropertiesDataT, ManagerT, updateProperties>:: setProperties(const PropertiesData& properties) { static_cast(mProperties) = properties; @@ -104,9 +104,9 @@ setProperties(const PropertiesData& properties) //============================================================================== template + class ManagerT, void (*updateProperties)(BaseT*)> auto AddonWithProtectedPropertiesInSkeleton< - BaseT, PropertiesDataT, ManagerT, updateProperties, OptionalT>:: + BaseT, PropertiesDataT, ManagerT, updateProperties>:: getProperties() const -> const Properties& { return mProperties; @@ -114,24 +114,9 @@ getProperties() const -> const Properties& //============================================================================== template -bool AddonWithProtectedPropertiesInSkeleton< - BaseT, PropertiesDataT, ManagerT, updateProperties, OptionalT>:: -isOptional(common::AddonManager* oldManager) -{ - if(Optional) - return true; - - // If the Addon is not optional, we should check whether the Manager type is - // the kind that this Addon belongs to. - return (nullptr == dynamic_cast(oldManager)); -} - -//============================================================================== -template + class ManagerT, void (*updateProperties)(BaseT*)> SkeletonPtr AddonWithProtectedPropertiesInSkeleton< - BaseT, PropertiesDataT, ManagerT, updateProperties, OptionalT>::getSkeleton() + BaseT, PropertiesDataT, ManagerT, updateProperties>::getSkeleton() { if(mManager) return mManager->getSkeleton(); @@ -141,9 +126,9 @@ SkeletonPtr AddonWithProtectedPropertiesInSkeleton< //============================================================================== template + class ManagerT, void (*updateProperties)(BaseT*)> ConstSkeletonPtr AddonWithProtectedPropertiesInSkeleton< - BaseT, PropertiesDataT, ManagerT, updateProperties, OptionalT>::getSkeleton() const + BaseT, PropertiesDataT, ManagerT, updateProperties>::getSkeleton() const { if(mManager) return mManager->getSkeleton(); @@ -153,27 +138,27 @@ ConstSkeletonPtr AddonWithProtectedPropertiesInSkeleton< //============================================================================== template + class ManagerT, void (*updateProperties)(BaseT*)> ManagerT* AddonWithProtectedPropertiesInSkeleton< - BaseT, PropertiesDataT, ManagerT, updateProperties, OptionalT>::getManager() + BaseT, PropertiesDataT, ManagerT, updateProperties>::getManager() { return mManager; } //============================================================================== template + class ManagerT, void (*updateProperties)(BaseT*)> const ManagerT* AddonWithProtectedPropertiesInSkeleton< - BaseT, PropertiesDataT, ManagerT, updateProperties, OptionalT>::getManager() const + BaseT, PropertiesDataT, ManagerT, updateProperties>::getManager() const { return mManager; } //============================================================================== template + class ManagerT, void (*updateProperties)(BaseT*)> void AddonWithProtectedPropertiesInSkeleton< - BaseT, PropertiesDataT, ManagerT, updateProperties, OptionalT>:: + BaseT, PropertiesDataT, ManagerT, updateProperties>:: incrementSkeletonVersion() { if(const SkeletonPtr& skel = getSkeleton()) @@ -182,9 +167,9 @@ incrementSkeletonVersion() //============================================================================== template + class ManagerT, void (*updateProperties)(BaseT*)> void AddonWithProtectedPropertiesInSkeleton< - BaseT, PropertiesDataT, ManagerT, updateProperties, OptionalT>:: + BaseT, PropertiesDataT, ManagerT, updateProperties>:: setManager(common::AddonManager* newManager, bool /*transfer*/) { DART_COMMON_CAST_NEW_MANAGER_TYPE( @@ -201,10 +186,10 @@ setManager(common::AddonManager* newManager, bool /*transfer*/) //============================================================================== template + void (*updateProperties)(BaseT*)> AddonWithProtectedStateAndPropertiesInSkeleton< BaseT, StateDataT, PropertiesDataT, - ManagerT, updateState, updateProperties, OptionalT>:: + ManagerT, updateState, updateProperties>:: AddonWithProtectedStateAndPropertiesInSkeleton( common::AddonManager* mgr, const StateData& state, @@ -221,10 +206,10 @@ AddonWithProtectedStateAndPropertiesInSkeleton( //============================================================================== template + void (*updateProperties)(BaseT*)> AddonWithProtectedStateAndPropertiesInSkeleton< BaseT, StateDataT, PropertiesDataT, - ManagerT, updateState, updateProperties, OptionalT>:: + ManagerT, updateState, updateProperties>:: AddonWithProtectedStateAndPropertiesInSkeleton( common::AddonManager* mgr, const PropertiesData& properties, @@ -241,10 +226,10 @@ AddonWithProtectedStateAndPropertiesInSkeleton( //============================================================================== template + void (*updateProperties)(BaseT*)> std::unique_ptr AddonWithProtectedStateAndPropertiesInSkeleton< BaseT, StateDataT, PropertiesDataT, - ManagerT, updateState, updateProperties, OptionalT>:: + ManagerT, updateState, updateProperties>:: cloneAddon(common::AddonManager* newManager) const { DART_COMMON_CAST_NEW_MANAGER_TYPE_AND_RETURN_NULL_IF_BAD( @@ -255,10 +240,10 @@ cloneAddon(common::AddonManager* newManager) const //============================================================================== template + void (*updateProperties)(BaseT*)> void AddonWithProtectedStateAndPropertiesInSkeleton< BaseT, StateDataT, PropertiesDataT, - ManagerT, updateState, updateProperties, OptionalT>:: + ManagerT, updateState, updateProperties>:: setAddonState(const Addon::State& otherState) { setState(static_cast(otherState)); @@ -267,10 +252,10 @@ setAddonState(const Addon::State& otherState) //============================================================================== template + void (*updateProperties)(BaseT*)> const common::Addon::State* AddonWithProtectedStateAndPropertiesInSkeleton< BaseT, StateDataT, PropertiesDataT, - ManagerT, updateState, updateProperties, OptionalT>:: + ManagerT, updateState, updateProperties>:: getAddonState() const { return &mState; @@ -279,10 +264,10 @@ getAddonState() const //============================================================================== template + void (*updateProperties)(BaseT*)> void AddonWithProtectedStateAndPropertiesInSkeleton< BaseT, StateDataT, PropertiesDataT, - ManagerT, updateState, updateProperties, OptionalT>:: + ManagerT, updateState, updateProperties>:: setState(const StateData& state) { static_cast(mState) = state; @@ -292,10 +277,10 @@ setState(const StateData& state) //============================================================================== template + void (*updateProperties)(BaseT*)> auto AddonWithProtectedStateAndPropertiesInSkeleton< BaseT, StateDataT, PropertiesDataT, - ManagerT, updateState, updateProperties, OptionalT>:: + ManagerT, updateState, updateProperties>:: getState() const -> const State& { return mState; @@ -304,10 +289,10 @@ getState() const -> const State& //============================================================================== template + void (*updateProperties)(BaseT*)> void AddonWithProtectedStateAndPropertiesInSkeleton< BaseT, StateDataT, PropertiesDataT, - ManagerT, updateState, updateProperties, OptionalT>:: + ManagerT, updateState, updateProperties>:: setAddonProperties(const Addon::Properties& properties) { setProperties(static_cast(properties)); @@ -316,10 +301,10 @@ setAddonProperties(const Addon::Properties& properties) //============================================================================== template + void (*updateProperties)(BaseT*)> const common::Addon::Properties* AddonWithProtectedStateAndPropertiesInSkeleton< BaseT, StateDataT, PropertiesDataT, - ManagerT, updateState, updateProperties, OptionalT>:: + ManagerT, updateState, updateProperties>:: getAddonProperties() const { return &mProperties; @@ -328,10 +313,10 @@ getAddonProperties() const //============================================================================== template + void (*updateProperties)(BaseT*)> void AddonWithProtectedStateAndPropertiesInSkeleton< BaseT, StateDataT, PropertiesDataT, - ManagerT, updateState, updateProperties, OptionalT>:: + ManagerT, updateState, updateProperties>:: setProperties(const PropertiesData& properties) { static_cast(mProperties) = properties; @@ -343,10 +328,10 @@ setProperties(const PropertiesData& properties) //============================================================================== template + void (*updateProperties)(BaseT*)> auto AddonWithProtectedStateAndPropertiesInSkeleton< BaseT, StateDataT, PropertiesDataT, - ManagerT, updateState, updateProperties, OptionalT>:: + ManagerT, updateState, updateProperties>:: getProperties() const -> const Properties& { return mProperties; @@ -355,27 +340,10 @@ getProperties() const -> const Properties& //============================================================================== template -bool AddonWithProtectedStateAndPropertiesInSkeleton< - BaseT, StateDataT, PropertiesDataT, - ManagerT, updateState, updateProperties, OptionalT>:: -isOptional(common::AddonManager* oldManager) -{ - if(Optional) - return true; - - // If the Addon is not optional, we should check whether the Manager type is - // the kind that this Addon belongs to. - return (nullptr == dynamic_cast(oldManager)); -} - -//============================================================================== -template + void (*updateProperties)(BaseT*)> SkeletonPtr AddonWithProtectedStateAndPropertiesInSkeleton< BaseT, StateDataT, PropertiesDataT, - ManagerT, updateState, updateProperties, OptionalT>:: + ManagerT, updateState, updateProperties>:: getSkeleton() { if(mManager) @@ -387,10 +355,10 @@ getSkeleton() //============================================================================== template + void (*updateProperties)(BaseT*)> ConstSkeletonPtr AddonWithProtectedStateAndPropertiesInSkeleton< BaseT, StateDataT, PropertiesDataT, - ManagerT, updateState, updateProperties, OptionalT>:: + ManagerT, updateState, updateProperties>:: getSkeleton() const { if(mManager) @@ -402,10 +370,10 @@ getSkeleton() const //============================================================================== template + void (*updateProperties)(BaseT*)> ManagerT* AddonWithProtectedStateAndPropertiesInSkeleton< BaseT, StateDataT, PropertiesDataT, - ManagerT, updateState, updateProperties, OptionalT>:: + ManagerT, updateState, updateProperties>:: getManager() { return mManager; @@ -414,10 +382,10 @@ getManager() //============================================================================== template + void (*updateProperties)(BaseT*)> const ManagerT* AddonWithProtectedStateAndPropertiesInSkeleton< BaseT, StateDataT, PropertiesDataT, - ManagerT, updateState, updateProperties, OptionalT>:: + ManagerT, updateState, updateProperties>:: getManager() const { return mManager; @@ -426,10 +394,10 @@ getManager() const //============================================================================== template + void (*updateProperties)(BaseT*)> void AddonWithProtectedStateAndPropertiesInSkeleton< BaseT, StateDataT, PropertiesDataT, - ManagerT, updateState, updateProperties, OptionalT>:: + ManagerT, updateState, updateProperties>:: incrementSkeletonVersion() { if(const SkeletonPtr& skel = getSkeleton()) @@ -439,10 +407,10 @@ incrementSkeletonVersion() //============================================================================== template + void (*updateProperties)(BaseT*)> void AddonWithProtectedStateAndPropertiesInSkeleton< BaseT, StateDataT, PropertiesDataT, - ManagerT, updateState, updateProperties, OptionalT>:: + ManagerT, updateState, updateProperties>:: setManager(common::AddonManager* newManager, bool /*transfer*/) { DART_COMMON_CAST_NEW_MANAGER_TYPE( diff --git a/dart/dynamics/detail/EulerJointProperties.h b/dart/dynamics/detail/EulerJointProperties.h index f8f5dd687af17..133cf79c2ee8e 100644 --- a/dart/dynamics/detail/EulerJointProperties.h +++ b/dart/dynamics/detail/EulerJointProperties.h @@ -88,7 +88,7 @@ struct EulerJointProperties : class EulerJointAddon final : public AddonWithProtectedPropertiesInSkeleton< EulerJointAddon, EulerJointUniqueProperties, EulerJoint, - detail::JointPropertyUpdate, false > + detail::JointPropertyUpdate > { public: DART_DYNAMICS_JOINT_ADDON_CONSTRUCTOR( EulerJointAddon ) @@ -97,7 +97,7 @@ class EulerJointAddon final : //============================================================================== using EulerJointBase = common::AddonManagerJoiner< - MultiDofJoint<3>, common::SpecializedAddonManager >; + MultiDofJoint<3>, common::RequiresAddon >; } // namespace detail } // namespace dynamics diff --git a/dart/dynamics/detail/MultiDofJointProperties.h b/dart/dynamics/detail/MultiDofJointProperties.h index 8f19724cb77fd..f77ebef3b59d1 100644 --- a/dart/dynamics/detail/MultiDofJointProperties.h +++ b/dart/dynamics/detail/MultiDofJointProperties.h @@ -159,7 +159,7 @@ template class MultiDofJointAddon final : public AddonWithProtectedPropertiesInSkeleton< MultiDofJointAddon, MultiDofJointUniqueProperties, MultiDofJoint, - common::detail::NoOp*>, false > + common::detail::NoOp*> > { public: MultiDofJointAddon(const MultiDofJointAddon&) = delete; @@ -287,8 +287,8 @@ MultiDofJointAddon::MultiDofJointAddon( typename MultiDofJointAddon::Base, typename MultiDofJointAddon::PropertiesData, typename MultiDofJointAddon::ManagerType, - &common::detail::NoOp::Base*>, - MultiDofJointAddon::Optional>(mgr, properties) + &common::detail::NoOp::Base*> >( + mgr, properties) { // Do nothing } diff --git a/dart/dynamics/detail/PlanarJointProperties.h b/dart/dynamics/detail/PlanarJointProperties.h index 92c1191e5e931..1fc5c14e73d00 100644 --- a/dart/dynamics/detail/PlanarJointProperties.h +++ b/dart/dynamics/detail/PlanarJointProperties.h @@ -127,7 +127,7 @@ struct PlanarJointProperties : class PlanarJointAddon final : public AddonWithProtectedPropertiesInSkeleton< PlanarJointAddon, PlanarJointUniqueProperties, PlanarJoint, - detail::JointPropertyUpdate, false > + detail::JointPropertyUpdate > { public: DART_DYNAMICS_JOINT_ADDON_CONSTRUCTOR( PlanarJointAddon ) @@ -146,7 +146,7 @@ class PlanarJointAddon final : //============================================================================== using PlanarJointBase = common::AddonManagerJoiner< - MultiDofJoint<3>, common::SpecializedAddonManager >; + MultiDofJoint<3>, common::RequiresAddon >; } // namespace detail } // namespace dynamics diff --git a/dart/dynamics/detail/PrismaticJointProperties.h b/dart/dynamics/detail/PrismaticJointProperties.h index be628399971e3..5148ed8442b19 100644 --- a/dart/dynamics/detail/PrismaticJointProperties.h +++ b/dart/dynamics/detail/PrismaticJointProperties.h @@ -80,7 +80,7 @@ struct PrismaticJointProperties : class PrismaticJointAddon final : public AddonWithProtectedPropertiesInSkeleton< PrismaticJointAddon, PrismaticJointUniqueProperties, PrismaticJoint, - detail::JointPropertyUpdate, false > + detail::JointPropertyUpdate > { public: DART_DYNAMICS_JOINT_ADDON_CONSTRUCTOR( PrismaticJointAddon ) @@ -91,7 +91,7 @@ class PrismaticJointAddon final : //============================================================================== using PrismaticJointBase = common::AddonManagerJoiner< - SingleDofJoint, common::SpecializedAddonManager >; + SingleDofJoint, common::RequiresAddon >; } // namespace detail } // namespace dynamics diff --git a/dart/dynamics/detail/RevoluteJointProperties.h b/dart/dynamics/detail/RevoluteJointProperties.h index fbc00024181b7..8406ad54a3eb1 100644 --- a/dart/dynamics/detail/RevoluteJointProperties.h +++ b/dart/dynamics/detail/RevoluteJointProperties.h @@ -80,7 +80,7 @@ struct RevoluteJointProperties : class RevoluteJointAddon final : public AddonWithProtectedPropertiesInSkeleton< RevoluteJointAddon, RevoluteJointUniqueProperties, RevoluteJoint, - detail::JointPropertyUpdate, false > + detail::JointPropertyUpdate > { public: DART_DYNAMICS_JOINT_ADDON_CONSTRUCTOR( RevoluteJointAddon ) @@ -91,7 +91,7 @@ class RevoluteJointAddon final : //============================================================================== using RevoluteJointBase = common::AddonManagerJoiner< - SingleDofJoint, common::SpecializedAddonManager >; + SingleDofJoint, common::RequiresAddon >; } // namespace detail diff --git a/dart/dynamics/detail/ScrewJointProperties.h b/dart/dynamics/detail/ScrewJointProperties.h index 12cf0ba729890..c63256850396b 100644 --- a/dart/dynamics/detail/ScrewJointProperties.h +++ b/dart/dynamics/detail/ScrewJointProperties.h @@ -84,7 +84,7 @@ struct ScrewJointProperties : SingleDofJoint::Properties, class ScrewJointAddon final : public AddonWithProtectedPropertiesInSkeleton< ScrewJointAddon, ScrewJointUniqueProperties, ScrewJoint, - detail::JointPropertyUpdate, false > + detail::JointPropertyUpdate > { public: DART_DYNAMICS_JOINT_ADDON_CONSTRUCTOR( ScrewJointAddon ) @@ -97,7 +97,7 @@ class ScrewJointAddon final : //============================================================================== using ScrewJointBase = common::AddonManagerJoiner< - SingleDofJoint, common::SpecializedAddonManager >; + SingleDofJoint, common::RequiresAddon >; } // namespace detail } // namespace dynamics diff --git a/dart/dynamics/detail/SingleDofJointProperties.h b/dart/dynamics/detail/SingleDofJointProperties.h index 2f0e0b1c4fc55..31f84ab2b03a8 100644 --- a/dart/dynamics/detail/SingleDofJointProperties.h +++ b/dart/dynamics/detail/SingleDofJointProperties.h @@ -37,6 +37,8 @@ #ifndef DART_DYNAMICS_DETAIL_SINGLEDOFJOINTPROPERTIES_H_ #define DART_DYNAMICS_DETAIL_SINGLEDOFJOINTPROPERTIES_H_ +#include "dart/common/RequiresAddon.h" + #include "dart/dynamics/Addon.h" #include "dart/dynamics/Joint.h" @@ -137,7 +139,7 @@ struct SingleDofJointProperties : class SingleDofJointAddon final : public AddonWithProtectedPropertiesInSkeleton< SingleDofJointAddon, SingleDofJointUniqueProperties, - SingleDofJoint, common::detail::NoOp, false> + SingleDofJoint, common::detail::NoOp> { public: DART_DYNAMICS_ADDON_PROPERTY_CONSTRUCTOR( SingleDofJointAddon, &common::detail::NoOp ) @@ -165,6 +167,10 @@ class SingleDofJointAddon final : friend class dart::dynamics::SingleDofJoint; }; +//============================================================================== +using SingleDofJointBase = common::AddonManagerJoiner< + Joint, common::RequiresAddon >; + } // namespace detail } // namespace dynamics } // namespace dart diff --git a/dart/dynamics/detail/SpecializedNodeManager.h b/dart/dynamics/detail/SpecializedNodeManager.h index a4040940e1587..bcba31cade387 100644 --- a/dart/dynamics/detail/SpecializedNodeManager.h +++ b/dart/dynamics/detail/SpecializedNodeManager.h @@ -51,7 +51,7 @@ bool usedSpecializedNodeAccess; //============================================================================== template -SpecializedNodeManagerForBodyNode::SpecializedNodeManagerForBodyNode() +BodyNodeSpecializedFor::BodyNodeSpecializedFor() { mNodeMap[typeid( SpecNode )] = std::vector(); mSpecNodeIterator = mNodeMap.find(typeid( SpecNode )); @@ -60,7 +60,7 @@ SpecializedNodeManagerForBodyNode::SpecializedNodeManagerForBodyNode() //============================================================================== template template -size_t SpecializedNodeManagerForBodyNode::getNumNodes() const +size_t BodyNodeSpecializedFor::getNumNodes() const { return _getNumNodes(type()); } @@ -68,7 +68,7 @@ size_t SpecializedNodeManagerForBodyNode::getNumNodes() const //============================================================================== template template -NodeType* SpecializedNodeManagerForBodyNode::getNode(size_t index) +NodeType* BodyNodeSpecializedFor::getNode(size_t index) { return _getNode(type(), index); } @@ -76,16 +76,16 @@ NodeType* SpecializedNodeManagerForBodyNode::getNode(size_t index) //============================================================================== template template -const NodeType* SpecializedNodeManagerForBodyNode::getNode(size_t index) const +const NodeType* BodyNodeSpecializedFor::getNode(size_t index) const { - return const_cast*>(this)-> + return const_cast*>(this)-> _getNode(type(), index); } //============================================================================== template template -constexpr bool SpecializedNodeManagerForBodyNode::isSpecializedForNode() +constexpr bool BodyNodeSpecializedFor::isSpecializedForNode() { return _isSpecializedForNode(type()); } @@ -93,14 +93,14 @@ constexpr bool SpecializedNodeManagerForBodyNode::isSpecializedForNode //============================================================================== template template -size_t SpecializedNodeManagerForBodyNode::_getNumNodes(type) const +size_t BodyNodeSpecializedFor::_getNumNodes(type) const { return detail::BasicNodeManagerForBodyNode::getNumNodes(); } //============================================================================== template -size_t SpecializedNodeManagerForBodyNode::_getNumNodes(type) const +size_t BodyNodeSpecializedFor::_getNumNodes(type) const { #ifdef DART_UNITTEST_SPECIALIZED_NODE_ACCESS usedSpecializedNodeAccess = true; @@ -112,14 +112,14 @@ size_t SpecializedNodeManagerForBodyNode::_getNumNodes(type) //============================================================================== template template -NodeType* SpecializedNodeManagerForBodyNode::_getNode(type, size_t index) +NodeType* BodyNodeSpecializedFor::_getNode(type, size_t index) { return detail::BasicNodeManagerForBodyNode::getNode(index); } //============================================================================== template -SpecNode* SpecializedNodeManagerForBodyNode::_getNode(type, size_t index) +SpecNode* BodyNodeSpecializedFor::_getNode(type, size_t index) { #ifdef DART_UNITTEST_SPECIALIZED_NODE_ACCESS usedSpecializedNodeAccess = true; @@ -132,21 +132,21 @@ SpecNode* SpecializedNodeManagerForBodyNode::_getNode(type, //============================================================================== template template -constexpr bool SpecializedNodeManagerForBodyNode::_isSpecializedForNode(type) +constexpr bool BodyNodeSpecializedFor::_isSpecializedForNode(type) { return false; } //============================================================================== template -constexpr bool SpecializedNodeManagerForBodyNode::_isSpecializedForNode(type) +constexpr bool BodyNodeSpecializedFor::_isSpecializedForNode(type) { return true; } //============================================================================== template -SpecializedNodeManagerForSkeleton::SpecializedNodeManagerForSkeleton() +SkeletonSpecializedFor::SkeletonSpecializedFor() { mSpecializedTreeNodes[typeid( SpecNode )] = &mTreeSpecNodeIterators; @@ -157,7 +157,7 @@ SpecializedNodeManagerForSkeleton::SpecializedNodeManagerForSkeleton() //============================================================================== template template -size_t SpecializedNodeManagerForSkeleton::getNumNodes( +size_t SkeletonSpecializedFor::getNumNodes( size_t treeIndex) const { return _getNumNodes(type(), treeIndex); @@ -166,7 +166,7 @@ size_t SpecializedNodeManagerForSkeleton::getNumNodes( //============================================================================== template template -NodeType* SpecializedNodeManagerForSkeleton::getNode( +NodeType* SkeletonSpecializedFor::getNode( size_t treeIndex, size_t nodeIndex) { return _getNode(type(), treeIndex, nodeIndex); @@ -175,17 +175,17 @@ NodeType* SpecializedNodeManagerForSkeleton::getNode( //============================================================================== template template -const NodeType* SpecializedNodeManagerForSkeleton::getNode( +const NodeType* SkeletonSpecializedFor::getNode( size_t treeIndex, size_t nodeIndex) const { - return const_cast*>(this)-> + return const_cast*>(this)-> _getNode(type(), treeIndex, nodeIndex); } //============================================================================== template template -NodeType* SpecializedNodeManagerForSkeleton::getNode( +NodeType* SkeletonSpecializedFor::getNode( const std::string& name) { return _getNode(type(), name); @@ -194,17 +194,17 @@ NodeType* SpecializedNodeManagerForSkeleton::getNode( //============================================================================== template template -const NodeType* SpecializedNodeManagerForSkeleton::getNode( +const NodeType* SkeletonSpecializedFor::getNode( const std::string& name) const { - return const_cast*>(this)-> + return const_cast*>(this)-> _getNode(type(), name); } //============================================================================== template template -size_t SpecializedNodeManagerForSkeleton::_getNumNodes( +size_t SkeletonSpecializedFor::_getNumNodes( type, size_t treeIndex) const { return detail::BasicNodeManagerForSkeleton::getNumNodes(treeIndex); @@ -212,7 +212,7 @@ size_t SpecializedNodeManagerForSkeleton::_getNumNodes( //============================================================================== template -size_t SpecializedNodeManagerForSkeleton::_getNumNodes( +size_t SkeletonSpecializedFor::_getNumNodes( type, size_t treeIndex) const { #ifdef DART_UNITTEST_SPECIALIZED_NODE_ACCESS @@ -234,7 +234,7 @@ size_t SpecializedNodeManagerForSkeleton::_getNumNodes( //============================================================================== template template -NodeType* SpecializedNodeManagerForSkeleton::_getNode( +NodeType* SkeletonSpecializedFor::_getNode( type, size_t treeIndex, size_t nodeIndex) { return detail::BasicNodeManagerForSkeleton::getNode( @@ -243,7 +243,7 @@ NodeType* SpecializedNodeManagerForSkeleton::_getNode( //============================================================================== template -SpecNode* SpecializedNodeManagerForSkeleton::_getNode( +SpecNode* SkeletonSpecializedFor::_getNode( type, size_t treeIndex, size_t nodeIndex) { #ifdef DART_UNITTEST_SPECIALIZED_NODE_ACCESS @@ -277,7 +277,7 @@ SpecNode* SpecializedNodeManagerForSkeleton::_getNode( //============================================================================== template template -NodeType* SpecializedNodeManagerForSkeleton::_getNode( +NodeType* SkeletonSpecializedFor::_getNode( type, const std::string& name) { return detail::BasicNodeManagerForSkeleton::getNode(name); @@ -285,7 +285,7 @@ NodeType* SpecializedNodeManagerForSkeleton::_getNode( //============================================================================== template -SpecNode* SpecializedNodeManagerForSkeleton::_getNode( +SpecNode* SkeletonSpecializedFor::_getNode( type, const std::string& name) { #ifdef DART_UNITTEST_SPECIALIZED_NODE_ACCESS diff --git a/dart/dynamics/detail/UniversalJointProperties.h b/dart/dynamics/detail/UniversalJointProperties.h index 1245a1f294738..750e69237d728 100644 --- a/dart/dynamics/detail/UniversalJointProperties.h +++ b/dart/dynamics/detail/UniversalJointProperties.h @@ -81,7 +81,7 @@ struct UniversalJointProperties : class UniversalJointAddon final : public AddonWithProtectedPropertiesInSkeleton< UniversalJointAddon, UniversalJointUniqueProperties, UniversalJoint, - detail::JointPropertyUpdate, false > + detail::JointPropertyUpdate > { public: DART_DYNAMICS_JOINT_ADDON_CONSTRUCTOR( UniversalJointAddon ) @@ -93,7 +93,7 @@ class UniversalJointAddon final : //============================================================================== using UniversalJointBase = common::AddonManagerJoiner< - MultiDofJoint<2>, common::SpecializedAddonManager >; + MultiDofJoint<2>, common::RequiresAddon >; } // namespace detail } // namespace dynamics diff --git a/unittests/testAddon.cpp b/unittests/testAddon.cpp index d4b1158681311..7a71aa494acb2 100644 --- a/unittests/testAddon.cpp +++ b/unittests/testAddon.cpp @@ -46,7 +46,9 @@ #include "dart/common/Subject.h" #include "dart/common/sub_ptr.h" #include "dart/common/AddonManager.h" -#include "dart/common/SpecializedAddonManager.h" +#include "dart/common/SpecializedForAddon.h" + +#include "dart/dynamics/EulerJoint.h" using namespace dart::common; @@ -202,7 +204,7 @@ typedef StatefulAddon FloatAddon; typedef StatefulAddon CharAddon; typedef StatefulAddon IntAddon; -class CustomSpecializedManager : public SpecializedAddonManager { }; +class CustomSpecializedManager : public SpecializedForAddon { }; TEST(Addon, Generic) { @@ -502,6 +504,55 @@ TEST(Addon, Construction) EXPECT_EQ(mgr.get()->mProperties.val, p); } +TEST(Addon, Joints) +{ + usedSpecializedAddonAccess = false; + + dart::dynamics::SkeletonPtr skel = Skeleton::create(); + + dart::dynamics::EulerJoint* euler = + skel->createJointAndBodyNodePair().first; + euler->getMultiDofJointAddon(); + EXPECT_TRUE(usedSpecializedAddonAccess); usedSpecializedAddonAccess = false; + euler->getEulerJointAddon(); + EXPECT_TRUE(usedSpecializedAddonAccess); usedSpecializedAddonAccess = false; + + dart::dynamics::PlanarJoint* planar = + skel->createJointAndBodyNodePair().first; + planar->getMultiDofJointAddon(); + EXPECT_TRUE(usedSpecializedAddonAccess); usedSpecializedAddonAccess = false; + planar->getPlanarJointAddon(); + EXPECT_TRUE(usedSpecializedAddonAccess); usedSpecializedAddonAccess = false; + + dart::dynamics::PrismaticJoint* prismatic = + skel->createJointAndBodyNodePair().first; + prismatic->getSingleDofJointAddon(); + EXPECT_TRUE(usedSpecializedAddonAccess); usedSpecializedAddonAccess = false; + prismatic->getPrismaticJointAddon(); + EXPECT_TRUE(usedSpecializedAddonAccess); usedSpecializedAddonAccess = false; + + dart::dynamics::RevoluteJoint* revolute = + skel->createJointAndBodyNodePair().first; + revolute->getSingleDofJointAddon(); + EXPECT_TRUE(usedSpecializedAddonAccess); usedSpecializedAddonAccess = false; + revolute->getRevoluteJointAddon(); + EXPECT_TRUE(usedSpecializedAddonAccess); usedSpecializedAddonAccess = false; + + dart::dynamics::ScrewJoint* screw = + skel->createJointAndBodyNodePair().first; + screw->getSingleDofJointAddon(); + EXPECT_TRUE(usedSpecializedAddonAccess); usedSpecializedAddonAccess = false; + screw->getScrewJointAddon(); + EXPECT_TRUE(usedSpecializedAddonAccess); usedSpecializedAddonAccess = false; + + dart::dynamics::UniversalJoint* universal = + skel->createJointAndBodyNodePair().first; + universal->getMultiDofJointAddon(); + EXPECT_TRUE(usedSpecializedAddonAccess); usedSpecializedAddonAccess = false; + universal->getUniversalJointAddon(); + EXPECT_TRUE(usedSpecializedAddonAccess); usedSpecializedAddonAccess = false; +} + int main(int argc, char* argv[]) { ::testing::InitGoogleTest(&argc, argv);