/armagetronad-0.2.8.3.2/src/tools/tRecorder.cpp

# · C++ · 753 lines · 257 code · 110 blank · 386 comment · 35 complexity · fb44e71169c07083e927023d30f39523 MD5 · raw file

  1. /*
  2. *************************************************************************
  3. ArmageTron -- Just another Tron Lightcycle Game in 3D.
  4. Copyright (C) 2000 Manuel Moos (manuel@moosnet.de)
  5. **************************************************************************
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. ***************************************************************************
  18. */
  19. // declaration
  20. #ifndef TRECORDER_H_INCLUDED
  21. #include "tRecorder.h"
  22. #endif
  23. #include "tConfiguration.h"
  24. #include "tDirectories.h"
  25. #include "tRecorderInternal.h"
  26. #undef INLINE_DEF
  27. #define INLINE_DEF
  28. // *****************************************************************************************
  29. // *
  30. // * IsRecording
  31. // *
  32. // *****************************************************************************************
  33. //!
  34. //! @return true if a recording is running
  35. //!
  36. // *****************************************************************************************
  37. bool tRecorderBase::IsRecording( void )
  38. {
  39. return tRecordingBlock::GetArchive();
  40. }
  41. // *****************************************************************************************
  42. // *
  43. // * IsPlayingBack
  44. // *
  45. // *****************************************************************************************
  46. //!
  47. //! @return true if a playback is running
  48. //!
  49. // *****************************************************************************************
  50. bool tRecorderBase::IsPlayingBack( void )
  51. {
  52. return tPlaybackBlock::GetArchive();
  53. }
  54. // *****************************************************************************************
  55. // *
  56. // * IsRunning
  57. // *
  58. // *****************************************************************************************
  59. //!
  60. //! @return true if recording or playback are running
  61. //!
  62. // *****************************************************************************************
  63. bool tRecorderBase::IsRunning( void )
  64. {
  65. return IsRecording() || IsPlayingBack();
  66. }
  67. // *******************************************************************************************
  68. // *
  69. // * Record
  70. // *
  71. // *******************************************************************************************
  72. //!
  73. //! @param section the name of the section to record or play back
  74. //! @return true on success
  75. //!
  76. // *******************************************************************************************
  77. bool tRecorder::Record( char const * section )
  78. {
  79. // delegate
  80. return tRecorderTemplate1< tRecordingBlock >::Archive( false, section );
  81. }
  82. // *******************************************************************************************
  83. // *
  84. // * Playback
  85. // *
  86. // *******************************************************************************************
  87. //!
  88. //! @param section the name of the section to record or play back
  89. //! @return true on success
  90. //!
  91. // *******************************************************************************************
  92. bool tRecorder::Playback( char const * section )
  93. {
  94. // delegate
  95. return tRecorderTemplate1< tPlaybackBlock >::Archive( false, section );
  96. }
  97. // *******************************************************************************************
  98. // *
  99. // * PlaybackStrict
  100. // *
  101. // *******************************************************************************************
  102. //!
  103. //! @param section the name of the section to record or play back
  104. //! @return true on success
  105. //!
  106. // *******************************************************************************************
  107. bool tRecorder::PlaybackStrict( char const * section )
  108. {
  109. // delegate
  110. return tRecorderTemplate1< tPlaybackBlock >::Archive( true, section );
  111. }
  112. // *****************************************************************************************
  113. // *****************************************************************************************
  114. // *****************************************************************************************
  115. // *****************************************************************************************
  116. // *****************************************************************************************
  117. // *
  118. // * tLineString
  119. // *
  120. // *****************************************************************************************
  121. //!
  122. //! @param other the string to copy
  123. //!
  124. // *****************************************************************************************
  125. tLineString::tLineString( tString const & other )
  126. :tString( other )
  127. {
  128. }
  129. // *****************************************************************************************
  130. // *
  131. // * tLineString
  132. // *
  133. // *****************************************************************************************
  134. //!
  135. //!
  136. // *****************************************************************************************
  137. tLineString::tLineString( void )
  138. {
  139. }
  140. // *****************************************************************************************
  141. // *
  142. // * ~tLineString
  143. // *
  144. // *****************************************************************************************
  145. //!
  146. //!
  147. // *****************************************************************************************
  148. tLineString::~tLineString( void )
  149. {
  150. }
  151. //! persistent string writing operator
  152. std::ostream & operator << ( std::ostream & s, tLineString const & line )
  153. {
  154. // write magic character
  155. s << 'L';
  156. // print string, encode newlines
  157. for( int i=0; i<line.Len(); ++i)
  158. {
  159. char c = line[i];
  160. if ( c == '\n' )
  161. s << "\\n";
  162. if ( c == '\\' )
  163. s << "\\\\";
  164. else if ( c != '\0' )
  165. s << c;
  166. }
  167. return s << '\n';
  168. }
  169. //! persistent string reading operator
  170. std::istream & operator >> ( std::istream & s, tLineString & line )
  171. {
  172. // read magic character
  173. char c;
  174. s >> c;
  175. tASSERT( 'L' == c );
  176. tString read;
  177. // read line
  178. read.ReadLine(s);
  179. // std::cout << "Read: " << read << "\n";
  180. line.Clear();
  181. // copy line, replacing "\n" with real newline
  182. for(int i=0; i<read.Len()-1; ++i)
  183. {
  184. char c = read[i];
  185. if ( c != '\\' || i+1 == read.Len() || ( read[i+1] != 'n' && read[i+1] != '\\' ) )
  186. {
  187. line << c;
  188. }
  189. else if ( read[i+1] == '\\' )
  190. {
  191. line << "\\";
  192. i++;
  193. }
  194. else // if ( read[i+1] != 'n' )
  195. {
  196. line << "\n";
  197. i++;
  198. }
  199. }
  200. return s;
  201. }
  202. // *****************************************************************************************
  203. // *****************************************************************************************
  204. // *****************************************************************************************
  205. // *****************************************************************************************
  206. // *****************************************************************************************
  207. // *
  208. // * Initialize
  209. // *
  210. // *****************************************************************************************
  211. //!
  212. //! @param section name of the section to start
  213. //! @param recording recording to read block from
  214. //! @return true on success
  215. //!
  216. // *****************************************************************************************
  217. bool tRecordingBlockBase::Initialize( char const * section, tRecording * recording )
  218. {
  219. // initialize recording pointer
  220. recording_ = recording;
  221. if (!recording_)
  222. return false;
  223. // start section
  224. recording_->BeginSection( section );
  225. // return success
  226. return true;
  227. }
  228. // *****************************************************************************************
  229. // *
  230. // * Initialize
  231. // *
  232. // *****************************************************************************************
  233. //!
  234. //! @param section name of the section to start
  235. //! @return true on success
  236. //!
  237. // *****************************************************************************************
  238. bool tRecordingBlockBase::Initialize( char const * section )
  239. {
  240. // delegate
  241. return Initialize( section, tRecording::currentRecording_ );
  242. }
  243. // *****************************************************************************************
  244. // *
  245. // * Separator
  246. // *
  247. // *****************************************************************************************
  248. //!
  249. //!
  250. // *****************************************************************************************
  251. void tRecordingBlockBase::Separator( void )
  252. {
  253. GetRecordingStream() << "\n";
  254. separate_ = false;
  255. }
  256. // ******************************************************************************************
  257. // *
  258. // * GetArchive
  259. // *
  260. // ******************************************************************************************
  261. //!
  262. //! @return the currently running recording
  263. //!
  264. // ******************************************************************************************
  265. tRecording * tRecordingBlockBase::GetArchive( void )
  266. {
  267. return tRecording::currentRecording_;
  268. }
  269. // *****************************************************************************************
  270. // *
  271. // * tRecordingBlockBase
  272. // *
  273. // *****************************************************************************************
  274. //!
  275. //!
  276. // *****************************************************************************************
  277. tRecordingBlockBase::tRecordingBlockBase( void )
  278. : separate_( true ), recording_( NULL )
  279. {
  280. }
  281. // *****************************************************************************************
  282. // *
  283. // * ~tRecordingBlockBase
  284. // *
  285. // *****************************************************************************************
  286. //!
  287. //!
  288. // *****************************************************************************************
  289. tRecordingBlockBase::~tRecordingBlockBase( void )
  290. {
  291. // make sure everything is logged, even if program crashes
  292. if (recording_)
  293. GetRecordingStream().flush();
  294. recording_ = 0;
  295. }
  296. // *****************************************************************************************
  297. // *
  298. // * GetRecordingStream
  299. // *
  300. // *****************************************************************************************
  301. //!
  302. //! @return the stream of the recording
  303. //!
  304. // *****************************************************************************************
  305. std::ostream & tRecordingBlockBase::GetRecordingStream() const
  306. {
  307. tASSERT( recording_ );
  308. return recording_->DoGetStream();
  309. }
  310. // *******************************************************************************************
  311. // *
  312. // * tRecordingBlock
  313. // *
  314. // *******************************************************************************************
  315. //!
  316. //!
  317. // *******************************************************************************************
  318. tRecordingBlock::tRecordingBlock( void )
  319. {
  320. }
  321. // *******************************************************************************************
  322. // *
  323. // * ~tRecordingBlock
  324. // *
  325. // *******************************************************************************************
  326. //!
  327. //!
  328. // *******************************************************************************************
  329. tRecordingBlock::~tRecordingBlock( void )
  330. {
  331. }
  332. // *****************************************************************************************
  333. // *****************************************************************************************
  334. // *****************************************************************************************
  335. // *****************************************************************************************
  336. // *****************************************************************************************
  337. // *
  338. // * Initialize
  339. // *
  340. // *****************************************************************************************
  341. //!
  342. //! @param section name of section to read
  343. //! @param playback playback to read from
  344. //! @return true on success
  345. //!
  346. // *****************************************************************************************
  347. bool tPlaybackBlockBase::Initialize( char const * section, tPlayback * playback )
  348. {
  349. // initialize playback pointer
  350. playback_ = playback;
  351. if (!playback_)
  352. return false;
  353. // read section
  354. if( playback_->GetNextSection() != section )
  355. {
  356. playback_ = NULL;
  357. return false;
  358. }
  359. // return success
  360. return true;
  361. }
  362. // *****************************************************************************************
  363. // *
  364. // * Initialize
  365. // *
  366. // *****************************************************************************************
  367. //!
  368. //! @param section name of section to read
  369. //! @return true on success
  370. //!
  371. // *****************************************************************************************
  372. bool tPlaybackBlockBase::Initialize( char const * section )
  373. {
  374. return Initialize( section, tPlayback::currentPlayback_ );
  375. }
  376. // *****************************************************************************************
  377. // *
  378. // * Separator
  379. // *
  380. // *****************************************************************************************
  381. //!
  382. //!
  383. // *****************************************************************************************
  384. void tPlaybackBlockBase::Separator( void ) const
  385. {
  386. }
  387. // ******************************************************************************************
  388. // *
  389. // * GetArchive
  390. // *
  391. // ******************************************************************************************
  392. //!
  393. //! @return the currently running playback
  394. //!
  395. // ******************************************************************************************
  396. tPlayback * tPlaybackBlockBase::GetArchive( void )
  397. {
  398. return tPlayback::currentPlayback_;
  399. }
  400. // *****************************************************************************************
  401. // *
  402. // * tPlaybackBlockBase
  403. // *
  404. // *****************************************************************************************
  405. //!
  406. //!
  407. // *****************************************************************************************
  408. tPlaybackBlockBase::tPlaybackBlockBase( void )
  409. : playback_( 0 )
  410. {
  411. }
  412. // *****************************************************************************************
  413. // *
  414. // * ~tPlaybackBlockBase
  415. // *
  416. // *****************************************************************************************
  417. //!
  418. //!
  419. // *****************************************************************************************
  420. tPlaybackBlockBase::~tPlaybackBlockBase( void )
  421. {
  422. // end current block and read next
  423. if ( playback_ )
  424. playback_->AdvanceSection();
  425. playback_ = 0;
  426. }
  427. // *****************************************************************************************
  428. // *
  429. // * GetPlaybackStream
  430. // *
  431. // *****************************************************************************************
  432. //!
  433. //! @return the stream of the playback
  434. //!
  435. // *****************************************************************************************
  436. std::istream & tPlaybackBlockBase::GetPlaybackStream() const
  437. {
  438. tASSERT( playback_ );
  439. return playback_->DoGetStream();
  440. }
  441. // *******************************************************************************************
  442. // *
  443. // * tPlaybackBlock
  444. // *
  445. // *******************************************************************************************
  446. //!
  447. //!
  448. // *******************************************************************************************
  449. tPlaybackBlock::tPlaybackBlock( void )
  450. {
  451. }
  452. // *******************************************************************************************
  453. // *
  454. // * ~tPlaybackBlock
  455. // *
  456. // *******************************************************************************************
  457. //!
  458. //!
  459. // *******************************************************************************************
  460. tPlaybackBlock::~tPlaybackBlock( void )
  461. {
  462. }
  463. // *****************************************************************************************
  464. // *****************************************************************************************
  465. // *****************************************************************************************
  466. // *****************************************************************************************
  467. static int st_debugLevelRecording=0;
  468. static tSettingItem<int>rdb( "RECORDING_DEBUGLEVEL",
  469. st_debugLevelRecording );
  470. // returns the playback debug level, archiving the result
  471. static int st_GetDebugLevelPlayback()
  472. {
  473. // sync level with recording
  474. int level = st_debugLevelRecording;
  475. tRecorder::Playback( "DEBUGLEVEL", level );
  476. tRecorder::Record( "DEBUGLEVEL", level );
  477. return level;
  478. }
  479. // *******************************************************************************************
  480. // *
  481. // * GetDebugLevelPlayback
  482. // *
  483. // *******************************************************************************************
  484. //!
  485. //! @return
  486. //!
  487. // *******************************************************************************************
  488. int tRecorderSyncBase::GetDebugLevelPlayback( void )
  489. {
  490. // get the playback level only once
  491. static int level = st_GetDebugLevelPlayback();
  492. return level;
  493. }
  494. // *******************************************************************************************
  495. // *
  496. // * GetDebugLevelRecording
  497. // *
  498. // *******************************************************************************************
  499. //!
  500. //! @return
  501. //!
  502. // *******************************************************************************************
  503. int tRecorderSyncBase::GetDebugLevelRecording( void )
  504. {
  505. // delegate so this doesn't change when the config changes
  506. return GetDebugLevelPlayback();
  507. // return st_debugLevelRecording;
  508. }
  509. REAL st_GetDifference( REAL a, REAL b)
  510. {
  511. return fabs( a - b );
  512. }
  513. REAL st_GetDifference( int a, int b)
  514. {
  515. return fabs( REAL( a - b ) );
  516. }
  517. REAL st_GetDifference( unsigned int a, unsigned int b)
  518. {
  519. return fabs( REAL( a - b ) );
  520. }
  521. REAL st_GetDifference( unsigned long int a, unsigned long int b)
  522. {
  523. return fabs( REAL( a - b ) );
  524. }
  525. REAL st_GetDifference( tString const & a, tString const & b )
  526. {
  527. return ( a == b ) ? 0 : 1;
  528. }
  529. static char const * st_fileOpen = "FILE_OPEN";
  530. static char const * st_fileRead = "FILE_READ";
  531. // *******************************************************************************
  532. // *
  533. // * Open
  534. // *
  535. // *******************************************************************************
  536. //!
  537. //! @param searchPath the path to search for the file
  538. //! @param fileName the name of the file to open
  539. //! @return true if opening succeeded
  540. //!
  541. // *******************************************************************************
  542. bool tTextFileRecorder::Open( tPath const & searchPath, char const * fileName )
  543. {
  544. tASSERT( !stream_ );
  545. bool result = false;
  546. // try to read opening state from recording
  547. if ( !tRecorder::Playback( st_fileOpen, result, eof_ ) )
  548. {
  549. // open the stream (if not in recording mode)
  550. stream_ = tNEW( std::ifstream );
  551. result = searchPath.Open( *stream_, fileName );
  552. eof_ = !result || !stream_->good() || stream_->eof();
  553. }
  554. tRecorder::Record( st_fileOpen, result, eof_ );
  555. return result;
  556. }
  557. // *******************************************************************************
  558. // *
  559. // * tTextFileRecorder
  560. // *
  561. // *******************************************************************************
  562. //!
  563. //! @param searchPath the path to search for the file
  564. //! @param fileName the name of the file to open
  565. //!
  566. // *******************************************************************************
  567. tTextFileRecorder::tTextFileRecorder( tPath const & searchPath, char const * fileName )
  568. : stream_(NULL), eof_(false)
  569. {
  570. Open( searchPath, fileName );
  571. }
  572. // *******************************************************************************
  573. // *
  574. // * tTextFileRecorder
  575. // *
  576. // *******************************************************************************
  577. //!
  578. //!
  579. // *******************************************************************************
  580. tTextFileRecorder::tTextFileRecorder( void )
  581. : stream_(NULL), eof_(false)
  582. {
  583. stream_ = NULL;
  584. }
  585. // *******************************************************************************
  586. // *
  587. // * ~tTextFileRecorder
  588. // *
  589. // *******************************************************************************
  590. //!
  591. //!
  592. // *******************************************************************************
  593. tTextFileRecorder::~tTextFileRecorder( void )
  594. {
  595. delete stream_;
  596. stream_ = NULL;
  597. }
  598. // *******************************************************************************
  599. // *
  600. // * EndOfFile
  601. // *
  602. // *******************************************************************************
  603. //!
  604. //! @return true if the end of file (or any other error that has the same effect) has been reached
  605. //!
  606. // *******************************************************************************
  607. bool tTextFileRecorder::EndOfFile( void ) const
  608. {
  609. return eof_;
  610. }
  611. // *******************************************************************************
  612. // *
  613. // * GetLine
  614. // *
  615. // *******************************************************************************
  616. //!
  617. //! @return the line read from the file or a recording thereof
  618. //!
  619. // *******************************************************************************
  620. std::string tTextFileRecorder::GetLine( void )
  621. {
  622. // try to read opening state from recording
  623. tLineString line;
  624. if ( !tRecorder::Playback( st_fileRead, line, eof_ ) )
  625. {
  626. // read a line
  627. tASSERT( stream_ );
  628. line.ReadLine( *stream_ );
  629. std::ws( *stream_ );
  630. eof_ = !stream_->good() || stream_->eof();
  631. }
  632. tRecorder::Record( st_fileRead, line, eof_ );
  633. // convert and return read line
  634. return std::string(line);
  635. }