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