Demento - 1.0 beta 2

Share your advanced PureBasic knowledge/code with the community.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Demento - 1.0 beta 2

Post by srod »

13 July 2010 - Demento 1.0 beta 2.

Beta 2 is effectively a completely new version of Demento. :) The earlier version didn't quite sit right with me.

It also comes with a detailed user guide (pdf format) which outlines the steps involved in using Demento to assist with the implementation of an undo/redo facility.

In terms of the biggest difference between beta 1 and beta 2 (which will only be of interest to those who delved head first into the first version) I would point out that this new version does not allocate any memory itself. Not a bean! There is no longer the danger of Demento running out of memory when hundreds and thousands of undo actions are being recorded etc. because it does not allocate any! Instead it works with a 'virtual undo stack' which makes a lot more sense given the generic nature of Demento itself.

This new version also encourages the host application to allocate larger chunks of memory in which to store multiple state-objects which makes for a much more efficient use of memory etc. You can see this with the new demo program. You will also see (in the demo) how Demento notifies the host that it can claim memory back under certain conditions etc.

Beta 2 just makes the whole business easier (when compared to the first beta!)

The manual discusses state-history and state-objects in some depth and I hope goes some way to making this utility easier to understand and indeed easier to use.

:)

==========================


12 July 2010 - Demento 1.0 beta 1.

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. Demento is based, loosely, on Memento Design Patterns.

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.

Please see the nxSoftware site for the download.


NOTE.
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.
Last edited by srod on Wed Jul 14, 2010 10:21 pm, edited 2 times in total.
I may look like a mule, but I'm not a complete ass.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Demento!

Post by Trond »

Suppose the user of our demo drags the button 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.
This behaviour is so annoying. Imagine you alter the file from another program, but want to revert to the saved state. Normally, you can just save the file again. But sometimes, some people thought it was a good idea to disable the save button. No problem, you just make a change, undo the change and save, right? Except the save button got disabled again when hitting undo! Arrg.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Demento!

Post by srod »

I am unsure as to the point you are making here? You are criticising a demo!

You have complete control over the saved state etc. to the point where you do not have to make use of it at all or you can supplement it with additional info such as other programs making changes to the file etc. The demo is there simply to show how you might use it. It is there to give some idea of what Demento can assit with, nothing more.
I may look like a mule, but I'm not a complete ass.
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Re: Demento!

Post by gnozal »

Interesting, thanks.

I like the name, reminds me of an Addams family character... :smile:
For free libraries and tools, visit my web site (also home of jaPBe V3 and PureFORM).
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Demento!

Post by Trond »

srod wrote:I am unsure as to the point you are making here? You are criticising a demo!

You have complete control over the saved state etc. to the point where you do not have to make use of it at all or you can supplement it with additional info such as other programs making changes to the file etc. The demo is there simply to show how you might use it. It is there to give some idea of what Demento can assit with, nothing more.
Just so people won't do this in their program.
remi_meier
Enthusiast
Enthusiast
Posts: 468
Joined: Sat Dec 20, 2003 6:19 pm
Location: Switzerland

Re: Demento!

Post by remi_meier »

Why not go for the command pattern directly?
http://en.wikipedia.org/wiki/Command_pattern

If I understood you correctly you prefer to save the
whole state of the application which, considering things
like image editing, is really really expensive on memory.

Or are you delta encoding the states? This would be
interesting for xml-encoded states which could be
transmitted over TCP for remote applications.

greetz
remi
Athlon64 3700+, 1024MB Ram, Radeon X1600
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Demento!

Post by srod »

remi_meier wrote:Why not go for the command pattern directly?
http://en.wikipedia.org/wiki/Command_pattern

If I understood you correctly you prefer to save the
whole state of the application which, considering things
like image editing, is really really expensive on memory.

Or are you delta encoding the states? This would be
interesting for xml-encoded states which could be
transmitted over TCP for remote applications.

greetz
remi
You have not understood me correctly. I do not record the whole state of the application no, that would be nuts.

