MOA Developer's Guide
MOA Interfaces | MOA Methods | MOA Types and Misc API

Director Xtra Development Kit: MOA Developer's Guide

Tips, Guidelines, and Gotchas


This discussion contains some general guidelines for all types of Xtra development, as well as specific suggestions for developing the four types of Xtras supported by the Director XDK. It's somewhat of a grab bag, including both very general and very specific coverage of a number of topics.

You may want to read through this information before you start developing Xtras. You should also review the information here as you develop your Xtras, since much of the information applies to specific areas of Xtra development.

General

Use the template and example projects

This XDK comes with template projects in the Examples folder for Transition, Sprite, Scripting, and Tool Xtras. These templates include projects for Visual C++ and Metrowerks CodeWarrior, and template code files containing comments that briefly describe modifications to make to create your Xtra.

There are also a number of working example projects that demonstrate various coding features described in this documentation. One way to begin Xtra development is to start with a working example that implements many of the features you plan to provide, and modify it to include your code.

Note that when modifying the template and example projects, you should only need to change source file names--and possibly add new source files--in the projects. If you are developing in C++, you can change the code model in the project.

IMPORTANT: YOU MAY FREELY CHANGE SOURCE FILES IN THE EXAMPLE PROJECTS. HOWEVER, TAKE CARE IN MODIFYING ANY PROJECT SETTINGS. THESE PROJECTS PROVIDE A NUMBER OF STANDARD SETTINGS REQUIRED TO MAKE XTRAS WORK CORRECTLY.

See the Readme file in the Examples folder for more details on using the example projects.

Use unique values

Be sure all class IDs you define are unique; these should be generated with the MSVC GUID program or the uuidgen command line tool on Macintosh.

Windows DLLs: Make sure the library name in your .DEF files is unique

Use resource files

If possible, use resources to store any strings, including your type symbol, display name, etc. This will provide a way for some users to resolve conflicts if there is a duplicate symbol name. Also it will make it easier to localize your Xtra.

Coding details

Unless otherwise noted, all string lengths specified include the terminating NULL (0x00) character (ie, standard C strings). Thus, where a string length is specified as 32, the maximum number of useable characters in the string is actually 31.

Do not depend on globals being initialized in Xtras. The behavior of global variables in code resources/code fragments/DLLs varies. Better yet: don't use globals at all.

Remember that your code may be shared by multiple applications or projectors running simultaneously. Again, this makes it very difficult to rely on global variables on platforms that only initialize them on a per-load basis (rather than per-instance).

Make your code re-entrant. Your Xtra may be called back as a result of a call your xtra makes to the host application. For example, if you post a moveable modal dialog using MacModalDialog, your Xtra may be called back (from within the MacModalDialog() call) to redraw thumbnails, re-image a sprite on the stage, etc., if the dialog is moved. This means that the data required to perform these operations must never be left in an inconsistent state while a call back to the host application is being made.

Registration and Initialization

In general, all interfaces you acquire through QueryInterface should be tested before you attempt any calls to them This is particularly crucial with regard to application-specific calls in your registration class (supporting IMoaRegister). The MoaCreate(), MoaDestroy(), and Register() methods of this class may be called by any MOA application. One approach is for your Register() implementation to test for the interfaces your Xtra needs from an application by calling QueryInterface(), and not register itself if they aren't present.

The IMoaMmInterrogate interface is provided for initializing libraries and allocating large blocks of memory at startup time. This process slows application startup, so you should be certain you need it before adding it to your Xtra. Whenever possible, use the IMoaRegister interface to cache initialization information, since it 's only instantiated the first time an application encounters your Xtra.

Testing
Accessing QuickDraw Globals on the Macintosh

Prior to Macintosh OS X, there was a global memory structure called "Quickdraw globals." This global data does not exist with OS X, so the following discussion only applies to earlier versions of the Macintosh operating system. There are two methods to access QuickDraw globals. Here is the first method:

#include <LowMem.h>
#include <Quickdraw.h>
#define qd (*((QDGlobals *) (*((GrafPtr **) LMGetCurrentA5()) + 1) - 1))


If you're already accessing Director's stage window's graphics context, then the pointer to Director's QuickDraw globals is available as part of the nativeGCInfo which you can get using the IMoaMmGC:GetNativeGCInfo interface. IMoaMmGC interfaces are supplied to sprite and transition Xtras at drawing time; you can also get the graphics context for a movie's stage window by calling IMoaDrMovie::GetStageWindowGC(). Note that at start-up initialization time, a movie is not yet open so you'll get an error if you try to obtain its graphics context at that time. However, it should be available in normal circumstances. (Always check your error codes!) Here is an example of the second technique:

MoaMmNativeGCInfo nativeInfo;
PIMoaDrMovie pMovie = NULL;
PIMoaMmGC pGC = NULL;
QDGlobals * pQDGlobals = NULL;

HANDLE_ERR( DrPlayer_GetActiveMovie(&pMovie) );
HANDLE_ERR( pMovie->lpVtbl->GetStageWindowGC(pMovie, &pGC) );
HANDLE_ERR( pGC->lpVtbl->GetNativeGCInfo(pGC, &nativeInfo ) );

pQDGlobals = nativeInfo.mac_window.qdGlobalsPtr;

/* Do your stuff with the QuickDraw globals. It's okay to save it too, since it won't change during the session.
*/

done:

/* Release interfaces we obtained */
if (pGC) pGC->lpVtbl->Release(pGC);
if (pMovie) pMovie->lpVtbl->Release(pMovie);

You might have to be careful with the first technique since support for A5 on PPC may go away in some future system software release (then again, so might the QuickDraw globals!). The second technique is currently Director API-specific, so it won't work if you're writing Xtras to be used in multiple products (for example, transitions for Director 5/Authorware 3.5).

Xtras must be unique

Remember that in general, Xtras have more than one GUID. There's a GUID for each class, so if you have a separate registration class, you need a unique GUID for that in addition to your asset and actor, Lingo, or tool classes. To ensure this, try running your Xtra with every sample Xtra in the Xtras folder; you should not get any conflict notices.

Managing interfaces and values

Throughout this API, you'll find cases where you create or use instances of MOA interfaces, sets of methods for manipulating objects, and MoaMmValues, object-like entities that represent specific types of values. Both MOA interfaces and MoaMmValues use reference counting to determine when they can be removed from memory.

There are various ways to acquire a value or interface, and the way you acquire it determines whether or not you are responsible for releasing it. Call the IMoaUnknown::Release() method to remove a reference to an interface; call the IMoaMmUtils::ValueRelease() method to remove a reference to a MoaMmValue.

The "caller owns" rule

Objects acquire interfaces and values by calling methods or by having their methods called. The "caller owns" rule define who is responsible for releasing an interface or value.

The rule is this: The owner of an interface or value is the object that calls the method requesting or providing it. The owner is always responsible for releasing an interface or value when through with it.

Here are the four cases to help clarify this rule:

As you develop your Xtras, make sure the instances and values you create and released when you expect. Similarly, make sure memory you allocate (via IMoaCalloc or IMoaHandle) is being released properly as your Xtra performs.


Copyright © 1995-2007 Adobe Macromedia Software LLC, Inc.