Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

llSensor & process-flow ~ Help needed to Understand

Debbie Trilling
Our Lady of Peenemünde
Join date: 17 Oct 2006
Posts: 434
07-07-2007 09:52
Hoping someone can help me clear up what is obviously a fundemental misunderstanding on my part in process-flow and/or llSensor.

I am simply trying to use llSensor to determine if the Owner is within range; if not then the name of the nearest Agent and failing that the key of the object itself. All this is working fine within the sensor() event itself.

The problem I'm *seemingly* having, or at least what I originally believed I am having, is making the key so determined by the sensor() event avaliable to other functions outside of the event itself. However, it could be that I'm missing a fundemental in the process-flow of scripts in LSL.

The follow code demonstrates the problem (and is a much simplified version of the code I am working on.)

~ On Touch, FuctionOne() is called
~ FunctionOne calls FunctionTwo()
~ FunctionTwo() makes the llSensor() call and initiates the sensor() event
~ The sensor() event both successfully populates TempTarget & assigns this value to GlobalTarget
~ However, when FunctionTwo() comes the use the value in GlobalTarget after the llSensor() call, it is NOT the same value as was successfully populated in the sensor() event

//*************************************************************************
key GlobalTarget;
integer DoSensor = TRUE;


FunctionTwo()
{
if (DoSensor == TRUE)
{
llSay(0, "DEBUG POINT 2 " + llKey2Name(GlobalTarget));
//llSensor() call
llSensor("", NULL_KEY, AGENT, 5, PI);
llSay(0, "DEBUG POINT 7: GlobalTarget is " + llKey2Name(GlobalTarget));
//use GlobalTarget that was correctly populated in the sensor() event
if (GlobalTarget == llGetOwner())
{
llSay(0, "GlobalTarget has been CORRECTLY populated";);
}
else
{
llSay(0, "GlobalTarget has been INCORRECTLY populated";);
}
}
}


FunctionOne()
{

llSay(0, "DEBUG POINT 1: GlobalTarget is " + llKey2Name(GlobalTarget));
FunctionTwo();
llSay(0, "DEBUG POINT 8: GlobalTarget is " + llKey2Name(GlobalTarget));
}

//************************************

default
{
state_entry()
{
llSay("Hello, Avatar";);
}

//************************************

touch_start(integer touch_number)
{
GlobalTarget = llGetKey();
FunctionOne();
}

//************************************

sensor(integer sensor_number)
{
key TempTarget;

integer i;
for (i = 0; i < sensor_number; i++)
{
llSay(0, "DEBUG POINT 3 " + llKey2Name(llDetectedKey(i)));
if (llDetectedKey(i) == llGetOwner())
{
llSay(0,"The Owner is " + llKey2Name(llDetectedKey(i)));
TempTarget = llDetectedKey(i);
llSay(0, "DEBUG POINT 4: TempTarget is " + llKey2Name(TempTarget));
}
}
llSay(0, "DEBUG POINT 5: TempTarget is " + llKey2Name(TempTarget));
GlobalTarget = TempTarget;
llSay(0, "DEBUG POINT 6: GlobalTarget is " + llKey2Name(GlobalTarget));
}
}
//*************************************************************************

The DEBUG POINTS in the above code show my (obviously erroneous) *expectation* for process-flow:

DEBUG POINT 1
DEBUG POINT 2
DEBUG POINT 3
"The Owner is....." (if Owner is within range)
DEBUG POINT 4 (if Owner is within range)
DEBUG POINT 5
DEBUG POINT 6
DEBUG POINT 7
"GlobalTarget has been [CORRECTLY/INCORRECTLY] populated" (dependant on whether GlobalTarget == GetOwner())
DEBUG POINT 8

BUT what is actually being produced is:

DEBUG POINT 1 (correctly populated)
DEBUG POINT 2 (correctly populated)
DEBUG POINT 7 (should be name of Owner but is actually name of Object)
"GlobalTarget has been INCORRECTLY populated"
DEBUG POINT 8 (should be name of Owner but is actually name of Object)
DEBUG POINT 3 (correctly populated)
"The Owner is....."
DEBUG POINT 4 (correctly populated)
DEBUG POINT 5 (correctly populated)
DEBUG POINT 6 (correctly populated)

