~ivantis/armagetronad/sty+ct+ivantis

« back to all changes in this revision

Viewing changes to src/tools/tRecorder.cpp

  • Committer: ivantis
  • Date: 2008-09-09 21:33:18 UTC
  • Revision ID: ivantis@ivantis.net-20080909213318-k43y6yuq0zd6wbsa
first commit

Show diffs side-by-side

added added

removed removed

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