Jump to content

Event handling: Sequentially or parallel?


primerib1
 Share

You are about to reply to a thread that has been inactive for 633 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

Let's say my script is busy handling a touch event.

Then someone or something sent a message to a channel that my script is listening to.

Will the script need to finish its touch_end() handler first before it triggers the listen() handler?

What if the event are the same? So the script is still busy doing touch_end() but another touch happened? Will it first complete the first touch_end() handling then picks up on the second touch, or will it run another touch_end() handling while the first one is still doing its job?

Or another scenario, can a script 'pauses' in state_entry() waiting for a listen() event to happen before continuing?

Edited by primerib1
Link to comment
Share on other sites

From the LSL wiki (https://wiki.secondlife.com/wiki/Category:LSL_Events), "Events do not interrupt each other, but instead are queued FIFO, though the state_entry event can jump the queue."

For your other scenario, no, you can't pause an event so another event can execute. You'd need to put the continuation code into the listen event itself.

  • Thanks 2
Link to comment
Share on other sites

1 hour ago, KT Kingsley said:

From the LSL wiki (https://wiki.secondlife.com/wiki/Category:LSL_Events), "Events do not interrupt each other, but instead are queued FIFO, though the state_entry event can jump the queue."

For your other scenario, no, you can't pause an event so another event can execute. You'd need to put the continuation code into the listen event itself.

I see. Thanks!

Link to comment
Share on other sites

I think it's more like the sim gathers as many touches as possible and raises them in one event to the touch() handlers.

But when the touch() handlers are busy it will not invoke the handlers again, but collect the unhandled touches to be queued and raised when the touch() handlers have completed.

Link to comment
Share on other sites

Okay maybe for an example case, one scenario in my script:

I have a script, let's say it's "sub-side". It listens for commands from "master-side", and responds. But some commands will require the "sub-side" to interrogate the avatar via RLV.

So the "sub-side" script needs to issue an RLV command via llOwnerSay() and listen to RLV's response, then based on the response formulate the answers to be sent back to "master-side".

Unfortunately, since event handling is sequential, I can't just 'pause' the listen() handler there and expect it to be available to listen to the RLV response.

Trying to shoehorn everything into one script by having variables holding the "listening mode" gets hairy and overly complicated, so at the moment I decided to move the second listener (to receive RLV responses) to a separate script having its own listen() handler, and feeds the results back to the "sub-side" script via LSD. The "sub-side" script controls this "rlv-recv" script via link message, turning the "rlv-recv" script on (listening) or off (not listening) as needed.

Edited by primerib1
Link to comment
Share on other sites

As already mentioned, once an event begins, it must finish its execution before another event can run. Newly triggered events will be queued up.

clicking on a prim normally results in up to 3 different events (if present in the script):

  • touch_start() triggers when someone first clicks
  • touch() repeatedly triggers as long as someone is holding their click
  • touch_end() triggers when someone releases their click

So if you're holding down the click, you'll be triggering multiple touch events. I believe it is entirely possible for a listen event to be queued up and executed in between those touch events if it happens before you (or anyone else who may be presently clicking on it) release the click.

Edited by Fenix Eldritch
  • Thanks 1
Link to comment
Share on other sites

6 minutes ago, Fenix Eldritch said:

As already mentioned, once an event begins, it must finish its execution before another event can run. Newly triggered events will be queued up.

This only applies to one script right?

Other scripts can process the same event (e.g., listen()) in parallel?

Link to comment
Share on other sites

Correct, each script should have its own event processing and queue. It would be chaos if they weren't isolated.

Edit: I'm not quite sure I follow your uses case as to why you need a second script though... Could you separate them by using a different channel?

Edited by Fenix Eldritch
  • Thanks 1
Link to comment
Share on other sites

1 hour ago, primerib1 said:

Trying to shoehorn everything into one script by having variables holding the "listening mode" gets hairy and overly complicated

Indeed, but either that of using multiple channels to disambiguate response types is ~usually the best option. If your second script can absolutely pinky-promise to send responses in a timely manner, waiting on a change to LSD caused by another script does seem like an interesting new paradigm.

Quote
// script A:
string request = "Sensor";
llLinksetDataDelete(request);
llMessageLinked(LINK_THIS,-5,request,NULL_KEY);
string response;
llResetTime();
do { llSleep(0.2);
}while((""==(response=llLinksetDataRead(request))) && (llGetTime()<5.0));
llOwnerSay(response);
    
//script B:
link_message(integer i, string s, key k)
{  if("Sensor"==s)
   {   llSensor(...);
   }
}
sensor(integer n)
{  list results; 
  while(~--n)
  {  results+=llDetectedName(n);
  }
  llLinksetDataWrite("Sensor",llList2CSV(results));
}
no_sensor() // IMPORTANT, else A could end up in an infinite loop.
{  llLinksetDataWrite("Sensor"," ");
}

 

  • Like 1
Link to comment
Share on other sites

Yup, I'm using LSD as a "poor girl's multithreading sync"

I have this function:

string WaitForLSD(string lsd_key) {
    string value = "";
    while ("" == value) {
        llSleep(0.1);
        value = llLinksetDataRead(lsd_key);
    }
    return value;
}

(Not optimized yet, I'm sure it can be optimized somehow.)

As long as the awaited script promise to put in a value in there, then I can use it like this:

for (i=0; i<llGetListLength($AvailOutfits); ++i) {
    folder = llList2String($AvailOutfits, i);
    InvokeRLVRecv("inspect!" + folder);
    SayToMaster("@OK:folder=" + folder + "=" + WaitForLSD(folder + ":state"));
}

For every iteration, it stops at WaitForLSD there. The InvokeRLVRecv() function is the trigger that makes the other script does the interrogation.

 

Link to comment
Share on other sites

10 minutes ago, primerib1 said:

(Not optimized yet, I'm sure it can be optimized somehow.)

  • strings are initialized to "", setting that is redundant.
  • You'll want to remove old values from the key, there are many ways to make the protocol, but you could perhaps write some additional information into the value of the key to cleanse it of any old response.
Link to comment
Share on other sites

17 minutes ago, Quistess Alpha said:

You'll want to remove old values from the key, there are many ways to make the protocol, but you could perhaps write some additional information into the value of the key to cleanse it of any old response.

Well in my code, after all 'multithreading' are finished, I do a cleanup using llLinksetDataReset() 😄

Link to comment
Share on other sites

Just now, Love Zhaoying said:

Currently, I have event scripts pass off their info to "client" scripts via linked message, so 1) the event script script has less overhead between events, and 2) the client script doesn't have to stall / wait for events (or be blocked by events).

 

Forgot: And the main client script is itself asynchronous, so in the middle of a task it can pause and a new link_message() can fire. 

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 633 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...