libzypp 8.13.6
|
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