Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

problem with llDeleteSubList (probably just me being dumb!)

psimagus Hax
Registered User
Join date: 3 Jul 2007
Posts: 73
06-15-2008 06:22
I'm trying to write some code to prompt a user to delete entries from a list ("Please type 'yes' or 'no'";), and I can't seem to get it to wait for an input before ploughing on through the script. The rest of the script is working fine - all the variables are properly typecast, the listens all listen as expected, llListFindList is selecting the correct message in messageList (the first one with position matching the position of the user's name in avList.) As far as I can tell, the rest of the script also works ok too (if I change the default to delete, instead of not delete, it deletes.) I just don't seem to be able to make it wait for input from the user.

I had thought that llListen( 0, "", currentname, "" ) would stop it proceeding until it heard something (anything) on channel 0 from the user in question, but this does not seem to be the case. Can any kind soul tell me, am I missing something obvious? Or does LSL just hate me? :0

the relevant section is:



listen( integer channel, string name, key id, string message )
{

...<snip for clarity>...

else if (channel == 899) { // 'edit' button relays name of button-pusher as message on this channel
string currentname = (string)message;
llSay(0, "HELLO " + (string)currentname + " STARTING EDITING MENU...";);
list current = [currentname];
integer index = llListFindList(avList, current);
if (index != -1)
{
llSay(0, currentname + " - would you like to delete the following entry? Please type 'yes' or 'no'";);
llListen( 0, "", currentname, "" );

// HERE'S THE PROBLEM POINT - how to make it wait for a response before ploughing on through the script?

llSay(0, llList2String(messageList, position));

if (message == "yes";)
{
messageList = llDeleteSubList(messageList, position, position);
avList = llDeleteSubList(avList, position, position);
timestamps = llDeleteSubList(timestamps, position, position);
llSay( 0, "Thankyou " + (string)currentname + ", your entry has been deleted.";);
}
else
{
// otherwise don't delete entry if "no" (or anything else) is typed:
llSay (0, "Okay " + (string)currentname + " - this entry has not been deleted.";);
}
}
}
}
revochen Mayne
...says
Join date: 14 Nov 2006
Posts: 198
06-15-2008 07:21
ok thats what i've guessing.
in the listen event you're checking for if message is passed on channel 899.
then the next coming code in that block asks if msg == "yes";(or no).
but the yes/no will be given at channel 0 :)
Dora Gustafson
Registered User
Join date: 13 Mar 2007
Posts: 779
06-15-2008 07:25
From: psimagus Hax
I had thought that llListen( 0, "", currentname, "" ) would stop it proceeding until it heard something (anything) on channel 0 from the user in question, but this does not seem to be the case. Can any kind soul tell me, am I missing something obvious? Or does LSL just hate me? :0
LSL will love you when you realize that what you are doing is starting a listen handle nothing more.
The handle enables the simulator to listen for something that fills your conditions.
When that happens a listen event takes place so you must have a listen event handler in your code.
In that handler you do the things you want to do AFTER the answer.
See: http://www.lslwiki.net/lslwiki/wakka.php?wakka=llListen
Note: 'currentname' in your call must be a Key.
Sorry! I see now that you have a listen event, but you put the lllisten() call inside it? how will it ever be triggered?
_____________________
From Studio Dora
psimagus Hax
Registered User
Join date: 3 Jul 2007
Posts: 73
06-15-2008 08:21
From: Dora Gustafson
LSL will love you when you realize that what you are doing is starting a listen handle nothing more.
The handle enables the simulator to listen for something that fills your conditions.
When that happens a listen event takes place so you must have a listen event handler in your code.
In that handler you do the things you want to do AFTER the answer.
See: http://www.lslwiki.net/lslwiki/wakka.php?wakka=llListen
Note: 'currentname' in your call must be a Key.


Ah, I'd used

string currentname = llDetectedName(0);
llSay (899, (string)currentname);

in the edit button to return the name, but I guess I can return a key instead. But I use llListen( 333, "", avname, "" ); in the state_entry to allow people to add entries to the list (and their name into a parallel list,) and that seems to work ok with av names rather than keys.

From: Dora Gustafson
Sorry! I see now that you have a listen event, but you put the lllisten() call inside it? how will it ever be triggered?


Ah... I think I see what you mean. But I don't know how to fix it :(
in the state_entry, I've got:

llListen( 333, "", avname, "" );
llListen( 998, "", NULL_KEY, "" );
llListen( 899, "", NULL_KEY, "" );

