src/tools/tRecorder.h

Go to the documentation of this file.
00001 /*
00002 
00003 *************************************************************************
00004 
00005 ArmageTron -- Just another Tron Lightcycle Game in 3D.
00006 Copyright (C) 2000  Manuel Moos (manuel@moosnet.de)
00007 
00008 **************************************************************************
00009 
00010 This program is free software; you can redistribute it and/or
00011 modify it under the terms of the GNU General Public License
00012 as published by the Free Software Foundation; either version 2
00013 of the License, or (at your option) any later version.
00014 
00015 This program is distributed in the hope that it will be useful,
00016 but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00023   
00024 ***************************************************************************
00025 
00026 */
00027 
00028 #ifndef     TRECORDER_H_INCLUDED
00029 #define     TRECORDER_H_INCLUDED
00030 
00031 #ifdef DEBUG
00032 #ifndef DEBUG_DIFFERENCE
00033 #define DEBUG_DIFFERENCE
00034 #endif
00035 #endif
00036 
00037 // self include
00038 #ifndef     TRECORDER_H_INCLUDED
00039 #include    "tRecorder.h"
00040 #endif
00041 
00042 #include    "tString.h"
00043 #include    "tError.h"
00044 
00045 // #include    "tRecorderInternal.h"
00046 
00047 // *****************************************************************************
00048 // Helpers required to work around VisualC's iability to handle out-of-line
00049 // template members. Just ignore them.
00050 // *****************************************************************************
00051 
00053 template< class BLOCK >
00054 class tRecorderTemplate1
00055 {
00056 public:
00057     static bool Archive( bool strict, char const * section );                  
00058 };
00059 
00061 template< class BLOCK, typename DATA >
00062 class tRecorderTemplate2
00063 {
00064 public:
00065     static bool Archive( bool strict, char const * section, DATA data );                  
00066 };
00067 
00069 template< class BLOCK, typename DATA1, typename DATA2 >
00070 class tRecorderTemplate3
00071 {
00072 public:
00073     static bool Archive( bool strict, char const * section, DATA1 data1, DATA2 data2 );  
00074 };
00075 
00076 // *****************************************************************************
00077 // tRecorder: simple recording interface. Most users will only need this.
00078 // *****************************************************************************
00079 
00080 class tRecordingBlock;
00081 class tPlaybackBlock;
00082 
00084 class tRecorderBase
00085 {
00086 public:
00087     static bool IsRecording();                          
00088     static bool IsPlayingBack();                        
00089     static bool IsRunning();                            
00090 };
00091 
00093 class tRecorder: public tRecorderBase
00094 {
00095 public:
00096     static bool Record( char const * section );         
00097     static bool Playback( char const * section );       
00098     static bool PlaybackStrict( char const * section ); 
00099 
00101     template< class DATA >
00102     static bool Record  ( char const * section, DATA const & data )
00103     { return tRecorderTemplate2< tRecordingBlock, DATA const & >::Archive( false, section, data ); }
00104 
00106     template< class DATA >
00107     static bool Playback( char const * section, DATA & data )
00108     { return tRecorderTemplate2< tPlaybackBlock, DATA & >::Archive( false, section, data ); }
00109 
00111     template< class DATA >
00112     static bool PlaybackStrict( char const * section, DATA & data )
00113     { return tRecorderTemplate2< tPlaybackBlock, DATA & >::Archive( true, section, data ); }
00114 
00116     template< class DATA1, class DATA2 >
00117     static bool Record( char const * section, DATA1 const & data1, DATA2 const & data2 )
00118     { return tRecorderTemplate3< tRecordingBlock, DATA1 const & , DATA2 const & >::Archive( false, section, data1, data2 ); }
00119 
00121     template< class DATA1, class DATA2 >
00122     static bool Playback( char const * section, DATA1 & data1, DATA2 & data2 )
00123     { return tRecorderTemplate3< tPlaybackBlock, DATA1 &, DATA2 & >::Archive( false, section, data1, data2 ); }
00124 
00126     template< class DATA1, class DATA2 >
00127     static bool PlaybackStrict( char const * section, DATA1 & data1, DATA2 & data2 )
00128     { return tRecorderTemplate3< tPlaybackBlock, DATA1 &, DATA2 & >::Archive( true, section, data1, data2 ); }
00129 };
00130 
00131 class tPath;
00132 
00134 class tTextFileRecorder: public tRecorderBase
00135 {
00136 public:
00137     tTextFileRecorder();
00138     ~tTextFileRecorder();
00139 
00141     bool Open( tPath const & searchPath, char const * fileName );
00142 
00144     tTextFileRecorder( tPath const & searchPath, char const * fileName );
00145 
00147     bool EndOfFile() const;
00148 
00150     std::string GetLine();
00151 private:
00152     // disable copying
00153     tTextFileRecorder(tTextFileRecorder const &);
00154     tTextFileRecorder & operator = (tTextFileRecorder const &);
00155 
00156     std::ifstream * stream_; 
00157     bool eof_;               
00158 };
00159 
00161 // typedef tRecorderTemplate<int> tRecorder;
00162 
00163 // *****************************************************************************
00164 // helper classes for converting data before it gets archived
00165 // *****************************************************************************
00166 
00168 template< class T > struct tTypeToStream
00169 {
00170     typedef T TOSTREAM;             
00171     typedef int DUMMYREQUIRED;      
00172 };
00173 
00175 // recording (and back after playback) by specializing the tTypeToStream class template
00176 #define tRECORD_AS( TYPE, STREAM ) \
00177 template<> struct tTypeToStream< TYPE > \
00178 { \
00179     typedef STREAM TOSTREAM; \
00180   typedef int * DUMMYREQUIRED; \
00181 } \
00182 
00184 #define tRECORDING_ENUM( TYPE ) tRECORD_AS( TYPE, int )
00185 
00186 // record chars as ints for human readability
00187 tRECORD_AS( char, int );
00188 tRECORD_AS( unsigned char, int );
00189 
00191 class tLineString: public tString
00192 {
00193 public:
00194     tLineString( tString const & ); 
00195     tLineString();                  
00196     ~tLineString();                 
00197 };
00198 
00200 std::ostream & operator << ( std::ostream & s, tLineString const & line );
00201 
00203 std::istream & operator >> ( std::istream & s, tLineString & line );
00204 
00206 tRECORD_AS( tString, tLineString );
00207 
00208 // *****************************************************************************
00209 // support for debugging only recording (for intermediate data)
00210 // *****************************************************************************
00211 
00213 class tRecorderSyncBase
00214 {
00215 public:
00217     static int GetDebugLevelPlayback();
00218 
00220     static int GetDebugLevelRecording();
00221 };
00222 
00224 template< class DATA >
00225 class tRecorderSync: public tRecorderSyncBase
00226 {
00227 public:
00229     static void Archive( char const * section, int debugLevel, DATA & data );
00230 
00231 private:
00233     static float GetDifference( DATA const & a, DATA const & b );
00234 };
00235 
00236 // *****************************************************************************
00237 // another helper class
00238 // *****************************************************************************
00239 
00241 template < class DATA > class tRecorderBlockHelper
00242 {
00243 public:
00244     static void Write ( std::ostream & stream, DATA const & data, int nodummyrequired );        
00245     static void Write ( std::ostream & stream, DATA const & data, int * dummyrequired );        
00246 
00247     static void Read  ( std::istream & stream, DATA & data, int nodummyrequired );        
00248     static void Read  ( std::istream & stream, DATA & data, int * dummyrequired );        
00249 };
00250 
00251 // *****************************************************************************
00252 // recording blocks for stuffing more data inside a section than two elements
00253 // *****************************************************************************
00254 
00255 class tRecording;
00256 
00258 class tRecordingBlockBase
00259 {
00260 public:
00261     bool Initialize( char const * section, tRecording * recording );  
00262     bool Initialize( char const * section );                          
00263 
00264     void Separator();                                                 
00265     static tRecording * GetArchive();                                 
00266 protected:
00267     tRecordingBlockBase();                                            
00268     ~tRecordingBlockBase();                                           
00269 
00270     std::ostream & GetRecordingStream() const;                        
00271 
00272     bool separate_;                                                   
00273 private:
00274     tRecording * recording_;                                          
00275 };
00276 
00278 class tRecordingBlock: public tRecordingBlockBase
00279 {
00280 public:
00281     tRecordingBlock();                                                     
00282     ~tRecordingBlock();                                                    
00283 
00285     template< class T > tRecordingBlock & operator << ( T const & data ) { return Write( data ); }
00286 
00288     template< class T > tRecordingBlock & Archive     ( T const & data ) { return Write( data ); }
00289 
00291     template< class T > tRecordingBlock & Write       ( T const & data )
00292     {
00293         // get stream
00294         std::ostream & stream = GetRecordingStream();
00295 
00296         // add separator
00297         if ( separate_ )
00298             stream << ' ';
00299         separate_ = true;
00300 
00301         // delegate to dummy using or dummyless function
00302         typename tTypeToStream< T >::DUMMYREQUIRED dummyRequired = 0;
00303         tRecorderBlockHelper< T >::Write( stream, data, dummyRequired );
00304 
00305         return *this;
00306     }
00307 };
00308 
00309 // *****************************************************************************
00310 
00311 class tPlayback;
00312 
00314 class tPlaybackBlockBase
00315 {
00316 public:
00317     bool Initialize( char const * section, tPlayback * playback );    
00318     bool Initialize( char const * section );                          
00319 
00320     void Separator() const;                                           
00321     static tPlayback * GetArchive();                                  
00322 protected:
00323     tPlaybackBlockBase();                                             
00324     ~tPlaybackBlockBase();                                            
00325 
00326     std::istream & GetPlaybackStream() const;                         
00327 
00328 private:
00329     tPlayback * playback_;                                             
00330 };
00331 
00333 class tPlaybackBlock: public tPlaybackBlockBase
00334 {
00335 public:
00336     tPlaybackBlock();                                         
00337     ~tPlaybackBlock();                                        
00338 
00340     template< class T > tPlaybackBlock & operator >> ( T & data ){ return Read( data ); }
00341 
00343     template< class T > tPlaybackBlock & Archive     ( T & data ){ return Read( data ); }
00344 
00346     template< class T > tPlaybackBlock & Read        ( T & data )
00347     {
00348         // delegate to dummy using or dummyless function
00349         typename tTypeToStream< T >::DUMMYREQUIRED dummyrequired = 0;
00350         tRecorderBlockHelper< T >::Read( GetPlaybackStream(), data, dummyrequired );
00351 
00352         return *this;
00353     }
00354 };
00355 
00357 // typedef tRecordingBlockTemplate< int > tRecordingBlock;
00358 // typedef tPlaybackBlockTemplate< int > tPlaybackBlock;
00359 
00360 // Note: both tRecordingBlock and tPlaybackBlock share common mebe fuctions. See uInputQueue.cpp
00361 // (or the tRecorderTemplate::Archive implementation) how to
00362 // exploit this with templates to make sure you read exaclty the same data as you write.
00363 
00364 // *****************************************************************************
00365 // * Implementation
00366 // *****************************************************************************
00367 
00368 /*
00369 
00370 // *******************************************************************************************
00371 // *
00372 // *    Record
00373 // *
00374 // *******************************************************************************************
00380 // *******************************************************************************************
00381 
00382 template< class DUMMY  >
00383 template<  class DATA >
00384 bool tRecorderTemplate< DUMMY >::Record( char const * section, DATA const & data )
00385 {
00386     // delegate
00387     return Archive< tRecordingBlock >( false, section, data );
00388 }
00389 
00390 // *******************************************************************************************
00391 // *
00392 // *    Playback
00393 // *
00394 // *******************************************************************************************
00400 // *******************************************************************************************
00401 
00402 template< class DUMMY  >
00403 template<  class DATA >
00404 bool tRecorderTemplate< DUMMY >::Playback( char const * section, DATA & data )
00405 {
00406     // delegate
00407     return Archive< tPlaybackBlock >( false, section, data );
00408 }
00409 
00410 // *******************************************************************************************
00411 // *
00412 // *    PlaybackStrict
00413 // *
00414 // *******************************************************************************************
00420 // *******************************************************************************************
00421 
00422 template< class DUMMY  >
00423 template<  class DATA >
00424 bool tRecorderTemplate< DUMMY >::PlaybackStrict( char const * section, DATA & data )
00425 {
00426     // delegate
00427     return Archive< tPlaybackBlock >( true, section, data );
00428 }
00429 
00430 // *******************************************************************************************
00431 // *
00432 // *    Record
00433 // *
00434 // *******************************************************************************************
00441 // *******************************************************************************************
00442 
00443 template< class DUMMY  >
00444 template<  class DATA1, class DATA2 >
00445 bool tRecorderTemplate< DUMMY >::Record( char const * section, DATA1 const & data1, DATA2 const & data2 )
00446 {
00447     // delegate
00448     return Archive< tRecordingBlock >( false, section, data1, data2 );
00449 }
00450 
00451 // *******************************************************************************************
00452 // *
00453 // *    Playback
00454 // *
00455 // *******************************************************************************************
00462 // *******************************************************************************************
00463 
00464 template< class DUMMY  >
00465 template<  class DATA1, class DATA2 >
00466 bool tRecorderTemplate< DUMMY >::Playback( char const * section, DATA1 & data1, DATA2 & data2 )
00467 {
00468     // delegate
00469     return Archive< tPlaybackBlock >( false, section, data1, data2 );
00470 }
00471 
00472 // *******************************************************************************************
00473 // *
00474 // *    PlaybackStrict
00475 // *
00476 // *******************************************************************************************
00483 // *******************************************************************************************
00484 
00485 template< class DUMMY  >
00486 template<  class DATA1, class DATA2 >
00487 bool tRecorderTemplate< DUMMY >::PlaybackStrict( char const * section, DATA1 & data1, DATA2 & data2 )
00488 {
00489     // delegate
00490     return Archive< tPlaybackBlock >( true, section, data1, data2 );
00491 }
00492 
00493 // *******************************************************************************************
00494 // *    
00495 // *    Archive
00496 // *    
00497 // *******************************************************************************************
00503 // *******************************************************************************************
00504 
00505 template< class DUMMY  >
00506 template<  class BLOCK >
00507 bool tRecorderTemplate< DUMMY >::Archive( bool strict, char const * section )
00508 {
00509     // create recording/playback block
00510     BLOCK block;
00511 
00512     // initialize
00513     if ( block.Initialize( section ) )
00514     {
00515         // return success
00516         return true;
00517     }
00518 
00519     // report failure
00520     tASSERT( !strict  || !BLOCK::GetArchive() );
00521     return false;
00522 }
00523 
00524 // *******************************************************************************************
00525 // *    
00526 // *    Archive
00527 // *    
00528 // *******************************************************************************************
00535 // *******************************************************************************************
00536 
00537 template< class DUMMY  >
00538 template<  class BLOCK, class DATA >
00539 bool tRecorderTemplate< DUMMY >::Archive( bool strict, char const * section, DATA & data )
00540 {
00541     // create recording/playback block
00542     BLOCK block;
00543 
00544     // initialize
00545     if ( block.Initialize( section ) )
00546     {
00547         // successfully initialized: archive data
00548         block.Archive( data );
00549 
00550         // return success
00551         return true;
00552     }
00553 
00554     // report failure
00555     tASSERT( !strict || !BLOCK::GetArchive() );
00556     return false;
00557 }
00558 
00559 // *******************************************************************************************
00560 // *    
00561 // *    Archive
00562 // *    
00563 // *******************************************************************************************
00571 // *******************************************************************************************
00572 
00573 template< class DUMMY  >
00574 template<  class BLOCK, class DATA1, class DATA2 >
00575 bool tRecorderTemplate< DUMMY >::Archive( bool strict, char const * section, DATA1 & data1, DATA2 & data2 )
00576 {
00577     // create recording/playback block
00578     BLOCK block;
00579 
00580     // initialize
00581     if ( block.Initialize( section ) )
00582     {
00583         // successfully initialized: archive data
00584         block.Archive( data1 ).Archive( data2 );
00585 
00586         // return success
00587         return true;
00588     }
00589 
00590     // report failure
00591     tASSERT( !strict  || !BLOCK::GetArchive() );
00592     return false;
00593 }
00594 
00595 // *******************************************************************************************
00596 // *******************************************************************************************
00597 // *******************************************************************************************
00598 // *******************************************************************************************
00599 
00600 // *******************************************************************************************
00601 // *
00602 // *    tRecordingBlockTemplate
00603 // *
00604 // *******************************************************************************************
00607 // *******************************************************************************************
00608 
00609 template< class DUMMY >
00610 tRecordingBlockTemplate< DUMMY >::tRecordingBlockTemplate( void )
00611 {
00612 }
00613 
00614 // *******************************************************************************************
00615 // *
00616 // *    ~tRecordingBlockTemplate
00617 // *
00618 // *******************************************************************************************
00621 // *******************************************************************************************
00622 
00623 template< class DUMMY >
00624 tRecordingBlockTemplate< DUMMY >::~tRecordingBlockTemplate( void )
00625 {
00626 }
00627 
00628 // *******************************************************************************************
00629 // *
00630 // *    operator <<
00631 // *
00632 // *******************************************************************************************
00637 // *******************************************************************************************
00638 
00639 template< class DUMMY  >
00640 template<  class T >
00641 tRecordingBlockTemplate< DUMMY > & tRecordingBlockTemplate< DUMMY >::operator <<( T const & data )
00642 {
00643     // delegate
00644     return Write( data );
00645 }
00646 
00647 // *******************************************************************************************
00648 // *
00649 // *    Archive
00650 // *
00651 // *******************************************************************************************
00656 // *******************************************************************************************
00657 
00658 template< class DUMMY  >
00659 template<  class T >
00660 tRecordingBlockTemplate< DUMMY > & tRecordingBlockTemplate< DUMMY >::Archive( T const & data )
00661 {
00662     // delegate
00663     return Write( data );
00664 }
00665 
00666 // *******************************************************************************************
00667 // *
00668 // *    Write
00669 // *
00670 // *******************************************************************************************
00675 // *******************************************************************************************
00676 
00677 template< class DUMMY  >
00678 template<  class T >
00679 tRecordingBlockTemplate< DUMMY > & tRecordingBlockTemplate< DUMMY >::Write( T const & data )
00680 {
00681     // get stream
00682     std::ostream & stream = GetRecordingStream();
00683 
00684     // add small separator
00685     if (separate_)
00686         stream << ' ';
00687     separate_ = true;
00688 
00689     // delegate to dummy using or dummyless function
00690     typename tTypeToStream< T >::DUMMYREQUIRED dummyrequired = 0;
00691     Write( data, dummyrequired );
00692 
00693     return *this;
00694 }
00695 
00696 // *******************************************************************************************
00697 // *
00698 // *    Write
00699 // *
00700 // *******************************************************************************************
00705 // *******************************************************************************************
00706 
00707 template< class DUMMY  >
00708 template<  class T >
00709 void tRecordingBlockTemplate< DUMMY >::Write( T const & data, int nodummyrequired )
00710 {
00711     // get stream
00712     std::ostream & stream = GetRecordingStream();
00713 
00714     // add small separator
00715     stream << ' ';
00716     
00717     // write
00718     stream << data;
00719 
00720 }
00721 
00722 // *******************************************************************************************
00723 // *
00724 // *    Write
00725 // *
00726 // *******************************************************************************************
00731 // *******************************************************************************************
00732 
00733 template< class DUMMY  >
00734 template<  class T >
00735 void tRecordingBlockTemplate< DUMMY >::Write( T const & data, int * dummyrequired )
00736 {
00737     // get stream
00738     std::ostream & stream = GetRecordingStream();
00739     
00740     // write ( converted )
00741     typedef typename tTypeToStream< T >::TOSTREAM TOSTREAM;
00742     TOSTREAM dummy = static_cast< TOSTREAM >( data );
00743     stream << dummy;
00744 }
00745 
00746 // *******************************************************************************************
00747 // *******************************************************************************************
00748 // *******************************************************************************************
00749 // *******************************************************************************************
00750 
00751 // *******************************************************************************************
00752 // *
00753 // *    tPlaybackBlockTemplate
00754 // *
00755 // *******************************************************************************************
00758 // *******************************************************************************************
00759 
00760 template< class DUMMY >
00761 tPlaybackBlockTemplate< DUMMY >::tPlaybackBlockTemplate( void )
00762 {
00763 }
00764 
00765 // *******************************************************************************************
00766 // *
00767 // *    ~tPlaybackBlockTemplate
00768 // *
00769 // *******************************************************************************************
00772 // *******************************************************************************************
00773 
00774 template< class DUMMY >
00775 tPlaybackBlockTemplate< DUMMY >::~tPlaybackBlockTemplate( void )
00776 {
00777 }
00778 
00779 // *******************************************************************************************
00780 // *
00781 // *    operator >>
00782 // *
00783 // *******************************************************************************************
00788 // *******************************************************************************************
00789 
00790 template< class DUMMY  >
00791 template<  class T >
00792 tPlaybackBlockTemplate< DUMMY > & tPlaybackBlockTemplate< DUMMY >::operator >>( T & data )
00793 {
00794     // delegate
00795     return Read( data );
00796 }
00797 
00798 // *******************************************************************************************
00799 // *
00800 // *    Archive
00801 // *
00802 // *******************************************************************************************
00807 // *******************************************************************************************
00808 
00809 template< class DUMMY  >
00810 template<  class T >
00811 tPlaybackBlockTemplate< DUMMY > & tPlaybackBlockTemplate< DUMMY >::Archive( T & data )
00812 {
00813     // delegate
00814     return Read( data );
00815 }
00816 
00817 // *******************************************************************************************
00818 // *
00819 // *    Read
00820 // *
00821 // *******************************************************************************************
00826 // *******************************************************************************************
00827 
00828 template< class DUMMY  >
00829 template<  class T >
00830 tPlaybackBlockTemplate< DUMMY > & tPlaybackBlockTemplate< DUMMY >::Read( T & data )
00831 {
00832     // delegate to dummy using or dummyless function
00833     typename tTypeToStream< T >::DUMMYREQUIRED dummyrequired = 0;
00834     Read( data, dummyrequired );
00835 
00836     return *this;
00837 }
00838 
00839 // *******************************************************************************************
00840 // *
00841 // *    Read
00842 // *
00843 // *******************************************************************************************
00848 // *******************************************************************************************
00849 
00850 template< class DUMMY  >
00851 template<  class T >
00852 void tPlaybackBlockTemplate< DUMMY >::Read( T & data, int nodummyrequired )
00853 {
00854     // get stream
00855     std::istream & stream = GetPlaybackStream();
00856     tASSERT( stream.good() );
00857 
00858     // read
00859     stream >> data;
00860 }
00861 
00862 // *******************************************************************************************
00863 // *
00864 // *    Read
00865 // *
00866 // *******************************************************************************************
00871 // *******************************************************************************************
00872 
00873 template< class DUMMY  >
00874 template<  class T >
00875 void tPlaybackBlockTemplate< DUMMY >::Read( T & data, int * dummyrequired )
00876 {
00877     // get stream
00878     std::istream & stream = GetPlaybackStream();
00879     tASSERT( stream.good() );
00880 
00881     // read ( with conversion )
00882     typedef typename tTypeToStream< T >::TOSTREAM TOSTREAM;
00883     TOSTREAM dummy ;
00884     stream >> dummy;
00885     data = static_cast< T >( dummy );
00886 }
00887 
00888 */
00889 
00890 // ******************************************************************************************
00891 // *
00892 // *    Archive
00893 // *
00894 // ******************************************************************************************
00900 // ******************************************************************************************
00901 
00902 template< class DATA >
00903 void tRecorderSync< DATA >::Archive( char const * section, int level, DATA & data )
00904 {
00905     // see if it is really a DEBUG only section
00906     tASSERT( section && *section == '_' );
00907 
00908     if ( level <= GetDebugLevelPlayback() )
00909     {
00910         DATA copy = data;
00911 
00912         // read data from archive
00913         if ( tRecorder::PlaybackStrict( section, copy ) )
00914         {
00915 #ifdef DEBUG_DIFFERENCE
00916             // determine difference
00917             REAL diff = GetDifference( data, copy );
00918 
00919             static REAL alarmDiff = EPS;
00920             if ( diff > alarmDiff )
00921             {
00922                 alarmDiff = diff * 2;
00923                 REAL st_GetDifference( REAL a, REAL b);
00924                 REAL st_GetDifference( int a, int b);
00925                 REAL st_GetDifference( tString const & a, tString const & b );
00926                 std::cout << "Syncing difference found: " << data << "!=" << copy << " by " << diff << "\n";
00927                 st_Breakpoint();
00928             }
00929 #endif
00930 
00931             // restore data, hoping that the playback can take the little bump
00932             if ( level <= GetDebugLevelRecording() )
00933             {
00934                 data = copy;
00935             }
00936         }
00937         else if ( tRecorder::IsPlayingBack() )
00938         {
00939             std::cout << "Syncing difference found: expected " << section << ".\n";
00940 
00941             st_Breakpoint();
00942         }
00943     }
00944 
00945     // archive data
00946     if ( level <= GetDebugLevelRecording() )
00947         tRecorder::Record( section, data );
00948 }
00949 
00950 REAL st_GetDifference( REAL a, REAL b);
00951 REAL st_GetDifference( int a, int b);
00952 REAL st_GetDifference( unsigned int a, unsigned int b);
00953 REAL st_GetDifference( long unsigned int a, long unsigned int b);
00954 REAL st_GetDifference( tString const & a, tString const & b );
00955 
00956 // ******************************************************************************************
00957 // *
00958 // *    GetDifference
00959 // *
00960 // ******************************************************************************************
00966 // ******************************************************************************************
00967 
00968 template< class DATA >
00969 float tRecorderSync< DATA >::GetDifference( DATA const & a, DATA const & b )
00970 {
00971     return st_GetDifference( a, b );
00972 }
00973 
00974 // ******************************************************************************************
00975 // *
00976 // *    Archive
00977 // *
00978 // ******************************************************************************************
00984 // ******************************************************************************************
00985 
00986 template< class BLOCK >
00987 bool tRecorderTemplate1< BLOCK >::Archive( bool strict, char const * section )
00988 {
00989     // create recording/playback block
00990     BLOCK block;
00991 
00992     // initialize
00993     if ( block.Initialize( section ) )
00994     {
00995         // return success
00996         return true;
00997     }
00998 
00999     // report failure
01000     tASSERT( !strict  || !BLOCK::GetArchive() );
01001     return false;
01002 }
01003 
01004 // ******************************************************************************************
01005 // *
01006 // *    Archive
01007 // *
01008 // ******************************************************************************************
01015 // ******************************************************************************************
01016 
01017 template< class BLOCK, typename DATA >
01018 bool tRecorderTemplate2< BLOCK, DATA >::Archive( bool strict, char const * section, DATA data )
01019 {
01020     // create recording/playback block
01021     BLOCK block;
01022 
01023     // initialize
01024     if ( block.Initialize( section ) )
01025     {
01026         // successfully initialized: archive data
01027         block.Archive( data );
01028 
01029         // return success
01030         return true;
01031     }
01032 
01033     // report failure
01034     tASSERT( !strict || !BLOCK::GetArchive() );
01035     return false;
01036 }
01037 
01038 // ******************************************************************************************
01039 // *
01040 // *    Archive
01041 // *
01042 // ******************************************************************************************
01050 // ******************************************************************************************
01051 
01052 template< class BLOCK, typename DATA1, typename DATA2 >
01053 bool tRecorderTemplate3< BLOCK, DATA1, DATA2 >::Archive( bool strict, char const * section, DATA1 data1, DATA2 data2 )
01054 {
01055     // create recording/playback block
01056     BLOCK block;
01057 
01058     // initialize
01059     if ( block.Initialize( section ) )
01060     {
01061         // successfully initialized: archive data
01062         block.Archive( data1 ).Archive( data2 );
01063 
01064         // return success
01065         return true;
01066     }
01067 
01068     // report failure
01069     tASSERT( !strict  || !BLOCK::GetArchive() );
01070     return false;
01071 }
01072 
01073 // ******************************************************************************************
01074 // *
01075 // *    Write
01076 // *
01077 // ******************************************************************************************
01083 // ******************************************************************************************
01084 
01085 template< class DATA >
01086 void tRecorderBlockHelper< DATA >::Write( std::ostream & stream, DATA const & data, int nodummyrequired )
01087 {
01088     // write
01089     stream << data;
01090 }
01091 
01092 // ******************************************************************************************
01093 // *
01094 // *    Write
01095 // *
01096 // ******************************************************************************************
01102 // ******************************************************************************************
01103 
01104 template< class DATA >
01105 void tRecorderBlockHelper< DATA >::Write( std::ostream & stream, DATA const & data, int * dummyrequired )
01106 {
01107     // write ( converted )
01108     typedef typename tTypeToStream< DATA >::TOSTREAM TOSTREAM;
01109     TOSTREAM dummy = static_cast< TOSTREAM >( data );
01110     stream << dummy;
01111 }
01112 
01113 // ******************************************************************************************
01114 // *
01115 // *    Read
01116 // *
01117 // ******************************************************************************************
01123 // ******************************************************************************************
01124 
01125 template< class DATA >
01126 void tRecorderBlockHelper< DATA >::Read( std::istream & stream, DATA & data, int nodummyrequired )
01127 {
01128     tASSERT( stream.good() );
01129 
01130     // read
01131     stream >> data;
01132 }
01133 
01134 // ******************************************************************************************
01135 // *
01136 // *    Read
01137 // *
01138 // ******************************************************************************************
01144 // ******************************************************************************************
01145 
01146 template< class DATA >
01147 void tRecorderBlockHelper< DATA >::Read( std::istream & stream, DATA & data, int * dummyrequired )
01148 {
01149     tASSERT( stream.good() );
01150 
01151     // read ( with conversion )
01152     typedef typename tTypeToStream< DATA >::TOSTREAM TOSTREAM;
01153     TOSTREAM dummy ;
01154     stream >> dummy;
01155     data = static_cast< DATA >( dummy );
01156 }
01157 
01158 #endif // TRECORDING_H_INCLUDED

Generated on Sat Mar 15 22:56:01 2008 for Armagetron Advanced by  doxygen 1.5.4