Go Back   Cockos Incorporated Forums > REAPER Forums > ReaScript, JSFX, REAPER Plug-in Extensions, Developer Forum

Reply
 
Thread Tools Display Modes
Old 05-23-2018, 10:09 AM   #1
Thonex
Human being with feelings
 
Join Date: May 2018
Location: Los Angeles
Posts: 1,721
Default Question re: Lua Parsing User Inputs and persistent variables

Hello scripters,

I have 2 questions... and could really use some guidance...

Question 1:

I'm having a tough time wrapping my head around parsing the comma delimited Input strings in Reaper. In the code example below, what would be the simplest code to read the "1, 2, 3" after the user clicks OK on the input box?



Say I wanted to parse the data and end up with something like this:

Var_Field1 = 1
Var_Field2 = 2
Var_Field3 = 3

Or maybe even something like this would be easier like my attempt in the code?

t = {}
t[1] = 1
t[2] = 2
t[3] = 3


Here's my example code... I used (what I thought was simple) code I found as a split string function... and keep getting nil values for the string when I Msg(t[i]):

Code:
function Msg (param)
  reaper.ShowConsoleMsg(tostring (param).."\n")
end

function mysplit(inputstr, sep)
    if sep == nil then
            sep = "%s"
    end
    local t={} ; i=1
    for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
            t[i] = str      
            i = i + 1
    Msg(t[i])        
    end
        
end

function MAIN()
    reaper.ClearConsole()
    
    retval, retvals_csv = reaper.GetUserInputs( "Test", 3,"Field 1,Field 2,Field 3", "1,2,3" )
     
    Msg(retvals_csv)
     
    mysplit(retvals_csv,",")

end


MAIN()
Question 2:

