Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

How to be a good llListener?

Wildefire Walcott
Heartbreaking
Join date: 8 Nov 2005
Posts: 2,156
05-08-2006 15:20
I have several illustrative posters in a couple of my properties that I want to be able to hide when they're not needed. I wrote a script (my very first, yaaay!) that listens for commands and shows/hides accordingly. I know, a million people have done it before (or at least a couple hundred thousand) but I wanted to learn.

Anyway, I've heard that listener scripts can be a burden on the system, and I want to make sure I'm being as efficient and unobtrusive as possible. Can anyone offer tips to make my li'l show/hide dealy be a good Second Citizen?

Right now, my script handles listening like this: I've got the following command in the state_entry block: llListen(69, "", id, "";)

I had tried using "poster" as the fourth parameter so that I could filter off of that and have two-word commands, like "poster show" and "poster hide" but that didn't seem to work.

Should I be doing anything else, like removing the listen on a given object state, or re-instating the listen on rez or anything? (Hey, at least I knew not to listen on channel 0, but that's the extent of my eliteness.)

Thanks for your advice...

EDIT: P.S. What the heck does that third parameter mean, and what does "id" do? My script works, but I don't know if/how that parameter is affecting it. I don't define "id" anywhere in my script.
_____________________
Desperation Isle Estates: Great prices, great neighbors, great service!
http://desperationisle.blogspot.com/

New Desperation Isle: The prettiest BDSM Playground and Fetish Mall in SL!
http://desperationisle.com/

Desperation Isle Productions: Skyboxes for lots (and budgets) of all sizes!
Sator Canetti
Frustrated Catgirl
Join date: 20 Sep 2005
Posts: 130
05-08-2006 15:30
llListen(123 <channel it listens on>, "" <name of the object speaking... useful for inter-object comms>, id <the id of the person to listen to, like, owner only would be llGetOwner()>, "beep" <listens only for certain "beep"... "beeper" and "bee" fail>;);

llListen(123, "", llGetOwner(), "";); //Listens for anything on channel 123 by the owner of the object containing the script... can be filtered out later.

How I tend to filter is
CODE
listen(integer channel, string name, key id, string message)
{
if(llToLower(message) == "beep")
{
llPlaySound("beep", 1.0);
}
}


If using multiple channels...

CODE
listen(integer channel, string name, key id, string message)
{
if(llToLower(message) == "beep" && channel == 123)
{
llPlaySound("beep", 1.0);
}
}
_____________________
"Have gone to commit suicide. Intend to return from grave Friday. Feed cat." -- A memo by Spider Jerusalem in Transmetropolitan

"Some people are like Slinkies; not really good for anything, but they still bring a smile to your face when you push them down a flight of stairs."

If you're reading this signature, I've probably just disagreed with you. Welcome to the club :D
Joannah Cramer
Registered User
Join date: 12 Apr 2006
Posts: 1,539
05-08-2006 15:49
From: Wildefire Walcott
I have several illustrative posters in a couple of my properties that I want to be able to hide when they're not needed. I wrote a script (my very first, yaaay!) that listens for commands and shows/hides accordingly. I know, a million people have done it before (or at least a couple hundred thousand) but I wanted to learn.

Anyway, I've heard that listener scripts can be a burden on the system, and I want to make sure I'm being as efficient and unobtrusive as possible. Can anyone offer tips to make my li'l show/hide dealy be a good Second Citizen?

Not sure if i understand the description right, but if this is some sort of help drawings attached to items, maybe it'd be better to allow user toggle them either by directly clicking on the item, or through menu invoked with such click? This way there's no need for any long-term listen filters, and it might be even more user-friendly this way...
Teffler Detritus
Registered User
Join date: 14 Dec 2005
Posts: 19
05-08-2006 16:24
From: Wildefire Walcott
I have several illustrative posters in a couple of my properties that I want to be able to hide when they're not needed. I wrote a script (my very first, yaaay!) that listens for commands and shows/hides accordingly. I know, a million people have done it before (or at least a couple hundred thousand) but I wanted to learn.

Anyway, I've heard that listener scripts can be a burden on the system, and I want to make sure I'm being as efficient and unobtrusive as possible. Can anyone offer tips to make my li'l show/hide dealy be a good Second Citizen?

Right now, my script handles listening like this: I've got the following command in the state_entry block: llListen(69, "", id, "";)

I had tried using "poster" as the fourth parameter so that I could filter off of that and have two-word commands, like "poster show" and "poster hide" but that didn't seem to work.

Should I be doing anything else, like removing the listen on a given object state, or re-instating the listen on rez or anything? (Hey, at least I knew not to listen on channel 0, but that's the extent of my eliteness.)

Thanks for your advice...

EDIT: P.S. What the heck does that third parameter mean, and what does "id" do? My script works, but I don't know if/how that parameter is affecting it. I don't define "id" anywhere in my script.



The message filter is unforunately pretty unhelpful because noone knows what channel other items the owner is going to have, or what other objects are present locally if using a global listener.

I dont know how much of a overhead the message filter adds to a listener either. Assuming that a listener using the filter is less intensive than doing your own filter with substrings and the like, then a good way may be to use something like the following:

CODE


integer visible = TRUE;
integer handle;
integer chan = 69;

default
{
state_entry()
{
handle = llListen(chan,"",id,"poster");
}

listen(integer channel, string name, key id, string msg)
{
if (msg == "poster");
{
llOwnerSay("listening...");
llListenRemove(handle);
if (visible) handle = llListen(chan,"",id,"hide");
else handle = llListen(chan,"",id,"show");
}
if (msg == "hide");
{
llOwnerSay("hiding....");
hidePoster(); // hide poster function here
visible = FALSE;
llListenRemove(handle);
llListen(chan,"",id,"poster");
}
if (msg == "show");
{
llOwnerSay("showing....");
showPoster(); // show poster function here
visible = TRUE;
llListenRemove(handle);
llListen(chan,"",id,"poster");
}
}
}


Without testing its hard to say whether this would actually reduce the overhead on such a small script. On larger scripts though, removing listen handlers when they are not needed would be a good.

In fact having reread llListenRemove there may be a better way...

CODE


integer visible = TRUE;
integer channel = 69;

default
{
state_entry()
{
llListen(chan,"",id,"poster");
}

listen(integer channel, string name, key id, string msg)
{
llOwnerSay("listening....");
if (visible) state hide;
else state show;
}
}

state hide
{
state_entry()
{
llListen(chan,"",id,"hide");
}

listen(integer channel, string name, key id, string msg)
{
llOwnerSay("hiding....");
visible = FALSE;
hidePoster();
state default;
}
}

state show
{
state_entry()
{
llListen(chan,"",id,"show");
}

listen(integer channel, string name, key id, string msg)
{
llOwnerSay("showing....");
visible = TRUE;
showPoster();
state default;
}
}



Since a change in state removes any listeners in that state this does away with the need to manaually remove the listener.

In both cases you trigger the script to change to a state waiting for the next command, aslong as the initial value for visible is correct and nothing goes wrong this should trigger the function to hide or show the poster without having a listener waiting for absolutely any input, really it should have a timer in the show and hide state or show and hide if statements so that it resets automatically if the second command isnt given after a certain time.

As I said in this case I doubt it would make much difference, perhaps in a larger script with more commands :/

Could some uber LSL scripter shed some light on it :p
Wildefire Walcott
Heartbreaking
Join date: 8 Nov 2005
Posts: 2,156
05-08-2006 16:29
From: Joannah Cramer
Not sure if i understand the description right, but if this is some sort of help drawings attached to items, maybe it'd be better to allow user toggle them either by directly clicking on the item, or through menu invoked with such click? This way there's no need for any long-term listen filters, and it might be even more user-friendly this way...

So, basically, the posters are illustrations of how to use various objects in the room. The objects themselves are no-mod (and weren't created by me), so the posters must be external.

And to Teffler, I'm going to have to re-read your suggestion a couple more times to understand what you're demonstrating... but I have a feeling I'm going to have a couple questions. Thanks!
_____________________
Desperation Isle Estates: Great prices, great neighbors, great service!
http://desperationisle.blogspot.com/

New Desperation Isle: The prettiest BDSM Playground and Fetish Mall in SL!
http://desperationisle.com/

Desperation Isle Productions: Skyboxes for lots (and budgets) of all sizes!
Teffler Detritus
Registered User
Join date: 14 Dec 2005
Posts: 19
05-08-2006 16:37
Hehe

Sorry, I suck at the explaining bit :P
Pru Xingjian
Fnnn
Join date: 1 Oct 2005
Posts: 11
05-08-2006 16:40
From: Teffler Detritus
Could some uber LSL scripter shed some light on it :p


CODE

integer visible=TRUE;
listenSet(string m){
llListenRemove(listener);
listener=llListen(69,"",llGetOwner(),m);
}
default{
state_entry(){listenSet("poster hide");}
listen(integer c,string n,key d,string m){
if(visible){visible=FALSE;listenSet("poster show");hidePoster();}
else{visible=TRUE;listenSet("poster hide");showPoster();}
}
}


Oh god... lmao
Wildefire Walcott
Heartbreaking
Join date: 8 Nov 2005
Posts: 2,156
05-09-2006 10:15
From: Pru Xingjian
CODE

integer visible=TRUE;
listenSet(string m){
llListenRemove(listener);
listener=llListen(69,"",llGetOwner(),m);
}
default{
state_entry(){listenSet("poster hide");}
listen(integer c,string n,key d,string m){
if(visible){visible=FALSE;listenSet("poster show");hidePoster();}
else{visible=TRUE;listenSet("poster hide");showPoster();}
}
}

I had to read it a couple times to understand how it worked, but I do believe this is a thing of beauty. Thank you.
_____________________
Desperation Isle Estates: Great prices, great neighbors, great service!
http://desperationisle.blogspot.com/

New Desperation Isle: The prettiest BDSM Playground and Fetish Mall in SL!
http://desperationisle.com/

Desperation Isle Productions: Skyboxes for lots (and budgets) of all sizes!
jazz Spatula
jazz spatula
Join date: 7 Feb 2006
Posts: 11
voting machine
05-09-2006 10:21
Could someone send me the script that uses the "voting machine" that is around different places in sL?

thanks
Jon Marlin
Builder, Coder, RL & SL
Join date: 10 Mar 2005
Posts: 297
05-10-2006 07:41
When I want a low-lag listener (like in my vendors), I hook into touch_start. When the item is touched, it starts a 30 second timeout timer, and starts a listener. In the listen event handler, it resets the 30 second timeout timer. If the timer goes off, it turns off the listener and goes back to sleep.

- Jon
_____________________
Come visit Marlin Engineering at Horseshoe (222, 26) to see my line of flying vehicles.
Burnman Bedlam
Business Person
Join date: 28 Jan 2006
Posts: 1,080
05-10-2006 08:01
The following link from the WIKI will give you the option to touch the poster to activate the listen, and use a chat command to shut the listen off.

http://secondlife.com/badgeo/wakka.php?wakka=llListenControl

Alternately... you can use a touch start with a timer event to shut the listen off within 30 seconds (or whatever you need). This will give you the opportunity to use the listen feature while reducing system burden by disabling the listen when you don't need it.

Of course... if you need multiple posters to enable and disable at the same time without touching all of them before giving the command... this won't work for you.

Depending on whether or not you need to move the posters around, and their relative distance from one another... you could in fact use link messages to tell all of the posters to start listening when you touch 1 of them.

Just some ideas. :)
_____________________
Burnman Bedlam
http://theburnman.com


Not happy about Linden Labs purchase of XStreet (formerly SLX) and OnRez. Will this mean LL will ban resident run online shoping outlets in favor of their own?
Aislin Wallaby
Registered User
Join date: 4 Mar 2005
Posts: 27
Key to reducing server usage
05-10-2006 08:42
The touch idea is a great one, although I can see the issue if you can't link 'em. The key to reducing server usage is to filter them at the llListen call as much as possible. This is because the server only does anything with chat if it hits the criteria of the listen (i.e. on the right channel, is said by the right av or object, etc.) If you leave your listen wide open (as in the second example below) then the server will process the if statement every time something is said on channel 69.

Thus

CODE


integer channel=69;
string name="My Avatarname";
key id="mykey"; //not entirely necessary if you're already using your name
string message = "";

default
{
state_entry()
{
llListen(channel,name,key,message);
}
listen(integer ch, string nm, key avkey, string msg)
{
//insert whatever you want to do here
}
}


works much more efficiently than

CODE

default
{
state_entry()
{
llListen(69,"",NULL_KEY,"");
}
listen(integer ch, string nm, key avkey, string msg)
{
if(nm=="myname" & msg = "command")
{
//whatever you want it to do here
}
}
}


In all actuality though, I've found that unless you have a large number of listens, or a large number of people talking nearby, the actual server effect can be relatively minimal. The biggest thing to remember though is that unless you have a really good reason for user operability (i.e. in a vehicle where the user may be a little busy to type a specific channel), you should almost never place a listen on channel 0, and if you must be on 0, never use it without filtering for at least an avatar name.