/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2020, by the GROMACS development team, led by
+ * Copyright (c) 2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
*/
/*! \libinternal \file
* \brief
- * Declares gmx::MdModuleNotification.
+ * Declares gmx::MDModulesNotifier.
*
* \author Christian Blau <blau@kth.se>
* \inlibraryapi
namespace gmx
{
-/*! \libinternal \brief
- * Subscribe and trigger notification functions.
- *
- * Extends MdModuleNotificationBase with new notification function and routine
- * to subscribe new listeners.
- *
- * To create a class of this type that provides callbacks, e.g., for events
- * EventA, and EventB use registerMdModuleNotification<EventA, EventB>::type.
+/*! \libinternal
+ * \brief Organizes notifications about an event of interest to modules.
+ *
+ * An object of this type permits modules to subscribe to the
+ * corresponding event. The template types of this type encode what
+ * information is available when the event occurs. Modules \c
+ * subscribe() by providing a callback function that accepts a single
+ * parameter of such an event type. The code that handles that event
+ * has the responsibilty to call \c notify() afterwards. The
+ * subscribed modules then receive the callback with the requested
+ * event type as an argument.
+ *
+ * See gmx::MDModulesNotifiers for sequence diagrams for an example.
+ *
+ * This suits scenarios where several objects are built (or re-built)
+ * and one or more modules need to know when one or more of such
+ * objects are available (or updated), so they can adapt their
+ * internal state accordingly. Examples include responding to loading
+ * input data, or to changes related to a recurring process like
+ * checkpointing or partitioning. The coupling between these modules
+ * is now expressed indirectly. This improves the modularity and
+ * testability of those modules.
+ *
+ * The implementation provides the necessary flexibility to be
+ * parameterized with multiple event types and provide \c callback()
+ * and \b notify() methods corresponding to each related event. This
+ * is done by inheriting from a series of base classes, each of which
+ * handles a single type of event. BuildMDModulesNotifier implements
+ * the details. To create a class of this type that provides two
+ * events with callbacks that receive respectively types TypeA and
+ * TypeB, use BuildMDModulesNotifier<TypeA, TypeB>::type.
*
* \tparam CallParameter of the function to be notified
- * \tparam MdModuleNotificationBase class to be extended with a notification
+ * \tparam MDModulesNotifierBase class to be extended with a notification
* with CallParameter
*
- * \note All added subscribers are required to out-live the MdModuleNotification
+ * \note All added subscribers are required to out-live the MDModulesNotifier
*
*/
-template<class CallParameter, class MdModuleNotificationBase>
-class MdModuleNotification : public MdModuleNotificationBase
+template<class CallParameter, class MDModulesNotifierBase>
+class MDModulesNotifier : public MDModulesNotifierBase
{
public:
//! Make base class notification trigger available to this class
- using MdModuleNotificationBase::notify;
+ using MDModulesNotifierBase::notify;
//! Make base class subscription available to this class
- using MdModuleNotificationBase::subscribe;
+ using MDModulesNotifierBase::subscribe;
- /*! \brief Trigger the subscribed notifications.
+ /*! \brief Notifies subscribers of the event described by \c
+ * callbackParameter.
+ *
* \param[in] callParameter of the function to be called back
*/
void notify(CallParameter callParameter) const
}
/*! \brief
- * Add callback function to be called when notification is triggered.
- *
- * Notifications are distinguished by their call signature.
+ * Add callback function to be called when \c notify() is called
*
- * \param[in] callBackFunction to be called from this class
+ * \param[in] callBackFunction to be called
*/
void subscribe(std::function<void(CallParameter)> callBackFunction)
{
};
/*! \internal
- * \brief Aide to avoid nested MdModuleNotification definition.
+ * \brief Aide to avoid nested MDModulesNotifier definition.
*
* Instead of
- * MdModuleNotification<CallParameterA, MdModuleNotification<CallParameterB, etc ... >>
+ * MDModulesNotifier<CallParameterA, MDModulesNotifier<CallParameterB, etc ... >>
* this allows to write
- * registerMdModuleNotification<CallParameterA, CallParameterB, ...>::type
+ * BuildMDModulesNotifier<CallParameterA, CallParameterB, ...>::type
*
- * \tparam CallParameter all the event types to be registered
+ * \tparam CallParameter all the callback types to be registered
*/
template<class... CallParameter>
-struct registerMdModuleNotification;
+struct BuildMDModulesNotifier;
/*! \internal \brief Template specialization to end parameter unpacking recursion.
*/
template<>
-struct registerMdModuleNotification<>
+struct BuildMDModulesNotifier<>
{
/*! \internal
- * \brief Do nothing but be base class of MdModuleNotification.
+ * \brief Do nothing but be base class of MDModulesNotifier.
*
- * Required so that using MdModuleNotificationBase::notify and
- * MdModuleNotificationBase::subscribe are valid in derived class.
+ * Required so that using MDModulesNotifierBase::notify and
+ * MDModulesNotifierBase::subscribe are valid in derived class.
*/
class NoCallParameter
{
public:
- //! Do nothing but provide MdModuleNotification::notify to derived class
+ //! Do nothing but provide MDModulesNotifier::notify to derived class
void notify() {}
- //! Do nothing but provide MdModuleNotification::subscribe to derived class
+ //! Do nothing but provide MDModulesNotifier::subscribe to derived class
void subscribe() {}
};
/*! \brief Defines a type if no notifications are managed.
*
- * This ensures that code works with MdModuleCallParameterManagement that
+ * This ensures that code works with MDModuleCallParameterManagement that
* does not manage any notifications.
*/
using type = NoCallParameter;
};
/*! \libinternal
- * \brief Template specialization to assemble MdModuleNotification.
+ * \brief Template specialization to assemble MDModulesNotifier.
*
- * Assembly of MdModuleNotification is performed by recursively taking off the
+ * Assembly of MDModulesNotifier is performed by recursively taking off the
* front of the CallParameter parameter pack and constructing the nested type
- * definition of MdModuleNotification base classes.
+ * definition of MDModulesNotifier base classes.
*
* \tparam CurrentCallParameter front of the template parameter pack
- * \tparam CallParameter rest of the event types
+ * \tparam CallParameter rest of the callback types
*/
template<class CurrentCallParameter, class... CallParameter>
-struct registerMdModuleNotification<CurrentCallParameter, CallParameter...>
+struct BuildMDModulesNotifier<CurrentCallParameter, CallParameter...>
{
// private:
//! The next type with rest of the arguments with the front parameter removed.
- using next_type = typename registerMdModuleNotification<CallParameter...>::type;
- //! The type of the MdModuleNotification
- using type = MdModuleNotification<CurrentCallParameter, next_type>;
+ using next_type = typename BuildMDModulesNotifier<CallParameter...>::type;
+ //! The type of the MDModulesNotifier
+ using type = MDModulesNotifier<CurrentCallParameter, next_type>;
};
} // namespace gmx