Mixer: Hide panner widget until it's ready to be connected to something...
[nondaw.git] / nonlib / Loggable.H
blob0e43a7c079dc10ba23bb88c8a2b900553deaeb52
2 /*******************************************************************************/
3 /* Copyright (C) 2008 Jonathan Moore Liles                                     */
4 /*                                                                             */
5 /* This program is free software; you can redistribute it and/or modify it     */
6 /* under the terms of the GNU General Public License as published by the       */
7 /* Free Software Foundation; either version 2 of the License, or (at your      */
8 /* option) any later version.                                                  */
9 /*                                                                             */
10 /* This program is distributed in the hope that it will be useful, but WITHOUT */
11 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       */
12 /* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for   */
13 /* more details.                                                               */
14 /*                                                                             */
15 /* You should have received a copy of the GNU General Public License along     */
16 /* with This program; see the file COPYING.  If not,write to the Free Software */
17 /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
18 /*******************************************************************************/
21 /* Master class for journaling. */
23 #pragma once
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
30 #include <map>
31 #include <string>
32 #include <queue>
34 // #include "types.h"
36 typedef void (progress_func)( int, void * );
37 typedef void (snapshot_func)( void * );
39 class Log_Entry;
40 class Loggable;
41 typedef Loggable *(create_func)(Log_Entry &, unsigned int id);
43 #define LOG_REGISTER_CREATE( class ) \
44     Loggable::register_create( #class, & class ::create  );
46 #define LOG_NAME_FUNC( class ) \
47     virtual const char *class_name ( void ) const { return #class ; }
49 #define LOG_CREATE_FUNC( class )                                        \
50     static Loggable *                                                   \
51     create ( Log_Entry &e, unsigned int id )                                     \
52     {                                                                   \
53         class *r = new class;                                           \
54         r->update_id( id );                                             \
55         r->set( e );                                                    \
56         return (Loggable *)r;                                           \
57     }                                                                   \
58     LOG_NAME_FUNC( class );                                             \
61 #define LOG_NOT_LOGGABLE_FUNC( class ) \
62     virtual const char *class_name ( void ) const { return #class ; } \
64 class Logger;
65 class Loggable
67     struct log_pair {
68         Loggable * loggable;
69         Log_Entry * unjournaled_state;
70     };
72     static FILE *_fp;
73     static unsigned int _log_id;
74     static int _level;
76     static off_t _undo_offset;
78     static std::map <unsigned int, Loggable::log_pair > _loggables;
80     static std::map <std::string, create_func*> _class_map;
82     static std::queue <char *> _transaction;
84     static progress_func *_progress_callback;
85     static void *_progress_callback_arg;
87     static snapshot_func *_snapshot_callback;
88     static void *_snapshot_callback_arg;
90 private:
92     unsigned int _id;
94     Log_Entry *_old_state;
96     int _nest;
98     static void ensure_size ( size_t n );
100     void log_print ( const Log_Entry *o, const Log_Entry *n ) const;
101     static void log ( const char *fmt, ... );
103     static void flush ( void );
106     void init ( bool loggable=true )
107         {
108             // _new_state
109             _old_state = NULL;
110             _nest = 0;
112             if ( loggable )
113             {
114                 _id = ++_log_id;
116                 _loggables[ _id ].loggable = this;
117             }
118             else
119                 _id = 0;
121         }
123     /* not implemented */
124     const Loggable & operator= ( const Loggable &rhs );
126     void record_unjournaled ( void ) const;
127     static bool load_unjournaled_state ( void );
129     static bool replay ( FILE *fp );
130     static bool replay ( const char *name );
132 public:
135     static bool snapshot( FILE * fp );
136     static bool snapshot( const char *name );
138     static void snapshot_callback ( snapshot_func *p, void *arg ) { _snapshot_callback = p; _snapshot_callback_arg = arg; }
139     static void progress_callback ( progress_func *p, void *arg ) { _progress_callback = p; _progress_callback_arg = arg;}
140     static const char *escape ( const char *s );
142     unsigned int id ( void ) const { return _id; }
144     static bool save_unjournaled_state ( void );
145     static bool open ( const char *filename );
146     static bool close ( void );
147     static void undo ( void );
149     static void compact ( void );
151     static void block_start ( void );
152     static void block_end ( void );
154     static Loggable * find ( unsigned int id );
156     Loggable ( bool loggable=true )
157         {
158             init( loggable );
159         }
161     void update_id ( unsigned int id );
163     virtual ~Loggable (  );
165     static
166     void
167     register_create ( const char *name, create_func *func )
168         {
169             _class_map[ std::string( name ) ] = func;
170         }
172     /* log messages for journal */
173     virtual void get ( Log_Entry &e ) const = 0;
174     virtual void get_unjournaled ( Log_Entry & ) const
175         {
176             /* implementation optional */
177         }
178     virtual void set ( Log_Entry &e ) = 0;
180     virtual const char *class_name ( void ) const = 0;
182     virtual void log_children ( void ) const { return; }
184     static bool do_this ( const char *s, bool reverse );
186     void log_create  ( void ) const;
188 protected:
190     void log_start ( void );
191     void log_end ( void );
193     void log_destroy ( void ) const;
195     /* leaf subclasses *must* call log_create() at the end of their copy contructors */
196     Loggable ( const Loggable & )
197         {
198             init( true );
199         }
201 public:
203     friend class Logger;
207 class Logger
210     Loggable *_this;
211     Logger ( ) {}
213     /* not permitted */
214     Logger ( const Logger &rhs );
215     const Logger & operator= ( const Logger &rhs );
217 public:
219     Logger ( Loggable *l ) : _this( l )
220         {
221             _this->log_start();
223         }
225     ~Logger ( )
226         {
227             _this->log_end();
228         }
230     void hold ( void )
231         {
232             _this->_nest++;
233         }
235     void release ( void )
236         {
237             _this->_nest--;
238             assert( _this->_nest );
239         }
242 #include "Log_Entry.H"