Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

multiple concurrent open dialogs?

Baron Hauptmann
Just Designs / Scripter
Join date: 29 Oct 2005
Posts: 358
02-20-2007 19:02
Question regarding llDialog. This one is harder for me to test out by myself, so I'll ask here first. . .

I would like to be able to handle a dialog in a way that several people might have a dialog open at the same time.

Is this how I do it (will this work)?

CODE

touch_start(integer num_detected)
{
llDialog(llDetectedKey(0), "pick one", ["yes", "no"], channel);
if (!handle)
{
handle = llListen(channel, "", NULL_KEY, "");
}
}

listen(integer channel, string name, key id, string message)
{
if (message == "yes")
list += [id];
}


What I'm trying to do is enable several people to touch the object and bring up a dialog in close proximity and limit the number of open listens, but keep track of who picks each choice from the dialog.

Baron Hauptmann
Johan Laurasia
Fully Rezzed
Join date: 31 Oct 2006
Posts: 1,394
multiple dialog boxes
02-20-2007 20:14
The secondary dialog box will overlap (entirely) the first. Once the choice is made on the secondary dialog box, it will disappear, and the one below will still be there.
ed44 Gupte
Explorer (Retired)
Join date: 7 Oct 2005
Posts: 638
02-21-2007 00:34
Sorry, Johan, I think you missed Baron's point. The same dialog box will go to whoever touches the object. Only if an agent clicks on the box twice will he/she see two dialogs.

This is where an alt or a patient friend comes in real handy.

Baron, your script looks fine, but then I am not in world to test it!

Ed
Pale Spectre
Registered User
Join date: 2 Sep 2005
Posts: 586
02-21-2007 01:41
I wonder about a couple of things. Multiple agents clicking simultaneously, and also bear in mind that llDialog launches its menu immediately so I think it's best to have the listen establised before the llDialog statement.

CODE
touch_start(integer num_detected)
{
integer i;

// Unlikely, but in case of extreme lag set up the listen before issuing the dialog.
if (!handle)
{
handle = llListen(channel, "", NULL_KEY, "");
}

// check for more than one agent touching simultaneously
for (i = 0, i < num_detected, i++)
{
llDialog(llDetectedKey(i), "pick one", ["yes", "no"], channel);
}
}


listen(integer channel, string name, key id, string message)
{
if (message == "yes")
list += [id];
}
Squirrel Wood
Nuteater. Beware!
Join date: 14 Jun 2006
Posts: 471
02-21-2007 04:56
I would do this like this:

use a list to store channel IDs and user keys and a timeout value.

Someone touches, i check the list to see if the key is in it.
If it is, I check the timeout.
Only if the dialog has timed out, I send a new one to the user. otherwise, nothing happens.

Now, if the key is not in the list, I add it, assign a channel and timeout and display the dialog to the user.

When the user picks an option, I check the list again and see if the dialog has timed out or not.
If it has timed out I notify the user and reset the timeout value as well as display the dialog again.

If it has not timed out, I remove the key from the list as appropriate and carry out whatever selection the user has made.

This method should allow you to handle quite a few concurrent users.
Baron Hauptmann
Just Designs / Scripter
Join date: 29 Oct 2005
Posts: 358
02-21-2007 07:18
Pale: Thanks, I'll get in the better habit of listening before speaking ;)

Squirrel: I had thought about that, but I am trying to reduce the amount of overhead . . . I have enough lists going on already, was trying to avoid that and simply deal with this in the listen phase.

As I did not post the whole script so far, it is not obvious, but this only happens in one phase of a larger series of events. So the dialogs and listen cannot go on forever . . . They will be terminated by a host avatar at some point. So I am not worried about putting timeouts on the dialogs.

Also, I had modified the script slightly, as the dialogs are actually initiated from a money() event rather than a touch. So I am not as concerned about multiple touches by the same user or simultaneous touches by different users.

I just wanted to be sure that all of the dialogs would get handled correctly. I am used to bringing up dialogs only for one individual at a time, not leaving it open to allow several to be up at once, and wanted to check my logic and understanding of the involved functions.

Thanks,
Baron Hauptmann
Learjeff Innis
musician & coder
Join date: 27 Nov 2006
Posts: 817
02-21-2007 08:12
Think of the dialog and the response as independent things.

There's no specific limit to the number of dialogs you can post (well, none I've encountered). When you post a dialog, that dialog is handled by the avatar you posted it to. All it does is it gives them an easy way to send your object one of a set of messages on a given chat channel.

There is no specific need to timeout a dialog. Sometimes I do this, but only when I'm keeping track that a dialog is open for some reason. While this can be a good thing, it's usually better to avoid it and keep things simpler.

So, post dialogs with abandon, don't worry about them. Focus on handling the response messages and what it means.

If the menu is always the same, this simple approach works best.

However, if the contents of the menu depends on the state of the object (the LSL state, or the value of any global variables), then things can get more complicated, because folks can leave a menu up for a while and then when they select, their message might be based on "old news". Therefore, for simplicity, things work best when the menu is always the same (at least, always the same for any given avatar). Of course, you can work around this 9if necessary by carefully making sure that any posts based on old news get handled appropriately -- usually by ignoring them.

Remember the KISS principle, "Keep it simple, stupid!"

- As mentioned above, post the listen before the llDialog. I generally post the listen in the entry handler for each state where I'll be posting dialogs. Remember that a listen doesn't survive a state transition, so no need to cancel them or save the handler, in this case.
- No timeout unless there's an important reason for it.
- Use the same channel for all dialogs.
- don't track the llDialog calls you make. Just call 'em and let what happens happen. You'll either get a message from them or not.
- Use the 'id' field to differentiate between users, not the channel.
- Use a chat channel selected using llFrand() -- do this at rez time, so if there are multiple of the same object, you don't get interference. A simple way is to add a rez handler in every state, and call llResetScript(). Call llFrand in the default state's state_entry() handler, like this:

CODE

integer MenuChan;

default
{
state_entry()
{
MenuChan = 1000 + (integer) llFrand(64535.0);
}
...
}


I add 1000 just to keep it out of the range folks often use for hard-coded chat channels (and thus the limit of 64535 rather than 65535.)

HTH and good luck
Jeff
Baron Hauptmann
Just Designs / Scripter
Join date: 29 Oct 2005
Posts: 358
02-21-2007 08:28
Great summary, Learjeff!

One question, though: according to the wiki,
There are 4,294,967,294 possible channels (-2,147,483,648 to 2,147,483,647).

Is there any other need to limit to 65535?

Baron
Learjeff Innis
musician & coder
Join date: 27 Nov 2006
Posts: 817
02-21-2007 10:37
No, just my mistake! In fact, it's better to use a wider range, less chance of two objects choosing the same channel. Thanks for pointing that out. :)