Overview of the GOM Core Interfaces

Last Updated April 8, 2000

1.

1.1. Overview of the GOM Core Interfaces

This section defines a set of objects and interfaces for accessing and manipulating game objects. The functionality specified in this section (the Core functionality) is sufficient to allow software developers and game script authors to access and manipulate parsed game content inside conforming products. The GOM Core API also allows creation and population of a Game object using only GOM API calls; loading a Game and saving its state persistently is left to the product that implements the GOM API.

1.1.1. The GOM Structure Model

The GOM presents games as a hierarchy of Gob objects that also implement other, more specialized interfaces. Some types of gobs may have child gobs of various types, and others are leaf gobs that cannot have anything below them in the game’s structure. The gob types, and which gob types they may have as children, are as follows:

The GOM also specifies a GobList interface to handle ordered lists of gobs, such as the children of a Gob, or the agents returned by the getAgentsByName method of the Agent interface, the items returned by the getItemsByName method of the Item interface, and also a NamedGobMap interface to handle unordered sets of gobs referenced by their ID, such as the ID of an Agent. GobList and NamedGobMap objects in the GOM are “live”, that is, changes to the underlying game structure are reflected in all relevant GobList and NamedGobMap objects. For example, if a GOM user gets a GobList object containing the children of an Agent, then subsequently adds more children to that agent (or removes children, or modifies them), those changes are automatically reflected in the GobList, without further action on the user’s part. Likewise, changes to a Gob in the tree are reflected in all references to that Gob in GobList and NamedGobMap objects.

1.1.2. Memory Management

Most of the APIs defined by this specification are interfaces rather than classes. That means that an actual implementation need only expose methods with the defined names and specified operation, not actually implement classes that correspond directly to the interfaces. This allows the GOM APIs to be implemented as a thin veneer on top of legacy applications with their own data structures, or on top of newer applications with different class hierarchies. This also means that ordinary constructors (in the Java or C++ sense) cannot be used to create GOM objects, since the underlying objects to be constructed may have little relationship to the GOM interfaces. The conventional solution to this in object-oriented design is to define factory methods that create instances of objects that implement the various interfaces. Objects implementing some interface “X” are created by a “createX()” method on the game interface; this is because all GOM objects live in the context of a specific game.

The GOM API does not define a standard way to create GOMImplementation objects; actual GOM implementations must provide some proprietary way of bootstrapping these GOM interfaces, and then all other objects can be built from there.

The Core GOM APIs are designed to be compatible with a wide range of languages, including both general-user scripting languages and the more challenging languages used mostly by professional programmers. Thus, the GOM APIs need to operate across a variety of memory management philosophies, from language platforms that do not expose memory management to the user at all, through those (notably Java) that provide explicit constructors but provide an automatic garbage collection mechanism to automatically reclaim unused memory, to those (especially C/C++) that generally require the programmer to explicitly allocate object memory, track where it is used, and explicitly free it for re-use. To ensure a consistent API across these platforms, the GOM does not address memory management issues at all, but instead leaves these for the implementation.

1.1.3. Naming Conventions

While it would be nice to have attribute and method names that are short, informative, internally consistent, and familiar to users of similar APIs, the names also should not clash with the names in legacy APIs supported by GOM implementations. Furthermore, both OMG IDL and ECMAScript have significant limitations in their ability to disambiguate names from different namespaces that makes it difficult to avoid naming conflicts with short, familiar names. So, some GOM names tend to be long and quite descriptive in order to be unique across all environments.

It has also been attempted to be internally consistent in its use of various terms, even though these may not be common distinctions in other APIs. For example, the method name “remove” is used when the method changes the structural model, and the method name “delete” when the method
gets rid of something inside the structure model. The thing that is deleted is not returned. The thing that is removed may be returned, when it makes sense to return it.

1.1.4. Inheritance vs Flattened Views of the API

