Jump to content
mySky Phenomena

Simplifying Dialog Menu Control Flow

You are about to reply to a thread that has been inactive for 253 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

Hello,

I am fairly new to lsl scripting, but have some programming experience. I am currently working on a project that includes some dialog menus, which are more complicated than any I have previously worked on. Functionally, the code is working (as far as I can tell), but I'm wondering if there is any way to streamline or simplify what I've written.

The attached diagram is supposed to show how the menus are organized, sorry if it's confusing. Basically, the part that gets really really long is the control flows associated with levels B and C. For each choice in level B (B1 - B10) there are 15 options (C1 - C15). 

My question is: Does anyone have an example script of a multilevel menu with a lot of options associated with each level?

I'm trying to see if anyone has a better way of handling the control flow. I can attach some examples of my code if that would be helpful, and I am also looking at the lsl libraries online.

Thanks!

*In Level A of the diagram, that's supposed to be A11 (A eleven), not the word "All".

menu_diagram.jpg

Edited by mySky Phenomena

Share this post


Link to post
Share on other sites

How important to the user experience is being able to navigate from Level C back to Level A ("Main") without going through Level B? (I mean, yeah, it's an extra mouse click, but is that a big deal cuz it happens a lot?)

Share this post


Link to post
Share on other sites

Yes, there are fifteen distinct C options. Originally, I was going to build each menu and store it in a list beforehand. Then, I realized I should just build them only when they're needed because there are sooooo many of them. The control flow for the listen and the dataserver (or whatever the server event is called) events are really really really long. I'm hoping there's some smart way of cutting down on it that I'm not thinking of because I'm a novice, but all of the dialog menu example scripts I'm looking at are short (in terms of the amount of options for each menu) because (obviously) they are just examples.

Share this post


Link to post
Share on other sites

Just to confirm again: it's not that there are fifteen different Cs that appear ten times, once for each B, but rather 150 different Cs, divided up among ten Bs, right?

In any case, what does the script do when it gets a choice of B & C? What I'm trying to ask is whether there needs to be a monstrous huge if/else tree for the menu responses or if the script can simply do some computed thing based on finding the response in a list. Like, for example, there could be a long list of pairs that associate response "B1C1" with a texture to paint somewhere. The nightmare alternative is that there are 150 altogether different things the script needs to do -- like call a whole different function for each, or the like (because LSL has no concept of computed control flow like function pointers).

  • Thanks 1

Share this post


Link to post
Share on other sites
41 minutes ago, Qie Niangao said:

Just to confirm again: it's not that there are fifteen different Cs that appear ten times, once for each B, but rather 150 different Cs, divided up among ten Bs, right?

In any case, what does the script do when it gets a choice of B & C? What I'm trying to ask is whether there needs to be a monstrous huge if/else tree for the menu responses or if the script can simply do some computed thing based on finding the response in a list. Like, for example, there could be a long list of pairs that associate response "B1C1" with a texture to paint somewhere. The nightmare alternative is that there are 150 altogether different things the script needs to do -- like call a whole different function for each, or the like (because LSL has no concept of computed control flow like function pointers).

Yes, it's 150 different Cs. Right now, I have all of the C options stored in 10 separate lists (one for each B) because, like Wulfie Reanimator said, I discovered there are no lists within lists allowed. I then store which B# they chose in a variable (call it "numB"). Inside listen I say:

if(message == C1)
{
	if(numB == B1)
	{
		//get necessary info from B1 list associated with option C1
	}
	else if(numB == B2)
	.
	.
	.
}
else if(message == C2)...

So, as you can see it's getting a little ridiculous, because inside listen there are 15 C if/else if statements, each with 10 B if/else if statements inside. 

I'm thinking there's an easier way to do this, because I figured someone somewhere must be writing large menus like this.

Edited by mySky Phenomena
clarity
  • Haha 1

Share this post


Link to post
Share on other sites
27 minutes ago, mySky Phenomena said:

So, as you can see it's getting a little ridiculous, because inside listen there are 15 C if/else if statements, each with 10 B if/else if statements inside. 

You could always just combine all of the lists into one and do the old XY index search (you have to treat the single list as if it was a two-dimensional array), assuming each C-level menu has the same amount of data. Like:

// menu_length = the number of total indexes that belong to each C in B
// data_length = the number of indexes that belong to C

// bYcX = a stride of all relevant data for that specific C-level menu.
list data = [b1c1, b1c2, b1c3... b2c1, b2c2, b3c3...];

// Get all of the data for numB, numC. (or Y, X, respectively.)
list final_data = llList2List(data, (Y * menu_length) + (X * data_length), data_length);

 

Edited by Wulfie Reanimator

Share this post


Link to post
Share on other sites

How do the menus look. Is that B1-B10 and C1-C15 on the buttons or are there 150 different texts?

What you do with the result. Do you need 150 different script-actions or are things calculated out of the answers or are you just passing numbers?

 

Share this post


Link to post
Share on other sites
12 minutes ago, Wulfie Reanimator said:

You could always just combine all of the lists into one and do the old XY index search (you have to treat the single list as if it was a two-dimensional array), assuming each C-level menu has the same amount of data. Like:


// menu_length = the number of total indexes that belong to each C in B
// data_length = the number of indexes that belong to C

// bYcX = a stride of all relevant data for that specific C-level menu.
list data = [b1c1, b1c2, b1c3... b2c1, b2c2, b3c3...];

list final_data = llList2List(data, (Y * menu_length) + (X * data_length), data_length);

 

Thank you, that will definitely cut down on the number of separate lists I have!

Share this post


Link to post
Share on other sites
11 minutes ago, Nova Convair said:

How do the menus look. Is that B1-B10 and C1-C15 on the buttons or are there 150 different texts?

What you do with the result. Do you need 150 different script-actions or are things calculated out of the answers or are you just passing numbers?

 

Each B and C have a separate button. For example, if you chose button B2, you'd get another menu with buttons C1, C2, C3,..., C14, C15 (of course this would be broken up into two separate menus). With the result, I grab the list associated with the B button (which contains all the values for each C associated with that B button) and then find the C value in that list. For example, if someone chose B3 then C9, I would go into the B3 list and grab the value inside the C9 index (so index 8). The C9 value is a UUID for a texture that I'm applying to an object. 

Let me know if I'm not explaining myself well.

Edited by mySky Phenomena
Edited for clarity

Share this post


Link to post
Share on other sites
32 minutes ago, mySky Phenomena said:

Thank you, that will definitely cut down on the number of separate lists I have!

It would also eliminate any need for massive if-trees.

Since, if everything is in one list, and you already know which B and which C have been selected, you can immediately calculate the correct position in the main list without any if-checks, and get the right amount of data out.

Share this post


Link to post
Share on other sites
23 minutes ago, Wulfie Reanimator said:

It would also eliminate any need for massive if-trees.

Since, if everything is in one list, and you already know which B and which C have been selected, you can immediately calculate the correct position in the main list without any if-checks, and get the right amount of data out.

Just to make sure I understand: If I did it this way, all I would need in the listen is:

if(message == C1)
{
	//Use stored B# to search for the position B#C1 in the "master" data list
}
else if()...

instead of the nested if-checks I had in my original code snippet?

Edited by mySky Phenomena
Edited for clarity

Share this post


Link to post
Share on other sites
45 minutes ago, mySky Phenomena said:

Just to make sure I understand: If I did it this way, all I would need in the listen is:


if(message == C1)
{
	//Use stored B# to search for the position B#C1 in the "master" data list
}
else if()...

instead of the nested if-checks I had in my original code snippet?

I was thinking even more broadly, but I think the method you're showing there is more practical.

  • Thanks 1

Share this post


Link to post
Share on other sites

If I understood that right it's not too complicated:

global:

integer	gBnumber;
list	uuid; // fill up with 10*15 uuid's


listen event:

string	menuType = llGetSubString(msg,0,1);

if (menuType == "B") {
	gBnumber = (integer)llGetSubString(msg,1,-1);
	llDialog( ...show the C menu ...);
}
else if (menuType == "C") {
	integer Cnumber = (integer)llGetSubString(msg,1,-1);
	integer index = (gBnumber-1)*15 + Cnumber - 1;
	
	// do something with uuid[index]
}
else if .....

You need a list with 10 * 15 uuids and the listen event needs to handle the A menu and back and cancel buttons and all the stuff around. But B+C menus can be done simple.

  • Thanks 1

Share this post


Link to post
Share on other sites

mySky, assuming that this is a texture picker. with the picked texture being applied to some object then it might be better to make it as a HUD.  The HUD similar in design to a tabbed dialog. 10 tabs of 15 texture swatches per tab

from the user's pov, texture HUDs are easier to operate because they can see a swatch/thumbnail of the textures rather than have to remember what B4:C3 looks like

edit add:

when a HUD then all the uuids can be in a single list.  ListIndex = TabIndex * 10 + SwatchIndex

TabIndex and SwatchIndex derived from touches on the HUD surface using: http://wiki.secondlife.com/wiki/LlDetectedTouchST

edit more for completeness:

a HUD doesn't have to contain the uuids either. The uuids can be in the receiving object (garment for example) and the message sent from the HUD to the object/garment  need only contain the ListIndex

Edited by Mollymews
  • Thanks 1

Share this post


Link to post
Share on other sites
You are about to reply to a thread that has been inactive for 253 days.

Please take a moment to consider if this thread is worth bumping.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...