moock.org is supported in part by


May 24, 2007

Chapter 23, Pages 1-4, Essential ActionScript 3.0

Here are the first 4 pages of Chapter 23 of Essential ActionScript 3.0

Chapter 23. Screen Updates

Conceptually speaking, all screen updates in ActionScript can be separated into two categories: those that occur at regular intervals (scheduled updates), and those that occur immediately following the execution of certain event listener functions (post-event updates). Regardless of the category, all screen updates are automated. In ActionScript there is no general, arbitrary means of requesting an immediate screen update. Instead, new visual content created programmatically or manually in the Flash authoring tool is rendered automatically by a scheduled or post-event update. This chapter investigates ActionScriptís two varieties of screen updates.

While most of this book focuses on pure ActionScript code rather than specific .swf authoring tools, the following discussion requires some basic knowledge of the Flash authoring toolís timeline and timeline-scripting techniques. If you are unfamiliar with the Flash authoring tool, you should read Chapter 29, before continuing with this chapter.

Scheduled Screen Updates

In ActionScript, screen updates are inexorably linked to the Flash runtimeís animation capabilities. Even pure ActionScript applications created with Flex Builder 2 or the mxmlc command-line compiler are governed by the Flash runtimeís animation-centric screen-update system.

The Flash runtimeís screen-update system is designed to accommodate the Flash authoring toolís model for creating scripted animated-content. In the Flash authoring tool, animated content is produced manually as a series of frames on a timeline, exactly like the frames in a physical filmstrip. Each visual frame can be associated with a block of code known as a frame script. In very general terms, when the Flash runtime plays an animation that was created in the Flash authoring tool, it adheres to the following screen-update cycle:

1. Execute current frameís code
2. Update screen
3. Go to next frame
4. Repeat

For example, suppose we have a three-frame-long animation, created in the Flash authoring tool, and each frame has a frame script. The general process by which the Flash runtime plays the animation is as follows:

1. Execute Frame 1ís frame script
2. Display Frame 1ís content
3. Execute Frame 2ís frame script
4. Display Frame 2ís content
5. Execute Frame 3ís frame script
6. Display Frame 3ís content

At steps 1, 3, and 5, each frame script might create new visual content or modify existing visual content. Therefore, a more accurate description of the preceding animation-playback steps would be:

1. Execute Frame 1ís frame script
2. Display Frame 1ís content and render visual output of Frame 1ís frame-script
3. Execute Frame 2ís frame script
4. Display Frame 2ís content and render visual output of Frame 2ís frame-script
5. Execute Frame 3ís frame script
6. Display Frame 3ís content and render visual output of Frame 3ís frame-script

In the preceding list, notice that before rendering the visual output of a given frame script, the Flash runtime always finishes executing that script in its entirety.

** The Flash runtime never interrupts a frame script in order to update the screen. **

The speed with which the preceding six steps are performed is determined by the Flash runtimeís frame rate, which is measured in number of frames per second. For example, suppose the frame rate for the preceding animation is set to a very slow 1 frame per second. Further suppose that each frame script takes exactly 100ms to execute and that each frameís content takes exactly 50ms to render. Relative to the starting of the animation, the theoretical times at which the preceding six steps would be performed are as follows:

0ms: Begin executing Frame 1's frame script
100ms: Finish executing Frame 1's frame script
1000ms: Begin rendering Frame 1's content and frame-script output
1050ms: Finish rendering Frame 1's content and frame-script output

1051ms: Begin executing Frame 2's frame script
1151ms: Finish executing Frame 2's frame script
2000ms: Begin rendering Frame 2's content and frame-script output
2050ms: Finish rendering Frame 2's content and frame-script output

2051ms: Begin executing Frame 3's frame script
2151ms: Finish executing Frame 3's frame script
3000ms: Begin rendering Frame 3's content and frame-script output
3050ms: Finish rendering Frame 3's content and frame-script output

Notice that after each frame script has finished executing, the Flash runtime does not immediately update the screen. Instead, it renders the scriptís output at the next scheduled frame-render time. The Flash runtimeís screen updates can, therefore, be thought of as scheduled screen updates because they occur according to the preset schedule dictated by the frame rate.

