This annex provides a language and platform neutral definition of the ISO/IEC 14772-2 External Authoring Interface using the Object Management Group's Interface Definition Language (IDL). IDL is a language-neutral syntax, with well-defined mappings to a variety of standard languages, it serves as the baseline from which language-specific implementations are derived.
Certain aspects of the EAI are of necessity language and platform dependent, such as the various getBrowser operations. Therefore, implementations for specific languages and environments, such as Java Applets and C++ COM, are provided as additional annexes. As new implementations are developed, it is recommended that they employ the IDL Specification as the initial starting point.
See Table A.1 for the contents of this annex.
As with scripts within the VRML scene, the EAI allows access to the full functionality of the Browser script interface in ISO/IEC 14772-1. Browser state can be queried, routes can be added and deleted, and new nodes can be created. The EAI extends the basic browser interface with a number of extra capabilities such as retrieving node references and registering interest in browser events.
The IDL language provides an outline guide to the EAI specification. It provides a complete definition of the binding to the specification within the restrictions and implementation specific capabilities as noted in this part of ISO/IEC 14772. This specification does not provide a complete implementation of this part of ISO/IEC 14772 as the capabilities for obtaining a reference to the Browser object, the starting point of a session, is by necessity environment specific.
A conforming, language-specific implementation must match the language bindings as generated by the IDL mapping for that language. Conforming implementations must implement all the interfaces and methods defined in this annex. Implementations may add additional functions, method calls, or constructors.
The process for obtaining the initial reference to a browser object is implementation dependent.
The action type is dependent on the method used.
The browser reference type is defined to be an instance of the Browser interface.
Field access is defined by a set of interfaces used to represent the EAIFieldID. The base interface BaseField defines the basic field properties. The interfaces EventIn and EventOut inherited from BaseField provide representations of the access types.
There is a distinct difference between the access type of the underlying
field that was retrieved from the node and how it is represented by the
interfaces. A request is made of the node to access any field to be viewed as either
an eventIn or an eventOut. The node interface then either returns the type or
generates an error condition. The acceptable conditions for successful
completion of the request are defined in Table A.2
Table A.2 — Rules for mapping VRML Field types to IDL interfaces
|
|
Interface |
|
|
|
EventIn |
EventOut |
VRML Field Types |
field |
Exception |
Exception |
eventIn |
yes |
Exception |
|
eventOut |
Exception |
yes |
|
exposedField |
yes |
yes |
The field identifier is an instance of the BaseField interface.
The name of the field is represented as a IDL string data type.
The field type may be represented in two alternative fashions.
The first alternative is provided through getType() method provided in the BaseField interface. This returns a long which has one of the values defined by the constant types also defined in that interface.
The second alternative is provided by the interface hierarchy. The EventIn and EventOut interfaces are further derived to provide interfaces for each exact field type.
The field value is defined on a per class and per field type instance.
The node identifiers is represented as an instance of the Node interface.
The node type is represented as a IDL string data type.
The requestor ID is represented as one of two interfaces depending on what information is being requested.
The requestor ID is an instance of the BrowserListener interface when the service request is Register Browser Interest.
The requestor ID is an instance of the VrmlEventListener interface when the service request is Register Field_Interest.
The URL is represented as a IDL string data type.
The string is represented as a IDL string data type.
The null is typically represented as the empty string.
Errors are represented as IDL exceptions.
The error type is represented as a VrmlException.
The error type is represented as a NoSuchBrowserException.
The error type is represented as a ConnectionException.
The error type is represented as two separate dual purpose exceptions depending on their scope.
InvalidBrowserException
is used to indicate an EAIBrowserRef has been
disposed of.
InvalidNodeException
is used to indicate an EAINodeID has been disposed of.
The error type is represented as two separate exceptions based on the implementation of EAINodeID and the rules defined in Table A.2.
InvalidEventInException is used to indicate the named field is not accessable as an eventIn from the Node.getEventIn() method.
InvalidEventOutException is used to indicate the named field is not accessable as an eventOut from the Node.getEventOut() method.
The error type is represented as an InvalidBrowserException.
The error type is expresented as different exceptions depending on the situation. The Browser.getNode() method uses InvalidNodeException. The Node interface getEventIn() and getEventOut() methods use InvalidEventInException and InvalidEventOutException respectively.
The error type is represented as an InvalidNodeException.
The error type is represented as an InvalidFieldException, an InvalidEventInException, or an InvalidEventOutException.
The error type is represented as an InvalidURLException.
The error type is represented as an InvalidvrmlException.
The error type is represented as an URLUnavailableException.
In MF fields, sequences are used to represent the data contained in the VRML field. Setting the value of that field with a sequence of length 0 shall result in the contents of the field being cleared and is the equivalent of the VRML text file declaration of
SomeNode {
MFField
[]
}
An empty MF field shall return an sequence of length zero if queried about its value. The size() method of the MField base interfaces shall return a value of 0.
MField interfaces contain a set1Value method for setting an individual value in the field.
If beginUpdate has been called and multiple set1Values have been called on that field, the result when endUpdate is called shall be a single event with all of the individual values set. If two calls are made to set a particular array index, the last value written shall be used.
If beginUpdate has not been called, the result shall be an event that contains the entire field value with the individual value changed. Multiple set1Value calls to the field shall result in the equivalent number of events being generated inside the VRML browser.
The IDL specification does not define an interface for establishing a Browser interface, as this is necessarily dependent upon the representation of a VRML Browser for a specific language binding. Refer to specific language bindings for that binding's implementation.
Once a reference to a browser has been established, services may be requested of the browser. This clause defines the IDL representation of the browser services. The browser reference is represented by the Browser interface.
The name returned is a string representing the name of the browser. If this is not supported, the empty string shall be returned.
The version returned is a string representing the version number of the browser. If this is not supported, the empty string shall be returned.
The speed value returned shall be a floating point number or 0.0 if it is not supported.
The frame rate value shall be a floating point number or 0.0 if it is not supported.
The world URL shall be a string indicating the complete world URL as defined in 6.3.11 getWorldURL.
The parameter shall be a sequence of Node instances which shall be used to replace the currently loaded world. If one or more of the node instances have been disposed of, an IllegalArgumentException shall be generated.
The parameters shall be a sequence of strings for the URL list and a sequence of strings for the parameters. If the browser determines that it cannot load any of the URLs passed, the browser event listener shall receive an event notifying it of an error.
This service sets the description string of the browser. If the browser is running as a Web Browser plugin, this shall set the title of the page (if the containing web browser supports this). For component browsers the result shall be implementation dependent.
The parameter shall be a string that contains legal syntax as defined in ISO/IEC 14772-1. The only difference is that the file header #VRML V2.0 utf8 need not be present as the first line in the string. If the string does not contain legal VRML97 syntax, an InvalidVrmlException shall be generated. Returned is an sequence of the top level Nodes in the order that they are declared in the string parameter.
The parameter list shall consist of a sequence of strings describing the list of URLs, a reference to a destination Node and a string which is the name of the eventIn to send the loaded URL nodes to. If the browser determines that it cannot load any of the URLs passed, the browser event listener shall receive and event notifying it of an error.
This service is split into two separate methods: addRoute and deleteRoute. They both take the same argument list. The first parameter is a Node reference that the event will leave from. The second is a string describing the name of the eventOut. Third and forth parameters are the destination node reference and the eventIn as a string. If either of the Node references have been disposed of, an InvalidNodeException shall be generated. If either of the nodes do not contain the nominated eventIn/eventOut, an InvalidEventIn/EventOutException shall be generated appropriately.
This service is split into two separate methods beginUpdate and endUpdate. The functionality remains as described in 6.3.16 Update Control.
Registering interest in browser events is through a browser event listener. The listener is an interface which is passed browser events when the state of the browser changes or asyncrhonous error messages must be sent (for example, inability to load and of the requested URLs). Methods shall be provided to allow listeners to be added and removed dynamically. A separate event interface shall be used to indicate the event information. This interface has a predefined number of events although specific browser implementations may send more events than the defined values. Any extra event types must not have values below the figure defined by LAST_IDENTIFIER.
The return value is a Node reference. The parameter is a string defining the DEF name of the required node. If the browser cannot find the node name, an InvalidNodeException shall be generated.
Dispose shall notify the browser that the application is no longer interested in the VRML browser. Any further requests to methods of this instance of the browser interface shall generate an InvalidBrowserException.
The 6.4.5 getType and 6.4.4 getName services are method requests that return the name of the node as a string.
The 6.4.3 getField service is implemented as two separate methods getEventIn() and getEventOut() which allow access to eventIns and eventOuts but not to fields. An exposedField may be accessed as either the eventIn or eventOut portion separately through these two methods. The normal field name or with the set_ modifier may be used with the getEventIn method. The normal field name or the _changed modifier may be used with the getEventOut method.
Dispose shall notify the browser that the application is no longer interested in this node instance and it is free to do as required with the node representation. Any further requests to methods of this instance of the node reference shall generate an InvalidNoderException.
Field services are implemented using the BaseField interface and its derived interfaces.
6.5.2 getAccessType returns a long which has one of the values defined by the BaseField interface.
The getType method of BaseField returns a long representing the type of field represented. The list of legal type identifiers is defined in the BaseField interface. The return value of the getType() method shall be one of these values.
The getName method of BaseField returns a string containing the name of the field.
The getValue service is supported only on interfaces derived from EventOut. It is not possible to read values from eventIn as there is no method to support this operation. On fields which are exposedFields, an eventOut derived interface must be used to access the field to read its value.
A get1Value method is provided for MF fields. This allows access to a single value out of the many values. When an attempt is made to access a value at an index greater than the number of items in that eventOut, an ArrayIndexOutOfBoundsException shall be generated.
Specific language bindings may define additional or overloaded getValue methods as appropriate for the particular language.
The setValue service is supported only on interfaces derived from EventIn. It is not possible to write values from eventIn as there is no method to support this operation. On fields which are exposedFields, an EventIn derived interface must be used to write a new value.
A set1Value method is provided for MFFields. This allows the ability to change a single value of a field without having to re-create the entire array of values. When an attempt is made to set a value at an index greater than the number of items in that eventIn, an ArrayIndexOutOfBoundsException shall be generated.
Specific language bindings may define additional or overloaded setValue methods as appropriate for the particular language.
Registering interest is accomplished through the addVrmlEventListener method of the BaseField interface.
typedef sequence<string> stringarray;
typedef sequence<float> floatarray;
typedef sequence<long> longarray;
typedef sequence<double> doublearray;
typedef sequence<octet> bytearray;
typedef sequence<stringarray> stringdoublearray;
typedef sequence<floatarray> floatdoublearray;
typedef sequence<longarray> longdoublearray;
module vrml {
/* forward declarations */
module eai {
interface Browser;
module field {
interface BaseField;
interface EventIn;
interface EventOut;
};
module event {
interface BrowserEvent {
const long INITIALIZED = 1;
const long SHUTDOWN = 2;
const long URL_ERROR = 3;
const long CONNECTION_ERROR = 4;
const long LAST_IDENTIFIER = 5;
long getID();
Browser getSource();
};
interface BrowserListener {
void browserChanged(in BrowserEvent evt);
};
interface VrmlEvent {
field::BaseField getSource();
double getTime();
};
interface VrmlEventListener {
void eventOutChanged(in VrmlEvent evt);
};
};
exception VrmlException {};
exception IllegalArgumentException {};
exception ArrayIndexOutOfBoundsException {};
module field {
exception InvalidFieldException {};
exception InvalidEventInException {};
exception InvalidEventOutException {};
};
exception InvalidBrowserException {};
exception InvalidNodeException {};
exception InvalidVrmlException {};
exception NoSuchBrowserException {};
exception NotSupportedException {};
exception ConnectionException {};
interface Node {
string getType()
raises (InvalidNodeException);
string getName()
raises (InvalidNodeException);
eai::field::EventIn getEventIn(in string name)
raises (eai::field::InvalidEventInException, InvalidNodeException);
eai::field::EventOut getEventOut(in string name)
raises (eai::field::InvalidEventOutException, InvalidNodeException);
void dispose()
raises (InvalidNodeException);
};
typedef sequence<Node> nodearray;
interface Browser {
string getName()
raises (InvalidBrowserException, ConnectionException);
string getVersion()
raises (InvalidBrowserException, ConnectionException);
float getCurrentSpeed()
raises (InvalidBrowserException, ConnectionException);
float getCurrentFrameRate()
raises (InvalidBrowserException, ConnectionException);
string getWorldURL()
raises (InvalidBrowserException, ConnectionException);
void replaceWorld(in nodearray node_names)
raises (IllegalArgumentException, InvalidBrowserException,
ConnectionException);
void loadURL(in stringarray url, in stringarray parameter)
raises (InvalidBrowserException, ConnectionException);
void setDescription(in string description)
raises (InvalidBrowserException, ConnectionException);
nodearray createVrmlFromString(in string vrmlSyntax)
raises (InvalidVrmlException, InvalidBrowserException,
ConnectionException);
void createVrmlFromURL(in stringarray url, in Node node,
in string event)
raises (InvalidBrowserException, InvalidNodeException,
ConnectionException);
Node getNode(in string name)
raises (InvalidNodeException, InvalidBrowserException,
ConnectionException);
void addRoute(in Node fromNode, in string fromEventOut,
in Node toNode, in string toEventIn)
raises (eai::field::InvalidEventInException,
eai::field::InvalidEventOutException,
InvalidBrowserException, InvalidNodeException,
ConnectionException);
void deleteRoute(in Node fromNode, in string fromEventOut,
in Node toNode, in string toEventIn)
raises (eai::field::InvalidEventInException,
eai::field::InvalidEventOutException,
InvalidBrowserException, InvalidNodeException,
ConnectionException);
void beginUpdate()
raises (InvalidBrowserException, ConnectionException);
void endUpdate()
raises (InvalidBrowserException, ConnectionException);
void dispose();
void addBrowserListener(in eai::event::BrowserListener l)
raises (InvalidBrowserException, ConnectionException);
void removeBrowserListener(in eai::event::BrowserListener l)
raises (InvalidBrowserException, ConnectionException);
};
module field {
interface BaseField {
const long SFBool = 1;
const long SFColor = 2;
const long SFFloat = 3;
const long SFImage = 4;
const long SFInt32 = 5;
const long SFNode = 6;
const long SFRotation = 7;
const long SFString = 8;
const long SFTime = 9;
const long SFVec2f = 10;
const long SFVec3f = 11;
const long MFColor = 12;
const long MFFloat = 13;
const long MFInt32 = 14;
const long MFNode = 15;
const long MFRotation = 16;
const long MFString = 17;
const long MFTime = 18;
const long MFVec2f = 19;
const long MFVec3f = 20;
const long UNSET_FIELD = 21;
/* access types */
const long EVENTIN = 22;
const long EVENTOUT = 23;
const long EXPOSEDFIELD = 24;
long getType();
long getAccessType();
string getName();
void addVrmlEventListener(in eai::event::VrmlEventListener l);
void removeVrmlEventListener(in eai::event::VrmlEventListener l);
};
/*
note: IDL does not support overloading methods, so each interface has only one
setValue and getValue method. Specific language bindings are free to add additional overloaded
methods
*/
interface EventIn: BaseField {
};
interface EventInMFColor: EventIn {
void setValue(in floatdoublearray value)
raises(IllegalArgumentException,
ArrayIndexOutOfBoundsException);
void set1Value(in long index, in floatarray value)
raises(IllegalArgumentException,
ArrayIndexOutOfBoundsException);
};
interface EventInMFFloat: EventIn {
void setValue(in floatarray value);
void set1Value(in long index, in float value)
raises(ArrayIndexOutOfBoundsException);
};
interface EventInMFInt32: EventIn {
void setValue(in longarray value);
void set1Value(in long index, in long value)
raises(ArrayIndexOutOfBoundsException);
};
interface EventInMFNode: EventIn {
void setValue(in nodearray node)
raises(InvalidNodeException);
void set1Value(in long index, in Node node)
raises(InvalidNodeException, ArrayIndexOutOfBoundsException);
};
interface EventInMFRotation: EventIn {
void setValue(in floatdoublearray value)
raises(ArrayIndexOutOfBoundsException);
void set1Value(in long index, in floatarray value)
raises(ArrayIndexOutOfBoundsException);
};
interface EventInMFString: EventIn {
void setValue(in stringarray value);
void set1Value(in long index, in string value)
raises(ArrayIndexOutOfBoundsException);
};
interface EventInMFTime: EventIn {
void setValue(in doublearray value);
void set1Value(in long index, in double value)
raises(ArrayIndexOutOfBoundsException);
};
interface EventInMFVec2f: EventIn {
void setValue(in floatdoublearray value)
raises(ArrayIndexOutOfBoundsException);
void set1Value(in long index, in floatarray value)
raises(ArrayIndexOutOfBoundsException);
};
interface EventInMFVec3f: EventIn {
void setValue(in floatdoublearray value)
raises(ArrayIndexOutOfBoundsException);
void set1Value(in long index, in floatarray value)
raises(ArrayIndexOutOfBoundsException);
};
interface EventInSFBool: EventIn {
void setValue(in boolean value);
};
interface EventInSFColor: EventIn {
void setValue(in floatarray value)
raises(IllegalArgumentException,
ArrayIndexOutOfBoundsException);
};
interface EventInSFFloat: EventIn {
void setValue(in float value);
};
interface EventInSFImage: EventIn {
void setValue(in long width, in long height,
in long numComponents, in longarray pixels)
raises(IllegalArgumentException, ArrayIndexOutOfBoundsException);
};
interface EventInSFInt32: EventIn {
void setValue(in long value);
};
interface EventInSFNode: EventIn {
void setValue(in Node value)
raises(InvalidNodeException);
};
interface EventInSFRotation: EventIn {
void setValue(in floatarray value)
raises(ArrayIndexOutOfBoundsException);
};
interface EventInSFString: EventIn {
void setValue(in string value);
};
interface EventInSFTime: EventIn {
void setValue(in double value);
};
interface EventInSFVec2f: EventIn {
void setValue(in floatarray value)
raises(ArrayIndexOutOfBoundsException);
};
interface EventInSFVec3f: EventIn {
void setValue(in floatarray value)
raises(ArrayIndexOutOfBoundsException);
};
interface EventOut {
};
interface EventOutMField: EventOut {
long size();
};
interface EventOutMFColor: EventOutMField {
floatdoublearray getValue();
floatarray get1Value(in long index)
raises (ArrayIndexOutOfBoundsException);
};
interface EventOutMFFloat: EventOutMField {
floatarray getValue();
float get1Value(in long index)
raises (ArrayIndexOutOfBoundsException);
};
interface EventOutMFInt32: EventOutMField {
longarray getValue();
long get1Value(in long index)
raises (ArrayIndexOutOfBoundsException);
};
interface EventOutMFNode: EventOutMField {
nodearray getValue();
Node get1Value(in long index)
raises (ArrayIndexOutOfBoundsException);
};
interface EventOutMFRotation: EventOutMField {
floatdoublearray getValue();
floatarray get1Value(in long index)
raises (ArrayIndexOutOfBoundsException);
};
interface EventOutMFString: EventOutMField {
stringarray getValue();
string get1Value(in long index)
raises (ArrayIndexOutOfBoundsException);
};
interface EventOutMFTime: EventOutMField {
doublearray getValue();
double get1Value(in long index)
raises (ArrayIndexOutOfBoundsException);
};
interface EventOutMFVec2f: EventOutMField {
floatdoublearray getValue();
floatarray get1Value(in long index)
raises (ArrayIndexOutOfBoundsException);
};
interface EventOutMFVec3f: EventOutMField {
floatdoublearray getValue();
floatarray get1Value(in long index)
raises (ArrayIndexOutOfBoundsException);
};
interface EventOutSFBool: EventOut {
boolean getValue();
};
interface EventOutSFColor: EventOut {
floatarray getValue();
};
interface EventOutSFFloat: EventOut {
float getValue();
};
interface EventOutSFImage: EventOut {
long getWidth();
long getHeight();
long getNumComponents();
longarray getPixels();
};
interface EventOutSFInt32: EventOut {
long getValue();
};
interface EventOutSFNode: EventOut {
Node getValue();
};
interface EventOutSFRotation: EventOut {
floatarray getValue();
};
interface EventOutSFString: EventOut {
string getValue();
};
interface EventOutSFTime: EventOut {
double getValue();
};
interface EventOutSFVec2f: EventOut {
floatarray getValue();
};
interface EventOutSFVec3f: EventOut {
floatarray getValue();
};
};
};
};