Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Deactivating and Reactivating Scripts with llSetScriptState()

Luz Melbourne
Registered User
Join date: 26 Nov 2006
Posts: 9
01-30-2007 18:34
I've been working on a modular system (a scene-rezzer, an intercom, a security system, and who-knows-what else) with several scripts that communicate via link messages. As a conscientious scripter, I am trying to make my scripts' load on the system as low as possible without significantly compromising functionality.

From watching the video of the Mono demonstration at (wherever it was), I learned that, under the current scripting engine, even the tiniest of my scripts is taking up the same amount of memory as the biggest, bulkiest single script in SL. Later, I learned that, even while sitting idle, each script will still take a little bit of a sim's processing power.

That brought my mind to a the "llSetScriptState()" function I'd seen in the LSLWikki and shrugged off earlier.

My first concern about the deactivating scripts in such a manner was whether the script would be suspended, then resume from whence it left off when it was reactivated, or it would restart when reactivated. The documentation I found didn't make this very clear to me, so I did a little experimenting. What I found out was: When a script is deactivated using llSetScriptState(), or via the "Running" check box, then reactivated in a like manner, the script will resume from the point at which it was stopped, with its variables intact.

The way I've already started implementing this is:

The script that does the actual work (the scene setter module), has a state called "standby", which is called after the script has initialized and looks something like:

CODE

state standby
{
state_entry()
{
llSetScriptState(llGetScriptName(), FALSE);
}

link_message(integer sender_num, integer num , string str, key id)
{
if(num == CMD_BUILD)
{
state SceneSelect;
}
}
}


(BTW: Hey, everybody... it looks like the Lindens have put up their own LSL Portal again.)

When the control module receives a command to build a scene, it wakes the Scene Setter up with llSetScriptState("SceneSetter", TRUE), then sends it the proper link message. Once Scene Setter has done it's job (or the scene selection dialog times out), it goes back to the standby state (and deactivates itself again, of course).

The only thread I could find on the forums that came close to discussing the starting and stopping of scripts in such a manner is was... one I lost the URL of when I cut and pasted the URL of the LSL Portal. :-o

Now, here's a couple more questions that maybe someone else can answer:

How are suspended scripts stored?
  1. Once the script is deactivated, it shouldn't take up processor resources, but will it still take up its full allotment of simulator memory?
  2. The scripts I'm currently putting to sleep are only used occasionally, but a script were to be deactivated and reactivated frequently, would that put a burden on SL's already over-taxed asset server?
Luz Melbourne
Registered User
Join date: 26 Nov 2006
Posts: 9
01-30-2007 19:23
Lot of good that edit did. :)

Oh, another question... When are we going to see Mono implemented so I don't have to worry about this stuff as much?
Lex Neva
wears dorky glasses
Join date: 27 Nov 2004
Posts: 1,361
01-31-2007 10:01
From: Luz Melbourne

How are suspended scripts stored?

* Once the script is deactivated, it shouldn't take up processor resources, but will it still take up its full allotment of simulator memory?


I believe that the script's memory/state is serialized and stored in the object. It might be cached in some way so that it doesn't go all the way out to the disk and back. I do know that once you set a script not-running, it stops having the per-frame simulator processing overhead that all running scripts have.

From: someone

* The scripts I'm currently putting to sleep are only used occasionally, but a script were to be deactivated and reactivated frequently, would that put a burden on SL's already over-taxed asset server?


Well, scripts get serialized and tossed around all the time. Every time you shift-drag something with a script in it, this happens. Same for when you take an object and rez it. The sim seems to be able to instantiate an object with a script and start the scripts running on their way almost instantly, so I think that deactivating and reactivating probably isn't a big deal. I wouldn't do it several times a second, but I imagine that if you're deactivating on the order of seconds, and if the result is that the script is spending a majority of its time deactivating, that'll be a big win as far as sim performance.


As to mono, don't hold your breath. I've heard some talk of this year, but I'm not making any mono-based plans at the moment.
Gaius Goodliffe
Dreamsmith
Join date: 15 Jan 2006
Posts: 116
02-01-2007 13:06
Heads up on one thing: llSetScriptState does not deactivate its target immediately, even if the target is itself. I once tried to make a script suspend at a specific point using it like this:

// Go to sleep
llSetScriptState(self, FALSE);
// I'm awake again, do stuff

The idea was, I wanted the script in question to go to sleep until woken up by another script; an llSleep that worked with an indefinite interval. You do this sort of thing a lot in multi-threaded applications. Unfortunately, the above construction doesn't do what you'd think. The script continues to execute for some random interval, then stops at an unpredictable point later. :( In the end, I had to rig up something much more complicated with link messages to simulate what I wanted.
Jacques Groshomme
Registered User
Join date: 16 Mar 2005
Posts: 355
02-01-2007 14:17
From: Luz Melbourne

(BTW: Hey, everybody... it looks like the Lindens have put up their own LSL Portal again.)

Lindens aren't behind it. The residents are. We're just using the official wiki to host it. Check out the stickies in this section or the discussion tabs in the Wiki itself. :)


In regards to your original post, I did something similar in a single prim dance machine I wrote. The scripts assigned to individual dancers were all deactivated, then set to awaken whenever needed. I used llSetScriptState() to reenable them, did llSleep(1.0) to give it time to actually happen, then llResetOtherScript() to clear out all the variables and restart fresh.
Jacques Groshomme
Registered User
Join date: 16 Mar 2005
Posts: 355
02-01-2007 14:22
From: Luz Melbourne
Lot of good that edit did. :)