So, what am I misunderstanding or doing wrong & how do I correct it?

Thanks in advance :)

DebbieT
XxX
Ynot Fenua
Registered User
Join date: 11 Oct 2006
Posts: 18
Process flow
07-07-2007 10:16
The problem that you are facing is the same with any asynchronous event - (like Sensor, Touch, dataserve).

even though the event might be triggered immediately (i.e. there is an object in range), the event wont get called until after the current event or function completes - it will not act as an intterupt.

If you want to process the output of the Sensor - then you could :

Do the processing in the sensor event or

Store the data in a global, with a flag to say that the Sensor event has been triggered, and then use a timer to periodically check, and only use the data once the Sensor even function has actually fired.

I would suggest having the processing in the Sensor Event - or called from it - would be the best idea to be honest
Debbie Trilling
Our Lady of Peenemünde
Join date: 17 Oct 2006
Posts: 434
07-08-2007 03:59
Thanks for your reply Ynot, and for our in-world conversation. This has certainly made it clear what is actually happening & cleared up my misunderstanding about the number of llSetTimerEvent() calls permitted in any given script.

Performing the reliant processing within the sensor() event itself is not an option in the actual script being written (as opposed to the demonstration code above).

Therefore we'll need to use a flag (""EndSensor";) to indicate whether the sensor event() event has completed its tasks. A llSetTimerEvent() function will be employed to periodically check the status of EndSensor, only allowing the reliant code to be executed when EndSensor = TRUE.

The script being written already has a llSetTimerEvent() call within a listen() event, and what I'm struggling at the moment to understand is how a second llSetTimerEvent() is implemented in the code so that the timer() event differentiates between the sensor() event and the listen() event....two timer() events?? how?? flags and an IF-ELSE within the timer() event?? Note, the listen() event has been removed long before the sensor() event kicks-in.

Bottom-line, I suppose, is *how* is the above demonsration code adapted to allow the llSetTimerEvent()/EndSensor solution to be implemented in code?

Thanks in advance

DebbieT
XxX
Qie Niangao
Coin-operated
Join date: 24 May 2006
Posts: 7,138
07-08-2007 08:10
Now I'm confused.
From: Debbie Trilling
Note, the listen() event has been removed long before the sensor() event kicks-in.
This seems to say that there aren't two overlapping intervals being timed, but rather first one, and then the other. If so, then a global flag variable could be used to distinguish between the two, or if otherwise appropriate, different states for the logic in effect at the time of the listen and for that during the sensor.

But this shouldn't be necessary, except for:
From: someone
Performing the reliant processing within the sensor() event itself is not an option...
..., which is most puzzling. If the timer is waiting on the completion of a sensor scan in order to trigger something, how can it be that the sensor event itself can't be used to trigger the same thing? (Well, yes, if the timer is triggering something else on a regular beat with which the sensor-triggered thing must coincide--but that doesn't seem to be happening here.)

So unless I'm missing something, it really seems like the processing should be in the sensor() event, and no timer should be needed for that part at all.
Debbie Trilling
Our Lady of Peenemünde
Join date: 17 Oct 2006
Posts: 434
07-08-2007 09:03
Thanks for your reply, Qie..."isn't an option" is probably too strong, lets amend that too "very inefficient".

The function containing the llSensor() is called from twelve different places within the code ~ in eleven of those cases, the key variable that I want llSensor() to populate is already known (NULL). Only one of the twelve calls requires a llSensor() call to populate the variable.

So, whilst I have been aware that I *could* put the reliant code within the sensor() event, it would mean eleven unnecessary llSensor() calls. An IF statement currently determines which one of the twelve is to use llSensor().

Whilst writing this, I think a solution might be to
1) move the llSensor() call to before the call to FunctionTwo() for the twelfth case
2) add a *copy* of the reliant code into the sensor event()
3) use an IF statement to ensure that the reliant code is *not* re-processed for the twelfth case
or 4) restructure so that the reliant code is in its own function & this is called from eleven locations normally and once from within the sensor() event

Yep, this would work! Thanks Ynot & Qie for your contributions & for making me think! :)

DebbieT
XxX