Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

How Much Cleanup is Needed?

Shorahmin Femto
Senior Citizen
Join date: 27 Feb 2004
Posts: 34
01-03-2005 18:37
Hope the answer to this isn't buried somewhere in another thread but...

Does the following make any sense?

CODE
integer ChatListen;
default
{
state_entry()
{
ChatListen = llListen(0, "", NULL_KEY, "";);
llSensorRepeat("", "", AGENT, 3.3, PI, 10.0);
llSetTimerEvent(10.0);
}
.
.
.
state_exit()
{
llListenRemove(ChatListen);
llSensorRemove();
llSetTimerEvent(0.0);
}
}//end of default state


My question is about the state_exit handler. (Dare I say destructor?) Is there any reason, good practice, or efficiency to explicitly remove the callbacks as you leave a state?
_____________________
Time is granular, Object Oriented, re-entrant, recursive, and therefore manifold.
Marker Dinova
I eat yellow paperclips.
Join date: 13 Sep 2004
Posts: 608
01-03-2005 19:24
From: Shorahmin Femto
Hope the answer to this isn't buried somewhere in another thread but...

Does the following make any sense?

CODE
integer ChatListen;
default
{
state_entry()
{
ChatListen = llListen(0, "", NULL_KEY, "";);
llSensorRepeat("", "", AGENT, 3.3, PI, 10.0);
llSetTimerEvent(10.0);
}
.
.
.
state_exit()
{
llListenRemove(ChatListen);
llSensorRemove();
llSetTimerEvent(0.0);
}
}//end of default state


My question is about the state_exit handler. (Dare I say destructor?) Is there any reason, good practice, or efficiency to explicitly remove the callbacks as you leave a state?


Only do this if you're sure you don't need these listens / sensors in the next state. States only exit when jumping to another state, I believe.
_____________________
The difference between you and me = me - you.
The difference between me and you = you - me.

add them up and we have

2The 2difference 2between 2me 2and 2you = 0

2(The difference between me and you) = 0

The difference between me and you = 0/2

The difference between me and you = 0

I never thought we were so similar :eek:
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
01-03-2005 20:32
From: Shorahmin Femto
My question is about the state_exit handler. (Dare I say destructor?) Is there any reason, good practice, or efficiency to explicitly remove the callbacks as you leave a state?

There is no reason to explicitly remove those callbacks. Basically, when a new state is entered, all event callback parameters (llSetTimerEvent, llListen, etc) are reset to their default values.

Also, "state destructor" is a valid, though rarely used, alternative for describing state_exit :)
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
01-03-2005 20:36
I believe all state information is destructed on a state change. Meaning that any sensor repeat, timer or listen is stopped. Don't take my word on this, test it. LSL historicly has been notoriusly buggy when it comes to cross state events.

Listens i'm 99% sure were made so that if you open a listen in one state it is automaticly closed on state exit (you don't need to destruct it). A state exit & entry's are not called when you link to a state from it self.


Example: In one set of my scripts i'm getting dataserver events sent to the wrong script in the object, took hours to figure out (wouldn't have been a problem except for a modulo by zero). Solution was to just check the paramaters of the modulo.
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river.
- Cyril Connolly

Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence.
- James Nachtwey
Danny DeGroot
Sub-legendary
Join date: 7 Jul 2004
Posts: 191
01-03-2005 22:10
Hi Shorahmin,

I don't know if it's a bug or a design decision, but in my experience, timers are a little different from the other mechanisms that can be fired off in an event.

I find it helpful to think of each script as having one timer mechanism, which lives outside all states, but which can be started and stopped from any state.

If you'll try this inside a simple prim...

CODE


vector dog_color = <1.0,0.0,0.0>;
vector cat_color = <0.0,1.0,0.0>;

default
{
state_entry()
{
llSay(0, "Ready.");
}

touch_start(integer total_number)
{
llSetTimerEvent( 3.0 );
state dog;
}
}

state dog
{

state_entry() { llSetColor( dog_color, ALL_SIDES ); }

timer() { llWhisper( 0, "Woof" ); }

touch_start(integer total_number) { state cat; }
}

state cat
{

state_entry() { llSetColor( cat_color, ALL_SIDES ); }

timer() { llWhisper( 0, "Meow" ); }

touch_start(integer total_number) { state dog; }
}



