Demento...
Here we present a small Purebasic source code utility providing a framework allowing applications to easily incorporate multi-level undo/redo facilities into their design*.
First thing to say regarding adding undo/redo to an application is that it simply must be designed into the application right at the outset. Only a jibbering idiot would attempt to add such facilities to an existing application which had previously given no thought to such facilities!
When an application instance (or a document) is altered in a way which is to be undoable, then that application/document's state has altered. Undoing that action is simply a matter of returning the application/document's state to the most recently recorded state and there are any number of ways of implementing this.
What Demento does is to allow the host application (that making
use of Demento) to easily manage its state-history. By a
state-history, I mean a sequence of objects, each of which may
reflect the state of an application/document at the time of the
object’s creation, but will more likely consist of the information
necessary to roll the application/document between states.
These state-objects can take any form whatsoever, but will be
inexorably tied to the nature and structure of the host application
itself. Demento is not concerned with either the nature or the
content of these objects. In some sense they will contain a set of
instructions for the host application, telling it how to roll the
application from one state to another. In this sense they are
quickly seen to hold meaning only to the host application and not to
Demento which simply allows for the effective management of these
objects (and their lifetimes).
In this way, when an application is requested to undo the last recorded user action, for example, it simply turns to Demento and requests information on the most recent state-object that it constructed. The application then uses this object in whatever way is appropriate to facilitate the aforementioned roll-back etc.
Simple!
Managing the lifetimes of these state-objects can be rather tricky, which is where Demento comes into it's own.
Main features :
- A simple OOP interface.
- Cross-platform, x86 and x64 compatible.
- Fully threadsafe etc.
- Automatic management of an application/document's history through state-objects.
This includes the automatic destruction of state-objects when they become invalid.
For example, following the undoing of some action or other, that action is ready for a redo if required. However, if a new action is then added to the state history of an application at that point, then the previously undone action is invalid because it can no longer be redone. It can no longer be reached from any combination of undoes and/or redoes. Demento detects such cases automatically and instructs the host application to destroy the state-object(s) in question. (Only the host app can do this because it was the host app which created the objects).
- Limit the size of an application's history or opt for a history which can grow dynamically. This effectively allows for an unlimited number of undoes etc. (subject to memory availability of course).
In the case of a fixed history size, state-objects (corresponding to undoable actions etc.) cycle around and thus newly added state-objects can, in the case of the history being full, over-write earlier ones. This is fine for many applications.
- Extensive notifications sent to the host application as to the state of the undo/redo history etc. These include notifications informing the host app that there are actions ready to be undone or that there are no more actions which can be undone and so on.
This is useful to allow the host app to enable/disable toolbar buttons as appropriate etc. No sense enabling an undo toolbar button if there are no more actions to undo!
- Ability to link an application's save-state with it's undo-state.
For example, our demo program allows the user to drag a couple of button controls around a window all subject to undo and redo etc. and to set a save point (basically saves the application document).
Suppose the user of our demo drags one of the buttons to the bottom left of the window and then hits the save button. Then Demento records this fact. If the user moves the button again, then Demento knows (and will inform the demo program) that the application is no longer in a saved state. At this point, our demo enables a toolbar button used to save the program. If the user then hits undo to return the button to the bottom left of the screen, then Demento will inform the demo that the application has returned to its saved state etc. The demo then duly disables the aforementioned toolbar button since it is not required etc.
The download includes all of the source-code, the aforementioned (and comprehensive) demo
program and a detailed user-guide.
The user guide explains, in some detail, how Demento itself is structured and gives some pointers on how you might best structure any application (in terms of undo/redo) in order to make good use of this utility.
The demo program shows Demento being used to assist in the implementation of a full undo/redo facility.
Enjoy!
* The name Demento has arisen from the fact that it is a demented
implementation (loosely speaking) of
Memento Design Patterns!
Please bear in mind that Demento does not provide applications with undo/redo facilities. It is simply a framework which can greatly assist in adding such features.