Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

How to handle an unknown number of variables?

Rock Ryder
Registered User
Join date: 6 Oct 2006
Posts: 384
09-14-2007 06:09
Hi guys,

I have just finished a simple notecard reader that reads each line of a notecard and places the contents of each line into separate string variables.

The example I worked on had 12 lines in the notecard (these are all urls), so I declared 12 string variables, like so:

string url01;
string url02;
string url03;
string url04;

etc to url12


then read each line in the notecard, and place each line into the 12 variables sequentially, like so:

if (noteline == 1) // read line 1
url01 = (string)sdata;

if (noteline == 2) // read line 2
url02 = (string)sdata;

if (noteline == 3) // read line 3
url03 = (string)sdata;

if (noteline == 4) // read line 4
url04 = (string)sdata;

etc to line 12

But I am now wondering if it is possible to adapt the above process to take into account an unknown number of lines in the notecard.

I think that I could read the number of lines in the notecard first to get the number of variables easily enough (for example 7 lines, so 7 variables to store), but I cannot think how to use that number of lines to declare my variables and then apply the number to the 'if' statements.

Any ideas?

Regards

Rock
DanielFox Abernathy
Registered User
Join date: 20 Oct 2006
Posts: 212
09-14-2007 06:19
You'll want to look into LSL's List type. They can contain strings, and you can concatenate list elements dynamically as you need them.
RJ Source
Green Sky Labs
Join date: 10 Jan 2007
Posts: 272
09-14-2007 06:51
While lists would likely do what you want, you may want to reexamine your overall strategy. Reading in an unknown number of notecard lines, and adding them all to a list, could eventually cause you to run out of memory.

Maybe it's possible to process the lines completely as you read them in, so you can discard them? Or if the line number in the notecard is somehow significant, you could just jump in anytime and just read that line number, rather than reading then all one after the other?

Hard to say though, without knowing the intent of the script.
Rock Ryder
Registered User
Join date: 6 Oct 2006
Posts: 384
09-14-2007 09:12
I looked at the List approach, and rapidly got very confused, because what I ended up with was not a list of urls, as I wanted, but a list of keys. Just spent a fruitless hour trying to convert the keys back to urls. Can anyone suggest how to get from where I am to a list of urls?

Code so far:

integer notecardLines;
integer x;
list urlList = [];
string urlKey;

default
{
state_entry()
{
llGetNumberOfNotecardLines("Tracks";); //name of notecard is "Tracks"
}

dataserver(key queryid, string data)
{
notecardLines = ((integer)data)-1;
//Note: data returns the number of lines but is a string, so convert to integer,
//then deduct 1, because the first line in the notecard is a comment line
}

touch_start(integer num)
{
llSay(0, "This notecard contains " + (string)notecardLines + " urls.";); // cast back to string, then Say for debug purposes

for (x = 1; x < (notecardLines + 1); x++) // add each url to a list
{
urlList += llGetNotecardLine("Tracks", x); // Populate the list with (notecardLines -1) keys. Argghhh I wanted the urls from the notecard, not keys!
}
}
}
Lear Cale
wordy bugger
Join date: 22 Aug 2007
Posts: 3,569
09-14-2007 09:17
llGetNotecardLine doesn't get the notecard line. It gets the KEY of the line, and causes a subsequent dataserver event containing the DATA on the line. Look at the example at .

I always use the same code to read and parse notecards. I posted it here:



You may find it helpful.
Rock Ryder
Registered User
Join date: 6 Oct 2006
Posts: 384
09-14-2007 09:25
From: RJ Source
While lists would likely do what you want, you may want to reexamine your overall strategy. Reading in an unknown number of notecard lines, and adding them all to a list, could eventually cause you to run out of memory.

Maybe it's possible to process the lines completely as you read them in, so you can discard them? Or if the line number in the notecard is somehow significant, you could just jump in anytime and just read that line number, rather than reading then all one after the other?

Hard to say though, without knowing the intent of the script.


Hi RJ, thanks for the interest.

This is what I am trying to do. Right now, I have a working couple of scripts. The first script reads a notecard containing the urls of a dozen mp3s that I have uploaded to my website. Each url is read from the notecard and placed into a variable.

The variables are then passed to a second script, which is the Menu script. This generates a simple 12-button Menu, with the buttons labelled Track01, Track02 etc. By selecting a button I can select and listen to any of my mp3s.

This works fine. What I was wondering, was if I want more than 12 urls in my notecard, or less, depending on what I want for a particular occasion.

