Jump to content

Breaking out of a loop


Jonathon Spires
 Share

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

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

Recommended Posts

I hope someone can help point me in the way to finding a solution to something that is probably pretty simple.

I wrote a script to alpha to certain faces of a mesh at various times in order to simulate complicated machine motion (connecting rods on a locomotive, to be specific).  This was successful, and I scripted this so that it the event is triggered by an if/else if statement that would engage the alpha setting or return it based on simple stop and start commands. That bit worked well.

Where I run into a problem is in making that function loop. I have put the alpha setting instructions into a do/while loop. Once that begins. using the "stop" statement no longer works. I can't seem to find any trigger to stop the loop, once it begins. Am I looking over something simple? Is this possible to do?

Link to comment
Share on other sites

You cannot interrupt an event in progress.  Once execution has entered the event, it has to proceed until it reaches an exit point from the event.  However, a script rarely remains in a single event very long unless you have created an infinite loop or some other process that has no exit.  For a job like yours,  therefore, you plan on entering and leaving an event regularly but checking each time to see whether some trigger variable has changed. You don't plan execution of a continuing process to be self-contained within a loop inside a single event.  You build the implicit loop into a timer of some kind that triggers repeatedly, and provide a way to stop the timer. For example, you might move your connecting rod in a timer event and ask whether someone has stepped on the brakes each time execution passes through the event:

timer()
{
    if ( iStop == FALSE )
    {
        // Move the rod
    }
    else
    {
        llSetTimerEvent(0.0);  // Stop the motion
    }
}

Then use your touch_start event to change the value of the iStop variable from FALSE to TRUE. 

  • Like 2
Link to comment
Share on other sites

Have a look at the jump function at http://wiki.secondlife.com/wiki/Jump. You can jump out a loop when a condition is met and the code will proceed to run at the target label. The target label must be within the same scope as the loop, it can not cross to other user functions or events.

e.g:

 

list fruits = ["apples","oranges,","peaches","bananas","papaya","kiwi"]
integer i = 0;
integer llength;

default
{

	state entry()
		{
           
			llength = llGetListLength(fruits);
  
		}

	 touch end(integer num)
		{

		    for(;i < llength; ++i)
             {
                 if(llList2String(fruits,i) == "peaches")
                  jump found;
                             
              
                            
             }
           
           llOwnerSay("No peaches found.");                   
                             
           @found;
           llOwnerSay("Peaches found in list.");                  

		}


}

 

Note that if you can not avoid jumps it is recommended you use them sparingly, if at all, because they can cause problems with recursion and cause spaghetti coding / make your code unreadable. 

 

Edited by Gayngel
  • Like 1
Link to comment
Share on other sites

8 hours ago, Rolig Loon said:

You cannot interrupt an event in progress.  Once execution has entered the event, it has to proceed until it reaches an exit point from the event.  However, a script rarely remains in a single event very long unless you have created an infinite loop or some other process that has no exit.  For a job like yours,  therefore, you plan on entering and leaving an event regularly but checking each time to see whether some trigger variable has changed. You don't plan execution of a continuing process to be self-contained within a loop inside a single event.  You build the implicit loop into a timer of some kind that triggers repeatedly, and provide a way to stop the timer. For example, you might move your connecting rod in a timer event and ask whether someone has stepped on the brakes each time execution passes through the event:


timer()
{
    if ( iStop == FALSE )
    {
        // Move the rod
    }
    else
    {
        llSetTimerEvent(0.0);  // Stop the motion
    }
}

Then use your touch_start event to change the value of the iStop variable from FALSE to TRUE. 

Thank you very much. Putting a timer function was exactly what was needed. I was not familiar with using timer in the form of a loop like that. I have a bit of delay with it, but its managable and it works well. Thanks once again.

Link to comment
Share on other sites

11 hours ago, Rolig Loon said:

You cannot interrupt an event in progress.  Once execution has entered the event, it has to proceed until it reaches an exit point from the event.

Kind of a contradictory statement, isn't it? "You can't interrupt an event, unless you do."

"return" is a keyword that will exit the current function or event, so you can have a conditional within the loop and "interrupt" everything.

Though, depending what else comes after the loop in the same function/event, you might not want to use return. This is a design decision the scripter has to make. A more "safe" option would be a conditional check at the beginning of the loop (like "while(continue && ++i)") and changing that condition within the loop (like "continue = FALSE").

  • Like 1
Link to comment
Share on other sites

13 minutes ago, VenKellie said:

break; usually works in a while loop in most languages, not to sure if it will work in lsl.

Well if you read the responses to this thread you would see someone posted the wiki link to jump statement 😜

Edited by ItHadToComeToThis
Link to comment
Share on other sites

On 3/31/2019 at 5:49 AM, Wulfie Reanimator said:

Kind of a contradictory statement, isn't it? "You can't interrupt an event, unless you do."

Yes it is, and that's the point. Somehow or other, you have to provide an exit from every event or you will stay in it forever.  Without some form of exit, stimuli that might trigger other events will be ignored.  That's a caution against writing scripts that may create inadvertent traps. 

New scripters in LSL often come with experience in languages that flow linearly.  They find it difficult to understand, as I did when I started, how execution in a LSL script follows responses to external stimuli.  Every event and each state is a self-contained module that must have at least one way in and one way out, but the order in which execution flows from one module to another is determined by the external environment. The state/event structure of LSL assumes that execution will only leave a state or event if (1) some external trigger is tripped and (2) there is a way for that trigger to be recognized.  Otherwise, the default is for the script to be idle, stuck in its current state and event.

One important implication is that if you want to let your script to change direction in response to an external trigger, like a touch, you need to create ways to exit from events and states when those triggers occur.  A repeating or incremental process has to provide a way out of the current event or the script will never sense external triggers. If you create a  loop like

integer i;
while (~i)
{
     llSetAlpha( 0.1 * i, iFace);
    if (++i > 10)
    {
        i = 0;
    }
}

without providing some way to get out of it and out of whatever event it is in, the script will never recognize a touch or an incoming message or a tripped sensor.  Therefore, you either build an exit into the loop itself -- for example, using the jump operation that others have suggested or keeping track of some counting flag --   or you build the loop in such a way that it is not contained entirely within one event, as I demonstrated in my example above.  

Edited by Rolig Loon
  • Like 1
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1853 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...