You are currently in the Forum Archive. All content within this area is Read-Only and cannot be modified. Active Forums can be found here.
Reply
New Resident
Pauric Blackheart
Posts: 2

how to exit a continuous loop

Being a total dumbass this is driving me nuts.

I have a simple script in a switch that sends a start/stop message to a prim to rotate - it works fine.

I have a second switch that uses the same script that sends a start/stop message (on a different channel) to another prim to move the prim back and forth in the x only. I want the prim to move until the switch is touched again which means using a loop in the target script, but for the life of me I can't get the target script to hear the stop message.

Here is the Switch Script:

(I use a lot of feedback llSays to see where things break down)

//list COG_CHANNELS = ;  // com channels for parts
integer COG_CHAN01 = -50001;
//integer COG_CHAN02 = -50002;
//integer COG_CHAN03 = -50003;
integer ON_OFF;
integer HANDLE_MOVE = 20;
rotation HANDLE_ROT;
string MSG_OPTS;
string DOOR_SND = "Door lock";
float SOUND_VOL = 1;
default
{
    state_entry()
    {
        HANDLE_ROT = llEuler2Rot(< 0.0, HANDLE_MOVE, 0.0> * DEG_TO_RAD);
    }
     
    touch_start(integer num_detected)
    {
        if (ON_OFF == 0)
        {
            HANDLE_ROT.s *= -1;
            llSetLocalRot( HANDLE_ROT * llGetLocalRot() );
            llPlaySound(DOOR_SND,SOUND_VOL);
            llSleep(0.5);
         
            MSG_OPTS = "Pump";
            llSay(0, "Pump init");
            llSay(COG_CHAN01,MSG_OPTS);
            //llSay(COG_CHAN02,MSG_OPTS);
            //llSay(COG_CHAN03,MSG_OPTS);
            llSay(0, "passed it");
            ON_OFF = 1;
        }
        else
        {
            HANDLE_ROT.s *= -1;
            llSetLocalRot( HANDLE_ROT * llGetLocalRot() );
            llPlaySound(DOOR_SND,SOUND_VOL);
            llSleep(0.5);
         
            MSG_OPTS = "Stop";
            llSay(0, "Pump Stop");
            llSay(COG_CHAN01,MSG_OPTS);
            //llSay(COG_CHAN02,MSG_OPTS);
            //llSay(COG_CHAN03,MSG_OPTS);
            llSay(0, "passed it");
            ON_OFF = 0;
         
            }
    }
}

============================================

Here is the Target Script:

integer LISTEN_CHANNEL = -50001;

integer ON_OFF = 0;

vector pos;

vector storepos;

default

{

    state_entry()

    {

      pos = llGetLocalPos();

      storepos = pos;

      llListen(LISTEN_CHANNEL,"","","");

    }

    listen(integer channel, string name, key id, string message)

    {

      ON_OFF = 1;

        do

        {

            if (message == "Pump")

            {

                llSay(0,"heard Pump");

                llSay(0, message);

                pos.x -= 0.3;

                llSetPos(pos);

//              llSleep(0.3);

                pos.x += 0.3;

                llSetPos(pos);

//              llSleep(0.3);

            }

            else

            {

                llSay(0,"heard Stop");

                llSay(0, message);

                ON_OFF = 0;

            }                 

        }

        while (ON_OFF == 1);

    }

}

Honored Resident
Rygel Ryba
Posts: 808

Re: how to exit a continuous loop

Reply to Pauric Blackheart - view message

Your second script is where the problem is - you have an event that loops the first time it hears something and never stops - thus the listen event is never triggered again.

Put your "movement" inside a timer event. When the script hears the start command, do an llSetTimerEvent(0.3) (to match your sleep amount - which you can remove) and delete the loop - the timer will trigger 3.3 times per second and do the "loop". Then in your listen, when it heres the stop command, set the timer event to 0 (llSetTimerEvent(0.0)). This will stop the timer and your movement in the timer event won't trigger anymore until it hears the start command again.

RezIdentity SL Social Network for Mature/Adult SL Users and Content Creators (now in Beta)
Rolig Loon
Posts: 25,302
Registered: ‎10-05-2009

Re: how to exit a continuous loop

Reply to Pauric Blackheart - view message

Your target switch isn't going to hear a second message if it's still busy dealing with the first one. If I were you, I'd take most of the action that's currently in its listen event and put it in a timer. Use the timer's trigger period to move your object back and forth, and then use the listen event to simply process a signal to turn the timer on and off.

Not as dumb as I look
Dora Gustafson
Posts: 1,885
Registered: ‎10-05-2009

Re: how to exit a continuous loop

Reply to Pauric Blackheart - view message

You can't exit a continuos loop. You have disabled the scripts ability to handle new events as long as the listen event is busy doing your loop.

What you should do instead of using llSleep(), is to use the timer. When the timer event handler is triggered you can do your stuff. When it is not, the script can handle any new event.

New Resident
Pauric Blackheart
Posts: 2

Re: how to exit a continuous loop

Reply to Pauric Blackheart - view message

Thank you very much indeed - this was really helpful and after a few attempts I got it to work. OK, so its not the neatest or cleanest (need to add ListenRemove etc) but it does what I wanted and I now understand the whole issue of TimerEvents and timers much better.

Thanks to all who replied so promptly even though I had to leave it alone for awhile (RL work sucks).

Here (for other noobs) is how it ended up:

integer LISTEN_CHANNEL = -50001;
vector pos;
vector storepos;
default
{
    state_entry()
    {
      pos = llGetLocalPos();
      storepos = pos;
      llListen(LISTEN_CHANNEL,"","","");
    }
    listen(integer channel, string name, key id, string message)
    {
        if (message != "Pump")
            {
                llSetTimerEvent(0.0);
                llResetScript();
            }
            else
            {
                llSetTimerEvent(0.3);
            }                   
    }
    timer()
    {
        pos.x -= 0.3;
        llSetPos(pos);
        pos.x += 0.3;
        llSetPos(pos);
    }
}
Rolig Loon
Posts: 25,302
Registered: ‎10-05-2009

Re: how to exit a continuous loop

Reply to Pauric Blackheart - view message

Congratulations! That's a nice job.

If you want to optimize even more, consider this. A binary switch only has two positions: ON and OFF. Since that's the case, each command coming to the switch is just going to reverse whatever position the switch has currently. You could squish your listen event into a single line and do the same (almost) with the timer event, like this....

integer LISTEN_CHANNEL = -50001;
vector pos;
integer SWITCH;
integer OFFSET = 1;
default
{
     state_entry()
     {
         pos = llGetLocalPos();
         llListen(LISTEN_CHANNEL,"","","");
     }
     listen(integer channel, string  name, key id, string message)
     {
        llSetTimerEvent( 0.3 * ( SWITCH = !SWITCH ) ); // Alternate SWITCH from 0 to 1
     }
     timer()
     {
        pos.x += (0.3 * ( OFFSET *= -1 )); //Alternate OFFSET from 1 to -1
        llSetPos(pos);

     }

}
Notice also that unless you are resetting parameters to specific intitial values, there's no real need to reset the script when you turn the timer off.
Not as dumb as I look