Skip to content

Commit

Permalink
iox-eclipse-iceoryx#1640 Document PolymorphicHandler
Browse files Browse the repository at this point in the history
Signed-off-by: Matthias Killat <[email protected]>
  • Loading branch information
MatthiasKillat committed Sep 20, 2022
1 parent a3b9e51 commit d061426
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,42 +8,62 @@
// TODO: change namespace? but DesignPattern is a bad namespace name ...
namespace iox
{
namespace design
{
// TODO: namespace of this concept? should not depend on templated class (e.g. PolymorphicHandler)

struct Activatable
/// @brief Implements the Activatable concept to be used in the PolymorphicHandler
/// The concept implements a binary switch. By default is switched on (active).
class Activatable
{
public:
Activatable() = default;

/// @brief Switch on.
void activate()
{
m_active = true;
}

/// @brief Switch off.
void deactivate()
{
m_active = false;
}

/// @brief Query switch state.
/// @return true if active (on), false otherwise (off).
bool isActive() const
{
return m_active;
}

private:
bool m_active = true;
bool m_active{true};
};

// we lose generality now wrt. the interface (require activate, deactivate etc. in the interface)
/// @brief Implements a singleton handler that has a default instance and can be changed
/// to another instance at runtime. All instances have to derive from the same interface.
/// The singleton handler owns the default instance but all other instances are created externally.
/// @tparam Interface The interface of the handler instances. Must inherit from Activatable.
/// @tparam Default The type of the default instance. Must be equal to or derive from Interface.
///
/// @note In the special case where Default equals Interface, no polymorphism is required.
/// It is then possible to e.g. switch between multiple instances of Default type.
/// @note The lifetime of external non-default instances must exceed the lifetime of the PolymorphicHandler.
/// @note The PolymorphicHandler is guaranteed to provide a valid handler during the whole program lifetime (static).
/// It is hence not advisable to have other static variables depend on the PolymorphicHandler.
/// It must be ensured that the are destroyed before the PolymorphicHandler.
template <typename Interface, typename Default>
class PolymorphicHandler
{
static_assert(std::is_base_of<Interface, Default>::value, "Default must inherit from Interface");

// actually it suffices to provide the methods activate, deactivate, isActive
// but they need to behave correctly and inheritance enforces this
static_assert(std::is_base_of<Activatable, Interface>::value, "Interface must inherit from Activatable");

public:
using Self = PolymorphicHandler<Interface, Default>;

// on first call (in a thread):
// 1. localHandler is initialized
// - getCurrent is called
Expand All @@ -66,8 +86,11 @@ class PolymorphicHandler
// under lock, we update the local handler to the new one (note that it cannot change
// while this happens as we hold the lock)

/// @brief get the current singleton instance
/// @return the current instance
static Interface& get()
{
// NOLINTNEXTLINE
thread_local Interface* localHandler = getCurrent(); // initialized once per thread on first call

if (!localHandler->isActive())
Expand All @@ -78,6 +101,9 @@ class PolymorphicHandler
return *localHandler;
}

/// @brief set the current singleton instance
/// @param handler the handler instance to be set
/// @return pointer to the previous instance
static Interface* set(Interface& handler)
{
auto& ins = instance();
Expand All @@ -100,11 +126,15 @@ class PolymorphicHandler
return prev;
}

/// @brief reset the current singleton instance to the default instance
/// @return pointer to the previous instance
static Interface* reset()
{
return set(getDefault());
}

/// @brief finalizes the instance, afterwards no further instance can be set
/// during program lifetime
static void finalize()
{
auto& ins = instance();
Expand Down Expand Up @@ -146,4 +176,5 @@ class PolymorphicHandler
}
};

} // namespace eh
} // namespace design
} // namespace iox
6 changes: 3 additions & 3 deletions iceoryx_hoofs/test/moduletests/test_polymorphic_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace
{
using namespace ::testing;

struct Interface : public iox::Activatable
struct Interface : public iox::design::Activatable
{
virtual ~Interface() = default;

Expand Down Expand Up @@ -61,7 +61,7 @@ Alternate& alternateHandler()
return h;
};

using Handler = iox::PolymorphicHandler<Interface, Default>;
using Handler = iox::design::PolymorphicHandler<Interface, Default>;

class PolymorphicHandler_test : public Test
{
Expand Down Expand Up @@ -177,7 +177,7 @@ class Activatable_test : public Test
}
}

iox::Activatable sut;
iox::design::Activatable sut;
};

TEST_F(Activatable_test, isActiveAfterConstruction)
Expand Down

0 comments on commit d061426

Please sign in to comment.