How to implement 'undo' feature

I am lazy :sunglasses:

Thanks for posting. I hadn’t considered undo, looks like my Polygene randomize channel button needs the special treatment.

Undo doesn’t undo context menu changes either? Is that something module developers should be handling, or a VCV ‘feature’? I can’t find any module that can undo a context menu change.

The Seq++ stuff might need looking at again. Undoing Rec and Scroll works, but Run doesn’t. Whilst VCV does know about ‘insert note’ actually running undo doesn’t update the display. I’ll file a bug - I’m using latest source builds for everything so could be a regression.

1 Like

Just make your context menu entry a parameter, then undo works out of the box and the state also get saved out of the box (no noodling with json needed). This only works for numeric values.

1 Like

@ Ahornberg , thanks for the code. It is a starting point I need!


Actually that is why I’m confused. Calling following line with an onHoverKey shortkey the change is added to the undo-list.

params[SEQ_1_VOLTAGE_PARAM+k].setValue(abs(1-params[SEQ_1_VOLTAGE_PARAM+k].getValue()));

But if I call following line with a similar onHoverKey shortkey then it’s ignored by the automatic history list.

params[STEPS_PARAM].setValue(rand() % 7 + 2);

May you post both onHoverKey() methods completely?

Relevant parts are

  • line 266 onHoverKey calls
  • line 63 invKnob (pressing ‘i’)
  • line 70 rndKnob (pressing ‘r’)

I downloaded and compiled your code and gave it a test-drive: Whatever hotkey I use, nothing is pushed to the history.

I think, you want to recall the complete state before changing the values from a bunch of knobs, so ComplexAction will be your friend here.

2 Likes

I would suspect there are a lot of modules that don’t have proper undo. As @Ahornberg points out, the only thing you get for free is parameter changes. Which is enough for a majority of module, but there are a bunch that require more.

I remember @clone45 mentioned that Voxglitch modules don’t use parameters. Looks like undo doesn’t work on them.

Primarily out of curiosity, parameter changes via CV do not go into undo, do they?

no, the stuff in VCV is in the param widget class (I now see). Which is probably good - I don’t think you would want a CV change to be “undoable” - it wouldn’t even really make sense. But turning a knob, adding/removing a module, patching… Those things are undoable.

1 Like

Exactly. The only reason I ask is that there is still a bug in Rack (I believe) that may involve, undo history, autosave, selection files, editing and “reset” in some very deep manner that eludes me as well as a couple of others who have dug into this.

Here is a question that I am interested in. Which actions reset (clear) the undo history? Is there any way to manually reset the undo history?

not 100% sure, but a quick look at the rack code and I think loading a new patch clears the undo history?

This is an important question for me. If I work on a single patch for quite a while through multiple actions, does the undo history just grow larger and larger? There is some circumstantial evidence that this is the case. What happens if the user reloads the current patch? Does this clear the history.

I’m also concerned that there is also circumstantial evidence that history related crashes may be aggravated (or caused) by some plugins or modules. Is everyone who is developing module undo management doing so correctly?

I know this is off-topic, but, I think these are valid questions.

How is the undo history maintained? Is it part of the patch file, or is it a json file and if so, at what level? Or is it something else entirely?

I am very concerned about “complex actions” history, such as with selection files as well as select and copy or duplicate for multiple modules and cables, as well as deletes.

1 Like

undo is stored in memory. As far as i know it just grows and grows.

Its not part of the patch file, there’s no way to serialise it from memory to persistent storage.

Its possible to get it very wrong, so there could be modules which have faulty undo management.

A “complex action” in this context is just a collection of smaller undo actions which are either undone or redone together. What concerns you about them?

1 Like

but remember “undo” and “redo” only happen if the user uses undo and redo. So even if my fully custom action has a faulty undo or redo, they won’t run unless the user does it intentionally. I guess an exception would be your destructor. Presumably all actions get “destroyed” when you load a new patch?

fwiw, every modern app that I’ve worked on keeps undo in memory “forever”. And on a modern OS you never run out of memory and crash, you start paging and the programs gets sluggish.

Most actions are tinny. The ones in my sequencer could potentially have a copy of every note (if you select all and delete I’m going to save off all those notes first).

Just that it seems that crashes sometimes seem to occur while editing patches after a selection file has bee loaded or deleting a selection. But, it is hard to tell. I’ve had a couple of very knowledgeable developers help me on this problem, but even under debug, they were not able to trace what was causing the crashes, even though with one of the developers, I produced a test patch that was pretty much guaranteed to crash on the n-th reset to modules.

But, this is off topic. I’ve taken this mentioned crash as far as I am willing to take it. It seems very deep and insidious to me.

Does this imply that the undo history is only kept for the current patch execution and that any load or reload clears the history?

Unfortunately yes, just try it out.