Old 10-18-2015, 02:22 PM   #1
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,509
Default No Undo point! "Defer"? How?

Hello!

I would like to run some custom actions and some cycle actions that I have created, but would like not to have any undo point created. I have heard that this could be possible with "defer", but how?

For example, could it be?:
function run()
(
Main_OnCommand(NamedCommandLookup("My action"), 0);
);
defer("run();");

Would this work?
amagalma is offline   Reply With Quote
Old 10-19-2015, 06:04 AM   #2
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,509
Default

Found this

How could I use it in my case?
amagalma is offline   Reply With Quote
Old 10-20-2015, 04:33 AM   #3
kenz
Human being with feelings
 
Join Date: Aug 2013
Posts: 339
Default

Why complicate matters with a function that runs in the background?

All you have to do is add this at the end (or similar):
Code:
function NoUndo()(abs(0)); defer("NoUndo()");
That is an empty function.

Here's a simple script that, for example, toggles MIDI Editor view on/off even if none of it is open yet:
Code:
MIDIEditor_GetActive() ? Main_OnCommand(40716, 0) : Main_OnCommand(40153, 0);

function NoUndo()(abs(0)); defer("NoUndo()");
You don't need any "run" function. Just insert any code and put that at the end.
kenz is offline   Reply With Quote
Old 10-20-2015, 11:25 AM   #4
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,509
Default

I've tried it but the cycle action still appears in my Undo History...

P.S. It seems to work with other actions except Cycle actions.. I think I have to translate my Cycle actions to scripts.. :/

Last edited by amagalma; 10-20-2015 at 11:33 AM.
amagalma is offline   Reply With Quote
Old 10-20-2015, 12:20 PM   #5
amagalma
Human being with feelings
 
Join Date: Apr 2011
Posts: 1,509
Default

Yay! At last! I can have my custom play/stop actions (cubase style) without flooding the undo history!! )))
amagalma is offline   Reply With Quote
Old 11-07-2015, 07:56 PM   #6
FnA
Human being with feelings
 
FnA's Avatar
 
Join Date: Jun 2012
Posts: 2,173
Default

Really? This is the secret then?

Surprised it hasn't generated more excitement.

Thanks...

I hope someday someone will explain defer for noobs.
FnA is offline   Reply With Quote
Old 02-17-2016, 11:35 AM   #7
Sju
Human being with feelings
 
Join Date: Jun 2015
Posts: 686
Default

*excited!*
Sju is offline   Reply With Quote
Old 01-22-2018, 07:49 PM   #8
_Stevie_
Human being with feelings
 
_Stevie_'s Avatar
 
Join Date: Oct 2017
Posts: 2,937
Default

I'm also super excited
However, this method does not seem to work with "reaper.ToggleTrackSendUIMute".
It automatically generates a "toggle send mute" entry in the undo history.
__________________
My Reascripts forum thread | My Reascripts on GitHub | Stephan Römer - film composer
If you wish to donate for my scripts: please consider an organization like: animal shelter, doctors without borders, UNICEF, etc...
_Stevie_ is offline   Reply With Quote
Old 01-22-2018, 09:53 PM   #9
FnA
Human being with feelings
 
FnA's Avatar
 
Join Date: Jun 2012
Posts: 2,173
Default

As you found in the other thread, there are a number of things like that. Csurf functions are another one. Even some selection mainoncommands.

I don't understand the undo mechanism, but it seems to be a bad idea to try to skirt undo points entirely for things like this. You might be able to with some other function, but it might switch to its previous state later when you undo something else.
FnA is offline   Reply With Quote
Old 01-23-2018, 07:58 AM   #10
_Stevie_
Human being with feelings
 
_Stevie_'s Avatar
 
Join Date: Oct 2017
Posts: 2,937
Default

I know what you mean, I won't force it, if it doesn't work.
It's just that I find it needless to clutter the undo history with
a "bypass sends" command
__________________
My Reascripts forum thread | My Reascripts on GitHub | Stephan Römer - film composer
If you wish to donate for my scripts: please consider an organization like: animal shelter, doctors without borders, UNICEF, etc...
_Stevie_ is offline   Reply With Quote
Old 01-23-2018, 08:51 AM   #11
FnA
Human being with feelings
 
FnA's Avatar
 
Join Date: Jun 2012
Posts: 2,173
Default

I have not tried it too many times, but it didn't work out when I did. One public example is in mehmethan's folder collapse script request. I thought it was worthless to have undo points for collapsing folders. But if I skipped them entirely, I found undoing a track volume change later might change the folders back to where they were before the script.

I suppose my previous post was too narrowly centered on one shot actions. It is proven useful in say a background script to reduce the number of points to a minimum. I think that's the whole reason it is the way it is. It's not the empty function that does it, it's the fact that the script includes defer. You could defer the whole main function. But I usually use this method, because I wonder if it might delay the execution speed of the main function, for instance in a macro where it needs to happen immediately.