Demento deals with 'state-objects' but does not offer any direction or impose any rules as to what these objects are to contain. That is exclusively down to the host application and has nothing to do with Demento.

A 'sensible' application will construct state-objects consisting of just the information necessary to roll the application back and forth between consecutive states in its history. E.g. an image editor program would be very ill-advised to store complete images in it's history in the same way that a word processing application would be ill-advised to store temporary copies of the whole document in order to facilitate undo/redo etc. Demento does not rule this out, however, as it takes no interest whatsoever in what the application does store within it's state-objects.

Now the main "ReadMe.txt" file accompanying Demento illustrates (briefly) how my Pyrex report designer makes use of Demento for it's undo/redo. If you read this then you will quickly appreciate just how wrong your above assertion is! :) In fact it efectively uses the Command Patterns you mention, but this is not down to Demento, it is down to Pyrex. Demento is just the glue which holds it all together.
ReadMe.txt wrote:...Note also that I was not daft enough to instruct Demento to store state-objects consisting of entire report objects! This would have been wasteful in the extreme...
@Trond : a fair point. I agree that it is not a particularly sensible thing to add, but I just wanted the demo to illustrate every one of Demento's notification messages. :)
I may look like a mule, but I'm not a complete ass.
remi_meier
Enthusiast
Enthusiast
Posts: 468
Joined: Sat Dec 20, 2003 6:19 pm
Location: Switzerland

Re: Demento!

Post by remi_meier »

srod wrote:You have not understood me correctly. I do not record the whole state of the application no, that would be nuts.

Demento deals with 'state-objects' but does not offer any direction or impose any rules as to what these objects are to contain. That is exclusively down to the host application and has nothing to do with Demento.
No, it's ok. I have understood you correctly.
That's why I wrote
prefer to save the whole state
In my experience, if you provide the ability to store state
objects so easily, it will usually turn out like this :wink: .

But of course I don't want to diminish the usefulness
of your framework. It is of course a very fine implementation
which is surely useful when used correctly.

I will post a command pattern implementation in a few
minutes because I like the way it encourages you to
only store the necessary information.

greetz
remi
Athlon64 3700+, 1024MB Ram, Radeon X1600
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Demento!

Post by srod »

Okay, but no where do I suggest or advise that state-objects should consist of copies of the entire 'document' etc. No sir! :)

As I say, the Pyrex designer uses command patterns, but these are by no means the only way or the most efficient in my opinion. Demento allows for just about any kind of implementation, bad or otherwise! :wink:
I may look like a mule, but I'm not a complete ass.
User avatar
Innesoft
Enthusiast
Enthusiast
Posts: 105
Joined: Mon Jan 18, 2010 10:30 am
Location: UK
Contact:

Re: Demento!

Post by Innesoft »

Sounds like a pretty useful idea to me, undo/redo can be a pain to manage, especially in more complex apps, and a framework like this could be a real timesaver.

Is this flexible enough to store multiple undo states in memory from various structures? Would you have to handle that yourself or can you just pass the undoable structs to the lib etc..? How does it work exactly?
Innesoft - The Software Marketplace - Innesoft Blog
» Applications, Educational Software, Casual Games
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Demento!

Post by srod »

I am unsure what you mean by 'multiple undo states', although I can take a guess? Do you mean that you would like to offer undo/redo to different aspects of the same application/document?

If so, then all you need do is create multiple 'Demento objects', one for each aspect of the app/document whose undo/redo you wish to manage.
I may look like a mule, but I'm not a complete ass.
User avatar
Innesoft
Enthusiast
Enthusiast
Posts: 105
Joined: Mon Jan 18, 2010 10:30 am
Location: UK
Contact:

Re: Demento!

Post by Innesoft »

srod wrote:I am unsure what you mean by 'multiple undo states', although I can take a guess? Do you mean that you would like to offer undo/redo to different aspects of the same application/document?