...you'll see that both the "dog" and "cat" states must set their own intercepts to the timer, which are then cleaned up as each state exits. However, the timer itself is started in the default state, and could be stopped in yet another one.

== danny d.
Shorahmin Femto
Senior Citizen
Join date: 27 Feb 2004
Posts: 34
01-04-2005 08:29
Thanks Danny, works just like you said it would. But it raises other questions - Questions related to obssessions about memory leaks.

When is the timer instantiated, at rez time but with a setting of 0.0? Or perhaps, the first time the script encounters llSetTimerEvent()?

Seems like once a timer is instantiated(whenever) it stays with you no matter how many states you go through, but you can change the settings for time and callback. True?

By commenting out a line or two in Danny's script you can demonstrate that as you leave a state, the timer is still around with its old timer value but the callback has been inactivated. Executing another llSetTimerEvent() doesn't instantiate another timer, it just changes the original one. True?

Last of all, there's some suspicion that timers work differently than other event handlers. Does the above apply to sensors and listens, etc. ? Or is each a science project by itself? LOL

An addendum: I tested listens and they do seem to work the way Christopher Omega described. I couldn't find any evidence that they had any residual life after a state change like timer values.
_____________________
Time is granular, Object Oriented, re-entrant, recursive, and therefore manifold.
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
01-04-2005 12:59
Hmm... that "resident timer" ability sounds more like a bug then valid functionality; it doesnt follow the same standards as all other event-callback parameters do. I wouldn't rely on it if I were you.
==Chris
Rickard Roentgen
Renaissance Punk
Join date: 4 Apr 2004
Posts: 1,869
01-04-2005 14:22
From: Christopher Omega
There is no reason to explicitly remove those callbacks. Basically, when a new state is entered, all event callback parameters (llSetTimerEvent, llListen, etc) are reset to their default values.

Also, "state destructor" is a valid, though rarely used, alternative for describing state_exit :)


not entirely true. It "should" be that way but here's an experiment for you. put a timer in state default. get out an active script scanner. it should show up as active. on the touch even go to a second state with nothing but an empty state entry event. unselect the object (as selected object often show active). Scan again, it will most likely still show active (inconsistant). now try again only this time in the state_exit event for default put llSetTimerEvent(0.0); on touch switch to you second state with no timer and make sure to unselect. Scan and see if that kept it from showing up active.
_____________________
Shorahmin Femto
Senior Citizen
Join date: 27 Feb 2004
Posts: 34
01-04-2005 14:53
From: Christopher Omega
Hmm... that "resident timer" ability sounds more like a bug then valid functionality; it doesnt follow the same standards as all other event-callback parameters do. I wouldn't rely on it if I were you.
==Chris


I agree Chris. I originally got in the habit of removing ALL event callbacks because of unpredictable behavior. Manually cleaning up everything in the state-destructor helped at the time (around version 1.2). Things seem to have improved.
_____________________
Time is granular, Object Oriented, re-entrant, recursive, and therefore manifold.
Kurt Zidane
Just Human
Join date: 1 Apr 2004
Posts: 636
01-04-2005 15:23
I rearely use more then one state. But I have a feeling even with one state scripts, some of this has an effect. ie rezzing, teleporting, copying..?
blaze Spinnaker
1/2 Serious
Join date: 12 Aug 2004
Posts: 5,898
01-04-2005 17:07
Avoid state changing if you can. Developing your own state machine is just as easy and far less murky.
_____________________
Taken from The last paragraph on pg. 16 of Cory Ondrejka's paper "Changing Realities: User Creation, Communication, and Innovation in Digital Worlds :

"User-created content takes the idea of leveraging player opinions a step further by allowing them to effectively prototype new ideas and features. Developers can then measure which new concepts most improve the products and incorporate them into the game in future patches."
Corva Raven
Registered User
Join date: 15 Dec 2004
Posts: 3
state of being
01-04-2005 21:01
From: blaze Spinnaker
Avoid state changing if you can. Developing your own state machine is just as easy and far less murky.


that's a shame. it seems to me, if an event is set to fire, it should always fire, regarless of what state was entered.

if no event handler is present, then the fired event is just lost.

my testing has shown that changing states does 'break' the firing of sensor events (at least).

