diff --git a/Timeline/Loggable.C b/Timeline/Loggable.C index da5cf31..64c8412 100644 --- a/Timeline/Loggable.C +++ b/Timeline/Loggable.C @@ -31,6 +31,8 @@ using std::min; using std::max; +#include // for Fl::check() + FILE *Loggable::_fp; @@ -43,6 +45,9 @@ Loggable ** Loggable::_loggables; std::map Loggable::_class_map; std::queue Loggable::_transaction; +progress_func *Loggable::_progress_callback = NULL; +void *Loggable::_progress_callback_arg = NULL; + /** Open the journal /filename/ and replay it, bringing the end state back into RAM */ @@ -83,6 +88,9 @@ Loggable::open ( const char *filename ) return true; } +#include +#include + /** replay journal or snapshot */ bool Loggable::replay ( FILE *fp ) @@ -90,6 +98,12 @@ Loggable::replay ( FILE *fp ) /* FIXME: bogus */ char buf[BUFSIZ]; + struct stat st; + fstat( fileno( fp ), &st ); + + off_t total = st.st_size; + off_t current = 0; + while ( fscanf( fp, "%[^\n]\n", buf ) == 1 ) { if ( ! ( ! strcmp( buf, "{" ) || ! strcmp( buf, "}" ) ) ) @@ -99,7 +113,14 @@ Loggable::replay ( FILE *fp ) else do_this( buf, false ); } + + current = ftell( fp ); + + if ( _progress_callback ) + _progress_callback( current * 100 / total, _progress_callback_arg ); } + + return true; } /** close journal and delete all loggable objects, returing the systemt to a blank slate */ @@ -360,21 +381,9 @@ Loggable::undo ( void ) delete[] buf; } -/* FIXME: we need a version of this that is fully const, right? */ -/** write a snapshot of the state of all loggable objects, sufficient - * for later reconstruction, to /fp/ */ -bool -Loggable::snapshot ( FILE *fp ) +void +Loggable::compact_ids ( void ) { - FILE *ofp = _fp; - - if ( ! ( _fp = fp ) ) - { - _fp = ofp; - return false; - } - - /* first, make all ids consecutive */ int id = 0; for ( int i = 0; i < _log_id; ++i ) if ( _loggables[ i ] ) @@ -390,6 +399,21 @@ Loggable::snapshot ( FILE *fp ) } _log_id = id; +} + +/* FIXME: we need a version of this that is fully const, right? */ +/** write a snapshot of the state of all loggable objects, sufficient + * for later reconstruction, to /fp/ */ +bool +Loggable::snapshot ( FILE *fp ) +{ + FILE *ofp = _fp; + + if ( ! ( _fp = fp ) ) + { + _fp = ofp; + return false; + } block_start(); @@ -419,6 +443,8 @@ Loggable::snapshot ( const char *name ) snapshot( fp ); fclose( fp ); + + return true; } /** Replace the journal with a snapshot of the current state */ @@ -428,7 +454,9 @@ Loggable::compact ( void ) fseek( _fp, 0, SEEK_SET ); ftruncate( fileno( _fp ), 0 ); - snapshot( _fp ); + compact_ids(); + if ( ! snapshot( _fp ) ) + FATAL( "Could not write snapshot!" ); _undo_index = 1; } diff --git a/Timeline/Loggable.H b/Timeline/Loggable.H index cecc7ef..1eaa738 100644 --- a/Timeline/Loggable.H +++ b/Timeline/Loggable.H @@ -35,6 +35,8 @@ #include "util/debug.h" +typedef void (progress_func)( int, void * ); + class Log_Entry; class Loggable; typedef Loggable *(create_func)(Log_Entry &); @@ -75,6 +77,9 @@ class Loggable static std::queue _transaction; + static progress_func *_progress_callback; + static void *_progress_callback_arg; + private: int _id; @@ -131,8 +136,11 @@ private: /* not implemented */ const Loggable & operator= ( const Loggable &rhs ); + static void compact_ids ( void ); + public: + static void progress_callback ( progress_func *p, void *arg ) { _progress_callback = p; _progress_callback_arg = arg;} static const char *escape ( const char *s ); int id ( void ) const { return _id; } diff --git a/Timeline/TLE.fl b/Timeline/TLE.fl index a4cb662..c0ec13b 100644 --- a/Timeline/TLE.fl +++ b/Timeline/TLE.fl @@ -152,14 +152,13 @@ asprintf( &path, "%s/options", user_config_dir ); free( path ); -menubar->add( "&Timeline", 0, 0, const_cast< Fl_Menu_Item *>( timeline->menu->menu() ), FL_SUBMENU_POINTER );} {selected - } +menubar->add( "&Timeline", 0, 0, const_cast< Fl_Menu_Item *>( timeline->menu->menu() ), FL_SUBMENU_POINTER );} {} } Function {make_window()} {open } { Fl_Window main_window { label Timeline open - xywh {225 89 1020 765} type Double resizable xclass Non_DAW visible + xywh {500 26 1020 765} type Double resizable xclass Non_DAW visible } { Fl_Menu_Bar menubar {open xywh {0 0 1024 25} @@ -192,6 +191,10 @@ main_window->redraw();} if ( ! name ) return; +progress->show(); +timeline->hide(); +Loggable::progress_callback( progress_cb, this ); + if ( ! Project::validate( name ) ) { fl_alert( "The path \\"%s\\"\\ndoes not refer to a valid Non-DAW project!", name ); @@ -201,7 +204,9 @@ else if ( ! Project::open( name ) ) fl_alert( "Could not open \\"%s\\" as a Non-DAW project!", name ); // we are in a somewhar ambiguous state now with no project open. -}} +} +progress->hide(); +timeline->show();} xywh {10 10 40 25} } MenuItem {} { @@ -544,15 +549,15 @@ delete win;} } } Fl_Group {} {open - xywh {0 23 1024 48} + xywh {-10 23 1034 51} } { Fl_Pack {} {open - xywh {0 23 473 46} type HORIZONTAL + xywh {-10 23 483 46} type HORIZONTAL code0 {o->spacing( 10 );} } { Fl_Box {} { label {} - xywh {0 23 184 46} color 30 + xywh {-10 23 194 46} color 30 code0 {transport = o;} code1 {o->labeltype( FL_NO_LABEL );} class Transport @@ -611,6 +616,10 @@ delete win;} } } } + Fl_Progress progress { + label {0%} + xywh {15 394 995 41} hide + } Fl_Box {} { label {} xywh {0 72 1024 695} box FLAT_BOX color 47 labelsize 100 resizable @@ -670,7 +679,8 @@ project_name->redraw();} {} snprintf( s, 5, "%d%%", (int)v ); -p->label( s );} {} +p->label( s );} {selected + } } Function {update_status()} {open } { @@ -701,7 +711,7 @@ xruns_output->value( engine->xruns() );} {} } { Fl_Window about_dialog_window { label About open - private xywh {658 165 495 600} type Double xclass {Non-DAW} visible + private xywh {758 335 495 600} type Double xclass {Non-DAW} visible } { Fl_Tabs {} {open xywh {0 213 497 392} @@ -795,6 +805,18 @@ save(); exit( 0 );} {} } + Function {progress_cb( int p, void *arg )} {open return_type {static void} + } { + code {Fl_Progress *progress = ((TLE*)arg)->progress; + +static char pat[10]; + +update_progress( progress, pat, p ); + +progress->redraw(); + +Fl::check();} {} + } } class New_Project_Dialog {open