Home / Products / Xtras / Developer Support /  
Icon or Spacer Adobe Xtras Developers Support

Building a Adobe Xtra

MOA is based on the concept of classes whose behaviors are described by interfaces. Each interface describes a clearly-defined unit of behavior. For example, the IMoaCalculation interface might define methods to Add, Subtract, Multiply, and Divide. Interfaces describe a set of methods (behaviors), but not how those behaviors are implemented. IMoaPrinting might define methods such as ChoosePrinter, StartPrinting, or CancelPrinting.

Classes are units of implementation. In defining a class, the implementor chooses one or more interfaces to implement, and provides method implementations for the method descriptions defined in the associated interface. For example, a SimpleCalculator class would implement the Add, Subtract, Multiply, and Divide methods in the IMoaCalculation interface using basic fixed point math. A PreciseCalculator class would implement the Add, Subtract, Multiply, and Divide methods using much more precise algorithms, and might also choose to implement the IMoaPrinting interface methods.

A class is really a template from which multiple objects, each complying to the same behavior (for example, interfaces), can be instantiated. An object is a run-time unit of operation. If you need three calculators, you simply instantiate three SimpleCalculator objects from the class at run-time, and they are used operationally to do the calculation behavior.

Each individual object instantiated from a class needs to be able to hold on to its own private data (for example, a calculator might need to keep track of its own registers and accumulators). Thus, when defining a class, besides choosing and implementing the interfaces, the developer defines a set of instance variables that can hold data specific for each instance of a class. When an object is instantiated from a class, special memory is allocated in each object to maintain the instance variable data. All the interfaces defined by a class have access to the data contained in an instance of that class. MOA is largely used to develop Xtras that can be plugged into applications, and to provide APIs into those applications for the Xtras to use. This is done by taking advantage of the interface/class/object/method taxonomy, as explained in detail below.

Advertising Functionality

Adobe has defined a set of cross-product application interfaces that are to be implemented by applications and a set of cross-product Xtra interfaces that are to be implemented by Xtras. To implement an interface, a developer typically defines a class that supports that interface.

An Xtra "advertises" its type by registering the interfaces it implements, along with any other required information for that interface, with each Adobe application. For example, each Asset Xtra registers its implementation of the IMoaMMXAsset interface.

Applications like Director or FreeHand each define a specific class or classes to encapsulate the behaviors of that application. Each class provides implementations for some cross-product interfaces, some product-specific interfaces, and perhaps some shared multimedia interfaces. One class is always designated as the "callback" class of that application, to serve as the primary point of outside contact with that application. This class is instantiated by MOA when the application starts, and the resulting callback object is made available to all Xtras by MOA through the standard pCallback instance variable. Other objects within the application that can be manipulated by an Xtra are represented by additional classes and their interfaces. For example, Director exposes cast members or sprites.

Each type of Xtra (for example, a hypothetical "morphing" Xtra), defines one or more classes that encapsulate the behavior of that Xtra. Each Xtra provides implementations for standard Adobe-defined Xtra interfaces. In addition, each Xtra developer can define some instance variables that are needed (for example, to record and manage the morphing state).

Connecting an Xtra

When an Xtra is prepared for use -- typically when it is invoked by the user from one of the application's menus -- the Xtra is initialized and given a reference to the application's callback class. Whenever the Xtra wants to invoke an operation on the application, it queries the callback to see if the desired interface is available in the application. If it is, the Xtra is free to call any method in that application interface.

An extremely important point here is that clients can take advantage of polymorphism. The client can query a class to discover if a particular interface is implemented by that class; if it is, the client is guaranteed that it can invoke the defined methods of that interface and receive appropriate results, without needing to know how it is implemented.