i wanted a sensor repeat that would detect my presence. this example is a bit contrived, but states my point. basically, the default state starts the sensorRepeat and immediatly switches to the near state. when the near state receives a no_sensor event, it switches to the far state, and when far gets a sensor event, it switches to the near state.

CODE

key gOwner;

default
{
state_entry()
{
gOwner = llGetOwner();

llSensorRepeat( "", gOwner, AGENT, 5, PI, 3.0 );
state near; // assume near
}
}

state near
{
state_entry()
{
llInstantMessage( gOwner, "Nearby" );
}

no_sensor()
{
state far;
}

touch_start( integer count )
{
llInstantMessage( gOwner, "near" );
}
}

state far
{
state_entry()
{
llInstantMessage( gOwner, "Not nearby" );
}

sensor( integer count )
{
state near;
}

touch_start( integer count )
{
llInstantMessage( gOwner, "far" );
}
}


being new to LSL, but not new to coding and event driven programming, i assumed that changing state did not destroy anything, and the correct events would still be fired. i obviously discovered my assumptions were wrong. if i set something up to fire events, i expect the events to be fired no matter which state i'm in. it's up to the state to handle it in its own specific way. in the above example, sensor and no_sensor are never fired, and IMHO they should.

to work around, i just have to call sensorRepeat in each state_entry, but that doesn't seem 'correct'. however, it seems as though setTimerEvent works as i expect based on danny's code. if anything, they are inconsistent.
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
01-04-2005 23:52
From: Corva Raven
to work around, i just have to call sensorRepeat in each state_entry, but that doesn't seem 'correct'. however, it seems as though setTimerEvent works as i expect based on danny's code. if anything, they are inconsistent.


~_~ get use to the inconsistentcies.

I usualy don't use states because of the loss of events during the state change itself. I only ever use states for getting permissions.
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river.
- Cyril Connolly

Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence.
- James Nachtwey
Shorahmin Femto
Senior Citizen
Join date: 27 Feb 2004
Posts: 34
01-05-2005 08:28
Thanks to all. Good thread I think, but the subject has drifted so I'm starting a new thread called What Use States?
_____________________
Time is granular, Object Oriented, re-entrant, recursive, and therefore manifold.
Alicia Eldritch
the greatest newbie ever.
Join date: 13 Nov 2004
Posts: 267
01-05-2005 23:57
Yeah, it can't hurt to clean everything up, even if it MIGHT not be necessary.

C does teach good habits too!

Also, don't trust ANY "automagic" bugs/features in LSL.
_____________________

<xNichG> anyone have a good way to visualize 3d vector fields and surfaces?
<Nap> LSD?


"Yeah, there's nothing like literal thirst to put metaphorical thirst into perspective"
- Get Your War On

"The political leader loves what you could become. It is only you he hates."
- Allan Thornton
Danny DeGroot
Sub-legendary
Join date: 7 Jul 2004
Posts: 191
01-06-2005 15:46
From: Shorahmin Femto

When is the timer instantiated, at rez time but with a setting of 0.0? Or perhaps, the first time the script encounters llSetTimerEvent()?

Seems like once a timer is instantiated(whenever) it stays with you no matter how many states you go through, but you can change the settings for time and callback. True?



This finally provoked me to do a simple test I'd been meaning to try for awhile.

CODE


default
{
state_entry()
{
llWhisper( 0, "Heap is " + (string)llGetFreeMemory() );
llSetTimerEvent( 0.5 );
llWhisper( 0, "Heap is " + (string)llGetFreeMemory() );
llSetTimerEvent( 0.0 );
llWhisper( 0, "Heap is " + (string)llGetFreeMemory() );
}

}



I got readings of: 15987, 15958, and 15958.

So, yeah, it looks like at least part of the timer hookup is allocated the first time it's called, and then the script is stuck with the RAM overhead.

That seems in line with what I've read about the high-water-mark approach LSL takes to memory management...apparently lists retain the maximum memory allocated to them throughout their lifetime during a script run.

I should see what happens with a particle system, if I ever start caring that much about particles :p

== danny d.
Nexus Nash
Undercover Linden
Join date: 18 Dec 2002
Posts: 1,084
01-06-2005 18:50
sensor, listen and timer are killed on any state change.
_____________________