LCOV - code coverage report
Current view: top level - ugbase/common/util - message_hub.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 4 0
Test Date: 2026-06-01 23:54:59 Functions: - 0 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2011-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Sebastian Reiter
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #ifndef __H__UG__message_hub__
      34              : #define __H__UG__message_hub__
      35              : 
      36              : #include <vector>
      37              : #include <list>
      38              : #include <string>
      39              : #include <map>
      40              : #include <functional> // for std::function
      41              : 
      42              : #include "common/assert.h"
      43              : #include "common/util/smart_pointer.h"
      44              : #include "common/util/metaprogramming_util.h"
      45              : #include "common/error.h"
      46              : #include "common/log.h"
      47              : 
      48              : namespace ug
      49              : {
      50              : 
      51              : /// \addtogroup ugbase_common_util
      52              : /// \{
      53              : 
      54              : class MessageHub;
      55              : typedef SmartPtr<MessageHub> SPMessageHub;
      56              : 
      57              : ///     Allows to register callbacks and post messages to those callbacks.
      58              : /**
      59              :  * The MessageHub provides a flexible way to register callbacks for a given
      60              :  * message-type, which can be called through the MessageHub::post_message method.
      61              :  *
      62              :  * Functions and member-functions of arbitrary classes can both be used as a
      63              :  * callback. Callback functions and methods have to have the following signature:
      64              :  *
      65              :  * void (*)(const TMsg&)
      66              :  *
      67              :  * where the message-type TMsg is derived from MessageHub::IMessage.
      68              :  * They can be registered through the register_callback methods.
      69              :  * If you're intending to register a member method of a class, then you have to use
      70              :  * additionally pass the pointer to the class instance, whose member-method shall
      71              :  * be called.
      72              :  *
      73              :  * On registration of a callback, an identifier is returned, which allows to
      74              :  * unregister the callback later on. The identifier is wrapped in a smart-pointer,
      75              :  * and supports an auto-free property. If this is property is enabled, then
      76              :  * the associated callback is automatically unregistered, as soon as the last
      77              :  * copy of the encapsulating smart-pointer is deleted.
      78              :  */
      79              : class MessageHub
      80              : {
      81              :         public:
      82              :         //      predeclarations
      83              :                 class IMessage;
      84              :                 class CallbackId;
      85              : 
      86              :         private:
      87              :         //      private type definitions
      88              :                 typedef std::function<void (const IMessage&)> Callback;
      89              : 
      90              :         ///     The CallbackEntry holds the actual callback and the associated callback-id.
      91              :         /**     If a MessageHub is destroyed before all callbacks are unregistered, this
      92              :          * information can be used to notify associated callback-ids, that the associated
      93              :          * hub is gone. Important if autoFree is enabled.
      94              :          */
      95            0 :                 struct CallbackEntry{
      96              :                         CallbackEntry(const Callback& cb, CallbackId* cbId);
      97              :                         Callback        m_callback;
      98              :                         CallbackId*     m_callbackId;
      99              :                 };
     100              : 
     101              :                 typedef std::list<CallbackEntry>  CallbackEntryList;
     102              :                 typedef CallbackEntryList::iterator     CallbackEntryIterator;
     103              :                 typedef std::map<size_t, CallbackEntryList>       CallbackMap;
     104              : 
     105              :         public:
     106              :         ///     Error codes which give information on the error-reason
     107              :                 enum ErrorIds{
     108              :                         MSG_HUB_UNKNOWN_ERROR,
     109              :                         MSG_HUB_TYPE_MISMATCH,
     110              :                         MSG_HUB_BAD_MESSAGE_ID,
     111              :                         MSG_HUB_BAD_CALLBACK_ID
     112              :                 };
     113              : 
     114              :         ///     Instances of this class are thrown if an error occurs in MessageHub
     115              :         /**     This class derives from UGError.
     116              :          * Use MessageHub::Error::get_message_hub_error_id() to get a more information
     117              :          * on what caused the error.
     118              :          */
     119              :                 class Error : public UGError
     120              :                 {
     121              :                         public:
     122            0 :                                 Error(const char* msg, ErrorIds errorId) :
     123            0 :                                         UGError(msg), m_errorId(errorId) {}
     124              : 
     125              :                                 ErrorIds get_message_hub_error_id()     {return m_errorId;}
     126              : 
     127              :                         protected:
     128              :                                 ErrorIds m_errorId;
     129              :                 };
     130              : 
     131              :         ///     This is the base class of all messages, which may be passed to callbacks.
     132              :                 class IMessage{
     133              :                         public:
     134            0 :                                 IMessage()      {}
     135              :                                 virtual ~IMessage()     {}
     136              :                 };
     137              : 
     138              :         ///     The callback-id allows to deregister previously registered callbacks.
     139              :         /**     Note that the class features an autoFree mechanism, which automatically
     140              :          * frees the associated callback. Since this class is always wrapped in a
     141              :          * smart-pointer, the the associated callback won't be freed, until the last
     142              :          * copy of that smart-pointer is deleted.
     143              :          * You can disable the auto-free mechanism through the set set_auto_free method
     144              :          * or by setting the autoFree parameter of the MessageHub::register_callback
     145              :          * methods to false.
     146              :          */
     147              :                 class CallbackId{
     148              :                         friend class MessageHub;
     149              : 
     150              :                         public:
     151              :                                 ~CallbackId();
     152              :                                 void set_auto_free(bool autoFree)       {m_autoFree = autoFree;}
     153              : 
     154              :                         private:
     155              :                                 CallbackId(MessageHub* hub, size_t msgTypeId,
     156              :                                                    CallbackEntryIterator callbackEntryIter, bool autoFree);
     157              : 
     158              :                                 MessageHub*                             m_hub;
     159              :                         ///     Make sure to only access the iterator while m_hub != NULL.
     160              :                                 size_t                                  m_msgTypeId;
     161              :                                 CallbackEntryIterator   m_callbackEntryIter;
     162              :                                 bool                                    m_autoFree;
     163              :                 };
     164              : 
     165              :                 typedef SmartPtr<CallbackId>      SPCallbackId;
     166              : 
     167              :         public:
     168              :                 MessageHub();
     169              :                 ~MessageHub();
     170              : 
     171              :         ///     registers a function callback given a message-type.
     172              :         /** The callback has to be of the type
     173              :          *
     174              :          * void (*FuncCallback)(const TMsg&)
     175              :          *
     176              :          * where TMsg is a type derived from MessageHub::IMessage.
     177              :          *
     178              :          * The method returns a smart-pointer to a callback-identifier.
     179              :          * The auto-free property is disabled for the returned callback-id by default.
     180              :          * Note that this behavior differs from the similar register_class_callback
     181              :          * method for class-methods.*/
     182              :                 template <class TMsg>
     183              :                 SPCallbackId register_function_callback(void (*callback)(const TMsg&),
     184              :                                                                                            bool autoFree = false);
     185              : 
     186              :         ///     registers a method callback given a message-type.
     187              :         /** The callback has to be of the type
     188              :          *
     189              :          * void (TClass::*ClassCallback)(const TMsg&)
     190              :          *
     191              :          * where TClass is the class whose member function is registered as callback
     192              :          * and TMsg a type derived from MessageHub::IMessage.
     193              :          *
     194              :          * The method returns a smart-pointer to a callback-identifier. When the
     195              :          * instance is deleted, the callback is unregistered by default.
     196              :          * Note that this behavior differs from the similar register_function_callback
     197              :          * method for function pointers.
     198              :          * It's a good idea to store the smart-pointer as a member in the class from
     199              :          * which you register the callback (if it is registered from a class at all).
     200              :          * You then won't have to deal with unregistration manually.*/
     201              :                 template <class TMsg, class TClass>
     202              :                 SPCallbackId register_class_callback(TClass* cls,
     203              :                                                                                    void (TClass::*callback)(const TMsg&),
     204              :                                                                                    bool autoFree = true);
     205              : 
     206              :         ///     Call this method to explicitly unregister a callback.
     207              :         /**     Note that if you're storing the callback-id in a class and if autoFree
     208              :          * is enabled for the callback-id, then the callback is automatically
     209              :          * unregistered, when the last instance of the smart-pointer is deleted.
     210              :          *
     211              :          * If you use this method, the autoFree property of the given CallbackId
     212              :          * will be automatically disabled.
     213              :          */
     214              :                 void unregister_callback(SPCallbackId cbId);
     215              : 
     216              :         ///     Posts a message to all callbacks which are registered for the given message tpye
     217              :                 template <class TMsg>
     218              :                 void post_message(const TMsg& msg);
     219              : 
     220              :         private:
     221              :         ///     registers a callback given a message-id.
     222              :         /**     Make sure to only pass msgIds which were retrieved through get_message_id
     223              :          * before. Also be sure to use the correct msg-type, which was registered with
     224              :          * the given message-id.
     225              :          *
     226              :          * The callback has to be of the type
     227              :          *
     228              :          * <tt>std::function\<void (const IMessage&)\></tt>
     229              :          *
     230              :          * The method returns a smart-pointer to an callback-identifier.
     231              :          *
     232              :          * If the message-id was not registered or if it was registered with a
     233              :          * different type, then an instance of MessageHub::Error is thrown
     234              :          * (derives from UGError).
     235              :          */
     236              :                 template <class TMsg>
     237              :                 SPCallbackId register_callback_impl(
     238              :                                                            std::function<void (const IMessage&)> callback,
     239              :                                                            bool autoFree);
     240              : 
     241              :         ///     performs unregistration of the given callback
     242              :                 void unregister_callback_impl(CallbackId* cbId);
     243              : 
     244              :         private:
     245              :                 CallbackMap     m_callbackMap;///< given a msg-type-id, this map returns a list of associated callbacks
     246              : };
     247              : 
     248              : // end group ugbase_common_util
     249              : /// \}
     250              : 
     251              : }//     end of namespace
     252              : 
     253              : 
     254              : ////////////////////////////////////////
     255              : //      include implementation
     256              : #include "message_hub_impl.hpp"
     257              : 
     258              : #endif
        

Generated by: LCOV version 2.0-1