Articles Archive
Articles Search
Director Wiki

Repeat loop blues

April 27, 1998
by Pat McClellan

Dear Multimedia Handyman,

I keep reading on the ShockeR listserv that I should never use repeat loops in Shockwave movies. Why not? They seem to work ok. And if I can do repeat loops, then how else can I do repetitive things?


Dear Pete,

The reason that repeat loops are a problem in Shockwave is in the way that the processor handles them. They are extremely powerful because the computer devotes 100% of it's focus to executing the repeat loop until it is finished. This is the case whether we're talking about a projector or a shockwave movie. In the case of a projector, that's not generally a problem, but in a Shockwave movie, the computer may need to devote some of its attention to other things which might be going on at the same time.

For example, let's say that you've got a dcr in which you are accessing linked files or you have other net functions going on in the background. Those things will function well, until the movie encounters the repeat loop. At that point, all netLingo functions will be put on hold while you're repeat loop commands all of the processor's attention.

"Okay," you say, "my movie doesn't use any netLingo, nor linked members. So does that mean I can use a repeat loop?" Well, you've also got to consider the fact that during a repeat loop, the processor not only ignores events going on in the movie, but also outside the movie. For example, your browser's scroll functions won't work. And the browser's back button. And you can't enter a URL in the browser's location window. Generally, it's not a good thing to "trap" your user this way.

Now, I'm not an unreasonable purist. In fact, I do use repeat loops on occasion - a fact that I will freely admit as long as I'm writing under a pseudonym. I use repeats for fast, discreet operations such as cycling through a short list of items. But, I know there are other ways to accomplish this task, so let's examine some options.

The Iterative Approach

Let's imagine an example in which we need to cycle through 100 items in a list. We'll use a variable, i, to be the index moving through the list.

The "old way" (using a repeat loop)

on cycleList
  global gOurList
  repeat with i = 1 to 100
  set theItem = getAt(gOurList, i)
  do whatever with theItem

In our "no repeats" option, we'll replace our index, i - a local variable - with a global variable, gIndex. This will allow us to "remember" where we are in the list so that we don't have to execute it all in one sweep. We'll also need a global "flag" to tell us whether to continue cycling through the list.

on cycleList2
  global gOurList, gIndex, gCycleFlag
  if gCycleFlag = 1 then         
    if gIndex <= 100 then
      set theItem = getAt(gOurList, gIndex)
      do whatever with theItem
      set gIndex = gIndex + 1
      set gCycleFlag = 0
    end if
  end if

Now, the handler will only access one item in the list at a time. The global variable that serves as the index will allow us to know which item is next the next time we go through the handler. Our problem is that we need a way to repeatedly call this handler - whenever the processor is free to deal with it.

If you're not familiar with the *on idle* event, take a moment to read up on it in the Lingo Dictionary. Basically, an on idle handler executes every time that the processor has a "free" moment. This will be very helpful to us because the *on idle* event can happen many times per frame. Since the *on idle* event happens throughout our program, we need a switch so that it will only call the handler when it is supposed to. That's why I put in that gCycleFlag global variable. When gCycleFlag is 1, then the *on idle* handler will call the cycleList2 handler. When the cycleList2 handler has gone through all 100 items, then gCycleFlag gets set to 0 and the handler ceases being called.

on idle
  global gCycleFlag
  if gCycleFlag = 1 then cycleList2

To begin the process, all you need to do is set gCycleFlag to 1 and gIndex to 1.

Zav pointed out that using the idle handler has the drawback that it's not predictable. Specifically, the on idle event happens whenever other processing tasks have been completed and the computer is waiting. Therefore, faster computers will have many more opportunities to idle. An alternative to calling cycleList2 in an idle handler is to call it *on exitFrame*. Simply put the same code from our idle handler into your exitFrame scripts. This way, you know that the handler will be called at least once for each frame. This approach is good for doing things that need to be more predictable in timing, but it would be very slow for cycling through a list of 100 items.

The Escape Hatch

Jim Collins posted an approach on the listserv which allows for repeats, but puts in an "escape hatch" that allows user input to interrupt the repeat. Note that this would not prevent the repeat loop from stopping netLingo operations. However, if you're not doing any netLingo, then this approach WILL allow user input -- such as a click on the scroll bar - to get through.

Jim's approach is to use *repeat while NOT the mouseDown*. This means that a mouseDown event would interrupt the repeat loop. You could also include the keyDown as an event which would interrupt the repeat.

on cycleList3
  global gOurList
  set myIndex = 1
  repeat while not the mouseDown
    set theItem = getAt(gOurList, myIndex)
    do whatever with theItem
    set myIndex = myIndex + 1
    if myIndex > 100 then exit repeat
  end repeat    

I hope those 2 options will help you avoid the pitfalls of repeat loops. If you're writing behaviors or objects, you can use properties to hold the indexes for your iterations. Good luck with your program.
Patrick McClellan is Director Online's co-founder. Pat is Vice President, Managing Director for Jack Morton Worldwide, a global experiential marketing company. He is responsible for the San Francisco office, which helps major technology clients to develop marketing communications programs to reach enterprise and consumer audiences.

Copyright 1997-2017, Director Online. Article content copyright by respective authors.