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 DistributeReport<_Report> Distributor;
00148 
00149         virtual ~ReceiveReport()
00150         { disconnect(); }
00151 
00152         ReceiveReport * whoIsConnected() const
00153         { return Distributor::instance().getReceiver(); }
00154 
00155         bool connected() const
00156         { return whoIsConnected() == this; }
00157 
00158         void connect()
00159         { Distributor::instance().setReceiver( *this ); }
00160 
00161         void disconnect()
00162         { Distributor::instance().unsetReceiver( *this ); }
00163 
00164         virtual void reportbegin()
00165         {}
00166         virtual void reportend()
00167         {}
00168       };
00169 
00171     template<class _Report>
00172       struct DistributeReport
00173       {
00174        public:
00175          typedef ReceiveReport<_Report> Receiver;
00176 
00177          static DistributeReport & instance()
00178          {
00179            static DistributeReport _self;
00180            return _self;
00181          }
00182 
00183          Receiver * getReceiver() const
00184          { return _receiver == &_noReceiver ? 0 : _receiver; }
00185 
00186          void setReceiver( Receiver & rec_r )
00187          { _receiver = &rec_r; }
00188 
00189          void unsetReceiver( Receiver & rec_r )
00190          { if ( _receiver == &rec_r ) noReceiver(); }
00191 
00192          void noReceiver()
00193          { _receiver = &_noReceiver; }
00194 
00195       public:
00196          Receiver * operator->()
00197          { return _receiver; }
00198 
00199       private:
00200         DistributeReport()
00201         : _receiver( &_noReceiver )
00202         {}
00203         Receiver _noReceiver;
00204         Receiver * _receiver;
00205       };
00206 
00208     template<class _Report>
00209       struct SendReport : private zypp::base::NonCopyable
00210       {
00211         typedef DistributeReport<_Report> Distributor;
00212 
00213         SendReport()
00214         { Distributor::instance()->reportbegin(); }
00215 
00216         ~SendReport()
00217         { Distributor::instance()->reportend(); }
00218 
00219         Distributor & operator->()
00220         { return Distributor::instance(); }
00221       };
00222 
00247     template<class _Report>
00248       struct TempConnect
00249       {
00250         typedef ReceiveReport<_Report>    Receiver;
00251         typedef DistributeReport<_Report> Distributor;
00252 
00253         TempConnect( Receiver & rec_r )
00254         : _oldRec( Distributor::instance().getReceiver() )
00255         {
00256           rec_r.connect();
00257         }
00258 
00259         ~TempConnect()
00260         {
00261           if ( _oldRec )
00262             Distributor::instance().setReceiver( *_oldRec );
00263           else
00264             Distributor::instance().noReceiver();
00265         }
00266       private:
00267         Receiver * _oldRec;
00268       };
00269 
00271   } // namespace callback
00274 } // namespace zypp
00276 #endif // ZYPP_CALLBACK_H

doxygen