My second question is regarding Lua Reascript Persistent Variables (and it's also related to User Input)... is there a way to make the user inputs persistent from the previous time "OK" was clicked? So if I have a script I need the same values on over and over on the same day, I don't need to re-type those values in... but on occasion I could edit those fields when needed?

Any guidance would be hugely appreciated.

Thanks in advance.

Cheers,

Andrew K

Last edited by Thonex; 05-23-2018 at 10:36 AM.
Thonex is offline   Reply With Quote
Old 05-23-2018, 11:07 AM   #2
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

1. You're incrementing i before you read the table, so [i]t is looking for a table slot that doesn't exist. Swap them around, problem solved.

However, you don't actually need to use i at all. As long as you're putting the values into contiguous slots (that is, 1 2 3 4 5 6... and not 1 5 6 8 ...) you can just use the table length (#) - t[#t+1] = str.

2. Storing values from one instance of the script to the next can be done by writing directly to a file (good for lots of data, or scripts with a lot of settings like Radial Menu), or with ExtStates. The API can save/load ExtStates in (I think) reaper-extstates.ini, or directly in project .rpps with the equivalent ProjectExtState functions.

Code:
function Msg (param)
  reaper.ShowConsoleMsg(tostring (param).."\n")
end

local vals = {}

function set_ext_state()
    
    local str = table.concat(vals, ",")
    --                  Section (script name)   Item name  Val.  Keep when Reaper is closed
    reaper.SetExtState("Andrew K GetUserInputs", "Values", str, true)
    
end

function get_ext_state()
   
    local str = reaper.GetExtState("Andrew K GetUserInputs", "Values")
    
    if str and str ~= "" then
        vals = mysplit(str, ",")
    end
    
end

function mysplit(inputstr, sep)
    if sep == nil then
            sep = "%s"
    end
    local t={}
    for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
            t[#t+1] = str      
    end
    
    Msg(t[#t])
    
    return t
end


function MAIN()
    reaper.ClearConsole()
    
    -- Load the values
    get_ext_state()
    
    local val_str
    if #vals == 0 then
        val_str = "1,2,3"
    else
        --        Returns a contiguous table as a string using the second
        --        as a separator
        val_str = table.concat(vals, ",")
    end
    
    retval, retvals_csv = reaper.GetUserInputs( "Test", 3,"Field 1,Field 2,Field 3", val_str )
    
    -- Don't try to split the CSV if the user pressed Cancel
    if not retval then break end
    
    Msg(retvals_csv)
    
    vals = mysplit(retvals_csv,",")

    -- Store the values
    set_ext_state()

end


MAIN()
__________________
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 05-23-2018, 11:51 AM   #3
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,900
Default

2. there is also the solution to write the value to an external file the script looks for when populating the user input popup.
X-Raym is offline   Reply With Quote
Old 05-23-2018, 12:06 PM   #4
Thonex
Human being with feelings
 
Join Date: May 2018
Location: Los Angeles
Posts: 1,721
Default

Quote:
Originally Posted by Lokasenna View Post
1. You're incrementing i before you read the table, so [i]t is looking for a table slot that doesn't exist. Swap them around, problem solved.
Arrrggggggg!!!! Dammit. How stupid of me! Jesus LOL Thanks Lokasenna...

And I'll look further into your length (#) - t[#t+1] = str example.

Regrettably, I know I will have to learn the file system or your ExtStates examples. As I'm getting more and more into reaper, the ability to call variables from disk as persistent vars WAY better in the long run than typing values over and over again.

Thanks again Lokasenna!!

Cheers,

Andrew K
Thonex is offline   Reply With Quote
Old 05-23-2018, 12:08 PM   #5
Thonex
Human being with feelings
 
Join Date: May 2018
Location: Los Angeles
Posts: 1,721
Default

Quote:
Originally Posted by X-Raym View Post
2. there is also the solution to write the value to an external file the script looks for when populating the user input popup.
Hi X-Raym,

Do you have a link for a simple Realscript function for that (Lua based)?

Maybe there isn't a "simple" way to do this?

Cheers,

Andrew K
Thonex is offline   Reply With Quote
Old 05-23-2018, 12:15 PM   #6
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

ExtStates are easy as hell - look at the code I pasted above.

You don't need to store anything on disk while the script is running - just to have them saved when the script is finished and loaded the next time it's run. My code above stores the values that were entered to a table, and then uses that table to create the value string for GetUserInputs.
__________________
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 05-23-2018, 12:24 PM   #7
Thonex
Human being with feelings
 
Join Date: May 2018
Location: Los Angeles
Posts: 1,721
Default

Quote:
Originally Posted by Lokasenna View Post
ExtStates. The API can save/load ExtStates in (I think) reaper-extstates.ini, or directly in project .rpps with the equivalent ProjectExtState functions.
Just tried it... BRILLIANT!!

Now... I just need to make sure I "really" understand what's going on. I too used to KSP LOL

Thanks again!
Thonex is offline   Reply With Quote
Old 05-23-2018, 01:51 PM   #8
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

There's not a lot to it; if you've ever programmed anything for Windows, it's the same idea as GetPrivateProfileString - you're just reading and writing key + value pairs to an .ini file. In this case, Reaper/Resources/reaper-extstate.ini is there specifically as a place for scripts to store their data. Here's part of mine:

Code:
[HeDaScriptsManager]
DOCK=0.0
LATESTDOCK=0.0
WINW=700.0
WINH=680.0
WINX=460.0
WINY=200.0
[Lokasenna_Copy values from selected midi notes]
Options=5,2,3
Options2=1
Window=1028.0,381.0
[Andrew K GetUserInputs]
Values=5,6
- Everything is stored and loaded as a string. If you try to load a value that isn't there, GetExtState will return a blank string rather than nil - thus why my code above checks for str ~= "" before trying to do anything.

- Sections can be named whatever you want. It makes the most sense to have the name match your script though.

- You can store (AFAIK) as many values as you like, or you can have the script combine everything into one string. It doesn't matter. In my head, at least, the latter approach seems like better manners as you aren't cluttering up the file with a million keys.
__________________
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 05-23-2018, 02:40 PM   #9
Thonex
Human being with feelings
 
Join Date: May 2018
Location: Los Angeles
Posts: 1,721
Default

@Lokasenna - Thanks man. Implementation seems very easy... that's the most important part for me at the moment. Good to know about the name referencing the script name.

Ok last question... If I'm careful with naming , does this mean I can share variables across scripts? That could be handy.

Cheers,

Andrew K
Thonex is offline   Reply With Quote
Old 05-23-2018, 02:54 PM   #10
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

Absolutely. The .ini is there for all to see. For instance, with my GUI I could theoretically let people customize the colors with a script, store them there, and have every GUI script check for user colors on startup.

You could also do something like this:
Code:
[Andrew K Scripts]
Script1 values=1,2,3,4
Script2 values=a,b,c,d,e
Script3 values=875.23
The .ini is accessible and therefore writeable by any script; there's concept of permissions or visibility.
__________________
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 05-23-2018, 03:38 PM   #11
Thonex
Human being with feelings
 
Join Date: May 2018
Location: Los Angeles
Posts: 1,721
Default

Quote:
Originally Posted by Lokasenna View Post
Absolutely. The .ini is there for all to see. For instance, with my GUI I could theoretically let people customize the colors with a script, store them there, and have every GUI script check for user colors on startup.

You could also do something like this:
Code:
[Andrew K Scripts]
Script1 values=1,2,3,4
Script2 values=a,b,c,d,e
Script3 values=875.23
The .ini is accessible and therefore writeable by any script; there's concept of permissions or visibility.

Thanks so much for all of this.

Now I have to slowly digest it so I don't forget it by tomorrow. I tend to have a very narrow scope to what I do. So I learn what I need to learn... do it and move on. Then when it comes time again... I have to relearn it LOL

Cheers,

Andrew K
Thonex is offline   Reply With Quote
Old 05-23-2018, 04:00 PM   #12
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

I'm certainly no stranger to Googling something and finding an answer... from three years earlier... from myself.
__________________
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 05-24-2018, 10:04 AM   #13
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,629
Default

If you need only these three numbers, you can use:

Code:
number1, number2, number3 = retvals_csv:match("(.-),(.-),(.*)")
You may in some cases need to convert the number-variables to datatype numbers with

Code:
  number1=tonumber(number1)
  number2=tonumber(number2)
  number3=tonumber(number3)
This is the easiest way to get all three numbers.

Keep in mind: GetUserInputs has a problem with commas(,) input in the inputfields. It does not escape them, so when someone inputs into the fields

1,1
2
9,2

the retvals_csv will be "1,1,2,9,2" which is impossible to parse out, as you can't know, which comma is part of the number, which is the csv-separator.
Meo-Ada Mespotine is offline   Reply With Quote
Old 05-24-2018, 12:21 PM   #14
Thonex
Human being with feelings
 
Join Date: May 2018
Location: Los Angeles
Posts: 1,721
Default

Quote:
Originally Posted by mespotine View Post
You may in some cases need to convert the number-variables to datatype numbers with

Code:
  number1=tonumber(number1)
  number2=tonumber(number2)
  number3=tonumber(number3)
This is the easiest way to get all three numbers.

Keep in mind: GetUserInputs has a problem with commas(,) input in the inputfields. It does not escape them, so when someone inputs into the fields

1,1
2
9,2

the retvals_csv will be "1,1,2,9,2" which is impossible to parse out, as you can't know, which comma is part of the number, which is the csv-separator.
Thanks mespotine!


Yeah... I noticed rather quickly that I was getting nil errors or similar... I had a hunch that I needed to convert the "text" var to a number. tonumber is what I found online I and bingo... everything started to work more predictably.

Thanks a ton for the comma heads-up... I am bad typist so that may save me some head scratching in the future.

Oh... and thanks for this little gem:

Code:
number1, number2, number3 = retvals_csv:match("(.-),(.-),(.*)")
Cheers,

Andrew K
Thonex is offline   Reply With Quote
Old 05-24-2018, 01:00 PM   #15
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,900
Default

There is tons of user input scripts outthere and even trmplates on Reateam Templates repoyou shoul,
D take look, easier to mod these existing scripts than redoing everything some scratch (especially sanitization etc).
X-Raym is offline   Reply With Quote
Old 05-25-2018, 01:29 PM   #16
Thonex
Human being with feelings
 
Join Date: May 2018
Location: Los Angeles
Posts: 1,721
Default

Quote:
Originally Posted by X-Raym View Post
There is tons of user input scripts outthere and even trmplates on Reateam Templates repoyou shoul,
D take look, easier to mod these existing scripts than redoing everything some scratch (especially sanitization etc).
Thanks X-Raym.

Not exactly sure which repo... this one?

https://github.com/ReaTeam/ReaScripts-Templates

Cheers,

Andrew K
Thonex 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 10:36 AM.


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