Hope this clarifies it,

Rock
Shadow Subagja
Registered User
Join date: 29 Apr 2007
Posts: 354
09-14-2007 09:48
Your script should probably get one note card line, wait for the even, then get the next from the event. If you try to loop and read them all you'll be queuing up a bunch of events and risk dropping them or having things simply not work since lsl doesn't seem to like you spinning in loops while events are pending.
RJ Source
Green Sky Labs
Join date: 10 Jan 2007
Posts: 272
09-14-2007 09:50
If I understand what you're saying, the buttons are named Track01, Track02, etc, no matter what is in the notecard?

Then here is another approach:

You can use llGetNumberOfNotecardLines to check how many lines are in the notecard. Then, without reading the notecard at all, just generate your buttons, up to the max lines (but not over 12 for the first page).

When the user selects, say, Track03, reparse the 03 there, then read llGetNoteCardLine 03-1 (so line 2). That would get you the url name on demand (with a .1 second delay). Then play it. Etc.

This way, you don't have to read the entire notecard in.

For more than 12, you'd want one button to be something like PAGE 2. So if the user clicks on that instead of a TRACK button, you'd generate a new menu with new TRACK buttons, numbers at (page - 1) * 11 + 1. So page 2 would start at track id 12, page 1 would start at track id 1, etc.
Shadow Subagja
Registered User
Join date: 29 Apr 2007
Posts: 354
09-14-2007 09:53
From: Rock Ryder
Hi RJ, thanks for the interest.

This is what I am trying to do. Right now, I have a working couple of scripts. The first script reads a notecard containing the urls of a dozen mp3s that I have uploaded to my website. Each url is read from the notecard and placed into a variable.

The variables are then passed to a second script, which is the Menu script. This generates a simple 12-button Menu, with the buttons labelled Track01, Track02 etc. By selecting a button I can select and listen to any of my mp3s.

This works fine. What I was wondering, was if I want more than 12 urls in my notecard, or less, depending on what I want for a particular occasion.

Hope this clarifies it,

Rock


I would combine the scripts, use a 'loading state' to manage the reading of the notecard into a list, then jump to the active state which handles your touch/menu and do stuff (in this case playing music).

Solve the problem first for 12 stations and then add a menu function to manage flipping between 'pages' and presenting only 10 at a time and handling next/previous buttons.

It seems a bit overkill to blast the URL data between scripts as I don't see anything to suggest you are making a HUGE script that will run out of memory. If you are trying to manage a list of mp3's that is thousands long.. you are going to want to scrap local storage and go out to an http server or something and do the heavy lifting there.

PS. there are many free radio scripts, go take a cross section of them and see how others have done the problem, it should really help to steer you in the right direction:
/54/39/129409/1.html
/54/4f/172661/1.html
Rock Ryder
Registered User
Join date: 6 Oct 2006
Posts: 384
09-14-2007 11:10
From: RJ Source
If I understand what you're saying, the buttons are named Track01, Track02, etc, no matter what is in the notecard?

Then here is another approach:

You can use llGetNumberOfNotecardLines to check how many lines are in the notecard. Then, without reading the notecard at all, just generate your buttons, up to the max lines (but not over 12 for the first page).

When the user selects, say, Track03, reparse the 03 there, then read llGetNoteCardLine 03-1 (so line 2). That would get you the url name on demand (with a .1 second delay). Then play it. Etc.

This way, you don't have to read the entire notecard in.

For more than 12, you'd want one button to be something like PAGE 2. So if the user clicks on that instead of a TRACK button, you'd generate a new menu with new TRACK buttons, numbers at (page - 1) * 11 + 1. So page 2 would start at track id 12, page 1 would start at track id 1, etc.


What a great idea RJ. I had just solved my earlier problem of getting the urls instead of the keys, and was just contemplating how to get a list from one script into another, and was about to ask the advice of the forum on this, when I saw your alternative approach.

I will try this straight away.

Rock
PS Many thanks to the others who have helped with suggestions too.
Lear Cale
wordy bugger
Join date: 22 Aug 2007
Posts: 3,569
09-14-2007 13:10
RJ's suggestion is a good one.

To get a list from one script to another, use llMessageLinked(), and pass the list as a string encoded using llList2CSV() and parse it at the other end using llCSV2List().

If the list elements might contain commas (ignoring rotations and vectors; commas between angle brackets are ignored), then it's a bit trickier.