Old 03-08-2017, 03:37 PM   #1
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,451
Default Reaper Lua: Why this does not work?

I am puzzled... Please, have a look at this code:

Code:
function Prerequisites()
 local ok = 0
 local seltracks = reaper.CountSelectedTracks( 0 )
 if seltracks == 1 then
  local track = reaper.GetSelectedTrack( 0, 0 )
  local parent_folder = reaper.GetParentTrack( track )
  local item_count = reaper.CountSelectedMediaItems( 0 )
  local i = 0
  if item_count > 0 then
   for i=0, item_count-1, 1 do
    local sel_item =  reaper.GetSelectedMediaItem( 0, i )
    local parent_track = reaper.GetMediaItem_Track( sel_item)
    if parent_track == track then ok = 1
    end
   end
  end
 end
return ok, parent_folder, track
end

ok, parent_folder, track = Prerequisites()
For some reason it returns only variable ok. If I delete all the "local", then all three variables are returned.

Could someone knowledgeable explain it to me because I cannot get it! :S Thank you!
__________________
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 03-08-2017, 04:13 PM   #2
cfillion
Human being with feelings
 
cfillion's Avatar
 
Join Date: May 2015
Location: Québec, Canada
Posts: 4,937
Default

As stated on the Lua website: "Unlike global variables, local variables have their scope limited to the block where they are declared" (https://www.lua.org/pil/4.2.html).

Declare the variables outside of the `if` block to have their scope limited to the whole function rather than only to the condition:

Code:
function Prerequisites()
  local ok, track, parent_folder = 0

  if seltracks == 1 then
    -- the following line uses the `track` local variable declared above
    track = reaper.GetSelectedTrack( 0, 0 )
    parent_folder = reaper.GetParentTrack( track )
    -- ...
  end

  return ok, parent_folder, track
end
https://www.lua.org/manual/5.3/manual.html#3.5

Last edited by cfillion; 03-08-2017 at 04:26 PM.
cfillion is offline   Reply With Quote
Old 03-08-2017, 04:15 PM   #3
Sexan
Human being with feelings
 
Sexan's Avatar
 
Join Date: Jun 2009
Location: Croatia
Posts: 4,605
Default

Code:
function Prerequisites()
local parent_folder,track  ----- this
 local ok = 0  
 local seltracks = reaper.CountSelectedTracks( 0 )
 if seltracks == 1 then
  track = reaper.GetSelectedTrack( 0, 0 ) ----- this
  parent_folder = reaper.GetParentTrack( track ) ----- this
  local item_count = reaper.CountSelectedMediaItems( 0 )
  if item_count > 0 then
   for i=0, item_count-1, 1 do
    local sel_item =  reaper.GetSelectedMediaItem( 0, i )
    local parent_track = reaper.GetMediaItem_Track( sel_item)
    if parent_track == track then ok = 1
    end
   end
  end
 end
return ok, parent_folder, track
end

ok, parent_folder, track = Prerequisites()
when you use "local" in the loop (if,for,etc) it stays only there and you cannot access it outside that loop.
if you need to access them you can define them on top and then you can access them from anywhere

EDIT: oh... cfillion was faster
Sexan is online now   Reply With Quote
Old 03-08-2017, 04:49 PM   #4
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,451
Default

Thank you both for your replies!

Ok! Now I get it! I didn't know that a variable could be local to a block etc.. I thought that by declaring them local anywhere in the function, they would be local to that function
__________________
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 03-08-2017, 05:00 PM   #5
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

If you wanted to, for some reason, you could even do this:

Code:
do

  local blah = 5

  ...do stuff...

end
just to limit the scope of a variable. I don't know why you would need to, but there you go.
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 03-08-2017, 06:10 PM   #6
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,451
Default

I can't understand this last one.. hmm :?
__________________
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 03-08-2017, 06:43 PM   #7
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

You can make a block that does nothing specific, as opposed to being an if/then, for, or do while - it's just a block with its own scope.
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 03-08-2017, 06:48 PM   #8
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,451
Default

Ok, understood now! Thank you!

I am trying to do something different now, but I think my brain has stopped working.. :S .. How could I check if all selected items belong to the same track? It doesn't matter if there are any tracks selected or not, how many are selected, etc. What it matters is that all selected media items belong to the same track

I am up to here:
Code:
function Prerequisites()
 local parent_folder
 local ok = 0
 local item_count = reaper.CountSelectedMediaItems( 0 )
 if item_count > 0 then local i
  for i=0, item_count-1, 1 do
   local sel_item =  reaper.GetSelectedMediaItem( 0, i )
   local item_track = reaper.GetMediaItem_Track( sel_item ) 
  
 end
 return ok, parent_folder
end
__________________
Most of my scripts can be found in ReaPack.
If you find them useful, a donation would be greatly appreciated! Thank you! :)

