libzypp  10.5.0
Callback.h
Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #ifndef ZYPP_CALLBACK_H
00013 #define ZYPP_CALLBACK_H
00014 
00015 #include "zypp/base/NonCopyable.h"
00016 
00018 namespace zypp
00019 { 
00020 
00022   namespace HACK {
00023     class Callback
00024     {
00025     };
00026   } // namespace HACK
00027 
00029 
00129   namespace callback
00130   { 
00131 
00133     struct ReportBase
00134     {
00135       virtual ~ReportBase()
00136       {}
00137     };
00138 
00140     template<class _Report>
00141       class DistributeReport;
00142 
00144     template<class _Report>
00145       struct ReceiveReport : public _Report
00146       {
00147         typedef _Report                   ReportType;
00148         typedef ReceiveReport<_Report>    Receiver;
00149         typedef DistributeReport<_Report> Distributor;
00150 
00151         virtual ~ReceiveReport()
00152         { disconnect(); }
00153 
00154         ReceiveReport * whoIsConnected() const
00155         { return Distributor::instance().getReceiver(); }
00156 
00157         bool connected() const
00158         { return whoIsConnected() == this; }
00159 
00160         void connect()
00161         { Distributor::instance().setReceiver( *this ); }
00162 
00163         void disconnect()
00164         { Distributor::instance().unsetReceiver( *this ); }
00165 
00166         virtual void reportbegin()
00167         {}
00168         virtual void reportend()
00169         {}
00170       };
00171 
00173     template<class _Report>
00174       struct DistributeReport
00175       {
00176        public:
00177         typedef _Report                   ReportType;
00178         typedef ReceiveReport<_Report>    Receiver;
00179         typedef DistributeReport<_Report> Distributor;
00180 
00181          static DistributeReport & instance()
00182          {
00183            static DistributeReport _self;
00184            return _self;
00185          }
00186 
00187          Receiver * getReceiver() const
00188          { return _receiver == &_noReceiver ? 0 : _receiver; }
00189 
00190          void setReceiver( Receiver & rec_r )
00191          { _receiver = &rec_r; }
00192 
00193          void unsetReceiver( Receiver & rec_r )
00194          { if ( _receiver == &rec_r ) noReceiver(); }
00195 
00196          void noReceiver()
00197          { _receiver = &_noReceiver; }
00198 
00199       public:
00200          Receiver * operator->()
00201          { return _receiver; }
00202 
00203       private:
00204         DistributeReport()
00205         : _receiver( &_noReceiver )
00206         {}
00207         Receiver _noReceiver;
00208         Receiver * _receiver;
00209       };
00210 
00212     template<class _Report>
00213       struct SendReport : private zypp::base::NonCopyable
00214       {
00215         typedef _Report                   ReportType;
00216         typedef ReceiveReport<_Report>    Receiver;
00217         typedef DistributeReport<_Report> Distributor;
00218 
00219         SendReport()
00220         { Distributor::instance()->reportbegin(); }
00221 
00222         ~SendReport()
00223         { Distributor::instance()->reportend(); }
00224 
00225         Distributor & operator->()
00226         { return Distributor::instance(); }
00227       };
00228 
00254     template<class _Report>
00255       struct TempConnect
00256       {
00257         typedef _Report                   ReportType;
00258         typedef ReceiveReport<_Report>    Receiver;
00259         typedef DistributeReport<_Report> Distributor;
00260 
00261         TempConnect()
00262         : _oldRec( Distributor::instance().getReceiver() )
00263         {
00264           Distributor::instance().noReceiver();
00265         }
00266 
00267         TempConnect( Receiver & rec_r )
00268         : _oldRec( Distributor::instance().getReceiver() )
00269         {
00270           rec_r.connect();
00271         }
00272 
00273         ~TempConnect()
00274         {
00275           if ( _oldRec )
00276             Distributor::instance().setReceiver( *_oldRec );
00277           else
00278             Distributor::instance().noReceiver();
00279         }
00280       private:
00281         Receiver * _oldRec;
00282       };
00283 
00285   } // namespace callback
00288 } // namespace zypp
00290 #endif // ZYPP_CALLBACK_H