Imported Upstream version 14.45.0
[platform/upstream/libzypp.git] / zypp / Callback.h
index ef23a17..3956a0b 100644 (file)
@@ -13,6 +13,7 @@
 #define ZYPP_CALLBACK_H
 
 #include "zypp/base/NonCopyable.h"
+#include "zypp/UserData.h"
 
 ///////////////////////////////////////////////////////////////////
 namespace zypp
@@ -42,7 +43,7 @@ namespace zypp
    *
    * That way the sending side does not need to know whether some receiver
    * is listening. And it enables the receiver to return a reasonable value,
-   * in case he's got no idea, what to else to return.
+   * in case he's got no idea, what else to return.
    *
    * \code
    *   struct Foo : public callback::ReportBase
@@ -98,10 +99,10 @@ namespace zypp
    * structure had to provide this value, so it's probabely better
    * than anything you \e invent.
    * \code
-   *   int somefunktion()
+   *   int somefunction()
    *   {
    *     ...// don't know what to return?
-   *     return Foo::somefunktion();
+   *     return Foo::somefunction();
    *   }
    * \endcode
    *
@@ -116,22 +117,27 @@ namespace zypp
    * \endcode
    *
    * \li \c connect Connect this ReceiveReport (in case some other
-   * ReceiveReport is connected, it get disconneced. Remember its
+   * ReceiveReport is connected, it get disconnected. Remember its
    * a Callback light).
    * \li \c disconnect Disconnect this ReceiveReport in case it is
    * connected. If not connected nothing happens.
-   * \li \c connected Test wheter this ReceiveReport is currently
+   * \li \c connected Test whether this ReceiveReport is currently
    * connected.
    * \li \c whoIsConnected Return a 'ReceiveReport*' to the currently
    * connected ReceiveReport, or \c NULL if none is connected.
    *
-  */
+   * \par Passing Userdata via Callbacks
+   *
+   * For typesafe passing of user data via callbacks \see \ref UserData.
+   *
+   */
   namespace callback
   { /////////////////////////////////////////////////////////////////
 
     /**  */
     struct ReportBase
     {
+      typedef callback::UserData UserData;
       virtual ~ReportBase()
       {}
     };
@@ -144,6 +150,9 @@ namespace zypp
     template<class _Report>
       struct ReceiveReport : public _Report
       {
+       typedef _Report                   ReportType;
+       typedef typename ReportType::UserData UserData;
+       typedef ReceiveReport<_Report>    Receiver;
         typedef DistributeReport<_Report> Distributor;
 
         virtual ~ReceiveReport()
@@ -172,7 +181,10 @@ namespace zypp
       struct DistributeReport
       {
        public:
-         typedef ReceiveReport<_Report> Receiver;
+       typedef _Report                   ReportType;
+       typedef typename ReportType::UserData UserData;
+       typedef ReceiveReport<_Report>    Receiver;
+       typedef DistributeReport<_Report> Distributor;
 
          static DistributeReport & instance()
          {
@@ -208,6 +220,9 @@ namespace zypp
     template<class _Report>
       struct SendReport : private zypp::base::NonCopyable
       {
+       typedef _Report                   ReportType;
+       typedef typename ReportType::UserData UserData;
+        typedef ReceiveReport<_Report>    Receiver;
         typedef DistributeReport<_Report> Distributor;
 
         SendReport()
@@ -216,6 +231,12 @@ namespace zypp
         ~SendReport()
         { Distributor::instance()->reportend(); }
 
+        static Receiver * whoIsConnected()
+        { return Distributor::instance().getReceiver(); }
+
+        static bool connected()
+        { return whoIsConnected(); }
+
         Distributor & operator->()
         { return Distributor::instance(); }
       };
@@ -226,6 +247,7 @@ namespace zypp
      * to the ctor. The ReceiveReport is connected, a previously
      * connected ReceiveReport is remembered and re-connected in
      * the dtor.
+     * Use the default ctpr to temporarily disconnect any connected report.
      * \code
      *  struct FooReceive : public callback::ReceiveReport<Foo>
      *  {..};
@@ -247,9 +269,17 @@ namespace zypp
     template<class _Report>
       struct TempConnect
       {
+       typedef _Report                   ReportType;
+       typedef typename ReportType::UserData UserData;
         typedef ReceiveReport<_Report>    Receiver;
         typedef DistributeReport<_Report> Distributor;
 
+        TempConnect()
+        : _oldRec( Distributor::instance().getReceiver() )
+        {
+          Distributor::instance().noReceiver();
+        }
+
         TempConnect( Receiver & rec_r )
         : _oldRec( Distributor::instance().getReceiver() )
         {