00001 /*---------------------------------------------------------------------\ 00002 | | 00003 | __ __ ____ _____ ____ | 00004 | \ \ / /_ _/ ___|_ _|___ \ | 00005 | \ V / _` \___ \ | | __) | | 00006 | | | (_| |___) || | / __/ | 00007 | |_|\__,_|____/ |_| |_____| | 00008 | | 00009 | core system | 00010 | (C) SuSE GmbH | 00011 \----------------------------------------------------------------------/ 00012 00013 File: CallBack.h 00014 00015 Author: Michael Andres <ma@suse.de> 00016 Maintainer: Michael Andres <ma@suse.de> 00017 00018 Purpose: Template classes for callback handling. 00019 00020 /-*/ 00021 #ifndef CallBack_h 00022 #define CallBack_h 00023 00025 // 00026 // CLASS NAME : ReportCallback 00039 struct ReportCallback { 00043 virtual ~ReportCallback() {} 00047 virtual void reportbegin() {} 00051 virtual void reportend() {} 00052 }; 00053 00055 00057 // 00058 // CLASS NAME : RedirectCallback<class CB> 00099 template <class CB> class RedirectCallback : public ReportCallback { 00100 00101 private: 00102 00106 CB * _redirectTo; 00107 00111 CB * self() { return dynamic_cast<CB*>(this); } 00112 00113 protected: 00114 00119 CB * redirectTo( CB * to_r ) { 00120 CB * ret = _redirectTo; 00121 _redirectTo = ( to_r == self() ? 0 : to_r ); 00122 return ret; 00123 } 00128 CB * redirectTo( CB & to_r ) { 00129 return redirectTo( &to_r ); 00130 } 00131 00132 public: 00133 00137 virtual CB * operator->() { 00138 return( _redirectTo ? _redirectTo->operator->() : self() ); 00139 } 00140 00141 public: 00142 00146 RedirectCallback() 00147 : _redirectTo( 0 ) 00148 {} 00152 virtual ~RedirectCallback() {} 00153 }; 00154 00156 00158 // 00159 // CLASS NAME : Report<class CB> 00242 template <class CB> class Report : protected CB { 00243 00244 public: 00245 00249 Report() {} 00253 virtual ~Report() {} 00254 00255 public: 00256 00260 CB::redirectTo; 00261 00262 public: 00263 00265 // 00266 // CLASS NAME : Report<CB>::Send 00277 class Send { 00278 00279 private: 00280 00284 Report<CB> & _report; 00285 00286 public: 00287 00291 Send( Report<CB> & report_r ) 00292 : _report( report_r ) 00293 { operator->()->reportbegin(); } 00297 ~Send() { 00298 operator->()->reportend(); 00299 } 00300 00304 CB * operator->() { return _report.operator->(); } 00305 }; 00306 00308 }; 00309 00311 00313 // 00314 // CLASS NAME : 00320 template <class CB> class ReportRedirect { 00321 ReportRedirect( const ReportRedirect & rhs ); // FORBIDDEN 00322 ReportRedirect & operator=( const ReportRedirect & rhs ); // FORBIDDEN 00323 private: 00324 Report<CB> & _report; 00325 CB * _redirect; 00326 CB * _oredirect; 00327 public: 00328 ReportRedirect( Report<CB> & report_r, CB & redirect_r ) 00329 : _report( report_r ) 00330 , _redirect( &redirect_r ) 00331 { 00332 _oredirect = _report.redirectTo( _redirect ); 00333 } 00334 ReportRedirect( Report<CB> & report_r, CB * redirect_r ) 00335 : _report( report_r ) 00336 , _redirect( redirect_r ) 00337 { 00338 _oredirect = _report.redirectTo( _redirect ); 00339 } 00340 virtual ~ReportRedirect() { 00341 _report.redirectTo( _oredirect ); 00342 }; 00343 }; 00344 00346 00348 // 00349 // CLASS NAME : 00355 template <class CB> struct ReportReceive : public CB, public ReportRedirect<CB> { 00356 ReportReceive( Report<CB> & report_r ) 00357 : ReportRedirect<CB>( report_r, static_cast<CB*>(this) ) 00358 {} 00359 }; 00360 00362 00363 #endif // CallBack_h