Last edited by amagalma; 03-08-2017 at 06:54 PM.
amagalma is offline   Reply With Quote
Old 03-09-2017, 04:05 AM   #9
Sexan
Human being with feelings
 
Sexan's Avatar
 
Join Date: Jun 2009
Location: Croatia
Posts: 4,605
Default

Code:
function Prerequisites()
  local parent_folder,reference,check
  local track = {}
  local item_count = reaper.CountSelectedMediaItems( 0 )
 
  if item_count > 0 then
    for i=0, item_count-1 do
      local sel_item =  reaper.GetSelectedMediaItem( 0, i )       
      local item_track = reaper.GetMediaItem_Track( sel_item )
      
      -- add all tracks to table for checking
      track[#track+1] = item_track
      
      -- set first items track as reference track for checking
      reference = track[1]
      
      for j = 0 , #track do
        
        -- if reference track is same for all items
        if reference == item_track then
          
          -- items belong to same track
          check = true                
        else
          
          -- items are on different tracks
          check = false
        end
      end
        
    end
  end
  return ok, parent_folder ,check
end

ok,parent,check = Prerequisites()
Sexan is online now   Reply With Quote
Old 03-09-2017, 05:56 AM   #10
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

@Sexan
Maybe something more like this could be effective :P

Code:
function Prerequisites()
 local parent_folder
 local ok = true -- Init with True
 local item_count = reaper.CountSelectedMediaItems( 0 )
 if item_count > 1 then
  local track_id = -1 -- Init Variable
  local previous_track_id = -1 -- Init Variable
  ok = true
  for i=0, item_count-1 do
   local sel_item =  reaper.GetSelectedMediaItem( 0, i )
   local item_track = reaper.GetMediaItem_Track( sel_item )
   track_id =  reaper.GetMediaTrackInfo_Value( item_track, "IP_TRACKNUMBER")
   if track_id ~= previous_track_id and track_id > -1 then
     ok = false
     break
   end
   previous_track_id = track_id
 end
 return ok, parent_folder
end
Untested, but the main idea is to NOT store all tracks in a table, but to compare track_id one two by two and breaks as soon as it doesn't fit the condition.
X-Raym is offline   Reply With Quote
Old 03-09-2017, 06:00 AM   #11
Sexan
Human being with feelings
 
Sexan's Avatar
 
Join Date: Jun 2009
Location: Croatia
Posts: 4,605
Default

Yep thats better! did not think much while I was writing that
Sexan is online now   Reply With Quote
Old 03-09-2017, 06:35 AM   #12
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,451
Default

Thank you both of you guys for your help!

I am going to test and study the code and come back with questions regarding things that I didn't understand/do not know..

(I apologize for the many questions, but I have never had any experience with coding and I am trying to understand a bit by reverse-engineering codes of other people )
__________________
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 03-09-2017, 09:58 AM   #13
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,451
Default

Quote:
Originally Posted by X-Raym View Post
@Sexan
Maybe something more like this could be effective :P

Code:
function Prerequisites()
 local parent_folder
 local ok = true -- Init with True
 local item_count = reaper.CountSelectedMediaItems( 0 )
 if item_count > 1 then
  local track_id = -1 -- Init Variable
  local previous_track_id = -1 -- Init Variable
  ok = true
  for i=0, item_count-1 do
   local sel_item =  reaper.GetSelectedMediaItem( 0, i )
   local item_track = reaper.GetMediaItem_Track( sel_item )
   track_id =  reaper.GetMediaTrackInfo_Value( item_track, "IP_TRACKNUMBER")
   if track_id ~= previous_track_id and track_id > -1 then
     ok = false
     break
   end
   previous_track_id = track_id
 end
 return ok, parent_folder
end
Untested, but the main idea is to NOT store all tracks in a table, but to compare track_id one two by two and breaks as soon as it doesn't fit the condition.
I tested it and it does not work correctly.. It fails when it gets the very first selected item's track_id here:
Code:
  if track_id ~= previous_track_id and track_id > -1 then
     ok = false
     break
The previous_track_id was set to -1 when initialized and the track_id of the very first item is going to be different

Also, with no items selected, ok is true too..
__________________
Most of my scripts can be found in ReaPack.
If you find them useful, a donation would be greatly appreciated! Thank you! :)

