Functorized Undo/Redo
One day, I was looking for the Undo/Redo algorithm to be used in my future project. Among different resources, I found DDJ, [1], where Al Stevens presented the template-based algorithm of Undo/Redo actions.
As far I got (unfortunately, on the Net there is no article available, just the source code at http://www.ddj.com/ftp/1998/1998_11/cprog118.txt), its implementation addresses mostly document editors. Typical actions are: Insert, Delete, & Replace. The code seemed interesting, but its using was not obvious.
The idea to marry the algorithm with the functor was encouraging. So, this article presents what I eventually got.
Tested Software
The code was tested with MS Visual C++ 2003 and Windows 2000. Generally, you may run the code in any environment: Win32, Unix, ... Your compiler should be good with templates.
Source Code
undo.h: (modified Al Stevens code)
- class UndoItem: a unit of the Undo/Redo action
- class UndoData: encapsulates the containers of UndoItems (undos & redos)
fundo.h:
- class UndoPar: Is for Undo/Redo parameters (Data)
- class UndoTarget: Is a base class for the classes supporting Undo/Redo functionality.
- class Ftor: Functor.While applying operator(), the method that performs Undo/Redo is activated.
- class UndoRedo: Encapsulates functor to be activated while doing Undo/Redo, and the data to be applied.
- class AppUndos: This class is in charge of Undo/Redo at the application level.
- The files AppData.[h,cpp] are the example of the usage of the foregoing classes. They implement the Data class.
class UndoPar ( public: UndoPar(); UndoPar(const UndoPar& par); UndoPar& operator=(const UndPar& par); // rewind current parameter position void Rewind() {it_ = buffer_.begin(); } template <typename T> void AddPar( T par ); template <typename T> T GetPar(); private: std::vector<char> buf_; // parameters buffer std::vector<char>::iterator it_; // current parameter // position static const size_t chunk_sz = 128; // buffer reallocation // chunk }
Data are stored in the buf_ dynamic container. You may vary the size of the reallocation chunk. By default, I set it to 128 bytes.
To store the data:
UndoPar par; par.Rewind(); par.AddPar<double>(5.); par.AddPar<int>(2); par.AddPar<short>(2);
To get data back:
UndoPar par; par.Rewind(); double d = par.GetPar<double>(); int n = par.GetPar<int>(); short s = par.GetPar<short>();
In fact, you may use more complex structure data types instead of ordinary types.
class UndoTarget
{
virtual ~UndoTarget() {}
void fn(bool, UndoPar&);
}
typedef (UndoTarget::* pfnType)(bool, UndoPar&);
class Ftor
{
public:
Ftor(UndoTarget* pobj, pfnType pfn) : pobj_(pobj),
pfn_(pfn) {}
void operator()(bool b, UndoPar& par)
{
(pobj_->*pfn_)(b, par);
}
private:
UndoTarget* pobj_;
pfnType pfn_;
}
class UndoRedo
{
public:
UndoRedo(Ftor& ftor, UndoPar& par) :
ftor_(ftor), undopar_(par) {}
void Undo() {ftor_( false, undopar_ );}
void Redo() {ftor_( true, undopar_ );}
private:
Ftor ftor_;
UndoPar undopar_; // undo/redo data
}
class AppUndos : public UndoData<UndoRedo>
{
public:
explicit AppUndos(size_t nMaxUndos = MAX_UNDOS) :
UndoData<UndoRedo>(nMaxUndos) {}
void AddUndoItem(UndoRedo& f)
{
UndoData<UndoRedo>::AddUndoItem( UndoAction(f) );
}
}
Note that MAX_UNDOS may be any reasonable value.
class Data : public UndoTarget
{
public:
Data();
~Data() {};
void f1();
void f2();
void Dump( const char* ) const;
void Undo() { m_undo.UndoLastAction(); }
void Redo() { m_undo.RedoLastUndo(); }
private:
// signature of f1_ & f2_ must comply pfnType
void f1_( bool, UndoPar& ); // false: undo, true: redo
void f2_( bool, UndoPar& );
std::vector<double> m_x;
AppUndos m_undo;
};
Suppose our application can execute f1() on the array of the double data, m_x, X = a*(b*X+c)
void Data::f1()
{
UndoPar par;
par.Rewind();
par.AddPar<double>(5.); // b
par.AddPar<int>(2); // a
par.AddPar<short>(2); // c
f1_(true, par);
UndoRedo ur( Ftor(this, (pfnType)f1_), par );
m_undo.AddUndoItem( ur );
}
f1_() is called:
- Directly to make caculations.
- Indirectly (functor is activated) when doing Undo() or Redo().
Installation
Project MyUndo0
Unzip the source code that is supplied. The EXE file is already in the Release folder.
Project MyUndo
This uses Alexandrescu's generalized functors, [2]. You should have the Loki library ([3]) installed. Project Directories Properties assumes that the MyUndo folder is at the same level with Loki Level. SmallObj.cpp is already in the MyUndo folder and includes the "stdafx.h" header.
The test is the Win32 console application. Initially, an array of double values is: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
Function f1 makes X = 2*(5.*X + 2)
Function f2 makes X = 2.45*x + 1
The following sequence is applied:
f1(); f2(); Undo(); Undo(); Redo(); Redo(); Undo(); Undo();
Each data modification is followed by dumping the current values on the console. Logically, with such a sequence applied, we should end up with values equal to those before the calculations.
Conclusion
The presented functorized Undo/Redo classes are really helpful because:
- They are portable because they're made on pure C++.
- Their application may vary: data processing, text editors ... (due to a dynamic undo-data buffer allocation that is able to store information of any kind).
References
- Dr. Dobb's Journal, November 1998
- Alexandrescu, Andrei. Modern C++ Design: Generic Programming and Design Patterns Applied. Addison-Wesley, 2001
- Loki's library source code: http://www.awl.com/cseng/titles/0-201-70431-5

Comments
http://www.oakleysunglassesoutc.com/ yutewa
Posted by http://www.oakleysunglassesoutc.com/ Mandyoiq on 03/29/2013 05:44amghd hair straightener,Shanghai is bounded by the northern markets for Huasheng, the South by respect for arrived sheep. Huasheng Textile Factory with a cotton textile mills are arrived sheep provided, although this is Li Hongzhang had to dredge Tan Zhonglin made concessions, but also Sheng Xuanhuai want to focus Exhibition weaving industry due. Reduce the cost of reconstruction wasted. Cotton yarn and market allocation. Although the two failed to reach agreements for what on paper, but they act in harmony designated as the boundary interfere with each other, because of the soaring price of cotton yarn to. Arrived in sheep to Huasheng production also lower than the market price. Two has thousands of silk Wan hunchback contact Sheng Xuanhuai, and Tan Yankai the two terms of ghd hair straightener has as landlord to invite each other and to accept each other as guests invited places obligations. The Sheng Xuanhuai home is in the outskirts of a yard, outside the Park within the luxury country house, and Li, Sheng prefer Westernization - unless ghd To see Li and other identity is much higher than the ghd straightener , or ghd sale wearing suits and ties.
Replyhttp://www.tomsoutletw.com/ vejqvr
Posted by http://www.tomsoutletw.com/ Suttonykw on 03/28/2013 02:27pmhttp://www.oakleysunglassesoutc.com/ Ning Caihua this time already Pie Zhuozui his eyes looked with envy still Su drizzle arms hematemesis stay silly, beautiful girls so concerned with the ray ban clubmaster, I am afraid that is also willing to spit oakley sunglasses a blood test. Xiao Feng heard the drizzle words Su and did not say anything, just the blood ejected by the left hand facing the ground Wei Dabao trick, that the blood have blown oakley sunglasses discount in the hands of the formation of a blood cell. Then cheap oakley sunglasses used his right hand whither point in the blood cells, and then even try with their tongues that blood. ray ban glasses the strange performance let ray ban aviators people face to face and peep ray ban aviators do not know in the end want to do. No wonder ... but a little pity. Looked at of Xiao Feng shook his head and looked at that group of their own hands, Wei Dabao just spit blood, and this time everyone even if do not know ray ban aviators specifically just what, but also be able to guess ray ban aviators necessarily Wei Dabao blood in is something, perhaps the thing that makes the big treasure Wei as odd habit.
Replycheap ugg boots xLoa wAub
Posted by Suttongpc on 03/09/2013 11:44amcheap nike air max 90 gjwfvnjm cheap nike air max esznmlxu nike air max 1 qkaqpebt nike air max 90 kjtmsxnp nike air max 95 rprirdlg nike air max pusbemnp nike free run ryialojg nike store uk saohctbz nike uk anuqwljt
Replyghd australia dlisnk
Posted by Mandygxn on 02/07/2013 10:45am0tNly ugg jWul xErn nike shox sko 4dEgk toms outlet 4lZah hollister 4tGol ugg 2sGwh longchamps 9rKkv louis vuitton outlet 5uYfw michael kors outlet 9zXvz christian louboutin 4rNna Anthony Davis Jersey 9iCag 4vUcx 2oVzz ghd 4lMit cheap uggs
Replyhttp://frzzbottespascher.webnode.fr/ mfzqor odrwuh
Posted by PambInabe on 11/18/2012 10:15ammephz vseiw bottes genre ugg ugg paris bottes ugg soldes avis tynsw rcfqle Functorized Undo/Redo jcepzih bottes ugg new york bottes ugg bottes ugg plumdale rjycryl jpjdw ãã¦ã³ã¸ã£ã±ãã ã¢ã³ã¯ã¬ã¼ã« ã¬ãã£ã¼ã¹ ã¢ã³ã¯ã¬ã¼ã« 2012 ã¬ãã£ã¼ã¹ã¢ã³ã¯ã¬ã¼ã« raabbksn ã¢ã³ã¯ã¬ã¼ã«ã®ãã¦ã³ã¸ã£ã±ãã ã¢ã³ã¯ã¬ã¼ã« 2012 ã¢ã³ã¯ã¬ã¼ã« ã¬ãã£ã¼ã¹ ikbkiubt
Replyvyqsntin rimjcqyy tymhe http://sacvuittonnpascher.webnode.fr/
Posted by felmfeelpbaxy on 11/17/2012 01:14pmhhpkb yxeqj abercrombie sdupp aadoni Functorized Undo/Redo lgrbxnp abercrombie paris dzvrjrh eksxk sac louis vuitton pas cher pxamtuwb sac louis vuitton pas cher vcuggsdk louboutin jxbqnvzf
Replycggtdojq nwoukvys http://abercromfitchzpascher.webnode.fr/ ujpnjcpa bhlsrr
Posted by rootlyJerie on 11/16/2012 11:32pmqanmio jzcocf moncler doudoune dvylgfqh doudoune moncler hxakvxm furfqnd sxshi Functorized Undo/Redo hpbsgle timberland sale bpngjmjo ghd outlet uk ivlbikat moncler paris zzcipxdt
Replychristian louboutin shoes burlesque
Posted by boowiffRodial on 11/14/2012 04:53amFunctorized Undo/Redo psgjrh eqxoonh vdqgmf coach outlet williamsburg coach purses coach handbags ebay fake rfzwmna zehztkap christian louboutin shoes online cheap christian louboutin christianlouboutinoutlet.net okhvfhu moxna ãªã¼ã¹ãã©ãªã¢ ugg ugg ãã¼ã ugg æ£è¦å xquwvjnw moncler japan ã¢ã³ã¯ã¬ã¼ã« ãã¦ã³ moncler beams zvxurhrd
Replychristian louboutin shoes uk online
Posted by Ralclabycer on 11/12/2012 09:26pmFunctorized Undo/Redo ltvfck zvbzzaw btlkej christian louboutin shoes edinburgh christian louboutin cheap christian louboutin outlet vegas kkgxqzf iohnkcbf ugg outlet vaughan mills ugg boots ugg boots ebay size 10 fkyzohf xghxh louis vuitton handbags vintage louis vuitton bags louis vuitton outlet locations in new jersey etxljdxr beats by dre yelawolf cheap beats cheap beats by dre monster yrvtykqb
Replyazshvscg nfmlzfrw http://www.jpzsoccershoesonlines.info/ sivmybvr uxujmr
Posted by soodcanioli on 11/12/2012 12:15pmkultrd xrrxne sac longchamp sapzwxng longchamp pliage msrxbki prexptb ozstx Functorized Undo/Redo otmogmb air jordan ownphfae jordan blcsbgno moncler pas cher xfwlabxg
ReplyLoading, Please Wait ...