Animation, Timers, and Updates


Mac OS X is a very dynamic operating system. At any given time the computer may be working on several tasks at once. Your application has to be a good citizen in this environment and should not tie up the CPU any more than it has to. If you want to perform some animation in your application, you might do so by providing a loop that draws a frame, pauses for some time interval, and then draws another frame. Unfortunately, your application will be completely occupied while in this loop and might make better use of its time by performing some other calculations in the time that it has paused to render the next frame. Moreover, if the user tries to interact with your program during that pause, and the program is unable to respond, they might perceive your application as unresponsive and sluggish. To work around this problem, Mac OS X includes many different systems that provide timers.

The timer-based animation technique discussed in this chapter is subject to latency problems. For example when your application gets busy and doesn't make it back to the event loop often enough, this technique can lead to animations that display frames irregularly.

Mac OS X 10.4 Tiger introduced Core Video, a graphics library dedicated to handling buffers and timing services for displaying video. Using Core Video you can get very accurate animation timing. This system uses multithreading and a callback to tell the application the ideal time to display each frame so that it synchronizes with the display.

The multithreading that makes this system possible works ideally with OpenGL but doesn't mesh as well with update mechanisms of Carbon HIViews or Cocoa NSViews and their CGContexts. As a rule of thumb, Carbon and Cocoa both expect you to use Quartz 2D when drawing views from the application's main thread.

For applications with simple needs, the techniques described here should be sufficient. If your application needs more sophisticated and exact animation timings, however, you should investigate Core Video.


About Timers

A timer is little more than an entity on the system that calls back to your application at a fixed interval. Your application can set up a timer to call you back at the frame rate of your animation. When you receive the notification that the timer has fired, your application can draw one frame of the animation (or indicate to a view that the next frame needs to be drawn) and return. In the mean time, however, your application can continue to process user events or perform some important calculation. It only needs to worry about managing the animation when that animation needs attention.

One of the hardest parts about using timers is deciding which timing mechanism to use. At the lowest levels of the application frameworks, you have run loop timers, CFRunLoopTimer. Each of the application frameworks also offer timer objects. Carbon application can use Carbon event timers, and Cocoa applications can use NSTimer objects. The actual choice you make depends largely on what type of notification mechanism you prefer. CFRunLoopTimers notifies your application when the timer fires by invoking a callback routine. Carbon event timers, naturally, send a Carbon event when the timer fires. NSTimer objects can invoke a method on an Objective-C object when their timer expires. As a general rule of thumb, you will probably be best off if you use the timing mechanism that matches your application architecture. Just keep in mind that the other timing mechanisms are also there to help you if you need them.

Beginning with Mac OS X 10.4 Tiger, Apple has added a Cocoa class for managing animations called NSAnimation. The class contains several of features specifically aimed at creating transitions for user Interface work. It contains a number of handy features including the ability to run a series of animations, one after another, and tools for running the animation at varying rates over time.


Updating the Animation

The way you draw the frames of the animation is another important consideration on Mac OS X. The simplest way to respond to a timer asking you to draw the next frame of your animation might be to simply draw the frame and return control. However, on Mac OS X, the Carbon and Cocoa application frameworks like to take a more structured approach to drawing. In Carbon, your application usually draws its user interface in response to a kEventControlDraw message sent to a particular HIView. In Cocoa, an application draws an NSView in response to the drawRect: message. As a rule of thumb, in both frameworks, your application shouldn't be drawing outside of these two mechanisms unless it has very special drawing behavior (e.g., if has captured the screen and is drawing in full-screen mode).

To work with the operating system, your application should draw the frames of the transition animation within the appropriate context. All that your timer callback needs to do is induce the operating system to call your view's draw handler. To do that the timer callback mechanism might call HIViewSetNeedsDisplay for a Carbon application or one of the NSView methods that begin with setNeedsDisplay: in Cocoa.

Animation Speed and Refresh Rates

When you watch TV or view a movie, the screen is showing you the individual frames of the picture at a rate that is probably in the range of 24 to 36 frames per second. To prevent flickering as it updates the screen, Mac OS X tries to synchronize the flushing of windows to the refresh rate of the monitor. In contrast, the LCD displays on many Macintosh computers typically refresh their images at a rate of 60 frames per second, while CRT monitors might refresh a little more frequently.

What this means in terms of animation is that if your application is trying to draw an animation, like a Core Image transition, at a rate faster than 60 frames per second, you are not using your time effectively and the user is not likely to see all the frames you are drawing anyway. When you are trying to decide on an animation rate for your transition, unless your application has very special needs, you might start with 30 frames per second and test the transition. Use higher refresh rates if you must, but keep in mind that there is an upper limit on the number of images the user will see.




Quartz 2D Graphics for Mac OS X Developers
Quartz 2D Graphics for Mac OS X Developers
ISBN: 0321336631
EAN: 2147483647
Year: 2006
Pages: 100

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net