Work on transaction support for undo system.

This commit is contained in:
Jonathan Moore Liles 2008-03-03 10:13:17 -06:00
parent fbb9ca3c4c
commit e2c6442dee
2 changed files with 58 additions and 21 deletions

View File

@ -32,6 +32,7 @@ int Loggable::_undo_index = 1;
vector <Loggable *> Loggable::_loggables; vector <Loggable *> Loggable::_loggables;
map <string, create_func*> Loggable::_class_map; map <string, create_func*> Loggable::_class_map;
queue <char *> Loggable::_transaction;
bool bool
Loggable::open ( const char *filename ) Loggable::open ( const char *filename )
@ -315,18 +316,54 @@ Loggable::snapshot( const char *file )
void void
Loggable::log ( const char *fmt, ... ) Loggable::log ( const char *fmt, ... )
{ {
/* FIXME: bogus limit */
static char buf[1024];
static int i = 0;
va_list args; va_list args;
if ( fmt ) if ( fmt )
{ {
va_start( args, fmt ); va_start( args, fmt );
vfprintf( _fp, fmt, args ); i += vsprintf( buf + i, fmt, args );
va_end( args ); va_end( args );
} }
fflush( _fp ); if ( rindex( buf, '\n' ) )
{
_transaction.push( strdup( buf ) );
i = 0;
}
} }
void
Loggable::flush ( void )
{
int n = _transaction.size();
if ( n > 1 )
fprintf( _fp, "{\n" );
while ( ! _transaction.empty() )
{
char *s = _transaction.front();
_transaction.pop();
if ( n > 1 )
fprintf( _fp, "\t" );
fprintf( _fp, "%s", s );
free( s );
}
if ( n > 1 )
fprintf( _fp, "}\n" );
fflush( _fp );
}
void void
Loggable::log_print( char **o, char **n ) Loggable::log_print( char **o, char **n )
@ -395,15 +432,11 @@ Loggable::log_end ( void )
if ( --_nest > 0 ) if ( --_nest > 0 )
return; return;
// assert( _old_state );
char **_new_state = get(); char **_new_state = get();
// if ( _old_state )
if ( log_diff( _old_state, _new_state ) ) if ( log_diff( _old_state, _new_state ) )
{ {
indent(); // indent();
log( "%s 0x%X set ", class_name(), _id ); log( "%s 0x%X set ", class_name(), _id );
log_print( _old_state, _new_state ); log_print( _old_state, _new_state );
@ -417,19 +450,14 @@ Loggable::log_end ( void )
_old_state = NULL; _old_state = NULL;
/* if ( _old_state ) */ if ( Loggable::_level == 0 )
/* { */ Loggable::flush();
/* free_sa( _old_state ); */
/* _old_state = NULL; */
/* } */
// _old_state = NULL;
} }
void void
Loggable::log_create ( void ) Loggable::log_create ( void )
{ {
indent(); // indent();
log( "%s 0x%X create ", class_name(), _id ); log( "%s 0x%X create ", class_name(), _id );
char **sa = get(); char **sa = get();
@ -441,12 +469,15 @@ Loggable::log_create ( void )
} }
else else
log( "\n" ); log( "\n" );
if ( Loggable::_level == 0 )
Loggable::flush();
} }
void void
Loggable::log_destroy ( void ) Loggable::log_destroy ( void )
{ {
indent(); // indent();
log( "%s 0x%X destroy (nothing) << ", class_name(), _id ); log( "%s 0x%X destroy (nothing) << ", class_name(), _id );
char **sa = get(); char **sa = get();
@ -455,4 +486,7 @@ Loggable::log_destroy ( void )
log_print( NULL, sa ); log_print( NULL, sa );
free_sa( sa ); free_sa( sa );
if ( Loggable::_level == 0 )
Loggable::flush();
} }

View File

@ -27,11 +27,11 @@
#include <assert.h> #include <assert.h>
#include <vector> #include <vector>
using std::vector;
#include <map> #include <map>
using std::map;
#include <string> #include <string>
using std::string; #include <queue>
using namespace std;
class Loggable; class Loggable;
typedef Loggable *(create_func)(char **); typedef Loggable *(create_func)(char **);
@ -49,6 +49,8 @@ class Loggable
static map <string, create_func*> _class_map; static map <string, create_func*> _class_map;
static queue <char *> _transaction;
private: private:
int _id; int _id;
@ -60,6 +62,7 @@ private:
void log_print( char **o, char **n ); void log_print( char **o, char **n );
static void log ( const char *fmt, ... ); static void log ( const char *fmt, ... );
static void flush ( void );
static static
void indent ( void ) void indent ( void )
{ {
@ -81,7 +84,7 @@ public:
void void
block_start ( void ) block_start ( void )
{ {
indent(); // indent();
// log( "{\n" ); // log( "{\n" );
++Loggable::_level; ++Loggable::_level;
} }
@ -90,7 +93,7 @@ public:
block_end ( void ) block_end ( void )
{ {
assert( --Loggable::_level >= 0 ); assert( --Loggable::_level >= 0 );
indent(); // indent();
// log( "}\n" ); // log( "}\n" );
} }