nonlib: Remove sigc++ dependencey from OSC::Endpoint.
[nondaw.git] / nonlib / Loggable.H
blob84aa24265e249971c552a33970c0d43b48867092
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 * );
38 typedef void (dirty_func)( int, void * );
40 class Log_Entry;
41 class Loggable;
42 typedef Loggable *(create_func)(Log_Entry &, unsigned int id);
44 #define LOG_REGISTER_CREATE( class ) \
45     Loggable::register_create( #class, & class ::create  );
47 #define LOG_NAME_FUNC( class ) \
48     virtual const char *class_name ( void ) const { return #class ; }
50 #define LOG_CREATE_FUNC( class )                \
51     static Loggable *                           \
52     create ( Log_Entry &e, unsigned int id )    \
53     {                                           \
54         class *r = new class;                   \
55         r->update_id( id );                     \
56         r->set( e );                            \
57         return (Loggable *)r;                   \
58     }                                           \
59     LOG_NAME_FUNC( class );
62 #define LOG_NOT_LOGGABLE_FUNC( class ) \
63     virtual const char *class_name ( void ) const { return #class ; }
65 class Logger;
66 class Loggable
68     struct log_pair {
69         Loggable * loggable;
70         Log_Entry * unjournaled_state;
71     };
73     static FILE *_fp;
74     static unsigned int _log_id;
75     static int _level;
77     static off_t _undo_offset;
79     static std::map <unsigned int, Loggable::log_pair > _loggables;
81     static std::map <std::string, create_func*> _class_map;
83     static std::queue <char *> _transaction;
85     static progress_func *_progress_callback;
86     static void *_progress_callback_arg;
88     static snapshot_func *_snapshot_callback;
89     static void *_snapshot_callback_arg;
91     static dirty_func *_dirty_callback;
92     static void *_dirty_callback_arg;
94 private:
96     static unsigned int _relative_id;
98     unsigned int _id;
100     Log_Entry *_old_state;
102     int _nest;
104     static int _dirty;                                                 /* count of changes */
106     static void ensure_size ( size_t n );
108     void log_print ( const Log_Entry *o, const Log_Entry *n ) const;
109     static void log ( const char *fmt, ... );
111     static void flush ( void );
114     void init ( bool loggable=true )
115         {
116             // _new_state
117             _old_state = NULL;
118             _nest = 0;
120             if ( loggable )
121             {
122                 _id = ++_log_id;
124                 _loggables[ _id ].loggable = this;
125             }
126             else
127                 _id = 0;
129         }
131     /* not implemented */
132     const Loggable & operator= ( const Loggable &rhs );
134     void record_unjournaled ( void ) const;
135     static bool load_unjournaled_state ( void );
137     static bool replay ( FILE *fp );
139     static void signal_dirty ( int v ) { if ( _dirty_callback ) _dirty_callback( v, _dirty_callback_arg ); }
140     static void set_dirty ( void ) {  signal_dirty( ++_dirty ); }
141     static void clear_dirty ( void ) {  signal_dirty( _dirty = 0 ); }
143 public:
145     static bool replay ( const char *name );
147     static bool snapshot( FILE * fp );
148     static bool snapshot( const char *name );
150     static void snapshot_callback ( snapshot_func *p, void *arg ) { _snapshot_callback = p; _snapshot_callback_arg = arg; }
151     static void progress_callback ( progress_func *p, void *arg ) { _progress_callback = p; _progress_callback_arg = arg;}
152     static void dirty_callback ( dirty_func *p, void *arg ) { _dirty_callback = p; _dirty_callback_arg = arg;}
154     static const char *escape ( const char *s );
156     unsigned int id ( void ) const { return _id; }
158     static bool save_unjournaled_state ( void );
159     static bool open ( const char *filename );
160     static bool close ( void );
161     static void undo ( void );
163     static void compact ( void );
165     static void block_start ( void );
166     static void block_end ( void );
168     static Loggable * find ( unsigned int id );
170     Loggable ( bool loggable=true )
171         {
172             init( loggable );
173         }
175     void update_id ( unsigned int id );
177     virtual ~Loggable (  );
179     static
180     void
181     register_create ( const char *name, create_func *func )
182         {
183             _class_map[ std::string( name ) ] = func;
184         }
186     /* log messages for journal */
187     virtual void get ( Log_Entry &e ) const = 0;
188     virtual void get_unjournaled ( Log_Entry & ) const
189         {
190             /* implementation optional */
191         }
192     virtual void set ( Log_Entry &e ) = 0;
194     virtual const char *class_name ( void ) const = 0;
196     virtual void log_children ( void ) const { return; }
198     static void begin_relative_id_mode ( void );
199     
200     static void end_relative_id_mode ( void );
202     static bool do_this ( const char *s, bool reverse );
204     static int dirty ( void ) { return _dirty; }
206     void log_create  ( void ) const;
208 protected:
210     void log_start ( void );
211     void log_end ( void );
213     void log_destroy ( void ) const;
215     /* leaf subclasses *must* call log_create() at the end of their copy contructors */
216     Loggable ( const Loggable & )
217         {
218             init( true );
219         }
221 public:
223     friend class Logger;
227 class Logger
230     Loggable *_this;
231     Logger ( ) {}
233     /* not permitted */
234     Logger ( const Logger &rhs );
235     const Logger & operator= ( const Logger &rhs );
237 public:
239     Logger ( Loggable *l ) : _this( l )
240         {
241             _this->log_start();
243         }
245     ~Logger ( )
246         {
247             _this->log_end();
248         }
250     void hold ( void )
251         {
252             _this->_nest++;
253         }
255     void release ( void )
256         {
257             _this->_nest--;
258             assert( _this->_nest );
259         }
262 #include "Log_Entry.H"