Improve docs and naming for MdModulesNotifiers
[alexxy/gromacs.git] / src / gromacs / utility / mdmodulenotification-impl.h
index a4025046704bf2345c2fbf05c2a4d5960f2378e6..d48813210537749386b73c520f9725812e8b36fc 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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.
@@ -34,7 +34,7 @@
  */
 /*! \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
@@ -87,11 +112,9 @@ public:
     }
 
     /*! \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)
     {
@@ -103,63 +126,63 @@ private:
 };
 
 /*! \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