Callback: work at any arity
[xonotic/netradiant.git] / libs / undolib.h
1 /*
2    Copyright (C) 2001-2006, William Joseph.
3    All Rights Reserved.
4
5    This file is part of GtkRadiant.
6
7    GtkRadiant is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    GtkRadiant is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GtkRadiant; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 #if !defined ( INCLUDED_UNDOLIB_H )
23 #define INCLUDED_UNDOLIB_H
24
25 #include "iundo.h"
26 #include "mapfile.h"
27 #include "warnings.h"
28 #include "generic/callback.h"
29
30 template<typename Copyable>
31 class BasicUndoMemento : public UndoMemento
32 {
33 Copyable m_data;
34 public:
35 BasicUndoMemento( const Copyable& data )
36         : m_data( data ){
37 }
38
39 void release(){
40         delete this;
41 }
42
43 const Copyable& get() const {
44         return m_data;
45 }
46 };
47
48
49 template<typename Copyable>
50 class ObservedUndoableObject : public Undoable
51 {
52 typedef Callback1<const Copyable&> ImportCallback;
53
54 Copyable& m_object;
55 ImportCallback m_importCallback;
56 UndoObserver* m_undoQueue;
57 MapFile* m_map;
58 public:
59
60 ObservedUndoableObject<Copyable>( Copyable & object, const ImportCallback &importCallback )
61         : m_object( object ), m_importCallback( importCallback ), m_undoQueue( 0 ), m_map( 0 )
62 {
63 }
64 ~ObservedUndoableObject(){
65 }
66
67 MapFile* map(){
68         return m_map;
69 }
70
71 void instanceAttach( MapFile* map ){
72         m_map = map;
73         m_undoQueue = GlobalUndoSystem().observer( this );
74 }
75 void instanceDetach( MapFile* map ){
76         m_map = 0;
77         m_undoQueue = 0;
78         GlobalUndoSystem().release( this );
79 }
80
81 void save(){
82         if ( m_map != 0 ) {
83                 m_map->changed();
84         }
85         if ( m_undoQueue != 0 ) {
86                 m_undoQueue->save( this );
87         }
88 }
89
90 UndoMemento* exportState() const {
91         return new BasicUndoMemento<Copyable>( m_object );
92 }
93 void importState( const UndoMemento* state ){
94         save();
95         m_importCallback( ( static_cast<const BasicUndoMemento<Copyable>*>( state ) )->get() );
96 }
97 };
98
99 template<typename Copyable>
100 class UndoableObject : public Undoable
101 {
102 Copyable& m_object;
103 UndoObserver* m_undoQueue;
104 MapFile* m_map;
105
106 public:
107 UndoableObject( Copyable& object )
108         : m_object( object ), m_undoQueue( 0 ), m_map( 0 )
109 {}
110 ~UndoableObject(){
111 }
112
113 void instanceAttach( MapFile* map ){
114         m_map = map;
115         m_undoQueue = GlobalUndoSystem().observer( this );
116 }
117 void instanceDetach( MapFile* map ){
118         m_map = 0;
119         m_undoQueue = 0;
120         GlobalUndoSystem().release( this );
121 }
122
123 void save(){
124         if ( m_map != 0 ) {
125                 m_map->changed();
126         }
127         if ( m_undoQueue != 0 ) {
128                 m_undoQueue->save( this );
129         }
130 }
131
132 UndoMemento* exportState() const {
133         return new BasicUndoMemento<Copyable>( m_object );
134 }
135 void importState( const UndoMemento* state ){
136         save();
137         m_object = ( static_cast<const BasicUndoMemento<Copyable>*>( state ) )->get();
138 }
139 };
140
141 #endif