Last edited by amagalma; 03-09-2017 at 10:24 AM.
amagalma is offline   Reply With Quote
Old 03-09-2017, 10:23 AM   #14
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,451
Default

This code seems to work:

Code:
function Prerequisites()
local parent_folder, item_track
  local ok = 2 
  local item_count = reaper.CountSelectedMediaItems( 0 )
 if item_count > 0 then
   local track_id = -1 
   local previous_track_id = -1
  for i=0, item_count-1 do
    local sel_item =  reaper.GetSelectedMediaItem( 0, i )
    item_track = reaper.GetMediaItem_Track( sel_item )
   local track_id = reaper.GetMediaTrackInfo_Value( item_track, "IP_TRACKNUMBER")
   if track_id ~= previous_track_id then
     ok = ok-1
     if ok ~= 1 then ok = false break end
   end
   previous_track_id = track_id
  end
 else
  ok = false 
 end
 if ok == 1 then 
  parent_folder = reaper.GetParentTrack( item_track )
  ok = true
 end
 return ok, parent_folder
end
P.S Added (correctly I hope) the needed "local"
__________________
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 03-09-2017, 10:38 AM   #15
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,451
Default

Hmm, it seems that with this version, I have not taken into account when all items belong to a track that is not a child. In that case I would like ok=false but with this code ok=true...
__________________
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 03-09-2017, 11:06 AM   #16
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,451
Default

This does it:

Code:
function msg(str)
reaper.ShowConsoleMsg(str.."\n")
end

function Prerequisites()
local parent_folder, item_track
  local ok = 2 
  local item_count = reaper.CountSelectedMediaItems( 0 )
 if item_count > 0 then
   local track_id = -1 
   local previous_track_id = -1
  for i=0, item_count-1 do
    local sel_item =  reaper.GetSelectedMediaItem( 0, i )
    item_track = reaper.GetMediaItem_Track( sel_item )
   local track_id = reaper.GetMediaTrackInfo_Value( item_track, "IP_TRACKNUMBER")
   if track_id ~= previous_track_id then
     ok = ok-1 ; msg("this was checked")
     if ok ~= 1 then ok = false ; msg("items on different tracks") break end 
   end
   previous_track_id = track_id
  end
 else
  ok = false ; msg("no items selected") 
 end
 if ok == 1 then parent_folder = reaper.GetParentTrack( item_track )  
  if parent_folder ~= nil then ok = true msg("all items belong to a child track") else ok = false msg("track not a child") end 
 end
 return ok, parent_folder
end

reaper.ClearConsole()
ok, parent_folder = Prerequisites()
__________________
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 07:06 AM.


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