Nested listens - is it possible?
|
Tiggr Woodget
Registered User
Join date: 26 Jun 2007
Posts: 3
|
12-30-2009 15:22
Hi, I am just a beginning scripter and need a little help. The LSL Portal was of no use to me. I am trying to setup multiple listens (nested) and am unsure if it is even possible. I keep getting "syntax error" on the second listen. Below is the code integer range = "50.0"; state_entry llListen(0, "", llGetOwner(), ""  ; listen_id = llListen(channel_dialog, "", llGetOwner(), ""  ; first listen listen( integer channel, string name, key id, string message ) { if( id != llGetOwner() ) { return; } if( message == "help" ) { llSay( 0, "This object records the names of everyone who" ); second listen else if( message == "set range" ) { listen(channel_dialog, string name, key id, string msg) { if id != llGetOwner() { return } range = msg llSay(0, "The range has been set to " range "m"  ; llListenRemove(listen_id); } } Any advice would be appreciated. Thank you Tiggr
|
Talarus Luan
Ancient Archaean Dragon
Join date: 18 Mar 2006
Posts: 4,831
|
12-30-2009 15:30
Listens don't work that way. You can have multiple listens, each with different filter criteria, on different channels, but they all get sent to a single listen event in the current state.
I am not sure what you are trying to accomplish from the (pseudo-)code you posted. Can you run down the design of what you are trying to do in normal English descriptive terms? More or less the "design document" level?
|
Rolig Loon
Not as dumb as I look
Join date: 22 Mar 2007
Posts: 2,482
|
12-30-2009 16:14
You can only have one event of any given kind in each state in an LSL script, so you can't have two listen events, or two attach events, or two timer events, or ..... whatever. For listen events, though, you can have more than one triggering llListen handle. That effectively gives you more than one entry point for a listen event, since you can code the event to respond one way if it's triggered by listen handle A and a different way if it's triggered by listen handle B. You can do similar tricks with most other events if you use flags or counters to define different entry points.
_____________________
It's hard to tell gender from names around here but if you care, Rolig = she. And I exist only in SL, so don't ask....  Look for my work in XStreetSL at 
|
Tiggr Woodget
Registered User
Join date: 26 Jun 2007
Posts: 3
|
12-30-2009 16:41
The object listens in general chat for commands like "help" from owner. It is currently listening for 4 specific commands. When it receives the "set range" message, it then listens again in channel 10 for the range setting. When it receives the range setting it then sets a variable "range" which is global. At least, this is what I wanted to achieve. I considered having a dialog drop down with a list of possible ranges but only to be used by the owner and only to set the range variable and this dialog shows when the object is touch OR when the owner rezs it and can only be set by the owner of the object.
Thanks Tiggr
|
Lazink Maeterlinck
Registered User
Join date: 8 Nov 2005
Posts: 332
|
12-30-2009 16:58
maybe it is just a pet peeve of mine, but I seem to recall using return in an event is actually pretty bad. You shouldn't need to exclusively kick out of an event unless absolutely necessary. Functions are a little different, but same rule should apply. For Example I've seen this a lot:
if(id != llGetOwner) { return; }
if(message ...
why not just use if(id == llGetOwner()) { if(message ... ) . . . }
when code gets complicated, it's easier to debug and read if you don't use returns all over the place, IMO.
|
Viktoria Dovgal
…
Join date: 29 Jul 2007
Posts: 3,593
|
12-30-2009 17:16
From: Tiggr Woodget When it receives the "set range" message, it then listens again in channel 10 for the range setting. When it receives the range setting it then sets a variable "range" which is global. At least, this is what I wanted to achieve. OK, here is something that would do literally that, based on what you first posted. You can decide if that is the direction you really want to go. float gRange = 50.0;
// handles for listeners integer gListenZero; integer gListenTen;
default { state_entry() { gListenZero = llListen(0, "", llGetOwner(), ""); // commented out because it doesn't do anything yet // llListen(channel_dialog, "", llGetOwner(), ""); }
listen( integer channel, string name, key id, string message ) { // Can skip the llGetOwner checks here, because the llListen // already filters on that.
if (channel == 0) { if( message == "help" ) { llSay( 0, "This object records the names of everyone who" ); } else if( message == "set range" ) { // I don't know if you want to listen to the owner or // someone else on 10 here, just guessing... llSay(0, "OK, say a number on channel 10."); gListenTen = llListen(10, "", llGetOwner(), ""); } } else if (channel == 10) { gRange = (float)message; llSay(0, "The range has been set to " + (string)gRange + " m"); llListenRemove(gListenTen); } } }
|
Tiggr Woodget
Registered User
Join date: 26 Jun 2007
Posts: 3
|
12-30-2009 19:08
Thank you for your responses. I have altered the code as suggested and this works, to some extent.
The code compiles correctly now, however, when I run the "set range" section, it immediately sets the range to 0.00000 BEFORE I type /10 40 for example.
Tiggr
|
Paladin Pinion
The other one of 10
Join date: 3 Aug 2007
Posts: 191
|
12-30-2009 19:13
From: Lazink Maeterlinck maybe it is just a pet peeve of mine, but I seem to recall using return in an event is actually pretty bad.. I do it sometimes. I've always found it convenient to do a basic test right at the top. It prevents a lot of nested code, which I think is harder to read, and also shortstops the script right away if there is a known condition you don't want to deal with. But if it's bad for some reason, I won't do it any more. Is there a down side?
_____________________
Mote Particle Script Generator - easier and faster than any HUD Also: Paladin's Sunbeam. Up at dawn, gone by dusk, day and night sounds, fully configurable See more at: www.paladinpinion.com
|
Lear Cale
wordy bugger
Join date: 22 Aug 2007
Posts: 3,569
|
12-30-2009 19:14
From: Lazink Maeterlinck
when code gets complicated, it's easier to debug and read if you don't use returns all over the place, IMO.
After over 3 decades of software engineering, I find that careful, structured use of early returns makes code more readable and easier to maintain. The only disadvantage is that optimizers won't always work as well. For example, I recommend this if (condition1) { return; } ... stuff1 ... if (condition2) { return; } ... stuff2 ...
over this if (!condition1) { ... stuff1 ... if (!condition2) { ... stuff2 ... } }
The goal is to keep code linear, and once a case is handled, be done with it and forget about it. True, this is is NOT what educators teach you in college when they teach pure block structure. However, I find that it's based on research that compares block structured code with completely unstructured code, and any pundit I've asked has never pointed to a study that considers structured returns. However, good programmers use them well, frequently, including careful use of "break" and "continue" statements in loops (which LSL unfortunately does not have). Linearly structure code requires the programmer to keep fewer facts in mind to interpret the code. The more indentation, the more you have to keep in mind when reading, and the higher the likelihood of a mistake, especially in subsequent modifications. "return" works just fine from within events. However, they shouldn't be used willy-nilly. If they're not obvious and easy to find, they add complexity rather than reduce it.
|
Lear Cale
wordy bugger
Join date: 22 Aug 2007
Posts: 3,569
|
12-30-2009 19:16
From: Paladin Pinion I do it sometimes. I've always found it convenient to do a basic test right at the top. It prevents a lot of nested code, which I think is harder to read, and also shortstops the script right away if there is a known condition you don't want to deal with. But if it's bad for some reason, I won't do it any more. Is there a down side? LOL, you beat me by a minute. The only downside is if the early returns aren't obvious, it can obfuscate the code. But I see you're already following the same logic that I use, so you're unlikely to be very guitly of this. Oh, it does use more byte code in LSO. One byte more per return, I believe. I have no idea what the impact on Mono object code would be; there's hardly any way to tell. Since code segments grow in chunks of 512 bytes, this would only matter on boundary cases for largish handlers.
|