For example (again, this is hypothetical), the same Xtra for morphing could be used in both Director and Authorware. When Director launches, it sees that the morphing Xtra is in the Xtras folder and registers it. When the user picks Morph from the Xtras menu, Director instantiates and initializes that Xtra, and gives it a reference to the Director callback. This reference will appear to the Xtra as an instance variable named "pCallback" (a pointer to the callback class). The Director callback class has chosen to implement the IMoaPixelAccess interface (which defines several methods, including GetPixels), and has a Director-specific implementation for GetPixels.

Similarly, Authorware instantiates and initializes the same Xtra, and provides a pointer to its Authorware Class (the Authorware callbacks) in the pCallback instance variable of that Xtra. The Authorware Class implements the GetPixels method of the IMoaPixelAccess in an Authorware-specific manner.

To implement a particular type of morph (for example, a slow morph), the Xtra writer defines a SlowMorph class. The code for that class queries its pCallback instance variable to see if the class represented by the pCallback object implements the IMoaPixelAccess interface. If this Xtra is running in Director, pCallback references an object of the Director class and the query is positive. Similarly, if this Xtra is running in Authorware, pCallback references an object of the Authorware class and the query is positive. Now, the morphing algorithm in the Xtra can call any method of IMoaPixelAccess to do its drawing. The interface is application-neutral and makes no references to Director or Authorware; all references go through the IMoaPixelAccess interface, which Director and Authorware have each implemented in their specific fashion. If Extreme3D were to implement IMoaPixelAccess, then SlowMorph would work in that application without recompilation.

The above describes how an Xtra can operate in multiple applications that implement the same functionality. But for functions like morphing, the application needs to drive the Xtra, for example, in order to obtain names to put up in application dialogs, in order to post Xtra-provided dialog boxes, and in order to step morphs, or transitions, or animations through their steps. As expected, all Xtras that provide the same level of functionality (i.e. they need to be stepped through a series of phases), would implement an interface like IMoaStepper, with methods Start, Step, and Stop. All morphs might implement an IMorph interface as well. In an application, when you clicked on the Morph menu item, the application would query all Xtras to see if they implemented the IMorph interface. If they did, the application would issue a query to each Xtra that answered positively to obtain the name and icon of that particular morph, and put those in the Morph dialog box presented to the user. When the user chose a particular morph type from the dialog, the application would query and obtain a reference to the morph Xtra's IMoaStepper interface and invoke the Start method of that interface on the Xtra. As the application continued, it would, at appropriate points, call the IMoaStepper::Step() method of the Xtra. When complete, it would send IMoaStepper::Stop().

Product-Specific Examples

SoundEdit 16 Application
The SoundEdit application provides a single class that describes the main callback object to which all Xtras are provided with an automatic reference. Besides implementing the cross-product interfaces for registration and memory management, the SoundEdit callback class implements a single product-specific interface-IMoaSEService-that an Xtra uses to manipulate sounds, tracks, labels, cues, and files.

SECallback Class (the main SoundEdit 16 class) implements:

Method Description

IMoaCache General interface provided by all MOA applications.

IMoaCallback Creates an instance of an add-in media type.

IMoaCalloc Fixed memory allocation interface.

IMoaDict Interface for getting and setting registry entries.

IMoaHandle Relocatable memory allocation interface.

IMoaProgressBox Report progress of data processing.

Method Description

IMoaSEService Access to the sound data being edited, through the following methods:

GetColorInfo Get color information from a track..

GetCueInfo Get cue information from the sound documents.

GetLabelInfo Get label information from a track.

GetListenStatus Get status and listen to the input (record or meter) data.

GetTrackInfo Get format and information about a track.

SetColorInfo Set or delete colors in a track.

SetCueInfo Set or delete cue data in a sound document.

SetDocumentInfo Change format and information about processed document.

SetLabelInfo Set or delete labels in a track.

SetListening Turn listening on or off.

SetTrackInfo Set track information.

SoundDelete Delete data in track.

SoundInsert Insert data in track.

SoundRead Read original data from track.

SoundWrite Write processed data to track.

StretchNonAudio Scale non-audio information in the document.

TrackDelete Delete a track from the document.

