The Authorable Object is the heart of the APEX architecture. It is a data structure, the specification of how it will be authored, the specification of the run time functionality associated with it, and the software which implements this functionality.
APEX Modules implement one or more types of “authorable object”. For each authorable object, the module must implement 3 classes, derived from each of the 3 following base classes: AssetAuthoring, Asset, and Actor. The derived classes should be named: XxxYyyAssetAuthoring, XxxYyyAsset, and XxxYyyActor, where “Xxx” is the module name, and “Yyy” is the object name. The object name (“Yyy”) is optional if the module only contains one authorable object.
Thus, for every Asset class, there must be a corresponding Actor class, and a corresponding AssetAuthoring class.
Asset and AssetAuthoring classes are created, respectively, by the createAssetAuthoring() and createAsset() methods of the APEX SDK, whereas actor classes are created by the asset.
Level editing and loading functionality is outside the scope of what is provided by APEX. The game engine must provide this functionality.
APEX requires that the level loading system be able to instantiate named assets. The level loading system must be able to handle instances with and without a position in the level. For example, particle systems do not have a position, but particle emitters do.
The classes derived from AssetAuthoring provided advanced methods for authoring asset data.
These public interface classes only derive from the AssetAuthoring base class. However, the implementation classes derive from their corresponding public interface classes, the implementation base class (apexAssetAuthoring), and the corresponding Asset implementation class. Only the implementation class derives from the corresponding Asset implementation class. The Public interface classes, AssetAuthoring and Asset, do not derive from each other. Inheritance from the Asset implementation class is necessary because the Asset implementation class contains all the member data.
The AssetAuthoring class adds various methods that are used (typically by the authoring tool) to provide enhanced authoring functionality. Basic parameters are accessible through the NvParameterized asset classes, which may be retrieved using the getNvParameterized() method.
The classes derived from Asset are containers for authorable data. They always implement the createApexActor() method. The member variables and NvParameterized class in the implementation class contain all the asset data.
All assets must contain a name. When an asset is created or deserialized, the name must be registered with the Named Resource Provider (see below), together with a pointer to the asset (an Asset*). This allows the asset to be referenced by name by other assets.
It is sometimes useful to implement authorable objects that are generic enough to be included in other authorable objects. For example, a render mesh is included in a destructible or clothing asset. These objects may even be located in different modules.
The AssetAuthoring, Asset, or Actor classes of the included object must be automatically created by the corresponding classes of the “including” object when they are created.
The included asset is implemented using an NvParameterized included reference. It is automatically serialized and deserialized when the including asset is serialized or deserialized.
The including Actor must furthermore derive from Context. This will be the context in which the included Actor must be created, as shown above. This will be a different context than the one in which the including actor is created.
An alternative to “Asset Inclusion” is “Asset Referencing”. In asset referencing, an asset contains (at authoring time) the name and namespace of another asset. This could be another asset type defined in the same module, an asset type defined in another module, or even an asset type defined in the framework. Asset names can be resolved into a pointer to an asset (Asset*) using the Named Resource Provider. If the named asset has already been created, the pointer is returned immediately, but if the name cannot be resolved, the Named Resource Provider calls back to the application to give it a chance to create the named asset. If the application fails to create the named asset, a failure indication is returned and the name resolution fails. This, in turn, allows the referencing asset to fail actor creation.
Asset references are implemented using an NvParameterized named reference. This will include the name and “class name”, or APEX asset authorable namespace. For example, an APEX Impact Emitter will contain a named reference to an Instanced Object Simulation (IOS). This named reference will contain a name (BouncyPebblesIOS) and a className (BasicIosAsset), retrieved with NvParameterized::Interface::name() and NvParameterized::Interface::className(), respectively.
The Actor class represents a run time instance of the authorable data.
The Asset class is the primary source of configuration data for the Actor. All data that can be authored must come from the Asset. However, run time data may also be provided by the game engine. Run time data that is needed for Actor creation should be provided in an NvParameterized descriptor class passed to the createApexActor() method, for example, initial position. This data is typically provided by the game engine’s level loading code. Run time data that is not needed for Actor creation (i.e.: that can be provided later) should be provided by calling “set” methods of the Actor.
Even in cases where it only makes sense to have a single instance of the Actor class, the run-time functionality of the authorable object must still be placed in an Actor class rather than in the Asset class.
All instances of the Actor class are “owned” by the Asset that created them. (See discussion of ownership in “Actor Context” below.) Thus, the Asset implements the createActor() and releaseActor() methods.
All instances of the Actor class also have a “context”. The concept of a context is completely different than the owner. The “context” is the context in which the Actor is created or instantiated, and it will be a class that derives from Context. A pointer to the context of an Actor is a standard argument to the Asset::createApexActor() method.
For most Actors, the context will be an instance of the Scene class. However, some Actors may be created in other contexts, such as the ApexSdk. Some Actors may even be created in the context of another Actor. The type of an Actor’s context is defined on a Asset/Actor type basis.
The Context class provides a method to remove all actors, removeAllActors(), which removes all actors from the context and calls their release() methods. This allows the context itself to be easily released. Context also provides a method to create and release a renderable iterator, createRenderableIterator(), which provides an iterator to iterate over the set of renderables in the context.