Extensible 3D (X3D)
Part 2: Scene access interface (SAI)
4 Concepts
This clause describes key concepts in this part of ISO/IEC 19775. This includes describing the various components of the browser and how the interactions with the browser may be accomplished. It does not define what the individual interactions are. Those descriptions can be found in 6 Services reference.
Table 4.1 provides links to the major topics in this clause.
When a user wishes to interact with an X3D scene graph through use of custom code, either as a Script node as defined in 29 Scripting component of part 1 of ISO/IEC 19775 (see 2.[19775-1]) or from external applications, they shall use the Scene Authoring Interface (SAI) defined in this part of ISO/IEC 19775. This interface is a protocol for manipulating the X3D scene graph while not directly part of the scene graph itself.
This specification is aimed at providing a language neutral representation of all actions that can be performed by an external application across this interface. Bindings to specific languages are defined in 2.[I19777]. The SAI forms a common interface that can be used either for manipulating the browser and the scene graph from either an external application or from inside the scene graph through the Script node. However, it is not possible for code written for an external application to be immediately usable as a script. The two environments have quite different requirements and abilities to access and interact with the scene graph. This specification provides a single, unified programmatic interface and constraints that depend on the environment in which the code finds itself.
Conceptually, the SAI allows five types of access into the X3D scene:
If an X3D browser wishes to conform to ISO/IEC 14772 (VRML) (see 2.[I14772-1]), the browser shall support the event model and semantics defined in Annex A VRML scripting backwards compatibility in addition to the functionality specified in part 1 of ISO/IEC 19775. Such support shall only be used when processing files that conform to ISO/IEC 14772-1.
If an X3D browser wishes to conform to ISO/IEC 14772-2 (EAI) (see 2.[I14772-2]), the browser shall use the following rules to determine content validity:
Implementation dependence is defined in terms of the language binding or protocol encoding of the services defined in this specification. If a service is defined to be implementation dependent, it is a requirement of each binding and encoding to specify how that service is to be implemented, if at all.
Bindings and encodings to these services may define their own implementation dependent parts within that specification.
There are four main data collections in an X3D browser that can be accessed using the services of the SAI: The browser, meta data about the currently loaded scene, nodes within the scene graph, and fields within nodes. The definition and specifications are framed in terms of services. An X3D browser exposes a set of services that allow external applications to interact with it. In order to describe these concepts, a number of terms are defined.
Any code that makes use of the services defined in this part of ISO/IEC 19775 is considered to be user code. User code may exist either within the scene graph or external to the browser. It shall only use the services provided by this part and no browser implementation specific services. In addition, these services are not designed for, nor intended to be used for, writing native node extensions to a specific browser. A browser may provide their own proprietary programmatic interfaces to implement native extensions that are not part of this specification. If code uses proprietary extensions, it shall not be considered user code for the purposes of this Part.
A containing node is the node in the scene graph that is responsible for representing user code that wishes to take part in Internal Interactions (see 4.8.2 Internal Interactions). The life cycle of user code shall be governed entirely by the containing node. When the containing node becomes live, the user code becomes live. When the containing node is removed and is no longer considered live as defined in 4.4.2.5 Object life cycle of part 1 of ISO/IEC 19775 (see 2.[I19775-1]), the user code contained by that node shall be terminated. User code cannot prolong the lifetime of the containing node by keeping a reference to its containing node. The browser is the final arbiter of when the containing node is no longer live.
There is no requirement for there to be a one-to-one mapping between a containing node and its user code. Language bindings may permit one instance of user code to be shared between multiple instances of a containing node.
An application is the external process that is not implicitly part of the X3D browser. This application makes some form of connection to the X3D browser along which requests are made of the browser. The application does not exist as part of the X3D browser as defined in Figure 4.1 in part 1 of ISO/IEC 19775 (see 2.[I19775-1]) nor forms part of the execution model defined in 4.4.8.3 Execution model of 2.[I19775-1]. An application may reside on another machine from the X3D browser. An application may be responsible for creating a new browser instance that is embedded within that application or attaching itself to an already running instance of a browser (for example, an applet on a web page).
A session defines the life of a single connection between the user code and the X3D browser. It is possible for a single browser to be servicing multiple sessions simultaneously (for example, multiple script nodes in the one scene).
A single application may contain a number of separate sessions to multiple browsers, but a single script node shall not. Multiple simultaneous sessions between external applications and multiple X3D browsers is permissible. However, individual implementations may place some restrictions on such multiple simultaneous sessions.
A session is not an implementable part of this specification. It is purely a conceptual mechanism by which the user can make requests for services. It may exist prior to any connection being established between a browser and external application or is established simultaneously with the request for a browser connection.
The browser is the basic encapsulation mechanism for an active X3D scene graph (that is one where time is progressing, not as a file stored on disk). As it contains the entire scene graph, it also provides a minimal core set of capabilities for dynamically manipulating that scene graph at a coarse level.
A user may have many X3D browsers running simultaneously on their machine. Therefore, each browser shall be represented by a unique identifier within that session. This identifier is required to be identical for multiple requests of a single browser instance. This is to enable two applications that have access to the one browser instance to share information in an unambiguous way.
Any action that requires use of the browser functionality shall identify the service request with a browser identifier.
A scene represents a single X3D scene graph and all information about that scene graph. The scene is the programmatic equivalent of a X3D file. It may contain nodes, routes, proto declarations, imports and exports and all information a valid X3D file may contain. A browser may contain one or more scenes at any given time. For example one scene uses an Inline node to include another scene.
A scene is not required to be live or running in the browser. A user may construct a new scene that is not attached to a browser instance and then programmatically fill in information such as nodes and routes. This scene may then be passed directly to a utility program such as a pretty printer for publishing a source file or used to replace the current scene in the browser.
The smallest unit of interaction with the elements in the scene graph is the node. A node is equivalent to the X3D nodes that are defined in part 1 of ISO/IEC 19775 (see 2.[I19775-1]). A node can be removed as a unit from the scene graph, stored, and then re-inserted at another position at some later time in the same session without detrimental effect.
Each node is defined by a unique identifier. This identifier is unique for that session. That is, it is possible that a single browser may be servicing multiple applications simultaneously and therefore all node identifiers are unique and invariant for the life of the session. This allows two external applications to potentially share data between themselves unambiguously and still have either make service requests of the browser with that shared data.
Most operations in the SAI begin by obtaining a reference to a node. There are multiple ways to gain a reference to a node. It may be named using the DEF construct and fetched using the appropriate service or it may be obtained by walking the scene graph from some arbitrary parent node. Once a reference is obtained, all fields of that node may be accessed, but not necessarily read or written, including initializeOnly fields. Since an inputOutput field implicitly may be both read and written, these are accessible using the field name or with the set_ and _changed modifiers.
A node reference undergoes a lifecycle during which different capabilities are available. The lifecycle can be expressed as:
Field access for reading and writing is dependent on the state of the node. The states and capabilities are defined in Table 4.2.
Table 4.2 — Permitted field access capabilities during the node lifecycle.
Field type | Creation | Setup | Realized | Disposed |
---|---|---|---|---|
initializeOnly field | None | readable/writable | None | None |
inputOnly field | None | None | writable | None |
outputOnly field | None | None | readable | None |
inputOutput field | None | readable/writable | readable/writable | None |
The transition from setup to realized states may be either implicit or explicit. A service request exists so that the user may make a formal notification that setup is now finished and the node can complete whatever internal construction is required. The transition may be implicit due to the user's actions. At the point the user does anything with the node reference other than set the field values, the node shall transition to the realized state. For example, the user creates a Box node, sets the size field, creates a Shape node then immediately adds the Box to a Shape node, shall result in the state of the Box node changing to Realized, while leaving the Shape node in the setup state.
Node identifiers may also be used to represent an empty node. An
empty SFNode or MFNode field value is represented by a NULL
value.
For empty MFNode fields, the count of available nodes shall be zero
when the field value is NULL
.
Individual fields are within nodes. While it is not possible to directly manipulate a node, a field is the method of direct manipulation of individual properties.
It is not possible to directly manipulate a node's properties as entities separate from the node itself (i.e., fields do not exist outside their containing nodes).
The access granted to individual fields is defined by Part 1 of this standard. A field is assigned a field identifier. This is non-unique and requires a node identifier plus the field identifier to specify a particular field with which to interact. When accessing a field, the user shall be given the identifier to the whole field. All fields are implicitly treated as being both readable and writable by the service definition. Flags are used to indicate whether that field can be read or written at that point in time (and dependent on the node's state in the lifecycle as described in Table 4.2). This state may change over time as the node progresses through its lifecycle. For example, an initializeOnly field of a non-live node may be writable, but once that node is inserted into the scene graph, it shall no longer be writable. This is to aid authoring tools and users that wish to programmatically construct a scene around a third party browser.
Fields may be read or written at any time during the course of the session. User code may register and unregister to receive notification of when values of the field changes. During the registration process the user code can supply a token that will be returned along with the data value of the event. This token can be used by the user code to uniquely identify this event in cases where events are not implicitly unique. The token is not required to be passed along with the service request and may be kept as part of the internals of the implementation on the application interface.
Any output-capable field of a node to which the application has a reference can be read. The value read is the last value sent by that field or the default value for that field type if no event has ever been sent. The data read is specific to the field type of that field and is formatted appropriate to the language or protocol used.
A scene is a derived type of execution context. When the internal interaction requests the current execution context, a scene object is returned. The user code may then check to see if the execution context is an instance of a full scene and behave appropriately by casting up to the derived type, if available.
Any transient data is carried around the X3D scene graph through the use of events. The application may register to receive events from the X3D scene graph, and may initiate new events. Events are considered transient and generated only at the time when the specific action occurs. Events shall not be stored and have the delivery deferred to parties who have not expressed interest in the event at the time it occurred. For example an application that connects to a browser after the world has loaded shall not be delivered an Initialize event.
An application may write a value to a field or read a value from a field. This value does not become an event until that value is internally represented within the X3D browser. The border of the browser to the application is where an event stops. Events cannot exist externally from the X3D browser; that is, the application cannot be inserted in the middle of an event cascade. The application may be notified of events, initiate new events, but cannot process and pass on events while holding up processing of the current timestamp event cascades within the browser when it is notified of an event.
An event is not generated until a cascade is created. If an internal interaction directly writes to an output-capable field of another node, no event is generated and therefore does not form part of the event cascade. If the internal interaction writes to a input-capable field of the containing node, an event is formed with the written value, if the field is the subject of a ROUTE from somewhere else.
The browser may directly communicate to external applications with its own set of events. These events are used to indicate the status of the browser or of some asynchronous problem. The number and type of events available shall be implementation dependent. At a minimum, the following events shall be provided in all implementations of this specification.
Event delivery from the browser to the external application shall be guaranteed.
The initialize event is used to indicate that the browser has had a scene loaded where it has run through the initialization process (where the browser has loaded the world and just before it is about to issue its first time-related event). At this point in time, node identifiers shall be available from the getNode service of the scene (see 6.4.8 getNode).
The initialize event shall be generated immediately at the browser and delivered to the application. The event is considered to be asynchronous. That is, the delivery of the event (and any implementation dependent acknowledgement scheme) shall not delay the browser in starting the execution model evaluation.
The shutdown event is used to indicate that the browser is about to stop running the current scene. This may occur under a number of different conditions:
The shutdown event shall be generated immediately at the browser and delivered to the application. The event is considered to be asynchronous. That is, the delivery of the event (and any implementation dependent acknowledgement scheme) shall not delay the browser in halting the execution model evaluation and closing down of the browser resources except where needed to ensure the delivery of the event to the application.
The no URL event is used to notify the application that the browser was not able to load any of the URL/URNs in one of the asynchronous invocations of the loadURL service (See 6.3.12 loadURL). This indicates that no valid content was able to be loaded from any of the URLs specified in this call. Other calls that may involve other asynchronous loads such as replaceWorld (see 6.3.10 replaceWorld) and createX3DFromString and createX3DFromStream (see 6.3.14 createX3DFromString, 6.3.15 createX3DFromStream) may also use this event to indicate loading problems for any X3DUrlNode as specified in 9.3.2 X3DUrlObject of part 1 of ISO/IEC 19775 (see 2.[I19775-1]) such as Inlines, textures and EXTERNPROTOs, although it is not required.
The connection lost error is used to notify the application that the underlying implementation has lost the connection between the browser and the application that would result in service requests not being able to be honoured. An example would be a TCP network connection timing out or other similar problem.
An implementation may delay sending an event that the connection has been lost if it implements some automatic reconnection attempt. It shall only be sent at the point where it is deemed no longer possible to connect to the browser. There shall be no requirement for the implementation to attempt to re-establish the connection after this event has been generated or to attempt any form of automatic reconnection capability.
What constitutes an identifier is implementation dependent. In some cases it may be more efficient to represent a node identifier as the entire node which includes all field information. Requests for field information are then made on the local node. In other implementations an identifier may be only a simple integer. The job of ensuring unique identifiers is the sole responsibility of the browser such that applications may share data within reasonable constraints of the environment. The constraints on that environment may be specified as part of the individual implementation as defined in the attached appendices.
It is not considered reasonable that two applications using different service implementations be able to exchange data outside of the browser environment.
9.2.2 Relative URLs in part 1 of ISO/IEC 19775 (see 2.[I19775-1]) specifies the rules for dealing with relative URLs within a browser environment. The declaring file shall be defined as the base URL of the currently loaded world in the browser. The currently loaded world can be obtained by a request of the getWorldURL service (see 6.4.5 getWorldURL). In the case where a browser does not yet have an X3D file loaded, the base document directory shall be taken to be the current working directory of the browser. Where the browser is part of a web page, the current working directory shall be treated as the base URL of the page in which the web browser is embedded.
When nested relative URLs are generated (such as an EXTERNPROTO containing a reference to a script file) the top level RURL base is then resolved in accordance with part 1 of ISO/IEC 19775 (see 2.[I19775-1]).
Because the SAI fulfills the role of the programmatic interface for both external applications and scripts, the execution model is capable of working in both situations. Although the API calls are identical for both situations, the run-time evaluation of each service request may be different. For example, servicing a field changed notification in a script shall stop the current event cascade, but for an external application it shall not. This specification defines two types of interactions that services may participate in: internal (i.e., a script) and external (i.e., an application).
If an internal interaction registers any form of callback or listener functionality with objects defined by this specification, those callbacks are made at the time the change occurs. For example, a user code in Script A issues an event on an outputOnly field during the initialize service handling, and another piece of user code in Script B has a listener service on that eventOut. The listener would be fired immediately after the user code in Script A exits and returns control to the browser core.
An internal interaction is when the user code and containing node forms part of the X3D scene graph. These nodes are subject to and participate in the event cascade evaluation. Internal interactions may occur in the middle of the event cascade as a direct result of receiving an event, and may generate one or more output events in response. These events shall continue in the current cascade. When the output events are generated from asynchronous script evaluation or from some other process not directly related to processing of the current event cascade as defined in 29.2.4 EventsProcessed() in part 1 of ISO/IEC 19775 (see 2.[I19775-1]), a completely new event cascade is started.
An X3DScriptNode type as specified in 29.3.1 X3DScriptNode in part 1 of ISO/IEC 19775 (see 2.[I19775-1]) specifies a containing node although other node types may also be defined in the future. A browser shall only permit internal interactions by user code that is referenced from a X3DScriptNode type or other future defined containing node type. If the user code is referenced from any other node type, it shall consider the code as an external interaction and act accordingly.
Internal interactions also permit direct interaction with fields of other nodes, or some browser operations without participating in the event cascade. This action shall only be allowed dependent on the value of the directOutput field setting of the containing X3DScriptNode node. The definitions of when this behaviour is permitted is defined in 29 Scripting component in part 1 of ISO/IEC 19775 (see 2.[I19775-1]).
Because the user code is considered to be held inside of the containing node, the view of the node's fields are reversed to the normal situation. An inputOnly field is a readable field, not writable; an outputOnly field is a writable field, not readable; and an initializeOnly as well as an inputOutput field are both readable and writable. Contrast this with an external node that is not the containing node in Table 4.3. This resembles the type of access that any other built-in or native extension node may have.
Table 4.3 — Permitted field interactions of a live node
Access Type | Containing Node | External Node |
---|---|---|
initializeOnly |
readable/writable | no access |
inputOnly | readable | writable |
inputOutput | readable/writable | readable/writable |
outputOnly | writable | readable |
Internal interactions are permitted with the browser. Because the code lies inside the current scene, they are only permitted a limited set of the full browser services. The services clause outlines which services will be available to internal actions and which are off limits.
During the initialization phase of the internal action, a script shall be given a reference to the browser that is appropriate for its interactions. This shall remain constant throughout the lifetime of the script while it its containing node is considered live.
The purpose of an internal interaction is to respond to events, provide some processing and, optionally, also generate new output for the containing node. It may, also, provide asynchronous output that does not correspond to any input through the use of one or more threads. Generating output is considered in 4.8.3.4 Updating the scene graph. 4.8.3.4 describes the issues of responding to input resulting from an event cascade that sends an event to one or more output-capable fields of the containing node.
In order to respond to events, user code registers interest in the appropriate field(s) of the containing node. Interest may be registered with all field access types except outputOnly fields of the containing node. Once the containing node has completed its initialization phase any time that one of the fields of the containing node receives an event the user code shall be notified of this through the notification mechanism provided by the language-specific bindings. The browser may choose to either immediately notify the user code or to batch a number of events together and provide a deferred notification. In either case, the browser shall ensure that all events for that timestamp are delivered during that timestamp and not at some later time. The browser shall also obey the containing node's mustEvaluate field directive as specified in 29.4.1 Script in part 1 of ISO/IEC 19775 (see 2.[I19775-1]) when deciding whether to defer or immediately notify.
Upon notification, the browser shall not process any more events in the containing node's event cascade until processing has returned from the user code (although this does permit other event cascades to continue simultaneous processing). Values written to fields of other nodes and the input-capable fields of the containing node shall not be passed on to the destination node before the user code has relinquished control. Note that this does not exclude a browser implementation from delivering multiple events simultaneously to the user code if there are parallel event cascades being evaluated (for example a browser running on a multi-CPU machine where parallel event cascades can be evaluated and result in two cascades delivering events to the containing node simultaneously). The writer of the user code should be aware of and take appropriate precautions for this situation.
When the browser has determined that the cascade or cascades are completed, the browser may then call the containing node's eventProcessed() method as defined in 29.2.4 EventsProcessed() in part 1 of ISO/IEC 19775 (see 2.[I19775-1]). The user code is also notified of this situation and the user code may then choose to perform extra evaluation and generate more output. User code for internal notifications has no way of determining when the current rendered frame has finished and the next frame begins.
User code may choose to generate output in addition to receive inputs. For internal interactions, user code is not required to generate output in response to inputs. User code may asynchronously generate output or write directly to other nodes at any time that the containing node is considered live, within certain restrictions that are outlined in 4.8.3.3 Responding to events and 4.8.2.5 Asynchronous Actions.
User code has two options for influencing the scene graph; it may write to the output-capable fields of the containing node and have the values be subject to the usual event cascade, or it may directly write to the input-capable fields of another node to which the containing node and user code already has a reference. User code may write to the containing node's fields at any time and in accordance with the access rules defined in Table 4.2. Internal interactions with other nodes shall be subject to the rules defined by the containing node's directOutput field as specified in 29.2.6 Scripts with direct outputs in part 1 of ISO/IEC 19775 (see 2.[I19775-1]).
There are two special cases of user code not being permitted to make changes to fields of the containing node. The two fields of the X3DScriptNode abstract type mustEvaluate and directOutput are considered special and the user code shall not be permitted to modify these values at runtime. User code may read the values. If the containing node is also derived from the X3DUrlNode abstract type, it may choose to change its own URL fields, thereby replacing the current user code with new user code.
User code in some languages are allowed to operate using asynchronous threads of execution. These allow user code to run without the need for direct stimulus from the browser. A typical use of this situation is to monitor a network connection for changes to be made to the scene graph. This requires the use of internal interactions that are not created as a direct result of field changes being received by the user code.
Internal interactions are only permitted at the times specified by 4.8.3.7 User code lifecycle. The browser shall generate an error if user code attempts to make internal interactions at any other time. The prepareEvents service (see 6.10.3.1 prepareEvents), if defined by the user code, allows user code to perform completely asynchronous changes to the scene graph, at known points in time, without the need to clock the script using a TimeSensor or other node. This is in contrast to the eventsProcessed service (see 6.10.3.2 eventsProcessed), which is only called after the containing node has had to process field changes.
In addition, when user code registers for one of the listener services, the callbacks associated with this are considered asynchronous actions. User code operating during this period, shall not be permitted to make modifications to the scene graph.
The services definition for fields allows user code to register interest in the output of fields of other nodes. Internal interaction code shall not be permitted to register interest in field change information. If the user code wishes to be informed of field change information, it shall use the existing route mechanism and the appropriate scene services to add a route between the field of interest and an input-capable field of the containing node.
Internal user code may add register interest in the output-capable fields of other nodes. This shall only be permitted when the containing node's directOutput field is set to TRUE. It shall be an error to allow user code to register interest in outputs if this value set to FALSE.
The lifecycle of user code is important to know in order to maintain and effectively utilize resources from the underlying operating system. For user code involved in internal interactions, the lifecycle of the code is dependent on the lifecycle of the containing node. The user code shall have no greater life time than the containing node, although it may be shorter. The lifetime of user code may be shorter for many reasons, but principle reasons may include the download time needed to fetch the code from a remote site, other user code changing the URL of the containing node to replace the current user code with other user code. However, the lifecycle of user code follows the same basic principles of the containing node. It has the same phases and undergoes similar transitions.
The lifecycle of the containing node is defined in 4.4.2.5 Object life cycle in part 1 of ISO/IEC 19775 (see 2.[I19775-1]).
It is assumed that there will be some delay, however small, between when the containing node is initialized and when the user code will go through its initialization phase. While the containing node may already have finished the initialization phase and be in the running phase, the user code may not have started or may be processing its initialization.
During the initialization phase, internal interaction code is given all the information it needs for the rest of its lifecycle. The first step of the initialization phase is the instantiation of the user code. At instantiation, user code has no information about its containing environment or the containing node. During this time the user code may elect set up any resources it requires, such as threads, network connections or any other permitted actions of the containing environment (see 4.8.3.9 Execution environment and security).
After instantiation, the user code receives notification of resources needed to function within the internal interaction environment. It is given the identifier of the containing browser, the list of fields of a node (excluding any special fields) and the identifier of the containing node (needed so that user code may add and remove routes to it's containing node). User code shall not make any service requests with the one exception of printing messages during this period and if it does, the browser shall generate an error.
As the last step of the initialization phase, the user code shall have its initialize service called (see 6.10.2.3 initialize). At this point user code is free to make use of all the services available to internal interactions. For example, this would be a good time for the user code to register for change notifications of the containing node fields, or to perform external tasks like bind a particular viewpoint.
During the runtime phase, user code is subject to the requirements of this clause for receiving, sending and monitoring events as well as the X3D execution model.
User code is restricted about when it may make modifications to the scene graph. It shall only be permissible to make modification in response to prompts from the browser. The permitted times shall be defined as:
It shall be an error for user to make a service request at any time other than these where asynchronous interactions are not permitted. Each service request in 6 Service Requests defines whether user code is permitted to make asynchronous requests.
User code will enter the shutdown phase when either the node is no longer live or the actions of other user code has resulted in the user code being removed from the containing node (eg changing the URL of a script node to point at new executable content).
Notification of the change to the shutdown phase shall be through the calling of the shutdown service request in the user code (see 6.10.4.1 shutdown). During this phase user code may set values to an output-capable field of the containing nodes or write final values directly to the input-capable fields of other nodes. At the end of the phase, the identifiers to the browser and containing fields shall be considered as invalid. For example, if the user code contains a thread that continues to operate after the shutdown phase, it shall not be permitted to make modifications to the scene graph. To do so shall generate an error.
The containing node is permitted to have fields with the inputOutput access type. Because an inputOutput field represents both an inputOnly and outputOnly field the user code may wish to write to the values, user code is subject to some special conditions in order to remain consistent with the core specification.
For the purposes of defining the allowable behaviour, the containing node and the user code are considered as decoupled, non-related entities. Notification of changes in field values are a notification, and no more. Setting the value of a field that is defined as inputOutput is considered to be an instantaneous, atomic action. When the field is set, the value for both the input and output are set immediately. Then the notification to the user code is performed. Since the output of the inputOutput field has been set, any further attempt to change the value of the inputOutput field during the current timestamp is considered to be subject to 4.4.6.1 Loops in of part 1 of ISO/IEC 19775 (see 2.[I19775-1]). That is, if the user code receives an event notification for its containing node's inputOutput field, it cannot write another value to that same inputOutput field during the same timestamp because an output event has already been issued and the containing node is not permitted to issue another output event for the same field in the same timestamp.
In receiving events, the script shall only pass through the first event received by the containing node of the inputOutput field.
If the containing node has not yet received a change on the field during the current timestamp, the user code is permitted to write a value to the field. If a change is received to the field after the user code has modified it, only the inputOnly portion of the node is processed. A notification is sent to the user code, but the value of the field shall not be changed in accordance with the loop breaking rule in 4.4.6.1 Loops in part 1 of ISO/IEC 19775 (see 2.[I19775-1]).
A containing node may have a number of pre-defined fields. These fields shall be accessible and readable by the user code, but shall not be writable.
All user code participating within a particular internal interaction environment is considered to operate within a single execution space. Code in this context is subject to the security settings of the containing browser's environment and also the language's operating environment. This permits user code in internal interactions to communicate through asynchronous mechanisms that are external to the X3D execution environment (i.e., route and event evaluation). Some language bindings may be subject to more restrictions than others. This is implementation independent. For example, user code using the Java language bindings may operate in a web-browser sand box that does not allow network connections to any external server, while user code using the COM bindings may be given full access to the entire underlying operating system.
For security purposes, a browser may implement whatever schemes it feels necessary to ensure good security and to prevent content from undertaking nefarious activities. Such activities may include virus-like modification of the user's computer or denial of service activities or any other activity deemed a security risk on the day.
User code that is interacting with a browser from an external perspective is considered to have complete control over the entire lifecycle of not only the scene graph but also the browser. External interactions therefore have the full range of control over the browser.
Because an application is consider to be external to the browser, it does not have intimate knowledge of the internal state and therefore when actions may or may not be safe to make. Therefore, the external interactions are defined to be in an advisory capacity. An external interaction requests the browser make changes and then the browser shall decide exactly when it it safe to act on those requests. A browser shall honour all requests made, within the bounds of the individual services guideline outlined below.
An external application may also wish to monitor changes in nodes, fields and even the browser itself. The browser shall inform the external application of the changes, but shall do so in an asynchronous way. That is, any updates are considered to be notifications only, and shall not hold up the browser's internal evaluations. The result is that notifications may make it to the external application with some delay from when they happened within the browser. (For example an external application sitting on a remote computer to the browser and the associated networking delays that the browser has no control over.)
Browser interactions for external interactions include all the basic services provided to internal interactions. In addition to this a number of additional interactions are allowed. A single external application is permitted to interact with more than one browser at a time. It may also instruct multiple browsers to act together as a single entity or to work individually. The lifetime of the external application is independent of the browser.
A characteristic of external applications is that they will make a lot of changes in bursts to the X3D browser. It is also possible that a single browser may have a number of applications connected to it, all making requests of the browser.
Events can be batched to aid in performance of the application. The
mechanism provided by this is a simple gate mechanism to hold all requests
(beginUpdate
) to update the currently loaded world until the gate
is released (endUpdate
).
When beginUpdate
is invoked, all requests to modify the contents
of the current world are buffered and not passed to the browser. This buffering
effects all requests to modify the current world including calls to loadURL
and replaceWorld
. Once a call to beginUpdate
has been made,
any further beginUpdate
requests are ignored until the next call
to endUpdate
at which time endUpdate
releases all of the currently buffered updates
to the browser for processing.
If a modification service request is made on the scene after an
endUpdate
and before a beginUpdate
, it shall be passed to the scene immediately
with the timestamp at the discretion of the browser.
beginUpdate
/endUpdate
requests shall be limited to the
individual session. A request by one application to beginUpdate
shall only buffer the requests made by that application and not any others
that may be connected to that same browser instance.
When endUpdate
is invoked, the following order of execution of
requests shall be applied:
The loadURL
/replaceWorld
service requests
are not affected by the update control process.
As soon as the browser receives these requests their execution is begun.
The service definitions define the complete behaviour of these requests.
Buffered requests from the application shall be processed before processing any more requests either through another buffered queue or individual requests.
External interactions allow monitoring of any changes in the scene graph. Notifications of these changes shall be delivered in a timely manner and shall remain in the same sequence in which they are generated by the browser internals.
When multiple applications make requests of the browser, the requests shall
be serviced in order of arrival time at the browser. The browser shall
determine the arrival time. Buffered updates to the scene graph shall have
their arrival time determined to be at the time that endUpdate
is
requested. The arrival time is not necessarily the same as the timestamp
at which the browser chooses to send events into the scene graph. The timestamp
that the events are sent to the scene graph shall be determined by the
browser but shall be no earlier than the time that endUpdate
is
requested. The arrival time is used to sort out conflicting requests from
multiple applications to ensure consistent results in the application of
events in the correct order.
Should the browser determine that two requests arrive simultaneously the result is implementation dependent. Note that it is permissible for the external applications to send new values to a given inputOnly field simultaneously. For such situations the browser shall obey 4.4.8.5 Fan-in and fan-out in part 1 of ISO/IEC 19775 (see 2.[I19775-1]).
Should the browser receive a request to loadURL or replaceWorld while currently processing a similar request, the old request is immediately terminated and the new one begun. See 6.3.12 replaceWorld and 6.3.14 loadURL for more information.
All requests for services shall be guaranteed to be honoured where the underlying implementation supports that service. Once the application has made a service request, that request shall be transmitted to the browser assuming that a connection is still available. That is, all communications are assumed to be reliable. Delivery is not guaranteed if the connection between the browser and application has been broken (for example, a TCP connection fails). Implementations shall define an error condition that notifies the user that the connection has failed for each service request. Also, the browser interface may include an event that provides asynchronous notification to the user of the failure.