| @@ -41,6 +41,9 @@ Loggable ** Loggable::_loggables; | |||||
| std::map <std::string, create_func*> Loggable::_class_map; | std::map <std::string, create_func*> Loggable::_class_map; | ||||
| std::queue <char *> Loggable::_transaction; | std::queue <char *> Loggable::_transaction; | ||||
| /** Open the journal /filename/ and replay it, bringing the end state back into RAM */ | |||||
| bool | bool | ||||
| Loggable::open ( const char *filename ) | Loggable::open ( const char *filename ) | ||||
| { | { | ||||
| @@ -54,6 +57,7 @@ Loggable::open ( const char *filename ) | |||||
| /* replay log */ | /* replay log */ | ||||
| { | { | ||||
| /* FIXME: bogus */ | |||||
| char buf[BUFSIZ]; | char buf[BUFSIZ]; | ||||
| while ( fscanf( fp, "%[^\n]\n", buf ) == 1 ) | while ( fscanf( fp, "%[^\n]\n", buf ) == 1 ) | ||||
| @@ -68,13 +72,12 @@ Loggable::open ( const char *filename ) | |||||
| } | } | ||||
| } | } | ||||
| Loggable::_fp = fp; | Loggable::_fp = fp; | ||||
| return true; | return true; | ||||
| } | } | ||||
| /** close journal and delete all loggable objects */ | |||||
| /** close journal and delete all loggable objects, returing the systemt to a blank slate */ | |||||
| bool | bool | ||||
| Loggable::close ( void ) | Loggable::close ( void ) | ||||
| { | { | ||||
| @@ -104,8 +107,7 @@ Loggable::close ( void ) | |||||
| return true; | return true; | ||||
| } | } | ||||
| /** must be called after construction in create() methods */ | |||||
| /** must be called after construction in create() methods */ | |||||
| void | void | ||||
| Loggable::update_id ( int id ) | Loggable::update_id ( int id ) | ||||
| { | { | ||||
| @@ -192,11 +194,11 @@ Loggable::do_this ( const char *s, bool reverse ) | |||||
| if ( ! strcmp( command, destroy ) ) | if ( ! strcmp( command, destroy ) ) | ||||
| { | { | ||||
| /* deleting eg. a track, which contains a list of other | /* deleting eg. a track, which contains a list of other | ||||
| widgets, causes destroy messages to be emitted for all those | |||||
| widgets, but when replaying the journal the destroy message | |||||
| causes the children to be deleted also... This is a temporary | |||||
| hack. Would it be better to queue up objects for deletion | |||||
| (when?) */ | |||||
| widgets, causes destroy messages to be emitted for all those | |||||
| widgets, but when replaying the journal the destroy message | |||||
| causes the children to be deleted also... This is a temporary | |||||
| hack. Would it be better to queue up objects for deletion | |||||
| (when?) */ | |||||
| if ( l ) | if ( l ) | ||||
| delete l; | delete l; | ||||
| } | } | ||||
| @@ -231,6 +233,7 @@ Loggable::do_this ( const char *s, bool reverse ) | |||||
| return true; | return true; | ||||
| } | } | ||||
| /** Reverse the last journal transaction */ | |||||
| void | void | ||||
| Loggable::undo ( void ) | Loggable::undo ( void ) | ||||
| { | { | ||||
| @@ -311,7 +314,7 @@ Loggable::undo ( void ) | |||||
| s++; | s++; | ||||
| if ( ! strcmp( s, "{" ) ) | if ( ! strcmp( s, "{" ) ) | ||||
| break; | |||||
| break; | |||||
| if ( *s == '\t' ) | if ( *s == '\t' ) | ||||
| s++; | s++; | ||||
| @@ -377,10 +380,10 @@ Loggable::snapshot( FILE *fp ) | |||||
| return true; | return true; | ||||
| } | } | ||||
| /** Replace the journal with a snapshot of the current state */ | |||||
| void | void | ||||
| Loggable::compact ( void ) | Loggable::compact ( void ) | ||||
| { | { | ||||
| fseek( _fp, 0, SEEK_SET ); | fseek( _fp, 0, SEEK_SET ); | ||||
| ftruncate( fileno( _fp ), 0 ); | ftruncate( fileno( _fp ), 0 ); | ||||
| @@ -389,7 +392,7 @@ Loggable::compact ( void ) | |||||
| _undo_index = 1; | _undo_index = 1; | ||||
| } | } | ||||
| /** Buffered sprintf wrapper */ | |||||
| void | void | ||||
| Loggable::log ( const char *fmt, ... ) | Loggable::log ( const char *fmt, ... ) | ||||
| { | { | ||||
| @@ -413,11 +416,10 @@ Loggable::log ( const char *fmt, ... ) | |||||
| } | } | ||||
| } | } | ||||
| /** End the current transaction and commit it to the journal */ | |||||
| void | void | ||||
| Loggable::flush ( void ) | Loggable::flush ( void ) | ||||
| { | { | ||||
| if ( ! _fp ) | if ( ! _fp ) | ||||
| { | { | ||||
| // printf( "error: no log file open!\n" ); | // printf( "error: no log file open!\n" ); | ||||
| @@ -461,6 +463,7 @@ Loggable::flush ( void ) | |||||
| fflush( _fp ); | fflush( _fp ); | ||||
| } | } | ||||
| /** Print bidirectional journal entry */ | |||||
| void | void | ||||
| Loggable::log_print( const Log_Entry *o, const Log_Entry *n ) const | Loggable::log_print( const Log_Entry *o, const Log_Entry *n ) const | ||||
| { | { | ||||
| @@ -495,6 +498,9 @@ Loggable::log_print( const Log_Entry *o, const Log_Entry *n ) const | |||||
| } | } | ||||
| /** Remember current object state for later comparison. *Must* be | |||||
| * called before any user action that might change one of the object's | |||||
| * journaled properties. */ | |||||
| void | void | ||||
| Loggable::log_start ( void ) | Loggable::log_start ( void ) | ||||
| { | { | ||||
| @@ -507,10 +513,10 @@ Loggable::log_start ( void ) | |||||
| ++_nest; | ++_nest; | ||||
| } | } | ||||
| /** Log any change to the object's state since log_start(). */ | |||||
| void | void | ||||
| Loggable::log_end ( void ) | Loggable::log_end ( void ) | ||||
| { | { | ||||
| if ( --_nest > 0 ) | if ( --_nest > 0 ) | ||||
| return; | return; | ||||
| @@ -539,6 +545,8 @@ Loggable::log_end ( void ) | |||||
| Loggable::flush(); | Loggable::flush(); | ||||
| } | } | ||||
| /** Log object creation. *Must* be called at the end of all public | |||||
| * constructors for leaf classes */ | |||||
| void | void | ||||
| Loggable::log_create ( void ) const | Loggable::log_create ( void ) const | ||||
| { | { | ||||
| @@ -554,6 +562,8 @@ Loggable::log_create ( void ) const | |||||
| Loggable::flush(); | Loggable::flush(); | ||||
| } | } | ||||
| /** Log object destruction. *Must* be called at the beginning of the | |||||
| * destructors of leaf classes */ | |||||
| void | void | ||||
| Loggable::log_destroy ( void ) const | Loggable::log_destroy ( void ) const | ||||
| { | { | ||||