The GOM Core APIs present two somewhat different sets of interfaces to a game; one presenting an “object-oriented” approach with a hierarchy of inheritance, and a “simplified” view that allows all manipulation to be done via the Gob interface without requiring casts (in Java and other C-like languages) or query interface calls in COM environments. These operations are fairly expensive in Java and COM, and the GOM may be used in performance-critical environments, so we allow significant functionality using just the Gob interface. Because many other users will find the inheritance hierarchy easier to understand than the “everything is a Gob” approach to the GOM, we also support the full higher-level interfaces for those who prefer a more object-oriented API.

In practice, this means that there is a certain amount of redundancy in the API. The “inheritance” approach is considered to be the primary view of the API, and the full set of functionality on Gob to be “extra” functionality that users may employ, but that does not eliminate the need for methods on other interfaces that an object-oriented analysis would dictate. (Of course, when the O-O analysis yields an attribute or method that is identical to one on the Gob interface, a completely redundant one isn’t specified). Thus, even though there is a generic gobName attribute on the Gob interface, there is still a agentName attribute on the Agent interface; these two attributes must contain the same value, but it’s considered worthwhile to support both, given the different constituencies the GOM API must satisfy.

1.1.5. Gamespaces

The GOM supports “gamespaces” to allow creating and manipulating agents and items associated to a gamespace.

[gamespace description]

1.2.GOM Interfaces

The interfaces within this section are considered fundamental, and must be fully implemented by all conforming implementations of the GOM, unless otherwise specified.

ExceptionGOMException

GOM operations only raise exceptions in “exceptional” circumstances, i.e., when an operation is impossible to perform (either for logical reasons, because data is lost, or because the implementation has become unstable). In general, GOM methods return specific error values in ordinary processing situation, such as out-of-bound errors when using GobList.

Implementations may raise other exceptions under other circumstances. For example, implementations may raise an implementation-dependent exception if a null argument is passed.

Some languages and object systems do not support the concept of exceptions. For such systems, error conditions may be indicated using native error reporting mechanisms. For some bindings, for example, methods may return error codes similar to those listed in the corresponding method descriptions.

IDL Definition
exception GOMException
 { unsigned short   code;
 };
// ExceptionCode
const unsigned short      INDEX_SIZE_ERR                 = 1;
const unsigned short      HIERARCHY_REQUEST_ERR          = 2;
const unsigned short      WRONG_GAME_ERR                 = 3;
const unsigned short      NO_DATA_ALLOWED_ERR            = 4;
const unsigned short      NO_MODIFICATION_ALLOWED_ERR    = 5;
const unsigned short      NOT_FOUND_ERR                  = 6;
const unsigned short      NOT_SUPPORTED_ERR              = 7;
const unsigned short      INUSE_ATTRIBUTE_ERR            = 8;
const unsigned short      INVALID_STATE_ERR              = 9;
const unsigned short      SYNTAX_ERR                     = 10;
const unsigned short      INVALID_MODIFICATION_ERR       = 11;
const unsigned short      GAMESPACE_ERR                  = 12;
const unsigned short      INVALID_ACCESS_ERR             = 13;

Definition group ExceptionCode

An integer indicating the type of error generated.

Note: Other numeric codes are reserved for possible future use.

Defined Constants
INDEX_SIZE_ERR If index or size is negative, or greater than the allowed value
HIERARCHY_REQUEST_ERR If any gob is inserted somewhere it doesn’t belong
WRONG_GAME_ERR If a gob is used in a different game than the one that created it (that doesn’t support it)
NO_DATA_ALLOWED_ERR If data is specified for a gob which does not support data
NO_MODIFICATION_ALLOWED_ERR If an attempt is made to modify an object where modifications are not allowed
NOT_FOUND_ERR If an attempt is made to reference a gob in a context where it does not exist
NOT_SUPPORTED_ERR If the implementation does not support the type of object requested
INUSE_ATTRIBUTE_ERR If an attempt is made to add an attribute that is already inuse elsewhere
INVALID_STATE_ERR If an attempt is made to use an object that is not, or no longer,
usable.
SYNTAX_ERR If an invalid or illegal string is specified.
INVALID_MODIFICATION_ERR If an attempt is made to modify the type of the underlying
object.
GAMESPACE_ERR If an attempt is made to create or change an object in a way which is incorrect with regard to gamespaces.
INVALID_ACCESS_ERR If a parameter or an operation is not supported by the underlying object.