Actually get (single) undo working.

This commit is contained in:
Jonathan Moore Liles 2008-02-24 22:14:19 -06:00
parent cc39d05c7a
commit 359c2bd72f
4 changed files with 142 additions and 30 deletions

View File

@ -21,6 +21,7 @@
#include "Loggable.H" #include "Loggable.H"
#undef _LOGABLE_C #undef _LOGABLE_C
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
@ -43,22 +44,121 @@ Loggable::open ( const char *filename )
return true; return true;
} }
/* void */ /** sigh. parse a string of ":name value :name value" pairs into an array of strings, one per pair */
/* Loggable::log ( const char *module, const char *action, const char *fmt, ... ) */ static
/* { */ char **
/* va_list args; */ parse_alist( const char *s )
{
/* fprintf( _fp, "%-15s %-8s %p ", module, action, _id ); */ // FIXME: bogus over allocation...
/* if ( fmt ) */ int tl = strlen( s );
/* { */ char **r = (char**)malloc( sizeof( char* ) * tl );
/* va_start( args, fmt ); */
/* vfprintf( _fp, fmt, args ); */
/* va_end( args ); */
/* } */
/* fprintf( _fp, "\n" ); */ const char *e = s + tl;
/* } */
const char *c = NULL;
int i = 0;
for ( ; ; s++ )
{
/* if ( *s == '\n' ) */
/* break; */
// if ( *s == ':' || s == e )
if ( *s == ':' || *s == '\0' )
{
if ( c )
{
int l = s - c;
char *pair = (char*)malloc( l + 1 );
strncpy( pair, c, l );
pair[ l ] = '\0';
r[ i++ ] = pair;
}
c = s;
if ( *s == '\0' )
break;
}
}
r[ i ] = NULL;
return r;
}
void
Loggable::undo ( void )
{
char *buf = new char[ BUFSIZ ];
// fflush( _fp );
fseek( _fp, 0 - BUFSIZ, SEEK_END );
// fseek( _fp, 0, SEEK_SET );
size_t len = fread( buf, 1, BUFSIZ, _fp );
char *s = buf + len - 1;
// FIXME: handle blocks
for ( --s; *s && s > buf; --s )
if ( *s == '\n' )
{
s++;
break;
}
buf[ len ] = NULL;
printf( "undoing \"%s\"\n", s );
int id;
sscanf( s, "%*s %X ", &id );
Loggable *l = find( id );
assert( l );
char command[40];
char *arguments;
sscanf( s, "%*s %*X %s %*[^\n<] << %a[^\n]", command, &arguments );
if ( ! strcmp( command, "set" ) )
{
printf( "got set command.\n" );
char **sa = parse_alist( arguments );
l->set( sa );
}
delete buf;
}
void
Loggable::log ( const char *fmt, ... )
{
va_list args;
if ( fmt )
{
va_start( args, fmt );
vfprintf( _fp, fmt, args );
va_end( args );
}
}
static static
@ -72,22 +172,21 @@ void free_sa ( char **sa )
} }
static
void void
log_print( char **o, char **n ) Loggable::log_print( char **o, char **n )
{ {
if ( n ) if ( n )
for ( ; *n; n++ ) for ( ; *n; n++ )
printf( "%s%s", *n, *(n + 1) ? " " : "" ); log( "%s%s", *n, *(n + 1) ? " " : "" );
if ( o && *o ) if ( o && *o )
{ {
if ( n ) printf( " << " ); if ( n ) log( " << " );
for ( ; *o; o++ ) for ( ; *o; o++ )
printf( "%s%s", *o, *(o + 1) ? " " : "" ); log( "%s%s", *o, *(o + 1) ? " " : "" );
} }
printf( "\n" ); log( "\n" );
} }
/** compare elements of dumps s1 and s2, removing those elements /** compare elements of dumps s1 and s2, removing those elements
@ -152,7 +251,7 @@ Loggable::log_end ( void )
if ( log_diff( _old_state, _new_state ) ) if ( log_diff( _old_state, _new_state ) )
{ {
indent(); indent();
printf( "%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 );
} }
@ -178,7 +277,7 @@ void
Loggable::log_create ( void ) Loggable::log_create ( void )
{ {
indent(); indent();
printf( "%s 0x%X new ", class_name(), _id ); log( "%s 0x%X new ", class_name(), _id );
char **sa = log_dump(); char **sa = log_dump();
@ -188,14 +287,14 @@ Loggable::log_create ( void )
free_sa( sa ); free_sa( sa );
} }
else else
printf( "\n" ); log( "\n" );
} }
void void
Loggable::log_destroy ( void ) Loggable::log_destroy ( void )
{ {
indent(); indent();
printf( "%s 0x%X destroy ", class_name(), _id ); log( "%s 0x%X destroy ", class_name(), _id );
char **sa = log_dump(); char **sa = log_dump();

View File

@ -47,25 +47,30 @@ private:
int _nest; int _nest;
void log_print( char **o, char **n );
static void log ( const char *fmt, ... );
static static
void indent ( void ) void indent ( void )
{ {
int n = Loggable::_level; int n = Loggable::_level;
while ( n-- ) while ( n-- )
printf( "\t" ); log( "\t" );
} }
public: public:
static bool open ( const char *filename ); static bool open ( const char *filename );
static void undo ( void );
static static
void void
block_start ( void ) block_start ( void )
{ {
indent(); indent();
printf( "{\n" ); log( "{\n" );
++Loggable::_level; ++Loggable::_level;
} }
static static
@ -74,7 +79,7 @@ public:
{ {
assert( --Loggable::_level >= 0 ); assert( --Loggable::_level >= 0 );
indent(); indent();
printf( "}\n" ); log( "}\n" );
} }
static static
@ -84,7 +89,7 @@ public:
if ( id > _log_id ) if ( id > _log_id )
return NULL; return NULL;
return _loggables[ id ]; return _loggables[ id - 1 ];
} }
Loggable ( ) Loggable ( )
@ -108,7 +113,6 @@ public:
protected: protected:
// void log ( const char *module, const char *action, const char *fmt, ... );
void log_start ( void ); void log_start ( void );
void log_end ( void ); void log_end ( void );
void log_create ( void ); void log_create ( void );

View File

@ -88,7 +88,7 @@ protected:
strtok( s, " " ); strtok( s, " " );
char *v = s + strlen( s ); char *v = s + strlen( s ) + 1;
if ( ! strcmp( s, ":x" ) ) if ( ! strcmp( s, ":x" ) )
_offset = atol( v ); _offset = atol( v );
@ -122,6 +122,8 @@ protected:
} }
free( sa ); free( sa );
_track->redraw();
} }
public: public:

9
main.C
View File

@ -26,7 +26,7 @@
#include <FL/Fl_Pack.H> #include <FL/Fl_Pack.H>
#include <FL/Fl_Group.H> #include <FL/Fl_Group.H>
#include <FL/Fl_Slider.H> #include <FL/Fl_Slider.H>
#include <FL/Fl_Button.H>
#include "Scalebar.H" #include "Scalebar.H"
@ -104,6 +104,10 @@ cb_scroll ( Fl_Widget *w, void *v )
} }
void cb_undo ( Fl_Widget *w, void *v )
{
Loggable::undo();
}
int int
main ( int argc, char **argv ) main ( int argc, char **argv )
@ -129,6 +133,9 @@ main ( int argc, char **argv )
timeline->scrollbar->type( 1 ); timeline->scrollbar->type( 1 );
timeline->scrollbar->callback( cb_scroll, 0 ); timeline->scrollbar->callback( cb_scroll, 0 );
Fl_Button *o = new Fl_Button( 0, 0, 50, 50, "undo" );
o->callback( cb_undo, 0 );
main_window->end(); main_window->end();
main_window->show(); main_window->show();