beginNewTransaction and Values


#1

I’m setting values and I’ve assigned an undoManager. Problem is, every time I undo, everything since the last beginNewTransaction undoes, not just the last user action.

I think that I only need to use beginNewTransaction when I am setting parameters via code - it seems like everything a control sets should always call beginNewTransaction, or we need a better way to group transactions.

Is there a common workaround to this?

Bruce


#2

I usually start a timer for maybe 1 second when a change is made, and let the timer start a new transaction. That way streams of continuous changes keep restarting the timer, and only when the user pauses does a transaction get registered.


#3

Hmm. But even then some user actions will get lumped together that they may not want?

Wouldn’t you say this seems like a bodge, and that it’s extra work (and timer and code execution) for the 90%, where the 10% is cases where actions need to be undone or done together?

Wouldn’t an ‘end transaction’ or similar work better?

Bruce

Edit - plus if I have different values, I’m going to be scattering timers and begins around my code so that any of them will trigger a begin.


#4

No, it’s not a bodge! I’d say it’s exactly what you expect to happen - lump together events that happen in quick succession, and have transactions when there’s a pause in activity. Your use-case may be different, but this pattern has always worked very well for things I’ve done.


#5

So… if I wait for a pause in activity, then start a new transaction, what does the next undo get? The previous transaction?


#6

FYI - a begintransaction with “” instead of String::empty seems to bork the system. Maybe an assertion is needed?


#7

Yes, if you haven’t added any UndoableActions to the current transaction. Otherwise the current transaction will be undone.

I presume this is why you need to specify the name at the start of the transaction, there is no real end to a transaction, just current and previous (unless you’ve already undone some that can then be redone of course.)


#8

I can’t see how that could possibly be the case… String::empty and “” are exactly equivalent when passed to that method. When you say it broke, what actually happened, and in what context?


#9

When I used “” no undo’s happened, and changing to empty fixed it. Could that maybe affect the canUndo () that I was using to enable the command?


#10

No… I really think you must be mis-diagnosing that one - there’s no way it could behave any differently.


#11

Yes, I guess I was. Undo is now intermittant - sometimes new actions don’t seem undoable, it varies from run to run. At a guess, some values don’t have the undomanager, or something crazy, but that’s almost impossible - it’s set from a global shared variable (yeah yeah).

Will have to dig.

Bruce


#12

Hi Bruce. Any chance your undo transaction is causing an undoable action to occur? It’s been awhile since I ran into the problem so I might not be recalling exactly but I do recall having a situation where undoing would cause a valuetree listener to be invoked which would then perform an undoable action, which subsequently borked the undo state. Maybe you have something like that happening?


#13

Well, it’s all Values, using the juce controls having their Value linked to my Values. And yes, there’s ValueTree::Listeners - that’s the point in this design, to do something when the user moves a control.

I’ll look for that issue - Undoable actions wrecking the undo state, thanks Graeme.

I thought I was using this all for its intended purpose. :x

Bruce


#14

Well UndoManager::perform does have a reentrancy check for catching what I described, and a simple test here verifies that it does work. If there was a bug with it I would have reported it so in my case it’s unlikely that there was a failure of that. But it was something like I described anyway, I’m sorry I can’t remember exactly what it was.


#15

Thanks. I’ll look. I need to work out some vagaries of Values anyway. They’re deceptively simple, until something is odd.