Old 12-17-2018, 01:38 PM   #1
Mordi
Human being with feelings
 
Mordi's Avatar
 
Join Date: May 2014
Location: Norway
Posts: 982
Default Clean way of getting a list of selected items' tracks?

I want to get an array of tracks that have selected items on them. Here's how I go about it right now:

Code:
-- Get number of selected items
item_count = reaper.CountSelectedMediaItems()

-- Get array of tracks with selected items on them
  unique_tracks = {}
  index = 0
  for i=0, item_count-1 do
  
    -- Get media item
    item = reaper.GetSelectedMediaItem(0, i)
    
    -- Get track
    track = reaper.GetMediaItemTrack(item)
    
    shouldAdd = true;
    for n=0, #unique_tracks do
      if track==unique_tracks[n] then
        shouldAdd = false
      end
    end
    
    if shouldAdd then
      unique_tracks[index] = track
      index = index + 1
    end
  end
Is there a cleaner way of doing this?
Mordi is offline   Reply With Quote
Old 12-17-2018, 05:04 PM   #2
Edgemeal
Human being with feelings
 
Edgemeal's Avatar
 
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 3,913
Default

After the line, shouldAdd = false ,you should call break since you no longer need to keep looping.

Its always interesting to see how people code things, my $0.02,.

Code:
unique_tracks = {}
for i = 0, reaper.CountTracks()-1 do
  track = reaper.GetTrack(0, i) 
  for j = 0, reaper.CountTrackMediaItems(track)-1 do
    if reaper.IsMediaItemSelected(reaper.GetTrackMediaItem(track, j)) then
      unique_tracks[#unique_tracks+1] = track
      break
    end
  end
end
I'd want the fastest code possible, but have no clue how you benchmark code in ReaScript.

Last edited by Edgemeal; 12-17-2018 at 05:12 PM.
Edgemeal is offline   Reply With Quote
Old 12-17-2018, 09:39 PM   #3
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

Code:
init_time = reaper.time_precise()




code




duration = reaper.time_precise() - init_time

:P


For very fast code it may be intersting to wrap that in a 1000 timed loop or higher.
X-Raym is offline   Reply With Quote
Old 12-17-2018, 09:44 PM   #4
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

@edgemeal
Your loops limit call an API function everytime they run. You should store limit in variable instead if it doesnt change within the loop.



Loops limit are in fact a condition check




see this : https://www.tutorialspoint.com/lua/lua_for_loop.htm
X-Raym is offline   Reply With Quote
Old 12-17-2018, 10:37 PM   #5
Edgemeal
Human being with feelings
 
Edgemeal's Avatar
 
Join Date: Apr 2016
Location: ASU`ogacihC
Posts: 3,913
Default

Quote:
Originally Posted by X-Raym View Post
@edgemeal
Your loops limit call an API function everytime they run. You should store limit in variable instead if it doesnt change within the loop.
Thanks for the reaper.time_precise tip, will have to give a try.

Better?...
Code:
unique_tracks = {}
trackcount = reaper.CountTracks()-1

for i = 0, trackcount do
  track = reaper.GetTrack(0, i) 
  itemcount = reaper.CountTrackMediaItems(track)-1
  for j = 0, itemcount do
    if reaper.IsMediaItemSelected(reaper.GetTrackMediaItem(track, j)) then
      unique_tracks[#unique_tracks+1] = track
      break
    end
  end
end
Edgemeal is offline   Reply With Quote
Old 12-18-2018, 03:50 AM   #6
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

@Edgemeal
Better :P


But is there is less selected items than selected tracks, you should loop in selected items instead :P
X-Raym is offline   Reply With Quote
Old 12-18-2018, 12:51 PM   #7
Mordi
Human being with feelings
 
Mordi's Avatar
 
Join Date: May 2014
Location: Norway
Posts: 982
Default

Hey, you made it way cleaner, and leaner. Thanks!

I think I discovered a bug. It seemed that the unique_tracks index went from 1 and up, instead of 0.

Code:
unique_tracks = {}
trackcount = reaper.CountTracks()-1

for i = 0, trackcount do
  track = reaper.GetTrack(0, i) 
  itemcount = reaper.CountTrackMediaItems(track)-1
  for j = 0, itemcount do
    if reaper.IsMediaItemSelected(reaper.GetTrackMediaItem(track, j)) then
      unique_tracks[#unique_tracks] = track
      break
    end
  end
end

Last edited by Mordi; 12-18-2018 at 01:20 PM.
Mordi is offline   Reply With Quote
Old 12-18-2018, 01:35 PM   #8
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,451
Default

Code:
unique_tracks[#unique_tracks] = track
This is wrong. This way you will only get the last track.
Why don't you want the index to start from 1?

Anyway, if you want it to start from 0, then do this:

Code:
unique_tracks = {}
trackcount = reaper.CountTracks()-1
index = -1
for i = 0, trackcount do
  track = reaper.GetTrack(0, i) 
  itemcount = reaper.CountTrackMediaItems(track)-1
  for j = 0, itemcount do
    if reaper.IsMediaItemSelected(reaper.GetTrackMediaItem(track, j)) then
      index = index + 1
      unique_tracks[index] = track
      break
    end
  end
end
But I see no reason for doing it...
__________________
Most of my scripts can be found in ReaPack.
If you find them useful, a donation would be greatly appreciated! Thank you! :)
amagalma is offline   Reply With Quote
Old 12-18-2018, 01:49 PM   #9
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

Indeed using an index variable is better cause # count the table entries everytime ! :P
X-Raym is offline   Reply With Quote
Old 12-19-2018, 01:39 PM   #10
Mordi
Human being with feelings
 
Mordi's Avatar
 
Join Date: May 2014
Location: Norway
Posts: 982
Default

Ah yes, I see that doesn't work... X-raym is right, using an index is actually more efficient.
Mordi is offline   Reply With Quote
Old 12-19-2018, 03:13 PM   #11
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,451
Default

Test code for comparison of efficiency:
Code:
local a, b, c = {}, {}, {}

local st = reaper.time_precise()
for i = 1, 10000000 do
  a[#a+1] = true
end
table_length_time = reaper.time_precise() - st

-------------------------------------------

local st2 = reaper.time_precise()
for i = 1, 10000000 do
  b[i] = true
end
direct_index_time = reaper.time_precise() - st2


-------------------------------------------

local index = 0
local st3 = reaper.time_precise()
for i = 1, 10000000 do
  c[index+1] = true
  index = index + 1
end
indirect_index_time = reaper.time_precise() - st3

-------------------------------------------

reaper.ShowConsoleMsg("table_length_time = " .. table_length_time .. "\n")
reaper.ShowConsoleMsg("direct_index_time = " .. direct_index_time .. "\n")
reaper.ShowConsoleMsg("indirect_index_time = " .. indirect_index_time .. "\n")

Result:
Code:
table_length_time = 2.2679390417907
direct_index_time = 0.6098485052571
indirect_index_time = 0.97423272924061
__________________
Most of my scripts can be found in ReaPack.
If you find them useful, a donation would be greatly appreciated! Thank you! :)
amagalma is offline   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 11:10 AM.


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