TrackInsert Create a new, empty track in the document.

SoundEdit 16 Xtras

To implement a SoundEdit Xtra, a developer simply implements the methods in the IMoaRegister interface (to register the Xtra), and then implements the DoIt and/or DoFileFilter methods of the IMoaSEExtension interface, to provide Xtra specific behavior that will be invoked.

A SoundEdit Xtra class implements:

Method Description

IMoaRegister Interface for registering Xtras.

Method Description

IMoaSEExtension Interface for all SoundEdit Xtras uses one of the following two methods:

DoFileFilter Called from Import Dialog.

DoIt Called after Xtra is chosen from a Menu.

Director Application
Unlike SoundEdit, Director implements a number of interfaces. Interfaces are defined for the Director player, a Director movie, a cast, an individual castmember, a score, a sound, a frame, and a sprite.

Some applications, like SoundEdit, can define a single callback class that wraps together all of the interfaces that need to be implemented. However, Director's interfaces are designed so that an Xtra writer can have full access to the run-time data structures of Director, where there may be two movies open, five casts, 300 cast-members, two score-sounds, 30 active sprites, etc. Thus, for each major object type in Director, a class is defined that has instance variables to maintain information about that type of object and implements a MOA interface for that object type. An Xtra writer can then instantiate 15 objects from the MoaDrCastMem class if they want to have an Xtra that operates on a number of cast members.

In particular, the product-specific classes/interfaces implemented by Director are:

Class Interface Description

MoaDrPlayer IMoaDrPlayer Top-level interface to the Director playback engine.

MoaDrMovie IMoaDrMovie Gets movie-level information and invokes movie-level behaviors.

MoaDrCast IMoaDrCast Gets cast-level information and invokes behaviors on entire casts.

MoaDrCastMem IMoaDrCastMem Gets information and invokes behaviors on individual media assets.

MoaDrScoreAccessor MoaDrScoreAccessor Accesses, traverses, and edits the Director score.

IMoaDrMedia Accessor Accesses media tracks in the score.

MoaDrScore Frame IMoaDrScore Gets information and invokes behaviors on individual score frames.

MoaDrScoreSound IMoaDrScoreSound Gets information and invokes behaviors on sound channel in the score.

MoaDrScoreSprite IMoaDrScoreSprite Gets information and invokes behaviors on sprites in the score.


A real power of the MOA interface is the ability to specify well-defined interfaces that can abstract and encapsulate application and Xtra functionality. One example is the IMoaPixelAccess/IMoaPixelFilter interface set. IMoaPixelAccess provides an abstracted model for accessing and modifying a set of pixels, such as TIFF images. IMoaPixelFilter provides an abstracted model for a piece of code that uses IMoaPixelAccess to "filter" the pixels. These interfaces are not tied to any application and have few underlying assumptions. This technique makes it easy to write "adapter" Xtras for other plug-in technologies.

Photoshop and Illustrator Plug-Ins

FreeHand 5.5 and Director 5.0 include an Xtra that provides compatibility with Photoshop-style filters. This Xtra scans the disk for Photoshop filters and provides an IMoaPixelFilter "wrapper" for each one. Thus, any application that recognizes IMoaPixelFilter is capable of using Photoshop filters by dropping in a Photoshop adapter Xtra. Supporting IMoaPixelFilter/IMoaPixelAccess is much simpler than supporting Photoshop filters directly.

Similarly, the Illustrator plug-in compatibility Xtra that is included with FreeHand uses standard FreeHand interfaces to provide compatibility. Any application that provides the same set of callbacks will be able to use the Illustrator plug-in Xtra.

ActiveX Control Support

In addition to supporting the MOA component architecture, Adobe has developed an asset Xtra for Director that supports Microsoft's ActiveX control technology.

This (Windows only) Xtra allows any ActiveX control to operate inside a projector or a .DIR movie piece. A Shockwave movie can't host ActiveX controls because of security reasons.