| @@ -183,11 +183,12 @@ Loggable::undo ( void ) | |||||
| if ( ! strcmp( command, "destroy" ) ) | if ( ! strcmp( command, "destroy" ) ) | ||||
| { | { | ||||
| printf( "should create new %s here\n", classname ); | |||||
| char **sa = parse_alist( arguments ); | char **sa = parse_alist( arguments ); | ||||
| _class_map[ string( classname ) ]( sa ); | |||||
| if ( ! _class_map[ string( classname ) ] ) | |||||
| printf( "error class %s is unregistered!\n", classname ); | |||||
| else | |||||
| _class_map[ string( classname ) ]( sa ); | |||||
| } | } | ||||
| else | else | ||||
| if ( ! strcmp( command, "set" ) ) | if ( ! strcmp( command, "set" ) ) | ||||
| @@ -289,7 +290,7 @@ void | |||||
| Loggable::log_start ( void ) | Loggable::log_start ( void ) | ||||
| { | { | ||||
| if ( ! _old_state ) | if ( ! _old_state ) | ||||
| _old_state = log_dump(); | |||||
| _old_state = get(); | |||||
| ++_nest; | ++_nest; | ||||
| @@ -305,7 +306,7 @@ Loggable::log_end ( void ) | |||||
| // assert( _old_state ); | // assert( _old_state ); | ||||
| char **_new_state = log_dump(); | |||||
| char **_new_state = get(); | |||||
| // if ( _old_state ) | // if ( _old_state ) | ||||
| @@ -340,7 +341,7 @@ Loggable::log_create ( void ) | |||||
| indent(); | indent(); | ||||
| log( "%s 0x%X create ", class_name(), _id ); | log( "%s 0x%X create ", class_name(), _id ); | ||||
| char **sa = log_dump(); | |||||
| char **sa = get(); | |||||
| if ( sa ) | if ( sa ) | ||||
| { | { | ||||
| @@ -357,7 +358,7 @@ 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 = log_dump(); | |||||
| char **sa = get(); | |||||
| // log_print( sa, NULL ); | // log_print( sa, NULL ); | ||||
| log_print( NULL, sa ); | log_print( NULL, sa ); | ||||
| @@ -130,7 +130,7 @@ public: | |||||
| /* log messages for journal */ | /* log messages for journal */ | ||||
| virtual const char *class_name ( void ) = 0; | virtual const char *class_name ( void ) = 0; | ||||
| virtual char ** log_dump ( void ) = 0; | |||||
| virtual char ** get ( void ) = 0; | |||||
| /* this method must parse an array of name/value pair strings and make the appropriate changes too | /* this method must parse an array of name/value pair strings and make the appropriate changes too | ||||
| the object state */ | the object state */ | ||||
| @@ -60,7 +60,7 @@ protected: | |||||
| const char *class_name ( void ) { return "Region"; } | const char *class_name ( void ) { return "Region"; } | ||||
| char ** log_dump ( void ) | |||||
| char ** get ( void ) | |||||
| { | { | ||||
| // char *r; | // char *r; | ||||
| char **sa = (char**)malloc( sizeof( char* ) * 8 ); | char **sa = (char**)malloc( sizeof( char* ) * 8 ); | ||||
| @@ -40,20 +40,82 @@ protected: | |||||
| const char *class_name ( void ) { return "Tempo_Point"; } | const char *class_name ( void ) { return "Tempo_Point"; } | ||||
| char ** log_dump ( void ) | |||||
| char ** get ( void ) | |||||
| { | { | ||||
| char **sa = (char**)malloc( sizeof( char* ) * 3 ); | |||||
| char **sa = (char**)malloc( sizeof( char* ) * 4 ); | |||||
| sa[2] = NULL; | |||||
| int i = 0; | |||||
| asprintf( &sa[0], ":x %lu", _offset ); | |||||
| asprintf( &sa[1], ":tempo %f", _tempo ); | |||||
| asprintf( &sa[i++], ":track 0x%X", _track ? _track->id() : 0 ); | |||||
| asprintf( &sa[i++], ":x %lu", _offset ); | |||||
| asprintf( &sa[i++], ":tempo %f", _tempo ); | |||||
| sa[i] = NULL; | |||||
| return sa; | return sa; | ||||
| } | } | ||||
| void | |||||
| set ( char **sa ) | |||||
| { | |||||
| for ( int i = 0; sa[i]; ++i ) | |||||
| { | |||||
| char *s = sa[i]; | |||||
| strtok( s, " " ); | |||||
| char *v = s + strlen( s ) + 1; | |||||
| if ( ! strcmp( s, ":x" ) ) | |||||
| _offset = atol( v ); | |||||
| else | |||||
| if ( ! strcmp( s, ":tepmo" ) ) | |||||
| _tempo = atof( v ); | |||||
| else | |||||
| if ( ! strcmp( s, ":track" ) ) | |||||
| { | |||||
| int i; | |||||
| sscanf( v, "%X", &i ); | |||||
| Track *t = (Track*)Loggable::find( i ); | |||||
| assert( t ); | |||||
| t->add( this ); | |||||
| } | |||||
| free( s ); | |||||
| } | |||||
| free( sa ); | |||||
| timeline->rulers->redraw(); | |||||
| timeline->tracks->redraw(); | |||||
| _make_label(); | |||||
| } | |||||
| Tempo_Point ( ) | |||||
| { | |||||
| } | |||||
| public: | public: | ||||
| /* for loggable */ | |||||
| static Loggable * | |||||
| create ( char **sa ) | |||||
| { | |||||
| Tempo_Point *r = new Tempo_Point; | |||||
| r->set( sa ); | |||||
| r->log_create(); | |||||
| return (Loggable *)r; | |||||
| } | |||||
| Tempo_Point ( nframes_t when, float bpm ) | Tempo_Point ( nframes_t when, float bpm ) | ||||
| { | { | ||||
| _tempo = bpm; | _tempo = bpm; | ||||
| @@ -73,7 +135,6 @@ public: | |||||
| float tempo ( void ) const { return _tempo; } | float tempo ( void ) const { return _tempo; } | ||||
| void tempo ( float v ) { _tempo = v; } | void tempo ( float v ) { _tempo = v; } | ||||
| int | int | ||||
| handle ( int m ) | handle ( int m ) | ||||
| { | { | ||||
| @@ -25,12 +25,12 @@ | |||||
| struct time_sig | struct time_sig | ||||
| { | { | ||||
| int beats_per_bar; | int beats_per_bar; | ||||
| int note_type; | |||||
| int beat_type; | |||||
| time_sig ( int bpb, int note ) | time_sig ( int bpb, int note ) | ||||
| { | { | ||||
| beats_per_bar = bpb; | beats_per_bar = bpb; | ||||
| note_type = note; | |||||
| beat_type = note; | |||||
| } | } | ||||
| }; | }; | ||||
| @@ -47,28 +47,94 @@ class Time_Point : public Track_Point | |||||
| if ( ! _label ) | if ( ! _label ) | ||||
| _label = new char[40]; | _label = new char[40]; | ||||
| snprintf( _label, 40, "%d/%d", _time.beats_per_bar, _time.note_type ); | |||||
| snprintf( _label, 40, "%d/%d", _time.beats_per_bar, _time.beat_type ); | |||||
| } | |||||
| Time_Point ( ) : _time( 4, 4 ) | |||||
| { | |||||
| } | } | ||||
| protected: | protected: | ||||
| const char *class_name ( void ) { return "Time_Point"; } | const char *class_name ( void ) { return "Time_Point"; } | ||||
| char ** log_dump ( void ) | |||||
| char ** get ( void ) | |||||
| { | { | ||||
| char **sa = (char**)malloc( sizeof( char* ) * 4 ); | |||||
| char **sa = (char**)malloc( sizeof( char* ) * 5 ); | |||||
| sa[3] = NULL; | |||||
| int i = 0; | |||||
| asprintf( &sa[0], ":x %lu", _offset ); | |||||
| asprintf( &sa[1], ":beats_per_bar %d", _time.beats_per_bar ); | |||||
| asprintf( &sa[2], ":beat_type %d", _time.note_type ); | |||||
| asprintf( &sa[i++], ":track 0x%X", _track ? _track->id() : 0 ); | |||||
| asprintf( &sa[i++], ":x %lu", _offset ); | |||||
| asprintf( &sa[i++], ":beats_per_bar %d", _time.beats_per_bar ); | |||||
| asprintf( &sa[i++], ":beat_type %d", _time.beat_type ); | |||||
| sa[i] = NULL; | |||||
| return sa; | return sa; | ||||
| } | } | ||||
| void | |||||
| set ( char **sa ) | |||||
| { | |||||
| for ( int i = 0; sa[i]; ++i ) | |||||
| { | |||||
| char *s = sa[i]; | |||||
| strtok( s, " " ); | |||||
| char *v = s + strlen( s ) + 1; | |||||
| if ( ! strcmp( s, ":x" ) ) | |||||
| _offset = atol( v ); | |||||
| else | |||||
| if ( ! strcmp( s, ":beats_per_bar" ) ) | |||||
| _time.beats_per_bar = atoi( v ); | |||||
| else | |||||
| if ( ! strcmp( s, ":beat_type" ) ) | |||||
| _time.beat_type = atoi( v ); | |||||
| else | |||||
| if ( ! strcmp( s, ":track" ) ) | |||||
| { | |||||
| int i; | |||||
| sscanf( v, "%X", &i ); | |||||
| Track *t = (Track*)Loggable::find( i ); | |||||
| assert( t ); | |||||
| t->add( this ); | |||||
| } | |||||
| free( s ); | |||||
| } | |||||
| free( sa ); | |||||
| timeline->rulers->redraw(); | |||||
| timeline->tracks->redraw(); | |||||
| _make_label(); | |||||
| } | |||||
| public: | public: | ||||
| /* for loggable */ | |||||
| static Loggable * | |||||
| create ( char **sa ) | |||||
| { | |||||
| Time_Point *r = new Time_Point; | |||||
| r->set( sa ); | |||||
| r->log_create(); | |||||
| return (Loggable *)r; | |||||
| } | |||||
| Time_Point ( nframes_t when, int bpb, int note ) : _time( bpb, note ) | Time_Point ( nframes_t when, int bpb, int note ) : _time( bpb, note ) | ||||
| { | { | ||||
| _offset = when; | _offset = when; | ||||
| @@ -84,9 +150,9 @@ public: | |||||
| } | } | ||||
| /* beats_per_bar ( void ) const { return _time.beats_per_bar; } */ | /* beats_per_bar ( void ) const { return _time.beats_per_bar; } */ | ||||
| /* note_type ( void ) const { return _note_type; } */ | |||||
| /* beat_type ( void ) const { return _beat_type; } */ | |||||
| void time ( int bpb, int note ) { _time.beats_per_bar = bpb; _time.note_type = note; } | |||||
| void time ( int bpb, int note ) { _time.beats_per_bar = bpb; _time.beat_type = note; } | |||||
| time_sig time ( void ) const { return _time; } | time_sig time ( void ) const { return _time; } | ||||
| int | int | ||||
| @@ -53,7 +53,7 @@ protected: | |||||
| void set ( char ** ) { return; } | void set ( char ** ) { return; } | ||||
| char ** log_dump ( void ) | |||||
| char ** get ( void ) | |||||
| { | { | ||||
| // char *r; | // char *r; | ||||
| @@ -71,7 +71,9 @@ main ( int argc, char **argv ) | |||||
| Fl::scheme( "plastic" ); | Fl::scheme( "plastic" ); | ||||
| Loggable::open( "history" ); | Loggable::open( "history" ); | ||||
| Loggable::register_create( "Region", &Region::create ); | |||||
| Loggable::register_create( "Region", &Region::create ); | |||||
| Loggable::register_create( "Tempo_Point", &Tempo_Point::create ); | |||||
| Loggable::register_create( "Time_Point", &Time_Point::create ); | |||||
| timeline = new Timeline( 0, 0, 800, 600, "Timeline" ); | timeline = new Timeline( 0, 0, 800, 600, "Timeline" ); | ||||