So depending on what exactly you are up to, it might be possible to reduce the amount of points, but I recall a few complaints where even an undo block sandwich could not stop multiple points. I think that is kind of rare.

Maybe one of breeders functions or some other thingy might allow you to try to skip points for your example if you want to try for yourself. Can't check right now.
FnA is offline   Reply With Quote
Old 01-23-2018, 08:51 PM   #12
_Stevie_
Human being with feelings
 
_Stevie_'s Avatar
 
Join Date: Oct 2017
Posts: 2,937
Default

Valid points FnA!

The script I'm working on is actually very simple. It gets all sends on selected tracks and mutes them:

Code:
for i = 0, reaper.CountSelectedTracks(0)-1 do -- loop through all selected tracks
	track = reaper.GetSelectedTrack(0,i) -- save actual track to "track"
	if track then -- if track exists
		sends = reaper.GetTrackNumSends(track, 0) -- get amount of sends of selected track
		for i = 0, sends do
			reaper.ToggleTrackSendUIMute(track, i) -- toggle mute all sends
		end
	end
end
__________________
My Reascripts forum thread | My Reascripts on GitHub | Stephan Römer - film composer
If you wish to donate for my scripts: please consider an organization like: animal shelter, doctors without borders, UNICEF, etc...
_Stevie_ is offline   Reply With Quote
Old 01-23-2018, 08:58 PM   #13
cfillion
Human being with feelings
 
cfillion's Avatar
 
Join Date: May 2015
Location: Québec, Canada
Posts: 2,810
Default

SetTrackSendInfo_Value doesn't create undo points.

Code:
local track = reaper.GetTrack(0, 0)

local muted = 1 == reaper.GetTrackSendInfo_Value(track, 0, 0, 'B_MUTE')
reaper.SetTrackSendInfo_Value(track, 0, 0, 'B_MUTE', muted and 0 or 1)

reaper.defer(function() end)
cfillion is online now   Reply With Quote
Old 01-23-2018, 08:58 PM   #14
_Stevie_
Human being with feelings
 
_Stevie_'s Avatar
 
Join Date: Oct 2017
Posts: 2,937
Default

Tried that, same result
Both do not work with defer.
__________________
My Reascripts forum thread | My Reascripts on GitHub | Stephan Römer - film composer
If you wish to donate for my scripts: please consider an organization like: animal shelter, doctors without borders, UNICEF, etc...
_Stevie_ is offline   Reply With Quote
Old 01-23-2018, 10:29 PM   #15
FnA
Human being with feelings
 
FnA's Avatar
 
Join Date: Jun 2012
Posts: 2,173
Default

Well, you are both right.

I ran this on 2 tracks with 3 sends each. (for completeness, I think you need to put something in to check for hardware outputs and start your index after that for normal sends. Hm. Maybe not for every function. Something to double check...) With the "toggle" function (commented out), it makes 6 undo points right away. Some things appear to have something like UndoBlock or OnStateChange built in. In the form here with the uncommented function, it makes no undo point on execution, but after running it:

draw in 4 midi items
undo two of those
check sends: fine, still muted.
mute a track, undo that
check sends: not muted.

Code:
for i = 0, reaper.CountSelectedTracks(0)-1 do -- loop through all selected tracks
  track = reaper.GetSelectedTrack(0,i) -- save actual track to "track"
  if track then -- if track exists
    sends = reaper.GetTrackNumSends(track, 0) -- get amount of sends of selected track
    for i = 0, sends-1 do
      --reaper.ToggleTrackSendUIMute(track, i) -- toggle mute all sends
      reaper.SetTrackSendInfo_Value(track, 0, i, 'B_MUTE', muted and 0 or 1)
    end
  end
end

reaper.defer(function() end)

Last edited by FnA; 01-23-2018 at 11:43 PM.
FnA is offline   Reply With Quote
Old 10-28-2019, 06:08 AM   #16
lexaproductions
Human being with feelings
 
Join Date: Jan 2013
Posts: 431
Default

The thing with this "defer" trick is that if you run the script several times very quickly, you get the "Terminate running Script" dialog. This can be misleading to new user. Any ways to avoid this?
__________________
MP 12 Core 3.46GHZ 48GB OSX10.11.6, MBP 15" 2012 OSX10.12, RME Fireface UFX, MCU,
Reaper 5, SD2, Omnisphere, Wave Altiverb, PSP, VB3, Izotope, Scuffham, Soundtoys 5, Slate All Plugins.
lexaproductions is offline   Reply With Quote
Old 10-28-2019, 07:07 AM   #17
cfillion
Human being with feelings
 
cfillion's Avatar
 
Join Date: May 2015
Location: Québec, Canada
Posts: 2,810
Default

https://forum.cockos.com/showthread.php?p=2084802
cfillion is online now   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 12:40 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2019, vBulletin Solutions Inc.