Oh, another question... When are we going to see Mono implemented so I don't have to worry about this stuff as much?

They recently announced in the blog that they believe they're close to overcoming one of the last major obstacles. Hopefully in the not-so-distant future.
Luz Melbourne
Registered User
Join date: 26 Nov 2006
Posts: 9
02-04-2007 16:38
Thanks for the input, guys.

I think I'm going to have to do some longer term testing on the state integrity issue I mentioned in my first post. I think there may be instances where a dormant script will reset, while a running script will keep it's state. After the last update, when all the servers where restarted, my rezzer wasn't working until I went in and manually reset the scripts, and I was wondering if it had been because the inactivated script had been reset, so that while it was re-initializing after having woken up, it missed its link message.

The more I think about it, the more I think it might have missed its link message after waking up, but it probably was just due to other timing factors. Shoot... I need to start keeping a log of such problems (and I doubt I could figure out what I did from my chat logs even if I wanted to slog through them, since I didn't have enough debug messages to tell exactly what I was doing). I added "llSleep(0.5);" between the wakeup and the link message, but I still decided to comment out the deactivation command in the rezzer script for some reason.

Still, I think I'm going to modify my test scripts a little bit, and keep it rezzed in my (New! Yippee! :D So nice to have a 1024m rather than a 512m.) workshop, plus have another copy that I rez, check the status, and take back into my inventory, for a month or two before I un-comment the self-deactivation command in my rezzer script-- at least the one that's in a semi-public place.
_____________________
-----
Luz Melbourne
(Who speaks neither Spanish nor Australian.)
Gaius Goodliffe
Dreamsmith
Join date: 15 Jan 2006
Posts: 116
02-05-2007 03:29
From: Luz Melbourne
I think there may be instances where a dormant script will reset, while a running script will keep it's state.

I'm not sure if that's possible. I know from my own experiments that you can't reset a suspended script using llResetOtherScript. For example, the following:

llSetScriptState(script2, FALSE);
llResetOtherScript(script2);
llSetScriptState(script2, TRUE);

...will NOT reset script2. If script2 is suspended, you need to wake it up before resetting it or it doesn't reset, even after it's woken up later (thus shooting down another idea I had had for trying to have a suspended script wake up in a known state -- you can't reset it before waking it up, and if you wake it up, reset it, then suspend it again, you don't know how much of it executed between being reset and going back into suspended animation). It would appear that it's next to impossible to change the state of a suspended script -- it's the one thing almost guaranteed to keep its state when everything else would lose it.

Anyhow, hope this info is useful to someone. I spent a lot of time playing with those functions before finally realizing they couldn't be used for what I wanted. :p
Luz Melbourne
Registered User
Join date: 26 Nov 2006
Posts: 9
Darn...
02-05-2007 18:07
Just did a test.

I put two scripts in a cube.

The first is called "Control".

CODE

default
{
state_entry()
{
llSay(0, "Starting controller.");
state running;
}
}

state running
{
state_entry()
{
llSay(0, "Starting script.");
llSetScriptState("Test Script", TRUE);
}

touch_start(integer total_number)
{
state stopped;
}
}

state stopped
{
state_entry()
{
llSay(0, "Stopping script.");
llSetScriptState("Test Script", FALSE);
}

touch_start(integer total_number)
{
state running;
}
}


The second is called "Test Script".

CODE

integer count = 0;
default
{
state_entry()
{
llSay(0, "Script Starting.");
llSetTimerEvent(1.0);
llListen(0, "", llGetOwner(), "");
}

listen(integer channel, string name, key id, string message)
{
llSay(0, message);
}

timer()
{
llSay(0, (string) (++count));
}
}


I let the script run for a while, then click on the cube. The counting stops. When I click on it again, the counting resumes where it left off.

If I take the cube into inventory while the test script is active, then re-rez it, the count resumes from where it left off.

If I take the cube into inventory while the test script is inactive, then re-rez it and click on it, the script starts in the default state and starts counting from 1.

So... Whether it's a bug or a feature... that means that a non-running script won't retain its state when the object in which it is located is in inventory, and probably means that my hypothesis of it losing its state when the server was reset was correct.
_____________________
-----
Luz Melbourne
(Who speaks neither Spanish nor Australian.)
Lex Neva
wears dorky glasses
Join date: 27 Nov 2004
Posts: 1,361
02-07-2007 09:35
From: Luz Melbourne

So... Whether it's a bug or a feature... that means that a non-running script won't retain its state when the object in which it is located is in inventory, and probably means that my hypothesis of it losing its state when the server was reset was correct.


Nice work! I'd say that this is pretty inconsistent behavior, bordering on a bug. I wonder if LL will change it if we bug-report it.
Luz Melbourne
Registered User
Join date: 26 Nov 2006
Posts: 9
02-07-2007 15:46
I doubt it... I'd say it's probably akin to the permissions "exploit" (See the Knowledge Base article and archived forum thread while investigating that matter.) I discovered last night when buying a "Transfer, No-Copy" item to send to my alt (rather than logging off, logging on as the alt, and finding the store again). Yes, BTW, I did send an IM to the creator of the box, pointing out the security hole.

Even if the script status inconsistency would be easier to fix than the above-mentioned "feature", it would probably be low on the Lindens' list of priorities, especially with the expectation of contracting-- er, I mean "implementing" Mono in the near future.

Then again, I guess it wouldn't hurt to report it anyway.
_____________________
-----
Luz Melbourne
(Who speaks neither Spanish nor Australian.)