Hence, an even more accurate description of the preceding animation-playback steps would be:

1. Execute Frame 1ís frame script.
2. Wait until the next scheduled frame-render time
3. Display Frame 1ís content and render visual output of Frame 1ís frame-script.
4. Execute Frame 2ís frame script.
5. Wait until the next scheduled frame-render time.
6. Display Frame 2ís content and render visual output of Frame 2ís frame-script.
7. Execute Frame 3ís frame script.
8. Wait until the next scheduled frame-render time.
9. Display Frame 3ís content and render visual output of Frame 3ís frame-script.

Now letís suppose Frame 1ís frame script registers an event-listener function, clickListener(), with the Stage instance for MouseEvent.CLICK events. Every time clickListener() runs, it draws a red line to the current mouse pointer position. Hereís the code for Frame 1ís frame script:

import flash.events.*;
import flash.display.*;
stage.addEventListener(MouseEvent.CLICK, clickListener);
function clickListener (e:MouseEvent):void {
  graphics.lineStyle(2, 0xFF0000);
  graphics.lineTo(e.stageX, e.stageY);
}

Immediately after Frame 1ís frame script executes, clickListener() becomes eligible for MouseEvent.CLICK event notification.

Now suppose the user clicks the Flash runtimeís display area 500 milliseconds after the animation starts playing (i.e., during the wait period described in Step 2 of the preceding list). The clickListener() method executes immediately, but the visual output of clickListener() is not rendered until the next scheduled frame-render time. At the next frame-render time, the visual output of clickListener() is rendered along with Frame 1ís content and Frame 1ís frame-script output.

Hence, an even more accurate description of the preceding animation-playback steps would be:

1. Execute Frame 1ís frame script.
2. Wait until the next scheduled frame-render time. While waiting, if any events are triggered, execute associated event listeners.
3. Display Frame 1ís content; render visual output of Frame 1ís frame-script; render visual output of any event listeners executed during step 2.
4. Execute Frame 2ís frame script.
5. Wait until the next scheduled frame-render time. While waiting, if any events are triggered, execute associated event listeners.
6. Display Frame 2ís content; render visual output of Frame 2ís frame-script; render visual output of any event listeners executed during step 5.
7. Execute Frame 3ís frame script.
8. Wait until the next scheduled frame-render time. While waiting, if any events are triggered, execute associated event listeners.
9. Display Frame 3ís content; render visual output of Frame 3ís frame-script; render visual output of any event listeners executed during step 8.

The preceding steps reflect the Flash runtimeís default screen-update behavior. However, for certain event types the Flash runtime can be forced to update the screen more immediately. For details, see ďPost-Event Screen Updates,Ē later in this chapter.

Now suppose that Frame 2ís content is identical to Frame 1ís content, and that Frame 2ís frame script does not generate any visual output, and that no event listeners are triggered between Frame 1 and Frame 2. In such a case, the Flash runtime does not re-render the display area. Instead, when the frame-render time for Frame 2 arrives, the Flash runtime merely checks whether the screen needs updating. Frame 2 has no visual changes, so the screen is not re-rendered.

Hence, a still more accurate description of the preceding animation-playback steps would be:

1. Execute Frame 1ís frame script.
2. Wait until the next scheduled frame-render time. While waiting, if any events are triggered, execute all registered event listeners.
3. At frame-render time, check if the screen needs updating. The screen needs updating if any of the following is true:

* Frame 1 contains changes to the contents of the Stage made manually in the Flash authoring tool.
* Code in Frame 1ís frame script created new visual content or modified existing visual content.
* Code in a listener function executed during Step 2 created new visual content or modified existing visual content.

4. If necessary, update the screen to reflect all changes detected in Step 3.
5. Repeat steps 1-4 for frames 2 and 3.

For reference in the remainder of this chapter, and in the following chapter, weíll refer to the screen-update check that occurs at Step 3 as a scheduled screen-update check. Each time the Flash runtime performs a scheduled screen-update check, it dispatches the Event.ENTER_FRAME event (even when the screen is not actually updated). By responding to the Event.ENTER_FRAME event, objects can perform recurring tasks synchronized with each screen-update opportunity. In Chapter 24, weíll learn how to use the Event.ENTER_FRAME event to create animated content entirely through code.

