|
@@ -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 |
|
|
{ |
|
|
{ |
|
|