Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

test-Undoable.cxx

Go to the documentation of this file.
00001 #include "Undoable.h"
00002 #include <sigc++/bind.h>
00003 #include <sigc++/object_slot.h>
00004 
00005 class UndoableInt : public Undoable 
00006 {
00007 public:
00008     UndoableInt(int i) : fVal(i) {}
00009     virtual ~UndoableInt() {}
00010     void Set(int i) { fVal = i; }
00011     int Get(void) { return fVal; }
00012 
00013     // Undoable:
00014     UndoMemento GetMemento(void) 
00015         { return SigC::bind(SigC::slot(this,&UndoableInt::Set),fVal); }
00016 private:
00017     int fVal;
00018 };
00019 
00020 class BigUndoable : public Undoable
00021 {
00022 
00023 public:
00024 
00025     struct MyState {
00026         int fInt;
00027         float fFloat;
00028         MyState(int i, float f) : fInt(i), fFloat(f) {};
00029         MyState() : fInt(0), fFloat(0.0) {};
00030     };
00031     
00032     BigUndoable(int i, float f)  {fState.fInt = i; fState.fFloat = f;}
00033     ~BigUndoable() {}
00034 
00035     void SetState(MyState ms) { fState = ms; }
00036     int GetInt() { return fState.fInt; }
00037     float GetFloat() { return fState.fFloat; }
00038     void IncState() { ++fState.fInt; ++fState.fFloat; }
00039 
00040     UndoMemento GetMemento(void)
00041         { return SigC::bind(SigC::slot(this,&BigUndoable::SetState),fState); }
00042 
00043 private:
00044     MyState fState;
00045 };
00046 int test1()
00047 {
00048     UndoableInt i1(42);
00049     UndoHistory uh;
00050     UndoableInt i2(69), i3(1);
00051     BigUndoable bu(0,0.0);
00052 
00053     // Load up history
00054     for (int i=0; i<5; ++i) {
00055         UndoCommand uc;
00056 
00057         uc.push_back(UndoItem(i1));
00058         uc.push_back(UndoItem(i2));
00059         uh.Store(uc);
00060         assert(uc.size() == 0);
00061 
00062         uc.push_back(UndoItem(i3));
00063         uh.Store(uc);
00064         assert(uc.size() == 0);
00065 
00066         uc.push_back(UndoItem(bu));
00067         uh.Store(uc);
00068         assert(uc.size() == 0);
00069 
00070         cerr << "[" << i << "] "
00071              << "Stored as " 
00072              << "[i1=" << i1.Get() 
00073              << ", i2=" << i2.Get() 
00074              << "], [i3=" << i3.Get() << "], ("
00075              << bu.GetInt() << "," << bu.GetFloat() <<") ";
00076         i1.Set(i1.Get()+1);
00077         i2.Set(i2.Get()+1);
00078         i3.Set(i3.Get()+1);
00079         bu.IncState();
00080         cerr << "modify to "
00081              << "[i1=" << i1.Get()
00082              << ", i2=" << i2.Get() 
00083              << "], [i3=" << i3.Get() 
00084              << "], ("
00085              << bu.GetInt() << "," << bu.GetFloat() <<") " << endl;
00086     }
00087         
00088     cerr << endl;
00089 
00090     // Undo some
00091     for (int i=0; i<16; ++i) {
00092         cerr << "[undo #" << i << "] "
00093              << "i1=" << i1.Get() 
00094              << ", i2=" << i2.Get()
00095              << ", i3=" << i3.Get()
00096              << " (" << bu.GetInt() << "," << bu.GetFloat() <<") ";
00097         if (uh.Undo())
00098             cerr << " after: "
00099                  << "i1=" << i1.Get()
00100                  << ", i2=" << i2.Get() 
00101                  << ", i3=" << i3.Get() 
00102                  << " (" << bu.GetInt() << "," << bu.GetFloat() <<") "
00103                  << endl;
00104         else 
00105             cerr << " Nothing to undo\n";
00106     }
00107 
00108     cerr << endl;
00109 
00110     // Redo some
00111     for (int i=0; i<16; ++i) {
00112         cerr << "[redo #" << i << "] "
00113              << "i1=" << i1.Get() 
00114              << ", i2=" << i2.Get() 
00115              << ", i3=" << i3.Get() 
00116              << " (" << bu.GetInt() << "," << bu.GetFloat() <<") ";
00117         if (uh.Redo())
00118             cerr << " after: "
00119                  << "i1=" << i1.Get()
00120                  << ", i2=" << i2.Get() 
00121                  << ", i3=" << i3.Get() 
00122                  << " (" << bu.GetInt() << "," << bu.GetFloat() <<") "
00123                  << endl;
00124         else 
00125             cerr << " Nothing to redo\n";
00126     }
00127 
00128     return 0;
00129 }
00130 
00131 class Composite : public Undoable
00132 {
00133 public:
00134     Composite() : i1(1), i2(2), i3(3) {}
00135     virtual ~Composite() {}
00136 
00137 
00138     UndoMemento GetMemento(void) {
00139         vector<UndoMemento> umv;
00140         umv.push_back(i1.GetMemento());
00141         umv.push_back(i2.GetMemento());
00142         umv.push_back(i3.GetMemento());
00143         return SigC::bind(SigC::slot(this,&Composite::ProcVec),umv);
00144     }
00145 
00146     void ProcVec(vector<UndoMemento> umv) {
00147         vector<UndoMemento>::iterator vit;
00148         for (vit = umv.begin(); vit != umv.end(); ++vit) (*vit)();
00149     }
00150   
00151     void Increment() { 
00152         i1.Set(i1.Get()+1);
00153         i2.Set(i2.Get()+1);
00154         i3.Set(i3.Get()+1);
00155     }
00156 
00157     void Print() {
00158         cout << "i1="<< i1.Get()
00159              << " i2="<< i2.Get()
00160              << " i3="<< i3.Get()
00161              << endl;
00162     }
00163 
00164 private:
00165     UndoableInt i1, i2, i3;
00166 
00167 };
00168 
00169 int test2()
00170 {
00171     Composite c;
00172     UndoHistory uh;
00173 
00174     // Load up history
00175     for (int i=0; i<5; ++i) {
00176         UndoCommand uc;
00177 
00178         uc.push_back(UndoItem(c));
00179         uh.Store(uc);
00180         assert(uc.size() == 0);
00181 
00182         cout << "Before: "; c.Print();
00183         c.Increment();
00184         cout << "After:  "; c.Print();
00185 
00186     }
00187 
00188     cout << endl;
00189     
00190     // Undo some
00191     for (int i=0; i<6; ++i) {
00192         cout << "Before undo: "; c.Print();
00193         if (uh.Undo()) {
00194             cout << "After undo:  "; c.Print();
00195         }
00196         else
00197             cout << "Nothing to undo\n";
00198     }
00199 
00200     cerr << endl;
00201 
00202     // Redo some
00203     for (int i=0; i<6; ++i) {
00204         cout << "Before redo: "; c.Print();
00205         if (uh.Redo()) {
00206             cout << "After redo:  "; c.Print();
00207         }
00208         else
00209             cout << "Nothing to redo\n";
00210     }
00211 
00212     return 0;
00213 }
00214 
00215 int main (int argc, char *argv[]) 
00216 {
00217     char c = '1';
00218     if (argc > 1) c = argv[1][0];
00219     switch (c) {
00220     case '1':
00221         return test1();
00222         break;
00223     case '2': 
00224     default:
00225         return test2();
00226         break;
00227     }
00228     return 0;
00229 } // end of main()

Generated on Wed Sep 4 19:01:21 2002 for loon by doxygen1.2.16