If so, then all you need do is create multiple 'Demento objects', one for each aspect of the app/document whose undo/redo you wish to manage.
No, I just meant the ability to undo several actions in a row, given that an app might use several 'undoable' structures. I'll give an example:-

[undo state 2]
..structure for meshes
..structure for lights
..structure for textures
[/undo state2]

[undo state 1]
..structure for meshes
..structure for lights
..structure for textures
[/undo state1]


each structure would hold very different information, some of which has to be loaded from file. Storing a single undo state would need a fair bit of memory. Would you be able to pass those structures directly to the lib and have it store/restore the contents?

I suppose my question is; what is the step-by-step process for sending/retrieving an undo state to the lib, given that the app might have very complex needs such as in a 3D scene?
Innesoft - The Software Marketplace - Innesoft Blog
» Applications, Educational Software, Casual Games
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Demento!

Post by srod »

Yes, Demento imposes no restrictions whatsoever, a consequence of the fact that it does not actually implement the undo/redo for you. My Pyrex designer typically undoes multiple actions in response to a single request for an undo etc. The state-objects which Pyrex creates for Demento to manage are actually stored, in the first instance, in a large memory block and when this is full, it shoves them into additional blocks as required. I am toying with the idea of shoving some out to disc as well. The point is that Demento does not care where you store these objects, you can mix and match as appropriate. These objects can take any form you wish. Some may be pointers to structures, others pointers to interfaces and yet others can be array indexes.

The important thing to note is that you give Demento a single integer value to represent a state-object and Demento asks no questions as to what this value may physically equate to or represent? It could be a pointer or some kind of handle or an array index or a file pointer... Demento really takes no interest in it. You thus do not pass the actual contents of a state-object to Demento (not unless this can fit into an integer variable) but some kind of reference to the data. So if, for example, your state-object consists of a structure (as is the case with the Demento demo program) then you would typically pass a pointer to that structure in place of your state-object. I apologise if this seems to contradict in some way what I might have said in my initial posting, but it is difficult to describe Demento in full in such a brief manner.

As for a step by step guide to using Demento... difficult since it is really a tool for advanced uses since undo/redo is quite a complex thing to implement in just about any scenario. A general tutorial is made more complex because of the fact that any undo/redo implementation must be factored into an application right at the outset and a consequence of this is the fact that any use of Demento is inexorably tied to the inner workings of the host application.

Let me give it some thought. I was hoping to avoid creating a detailed user manual because I am really pushed for time right now.
I may look like a mule, but I'm not a complete ass.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Demento!

Post by srod »

Okay Innesoft, I have given it some thought and will create a more advanced demo which I can possibly turn into some kind of tutorial if there is a demand for it.

The demo will show how a drawing/image editing type program might implement undo/redo. It will use 'command patterns' at the heart of the entire program which, with the assistance of Demento, makes an undo/redo facility a breeze to add. The fact that my Pyrex designer makes use of this technique is a good testament to this fact.

It will take me a while to create the demo as I squeeze it in between my general coding work etc.

I have about 30 minutes right now to make a start... should manage to create about 245 bugs in that time! That is my usual rate of production! :wink:
I may look like a mule, but I'm not a complete ass.
User avatar
Innesoft
Enthusiast
Enthusiast
Posts: 105
Joined: Mon Jan 18, 2010 10:30 am
Location: UK
Contact:

Re: Demento!

Post by Innesoft »

I was hoping to avoid creating a detailed user manual because I am really pushed for time right now.
I wasn't really asking for a tutorial (more like.. (1)you do this (2)this happens like so.. (3)then it does this), to get a clearer idea of how it works/what it does, so don't go out of your way to write a lengthy tut' on my behalf, the demo will be more than enough to grasp it :wink:

I haven't had chance to download it yet, but I'll give it a go.. it sounds promising. I usually write my own undo/redo, because as you said, it really depends on the needs of the app, but this might save time keeping track of undo states etc..
Innesoft - The Software Marketplace - Innesoft Blog
» Applications, Educational Software, Casual Games
Post Reply