Ready for one last hypothetical scenario? Suppose we remove frames 2 and 3 from our animation, leaving Frame 1 only. As before, Frame 1ís frame script defines the MouseEvent.CLICK event listener, clickListener(). Once Frame 1ís content and frame-script output has been rendered (Step 4 in the preceding list), the animation has finished playing. Nevertheless, in order to allow for continued event-processing, the Flash runtimeís screen-update cycle must remain active. Therefore, for a .swf file that contains a single-frame only, the screen-update cycle is as follows (the following steps apply equally to a multi-frame .swf file that is simply paused on Frame 1):

1. Execute Frame 1ís frame script.
2. Wait until the next scheduled frame-render time. While waiting, if any events are triggered, execute all registered event listeners.
3. At frame-render time, check if the screen needs updating. The screen needs updating if any of the following is true:

* Frame 1 contains changes to the contents of the Stage made manually in the Flash authoring tool.
* Code in Frame 1ís frame script created new visual content or modified existing visual content.
* Code in a listener function executed during step 2 created new visual content or modified existing visual content.

4. If necessary, update the screen to reflect all changes detected in step 3.
5. Wait until the next scheduled frame-render time. While waiting, if any events are triggered, execute all registered event listeners.
6. At frame-render time, check if the screen needs updating. The screen needs updating if code in a listener function executed during step 5 created new visual content or modified existing visual content.
7. If necessary, update the screen to reflect all changes detected in step 6.
8. Repeat steps 5-7.

Steps 5 to 8 in the preceding list repeat indefinitely as long as the .swf file is running in the Flash runtime, thus binding all subsequent code execution to the frame-rate-based screen-update cycle.

In Chapter 20, we learned that ďwhen an empty Flash runtime opens a new .swf file, it locates that .swf fileís main class, creates an instance of it, and adds that instance to the display list as the Stage instanceís first child.Ē For pure ActionScript programs, immediately after the main class instanceís constructor method completes, the screen is updated. All subsequent screen updates occur in accordance with the frame-rate-based screen-update cycle presented in steps 5 to 8 of the preceding list. For example, consider the following extremely simple drawing program, which emphasizes screen updates by setting the frame rate to one frame per second.

package {
  import flash.display.*;
  import flash.events.*;
  public class SimpleScribble extends Sprite {
    public function SimpleScribble () {
      stage.frameRate = 1;
      graphics.moveTo(stage.mouseX, stage.mouseY);
      stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveListener);
    }
    private function mouseMoveListener (e:MouseEvent):void {
      graphics.lineStyle(2, 0xFF0000);
      graphics.lineTo(e.stageX, e.stageY);
    }
  }
}

The SimpleSribble constructor method creates no graphical content, but does register a listener, mouseMoveListener(), for the MouseEvent.MOUSE_MOVE event. Whenever the mouse moves, mouseMoveListener() draws a line to the current mouse position. However, that line is not actually displayed on screen until the next scheduled screen update, which occurs once per second. Hence, once every second, the Flash runtime updates the screen with a series of lines showing the mouse pointerís path through the display area since the last screen update. For a smoother drawing effect, we could increase the frame rate to 30 frames per second, or we could force immediate screen updates using the techniques described later under ďPost-Event Screen Updates.Ē

Letís review some of the key points covered so far:
* ActionScriptís screen-update system is fully automated.
* For pure ActionScript applications, the frame rate can be thought of as the number times per second the Flash runtime automatically checks to see if the screen needs updating. For example, if the Flash runtimeís frame rate is 1, then all visual changes made by a program will automatically be rendered once per second; if the frame rate is 10, then visual changes will automatically be rendered 10 times per second (every 100 ms).
* If the frame rate is very low (say, in the range of 1-10 frames per second), then there may be noticeable delays between the execution of code that generates visual output and the rendering of that output to the screen.
* Each time the Flash runtime performs a scheduled screen-update check, it dispatches the Event.ENTER_FRAME event.
* Flash Player will never interrupt the execution of a block of code in order to update the screen.

Posted by moock at May 24, 2007 09:18 PM