for the assorted listens the script is using (and they all work fine,) and I've tried adding:

llListen(0, "", currentname, "" );

but that doesn't seem to make any difference (probably because currentname hasn't been defined at that point, but only declared. It is not generally the same as avname.)
But because the script can be used by lots of different people, I don't know how to frame (or where to place) this listen to respond only to the specific person who later touches the button that sends their name on channel 899. I can't frame the condition before I know who's pressing the button - and they might press the button (or not) at any time (or never).
Is there a way to make this listen only active after the llListen(899"", NULL_KEY, "" ); ?

Or maybe I could have the script listen to everything on channel 0 and feed it into a string/list for each person it hears (and wouldn't that slow it down an awful lot, since there could potentially be an enormous amount of background chatter?) and then try to match up the most recent value for the string/list position corresponding to the specified user at the point I want to get the response? No - that seems horribly clunky, so I hope there's a better way.

I even tried putting the llListen inside a do-while loop, to keep it listening in a loop until it hears a response, but that didn't work either (not really surprising if you can't put an llListen inside a listen.)

Oh dear - my head hurts now :(
psimagus Hax
Registered User
Join date: 3 Jul 2007
Posts: 73
06-15-2008 08:28
From: revochen Mayne
ok thats what i've guessing.
in the listen event you're checking for if message is passed on channel 899.
then the next coming code in that block asks if msg == "yes";(or no).
but the yes/no will be given at channel 0 :)


Yes, I see - (string)message will be the name of the button-presser since the llListen( 0, "", currentname, "" ); is being skipped.
Maybe a state change after the listen on 899's triggered would do it, with a whole new listen on 0 ?
revochen Mayne
...says
Join date: 14 Nov 2006
Posts: 198
06-15-2008 08:48
no change of states necessary.
but you should exclude the if msg == "Yes"
would look like
CODE

listen(channel, name, key, msg)
{
if(ch==899)
{
// do stuff for here
// you might want to start a new listener here
// that is listening to the sender 'key' of 'msg'
}

else if(ch==333)
{
// do other stuff here
}

// an now ask for if msg=="yes" or "no"
// because its not passed through channels above
// also you can check if msg is passed through channel 0
else if(ch==0||msg=="Yes")
{
// do stuff for here
}
}


hope i did not got any wrong as its not that easy to help without being able to look at the full code.
psimagus Hax
Registered User
Join date: 3 Jul 2007
Posts: 73
06-15-2008 11:46
From: revochen Mayne
no change of states necessary.
but you should exclude the if msg == "Yes"
would look like
CODE

listen(channel, name, key, msg)
{
if(ch==899)
{
// do stuff for here
// you might want to start a new listener here
// that is listening to the sender 'key' of 'msg'
}

else if(ch==333)
{
// do other stuff here
}

// an now ask for if msg=="yes" or "no"
// because its not passed through channels above
// also you can check if msg is passed through channel 0
else if(ch==0||msg=="Yes")
{
// do stuff for here
}
}


hope i did not got any wrong as its not that easy to help without being able to look at the full code.



I think I understand, and it looks a little more promising perhaps (and a good deal more workable.) But 1 thing I'm worried about - isn't this going to trigger every time it detects the word "yes" (not an uncommon word!) from anyone within range on channel 0? And thus delete any entries they might have left recorded in the messageList, even if they're just chatting nearby?

I think I really need to establish some sort of "editing mode", where it won't delete entries from the list until they've specifically chosen to make that call. And I can't think how to do that without matching the name of the person who presses a button, with the name of the person who says "yes" (and preferably immediately after being asked "do you want to delete this...";)

To restate a universal law - if it can be messed up, it will be :(
revochen Mayne
...says
Join date: 14 Nov 2006
Posts: 198
06-15-2008 13:33
From: psimagus Hax
But 1 thing I'm worried about - isn't this going to trigger every time it detects the word "yes" (not an uncommon word!) from anyone within range on channel 0? And thus delete any entries they might have left recorded in the messageList, even if they're just chatting nearby?

Well therefor you have to set filters in the llListen method.
if ther is a key specified the script will only listen to the avatar its key is set.
psimagus Hax
Registered User
Join date: 3 Jul 2007
Posts: 73
06-16-2008 05:31
many thanks! That's sorted it admirably - I've added an integer to stay FALSE until the button's pressed (and it sets back to FALSE on all other operations):

else if (editflag==TRUE&&channel == 0&&;(string)message=="yes";)

and it works a treat! :)