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: 2025-09-21 23:31:46 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 <boost/function.hpp>
      41              : #include <boost/function_equal.hpp>
      42              : #include <boost/bind.hpp>
      43              : #include "common/assert.h"
      44              : #include "common/util/smart_pointer.h"
      45              : #include "common/util/metaprogramming_util.h"
      46              : #include "common/error.h"
      47              : #include "common/log.h"
      48              : 
      49              : namespace ug
      50              : {
      51              : 
      52              : /// \addtogroup ugbase_common_util
      53              : /// \{
      54              : 
      55              : class MessageHub;
      56              : typedef SmartPtr<MessageHub> SPMessageHub;
      57              : 
      58              : ///     Allows to register callbacks and post messages to those callbacks.
      59              : /**
      60              :  * The MessageHub provides a flexible way to register callbacks for a given
      61              :  * message-type, which can be called through the MessageHub::post_message method.
      62              :  *
      63              :  * Functions and member-functions of arbitrary classes can both be used as a
      64              :  * callback. Callback functions and methods have to have the following signature:
      65              :  *
      66              :  * void (*)(const TMsg&)
      67              :  *
      68              :  * where the message-type TMsg is derived from MessageHub::IMessage.
      69              :  * They can be registered through the register_callback methods.
      70              :  * If you're intending to register a member method of a class, then you have to use
      71              :  * additionally pass the pointer to the class instance, whose member-method shall
      72              :  * be called.
      73              :  *
      74              :  * On registration of a callback, an identifier is returned, which allows to
      75              :  * unregister the callback later on. The identifier is wrapped in a smart-pointer,
      76              :  * and supports an auto-free property. If this is property is enabled, then
      77              :  * the associated callback is automatically unregistered, as soon as the last
      78              :  * copy of the encapsulating smart-pointer is deleted.
      79              :  */
      80              : class MessageHub
      81              : {
      82              :         public:
      83              :         //      predeclarations
      84              :                 class IMessage;
      85              :                 class CallbackId;
      86              : 
      87              :         private:
      88              :         //      private type definitions
      89              :                 typedef boost::function<void (const IMessage&)> Callback;
      90              : 
      91              :         ///     The CallbackEntry holds the actual callback and the associated callback-id.
      92              :         /**     If a MessageHub is destroyed before all callbacks are unregistered, this
      93              :          * information can be used to notify associated callback-ids, that the associated
      94              :          * hub is gone. Important if autoFree is enabled.
      95              :          */
      96            0 :                 struct CallbackEntry{
      97              :                         CallbackEntry(const Callback& cb, CallbackId* cbId);
      98              :                         Callback        m_callback;
      99              :                         CallbackId*     m_callbackId;
     100              :                 };
     101              : 
     102              :                 typedef std::list<CallbackEntry>  CallbackEntryList;
     103              :                 typedef CallbackEntryList::iterator     CallbackEntryIterator;
     104              :                 typedef std::map<size_t, CallbackEntryList>       CallbackMap;
     105              : 
     106              :         public:
     107              :         ///     Error codes which give information on the error-reason
     108              :                 enum ErrorIds{
     109              :                         MSG_HUB_UNKNOWN_ERROR,
     110              :                         MSG_HUB_TYPE_MISMATCH,
     111              :                         MSG_HUB_BAD_MESSAGE_ID,
     112              :                         MSG_HUB_BAD_CALLBACK_ID
     113              :                 };
     114              : 
     115              :         ///     Instances of this class are thrown if an error occurs in MessageHub
     116              :         /**     This class derives from UGError.
     117              :          * Use MessageHub::Error::get_message_hub_error_id() to get a more information
     118              :          * on what caused the error.
     119              :          */
     120              :                 class Error : public UGError
     121              :                 {
     122              :                         public:
     123            0 :                                 Error(const char* msg, ErrorIds errorId) :
     124            0 :                                         UGError(msg), m_errorId(errorId) {}
     125              : 
     126              :                                 ErrorIds get_message_hub_error_id()     {return m_errorId;}
     127              : 
     128              :                         protected:
     129              :                                 ErrorIds m_errorId;
     130              :                 };
     131              : 
     132              :         ///     This is the base class of all messages, which may be passed to callbacks.
     133              :                 class IMessage{
     134              :                         public:
     135            0 :                                 IMessage()      {}
     136              :                                 virtual ~IMessage()     {}
     137              :                 };
     138              : 
     139              :         ///     The callback-id allows to deregister previously registered callbacks.
     140              :         /**     Note that the class features an autoFree mechanism, which automatically
     141              :          * frees the associated callback. Since this class is always wrapped in a
     142              :          * smart-pointer, the the associated callback won't be freed, until the last
     143              :          * copy of that smart-pointer is deleted.
     144              :          * You can disable the auto-free mechanism through the set set_auto_free method
     145              :          * or by setting the autoFree parameter of the MessageHub::register_callback
     146              :          * methods to false.
     147              :          */
     148              :                 class CallbackId{
     149              :                         friend class MessageHub;
     150              : 
     151              :                         public:
     152              :                                 ~CallbackId();
     153              :                                 void set_auto_free(bool autoFree)       {m_autoFree = autoFree;}
     154              : 
     155              :                         private:
     156              :                                 CallbackId(MessageHub* hub, size_t msgTypeId,
     157              :                                                    CallbackEntryIterator callbackEntryIter, bool autoFree);
     158              : 
     159              :                                 MessageHub*                             m_hub;
     160              :                         ///     Make sure to only access the iterator while m_hub != NULL.
     161              :                                 size_t                                  m_msgTypeId;
     162              :                                 CallbackEntryIterator   m_callbackEntryIter;
     163              :                                 bool                                    m_autoFree;
     164              :                 };
     165              : 
     166              :                 typedef SmartPtr<CallbackId>      SPCallbackId;
     167              : 
     168              :         public:
     169              :                 MessageHub();
     170              :                 ~MessageHub();
     171              : 
     172              :         ///     registers a function callback given a message-type.
     173              :         /** The callback has to be of the type
     174              :          *
     175              :          * void (*FuncCallback)(const TMsg&)
     176              :          *
     177              :          * where TMsg is a type derived from MessageHub::IMessage.
     178              :          *
     179              :          * The method returns a smart-pointer to a callback-identifier.
     180              :          * The auto-free property is disabled for the returned callback-id by default.
     181              :          * Note that this behavior differs from the similar register_class_callback
     182              :          * method for class-methods.*/
     183              :                 template <class TMsg>
     184              :                 SPCallbackId register_function_callback(void (*callback)(const TMsg&),
     185              :                                                                                            bool autoFree = false);
     186              : 
     187              :         ///     registers a method callback given a message-type.
     188              :         /** The callback has to be of the type
     189              :          *
     190              :          * void (TClass::*ClassCallback)(const TMsg&)
     191              :          *
     192              :          * where TClass is the class whose member function is registered as callback
     193              :          * and TMsg a type derived from MessageHub::IMessage.
     194              :          *
     195              :          * The method returns a smart-pointer to a callback-identifier. When the
     196              :          * instance is deleted, the callback is unregistered by default.
     197              :          * Note that this behavior differs from the similar register_function_callback
     198              :          * method for function pointers.
     199              :          * It's a good idea to store the smart-pointer as a member in the class from
     200              :          * which you register the callback (if it is registered from a class at all).
     201              :          * You then won't have to deal with unregistration manually.*/
     202              :                 template <class TMsg, class TClass>
     203              :                 SPCallbackId register_class_callback(TClass* cls,
     204              :                                                                                    void (TClass::*callback)(const TMsg&),
     205              :                                                                                    bool autoFree = true);
     206              : 
     207              :         ///     Call this method to explicitly unregister a callback.
     208              :         /**     Note that if you're storing the callback-id in a class and if autoFree
     209              :          * is enabled for the callback-id, then the callback is automatically
     210              :          * unregistered, when the last instance of the smart-pointer is deleted.
     211              :          *
     212              :          * If you use this method, the autoFree property of the given CallbackId
     213              :          * will be automatically disabled.
     214              :          */
     215              :                 void unregister_callback(SPCallbackId cbId);
     216              : 
     217              :         ///     Posts a message to all callbacks which are registered for the given message tpye
     218              :                 template <class TMsg>
     219              :                 void post_message(const TMsg& msg);
     220              : 
     221              :         private:
     222              :         ///     registers a callback given a message-id.
     223              :         /**     Make sure to only pass msgIds which were retrieved through get_message_id
     224              :          * before. Also be sure to use the correct msg-type, which was registered with
     225              :          * the given message-id.
     226              :          *
     227              :          * The callback has to be of the type
     228              :          *
     229              :          * <tt>boost::function\<void (const IMessage&)\></tt>
     230              :          *
     231              :          * The method returns a smart-pointer to an callback-identifier.
     232              :          *
     233              :          * If the message-id was not registered or if it was registered with a
     234              :          * different type, then an instance of MessageHub::Error is thrown
     235              :          * (derives from UGError).
     236              :          */
     237              :                 template <class TMsg>
     238              :                 SPCallbackId register_callback_impl(
     239              :                                                            boost::function<void (const IMessage&)> callback,
     240              :                                                            bool autoFree);
     241              : 
     242              :         ///     performs unregistration of the given callback
     243              :                 void unregister_callback_impl(CallbackId* cbId);
     244              : 
     245              :         private:
     246              :                 CallbackMap     m_callbackMap;///< given a msg-type-id, this map returns a list of associated callbacks
     247              : };
     248              : 
     249              : // end group ugbase_common_util
     250              : /// \}
     251              : 
     252              : }//     end of namespace
     253              : 
     254              : 
     255              : ////////////////////////////////////////
     256              : //      include implementation
     257              : #include "message_hub_impl.hpp"
     258              : 
     259              : #endif
        

Generated by: LCOV version 2.0-1