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