 |
| |
| META TOPICPARENT | name="ProjectWonderland" |
Home | Changes | Index | Search | Go <-- This creates the navigation links to : Home | Help | Index | etc. --> | | | The only client to the SERVER_MANAGER_CHANNEL communication channel is provided by an instance of class org.jdesktop.lg3d.wonderland.management.ManagerUI which can be opened using the ANT run-manager target.
| |
> > | 6.3 Guidelines for Managing Change at Client and Server
There is a distinction between two kinds of user interaction:
- User interaction that only changes the state of the client, perhaps in terms of the appearance of a
Cell. An example would be when a user's cursor hovers over a widget (see, for example, the sample module)
- User interaction that causes a change of state of a
CellGLO on the server. An example would be when a user clicks on a widget (see the sample module for an example)
The two cases are described below. In each case it is assumed that four clients (C1, C2, C3 and C4) are connected to a server.
6.3.1 Change of state of the client
- User interaction with
Cell on client C2 causes local state change in Cell (no change in server state)
-
Cell updates appearance
-
Cell broadcasts message to other clients on Cell's channel; message identifies "kind of change" and new state of Cell
- Other clients receive message and their corresponding
Cell updates its appearance
6.3.2 Change of state of the server
- User interaction with
Cell on client C2 causes state change in CellGLO on server
-
Cell updates local state (if necessary) and appearance
- Client C2 send message direct to server. Message describes "kind of change" and new state of
Cell
- Server identifies appropriate
CellGLO
-
CellGLO updates its state
- Server broadcasts message on
Cell's channel to all clients except originating client. Message describes "kind of change" and new state.
- Each client receives message and updates state of
Cell (if necessary) and appearance.
The above flow of control differs from conventional Model-View-Controller (MVC) in the following features:
- There is no clear separation between the model and its view. A
CellGLO determines its Cell (which is equivalent to saying that the model determines its view). This means that it is not possible to use the same CellGLO class to be rendered by multiple Cell classes. For example, a CellGLO class representing a die could not have two Cell classes that provided different renderings of a die.
- There is no clear separation between a view and its controller. The controller for a view (following the Swing etiquette) is provided by an inner class in the view class. So, for example, a controller for a
Cell is often provided by an inner class of the Cell class.
- Because multiple clients render the same
Cell, it's necessary to synchronise between the clients. This requirement is outside MVC, and is handled in Wonderland by the use of messages to the channel owned by a Cell.
Finally, the flow of control in MVC differs sublty from that of Wonderland. For example, if Wonderland used MVC, the flow of control would be
- User interaction with
Cell on client C2 causes state change in CellGLO on server
- Client C2 send message direct to server. Message describes "kind of change" and new state of
CellGLO
- Server identifies appropriate
CellGLO
-
CellGLO updates its state
- Server broadcasts message on
Cell's channel to all clients. Message describes "kind of change".
- Each client receives message and requests the state of the
CellGLO
- Each client updates state of
Cell (if necessary) and appearance.
The reason for this difference is performance. It is important that the user is notified of a change of appearance as soon as possible (i.e. before notifying the server).
| | | 7. Summary of Important Code Flow Sequences
This section summarizes the flow of control in the code for two aspects of Project |
| |
| META TOPICPARENT | name="ProjectWonderland" |
Home | Changes | Index | Search | Go <-- This creates the navigation links to : Home | Help | Index | etc. --> | | | When the user moves, it notifies the server and the server examines the UserCellCacheGLO to see if that client has already loaded all the cells in its immediate area.
If the server finds a cell the client hasn't seen yet, it sends it a message, telling the client to load the new cell. | |
< < | 6.1 Client-Server Direct Communication Channel | > > | 6.1 Client-Server Direct Communication | | | | |
< < | When a client connects to the server, a direct client-server communication channel is | > > | When a client connects to the server, a direct client-server communication link is | | | automatically set up by Project Darkstar. | |
< < | The server transmits the following messages to a client over this channel: | > > | The server transmits the following messages to a client over this mechanism | | |
- An initial message giving the version of the communication protocol (in
WonderlandBoot.loggedIn()).
- Potential error messages as instances of class
org.jdesktop.lg3d.wonderland.darkstar.common.messages.ErrorMessage (ditto, and also in WonderlandSessionListener.processFileTransferMessage().
| | |
-
NativeApplicationMessage messages are handled by the receivedMessage() method of the inner class MessageListener of class org.jdesktop.lg3d.wonderland.appshare.ServerApp2DCell.
-
SoftphoneMessage messages are also handled by ChannelController.handleMessage().
| |
< < | A client transmits the following messages to the server over this channel: | > > | A client transmits the following messages to the server over this mechanism: | | |
- Instances of classes
NativeApplicationMessage. These are sent by the constructor of class ServerApp2DCell.and the sendMessage() method of ChannelController.
- Instances of
org.jdesktop.lg3d.wonderland.darkstar.common.messages.SoftphoneMessage. These are sent by the connectSoftphone() and disconnectSoftphone() methods of ChannelController.
- Instances of
org.jdesktop.lg3d.wonderland.darkstar.common.messages.AvatarSetupMessage initiated by the method loggedIn() in class ChannelController.
- instances of some sublcass of
org.jdesktop.lg3d.wonderland.darkstar.common.messages.CellMessage. Currently there appear to be none.
| |
< < |
The server receives the following messages from the client over this channel: | > > | The server receives the following messages from the client over this mechanism: | | |
- Instances of classes
NativeApplicationMessage. These are handled by the receivedMessage() method of org.jdesktop.lg3d.wonderland.darkstar.server.WonderlandBaseSessionListener, and subsequently by its processNativeApplicationMessage() method.
- Instances of
SoftphoneMessage. These are handled by the receivedMessage() method of WonderlandSessionListener.
| | | When a cell becomes visible, the server steps through a list of all CellGLOs and
adds the client to the =CellGLO='s channel if it (the channel) exists. Currently, only the avatar | |
< < | cell creates a channel for itself. At that point, a SETUP message is sent to | > > | CellGLO? creates a channel for itself. At that point, a SETUP message is sent to | | | the client, which keeps a reference to the channel for future communication.
The server receives the following messages from the client over this channel: |
| |
| META TOPICPARENT | name="ProjectWonderland" |
Home | Changes | Index | Search | Go <-- This creates the navigation links to : Home | Help | Index | etc. --> | | |
- An initial message giving the version of the communication protocol (in
WonderlandBoot.loggedIn()).
- Potential error messages as instances of class
org.jdesktop.lg3d.wonderland.darkstar.common.messages.ErrorMessage (ditto, and also in WonderlandSessionListener.processFileTransferMessage().
- Instances of class
org.jdesktop.lg3d.wonderland.darkstar.common.messages.NativeApplicationMessage as messages in reply to a "create application cell" message (in WonderlandSessionListener.processNativeApplicationMessage()).
| |
< < |
- Instances of class
org.jdesktop.lg3d.wonderland.darkstar.common.messages.SoftphoneMessage (in the callStatusChanged() and
processSoftphoneMessage() methods of WonderlandSessionListener. | > > |
- Instances of class
org.jdesktop.lg3d.wonderland.darkstar.common.messages.SoftphoneMessage (in the callStatusChanged() and processSoftphoneMessage() methods of WonderlandSessionListener.
| | | These are handled by a client as follows:
- The protocol version and error messages are handled by
ChannelController.handleMessage().
| | |
- Instances of classes
NativeApplicationMessage. These are handled by the receivedMessage() method of org.jdesktop.lg3d.wonderland.darkstar.server.WonderlandBaseSessionListener, and subsequently by its processNativeApplicationMessage() method.
- Instances of
SoftphoneMessage. These are handled by the receivedMessage() method of WonderlandSessionListener.
| |
< < |
- Instances of
org.jdesktop.lg3d.wonderland.darkstar.common.messages.AvatarSetupMessage messages . These are also handled by the receivedMessage() method of WonderlandSessionListener.
| > > |
- Instances of
org.jdesktop.lg3d.wonderland.darkstar.common.messages.AvatarSetupMessage messages . These are also handled by the receivedMessage() method of WonderlandSessionListener.
| | |
- Other instances of some sublcass of
org.jdesktop.lg3d.wonderland.darkstar.common.messages.CellMessage messages, dispatched to instances of class org.jdesktop.lg3d.wonderland.darkstar.server.CellMessageListener.
6.2 Publish/Subscribe Communication Channels | | | 6.2.1 The USER_CHANGE channel
The USER_CHANGE communication channel is created by WonderlandBoot in its initialize() method, and all new clients | |
< < | are automatically added to it. | > > | are automatically added to it. It is used exclusively for server-->client communication. | | | The server transmits the following messages to the client over this channel: | | | 6.2.2 CELL_CACHE channels
The server creates a CELL_CACHE channel for each client connected. The name of the | |
< < | channel takes the form: user + CELL_CACHE, where 'user' is the name of the user. Each
channel is created by an instance of class UserCellCacheGLO in its contructor. All new clients are automatically
added to this channel. | > > | channel takes the form: user + CELL_CACHE, where 'user' is the name of the user. The CELL_CACHE
channel for a client is created by the instance of class UserCellCacheGLO that corresponds to that client (in its contructor). Each new client is automatically
added to one of these channels. | | | | |
< < | Each instance of class UserCellCacheGLO has a CELL_CACHE channel. Only one user (the user who's cache it is) is subscribed to that CELL_CACHE channel. The subscription is managed in the login() method of class UserCellCacheGLO. This channel is used exclusively for server-->client communication. | > > | Each instance of class UserCellCacheGLO has a CELL_CACHE channel. Only one client/user (the user who's cache it is) is subscribed to that CELL_CACHE channel. The subscription is managed in the login() method of class UserCellCacheGLO. This channel is used exclusively for server-->client communication. | | | The server transmits the following messages to the client over this channel. The messages are sent by the instance of UserCellCacheGLO. | | | The server creates an AVATAR_P2P channel for each client connected. The name of the
channel takes the form: user + AVATAR_P2P, where 'user' is the name of the user. | |
< < | This channel is created by an instance of class AvatarCellGLO during its constructor. Clients request to be joined
to an avatar's P2P? channel via the AvatarCellMessage(JOIN_P2P) message sent on
the AVATAR_CELL channel (see below). (Don't understand this. Bernard) | > > | This channel is created by an instance of class AvatarCellGLO during its constructor, and then maintained by that instance of AvatarCellGLO. Another client may request to join an client's P2P? channel via the AvatarCellMessage(JOIN_P2P) message sent on
the AVATAR_CELL channel (see below).
Each avatar sends its motion updates over its client's AVATAR_P2P channel, so any client that cares about those updates (generally any other client in visual range of the avatar) will subscribe to it. | | | The server transmits the following messages to a client over this channel: | |
< < |
- Instances of class
org.jdesktop.lg3d.wonderland.darkstar.common.messages.AvatarP2PMessage, of which there are three kinds:
| > > |
- Instances of class
org.jdesktop.lg3d.wonderland.darkstar.common.messages.AvatarP2PMessage, of which there are two kinds:
| | |
-
- The
SETUP message is sent by the receivedMessage() method of class AvatarCellGLO in response to an AvatarCellMessage(JOIN_P2P) message.
- The
SPEAKING message is sent by the callStatusChanged() and processAvatarCellMessage() methods of class WonderlandSessionListener and the setSpeakingStatus() method of AvatarCellGLO.
| | | The server currently receives messages on this channel via the handleMessage() method of an instance of class org.jdesktop.lg3d.wonderland.darkstar.serverAvatarP2PChannelListenerGLO . (The method is only used for logging purposes.)
| |
< < | | > > | Thus, this channel is used for inter-client communication (for AvatarP2PMessages of kind MOVE and CHAT), and for server-->client communication (for AvatarP2PMessages of kind SETUP and SPEAKING). | | |
6.2.4 AVATAR_CELL channels | | | The server transmits the following messages to the client over this channel: | |
< < |
- An instance of class
AvatarCellMessage, which has one basic kind: SETUP. This is sent when a cell first becomes visible.
| > > |
- An instance of class
AvatarCellMessage, which has one basic kind: SETUP. This is sent when a an avatar's cell (i.e. AvatarCellGLO) first becomes visible.
| | | | |
< < | When a cell becomes visible, the server steps through a list of all cells and
adds the client to the cell's channel if it exists. Currently, only the avatar | > > | When a cell becomes visible, the server steps through a list of all CellGLOs and
adds the client to the =CellGLO='s channel if it (the channel) exists. Currently, only the avatar | | | cell creates a channel for itself. At that point, a SETUP message is sent to | |
< < | the client, which stores the channel for future communication. | > > | the client, which keeps a reference to the channel for future communication. | | | The server receives the following messages from the client over this channel: |
| |
| META TOPICPARENT | name="ProjectWonderland" |
Home | Changes | Index | Search | Go <-- This creates the navigation links to : Home | Help | Index | etc. --> | | | This section outlines all of the communication channels and messages sent between the
Wonderland client and server and between clients. | |
> > | Each client is represented on the server by a number of objects. The objects are:
-
UserGLO -- basic user information, like name and preferred color
-
AvatarCellGLO -- the cell where the user's avatar is rendered
-
UserCellCacheGLO -- the cells that are visible to a specific user
There is one of each of these objects per user/client. As the user moves around the world, the server tracks which cells that user "knows about".
When the user moves, it notifies the server and the server examines the UserCellCacheGLO to see if that client has already loaded all the cells in its immediate area.
If the server finds a cell the client hasn't seen yet, it sends it a message, telling the client to load the new cell. | | | 6.1 Client-Server Direct Communication Channel
When a client connects to the server, a direct client-server communication channel is | | | The server creates a CELL_CACHE channel for each client connected. The name of the
channel takes the form: user + CELL_CACHE, where 'user' is the name of the user. Each
channel is created by an instance of class UserCellCacheGLO in its contructor. All new clients are automatically | |
< < | added to this channel. (Don't really understand what this means. Bernard) | > > | added to this channel.
Each instance of class UserCellCacheGLO has a CELL_CACHE channel. Only one user (the user who's cache it is) is subscribed to that CELL_CACHE channel. The subscription is managed in the login() method of class UserCellCacheGLO. This channel is used exclusively for server-->client communication. | | | The server transmits the following messages to the client over this channel. The messages are sent by the instance of UserCellCacheGLO. |
| |
| META TOPICPARENT | name="ProjectWonderland" |
Home | Changes | Index | Search | Go <-- This creates the navigation links to : Home | Help | Index | etc. --> | | | 4.3.4 Client-side cell classes and setup | |
< < | Each cell class on the server has a corresponding cell class on the client | > > | Each CellGLO class on the server has a corresponding Cell class on the client | | | which is responsible for rendering the cell. The name of the corresponding
client cell class is defined by each of the individual server-side cell subclasses via
the CellGLO.getClientCellClassName() method. | |
< < | A server-side cell communicates its visual contents and other setup data | > > | A server-side CellGLO communicates its visual contents and other setup data | | | via an instance of a class that implements the org.jdesktop.lg3d.wonderland.darkstar.common.CellSetup interface.
This is returned from the CellGLO.getSetupData() method that | |
< < | is implemented by each of the individual server-side cell subclasses. | > > | is implemented by each of the individual server-side CellGLO subclasses. | | | The CellSetup interface itself is simply an empty interface which extends the
java.io.Serializable interface so that it may be sent across the wire. Each server-side | |
< < | cell class defines its own "setup" class that implements the CellSetup interface. Examples (in package org.jdesktop.lg3d.wonderland.darkstar.common) | > > | CellGLO class defines its own "setup" class that implements the CellSetup interface. Examples (in package org.jdesktop.lg3d.wonderland.darkstar.common) | | | include AnimatedCellSetup, AvatarCellSetup, ModelViewerCellSetup,
SharedApp2DCellSetup, SimpleCellSetup, and SlideShowCellSetup. The
SimpleCellSetup class is used, for example, by the simple terrain cell and | | | 4.4 Server-side Cell Caching | |
< < | The set of cells which should be currently kept in memory by the client is | > > | The set of Cells which should be currently kept in memory by the client is | | | managed by the server via an instance of org.jdesktop.lg3d.wonderland.darkstar.server.cell.UserCellCacheGLO class, an instance of this
class exists for each user (which is equivalent to saying "client") and
is created when the user logs in. All instances of UserCellCacheGLO are managed
by the instance of MasterCellCacheGLO class that was created by WonderlandBoot (see section 4.1). They are managed objects within the Project
Darkstar infrastructure. | |
< < | The server-side cell caches support several state changes to cells. They are: | > > | The server-side cell caches support several state changes to CellGLOs They are: | | | cell created, root cell created, cell moved, cell deleted, and add parent to cell.
At the present time, the UserCellCacheGLO.revalidate() method considers those | |
< < | cells which are currently visible and adds those cells which are new and deletes | > > | CellGLOs which are currently visible and adds those CellGLOs which are new and deletes | | | from the client's memory those which are no longer visible. Changes in the | |
< < | state of cells are communicated via a dedicated channel associated with the instance of | > > | state of CellGLOs are communicated via a dedicated channel (named CELL_CACHE) associated with the instance of | | | UserCellCacheGLO class. At present, the messages that are communicated on this channel are
serialized instances of the org.jdesktop.lg3d.wonderland.darkstar.common.messages.CellHierarchyMessage class. | | | Wonderland client.
All communication with the Darkstar-based Wonderland server is managed by an instance of class | |
< < | org.jdesktop.lg3d.wonderland.darkstar.client.ChannelController. A new connection to the server is initiated via the | > > | org.jdesktop.lg3d.wonderland.darkstar.client.ChannelController. (This seems to be somewhat misleadingly named as it doesn't
control channels, instead it provides a direct client-server communication mechanism.) A new connection to the server is initiated via the | | | ChannelController.initCommunications() method. See Section 6 below for details
of class ChannelController. | | | 6. Client-Server Communication
This section outlines all of the communication channels and messages sent between the | |
< < | Wonderland client and server. | > > | Wonderland client and server and between clients. | | | 6.1 Client-Server Direct Communication Channel
When a client connects to the server, a direct client-server communication channel is
automatically set up by Project Darkstar. | |
< < | The server transmits the following messages to the client over this channel: | > > | The server transmits the following messages to a client over this channel:
- An initial message giving the version of the communication protocol (in
WonderlandBoot.loggedIn()).
- Potential error messages as instances of class
org.jdesktop.lg3d.wonderland.darkstar.common.messages.ErrorMessage (ditto, and also in WonderlandSessionListener.processFileTransferMessage().
- Instances of class
org.jdesktop.lg3d.wonderland.darkstar.common.messages.NativeApplicationMessage as messages in reply to a "create application cell" message (in WonderlandSessionListener.processNativeApplicationMessage()).
- Instances of class
org.jdesktop.lg3d.wonderland.darkstar.common.messages.SoftphoneMessage (in the callStatusChanged() and
processSoftphoneMessage() methods of WonderlandSessionListener.
These are handled by a client as follows:
- The protocol version and error messages are handled by
ChannelController.handleMessage().
-
NativeApplicationMessage messages are handled by the receivedMessage() method of the inner class MessageListener of class org.jdesktop.lg3d.wonderland.appshare.ServerApp2DCell.
-
SoftphoneMessage messages are also handled by ChannelController.handleMessage().
A client transmits the following messages to the server over this channel:
- Instances of classes
NativeApplicationMessage. These are sent by the constructor of class ServerApp2DCell.and the sendMessage() method of ChannelController.
- Instances of
org.jdesktop.lg3d.wonderland.darkstar.common.messages.SoftphoneMessage. These are sent by the connectSoftphone() and disconnectSoftphone() methods of ChannelController.
- Instances of
org.jdesktop.lg3d.wonderland.darkstar.common.messages.AvatarSetupMessage initiated by the method loggedIn() in class ChannelController.
- instances of some sublcass of
org.jdesktop.lg3d.wonderland.darkstar.common.messages.CellMessage. Currently there appear to be none.
| | | | |
< < |
- An initial message giving the version of the communication protocol.
- Potential error messages as instances of class
org.jdesktop.lg3d.wonderland.darkstar.common.messages.ErrorMessage.
- Instances of class
org.jdesktop.lg3d.wonderland.darkstar.common.messages.NativeApplicationMessage as messages in reply to a "create application cell" message.
| | | The server receives the following messages from the client over this channel: | |
< < |
- Instances of classes
NativeApplicationMessage and org.jdesktop.lg3d.wonderland.darkstar.common.messages.SoftphoneMessage as messages from the client.
- Instances of
org.jdesktop.lg3d.wonderland.darkstar.common.messages.AvatarSetupMessage messages from the client
- Other instances of some sublcass of
org.jdesktop.lg3d.wonderland.darkstar.common.messages.CellMessage messages from the client, dispatched to instances of class org.jdesktop.lg3d.wonderland.darkstar.server.CellMessageListener.
| > > |
- Instances of classes
NativeApplicationMessage. These are handled by the receivedMessage() method of org.jdesktop.lg3d.wonderland.darkstar.server.WonderlandBaseSessionListener, and subsequently by its processNativeApplicationMessage() method.
- Instances of
SoftphoneMessage. These are handled by the receivedMessage() method of WonderlandSessionListener.
- Instances of
org.jdesktop.lg3d.wonderland.darkstar.common.messages.AvatarSetupMessage messages . These are also handled by the receivedMessage() method of WonderlandSessionListener.
- Other instances of some sublcass of
org.jdesktop.lg3d.wonderland.darkstar.common.messages.CellMessage messages, dispatched to instances of class org.jdesktop.lg3d.wonderland.darkstar.server.CellMessageListener.
| | | 6.2 Publish/Subscribe Communication Channels
The Wonderland server also creates publish/subscribe communication channels, which
include: USER_CHANGE, CELL_CACHE, AVATAR_P2P, AVATAR_CELL, and | |
< < | SERVER_MANAGER_CHANNEL. | > > | SERVER_MANAGER_CHANNEL. A channel provides a communications mechanism between clients and also between a client and its server. | | | 6.2.1 The USER_CHANGE channel | |
< < | The USER_CHANGE communication channel is created by WonderlandBoot, and all new clients | > > | The USER_CHANGE communication channel is created by WonderlandBoot in its initialize() method, and all new clients | | | are automatically added to it.
The server transmits the following messages to the client over this channel: | |
< < |
- Instances of class
org.jdesktop.lg3d.wonderland.darkstar.common.messages.UserChangedMessage when users are added (USER_ADD) or when users leave (USER_LEFT).
| > > |
- Instances of class
org.jdesktop.lg3d.wonderland.darkstar.common.messages.UserChangedMessage when users are added (USER_ADD, in method processAvatarSetupMessage() of class WonderlandSessionListener) or when users leave (USER_LEFT, in method disconnected() of class WonderlandSessionListener).
| | | The server does not receive any messages from the client on this channel.
The client does not transmit any messages on this channel. | |
< < | The client handles these messages via the receivedMessage() method an instance of class org.jdesktop.lg3d.wonderland.darkstar.client.UserChannelListener. | > > | The client handles these messages via the receivedMessage() method of class org.jdesktop.lg3d.wonderland.darkstar.client.UserChannelListener. | | | | |
< < | 6.2.2 The CELL_CACHE channel | > > | 6.2.2 CELL_CACHE channels | | | The server creates a CELL_CACHE channel for each client connected. The name of the | |
< < | channel takes the form: user + CELL_CACHE, where 'user' is the name of the user. This
channel is created by an instance of class UserCellCacheGLO. All new clients are automatically
added to this channel. | > > | channel takes the form: user + CELL_CACHE, where 'user' is the name of the user. Each
channel is created by an instance of class UserCellCacheGLO in its contructor. All new clients are automatically
added to this channel. (Don't really understand what this means. Bernard) | | | | |
< < | The server transmits the following messages to the client over this channel: | > > | The server transmits the following messages to the client over this channel. The messages are sent by the instance of UserCellCacheGLO. | | |
- Instances of class
CellHiearchyMessage messages, which can be of the kind: LOAD_CELL, MOVE_CELL, CELL_INACTIVE, ADD_PARENT, REMOVE_PARENT, SET_WORLD_ROOT, and DELETE_CELL.
| | | The client handles these messages via the receivedMessage() method an instance of class org.jdesktop.lg3d.wonderland.darkstar.client.UserCellCacheChannelListener. | |
< < | 6.2.3 The AVATAR_P2P channel | > > | 6.2.3 AVATAR_P2P channels | | | The server creates an AVATAR_P2P channel for each client connected. The name of the
channel takes the form: user + AVATAR_P2P, where 'user' is the name of the user.
This channel is created by an instance of class AvatarCellGLO during its constructor. Clients request to be joined
to an avatar's P2P? channel via the AvatarCellMessage(JOIN_P2P) message sent on | |
< < | the AVATAR_CELL channel (see below). | > > | the AVATAR_CELL channel (see below). (Don't understand this. Bernard) | | | | |
< < | The server transmits the following messages to the client over this channel: | > > | The server transmits the following messages to a client over this channel:
- Instances of class
org.jdesktop.lg3d.wonderland.darkstar.common.messages.AvatarP2PMessage, of which there are three kinds:
- The
SETUP message is sent by the receivedMessage() method of class AvatarCellGLO in response to an AvatarCellMessage(JOIN_P2P) message.
- The
SPEAKING message is sent by the callStatusChanged() and processAvatarCellMessage() methods of class WonderlandSessionListener and the setSpeakingStatus() method of AvatarCellGLO.
| | | | |
< < |
- Instances of class
org.jdesktop.lg3d.wonderland.darkstar.common.messages.AvatarP2PMessage, of which there are three kinds: SETUP, MOVE, SPEAKING and CHAT.
| > > | A client handles messages via the method receivedMessage() of an instance of class org.jdesktop.lg3d.wonderland.darkstar.client.AvatarP2PChannelListener.
A client transmits instances of class AvatarP2PMessage over this channel, though only of kind MOVE and CHAT:
- The
MOVE message is sent by the userMoved() method of class org.jdesktop.lg3d.wonderland.scenemanager.avatar.Avatar, in response to user interaction.
- The
CHAT message is sent by the sendChatMessage() method of class Avatar.
| | | The server currently receives messages on this channel via the handleMessage() method of an instance of class org.jdesktop.lg3d.wonderland.darkstar.serverAvatarP2PChannelListenerGLO . (The method is only used for logging purposes.) | |
< < | The client transmits instances of class AvatarP2PMessage over this channel, though only of kind MOVE and CHAT (see class org.jdesktop.lg3d.wonderland.scenemanager.avatar.Avatar.) | | | | |
< < | The client handles messages via the method receivedMessage() of an instance of class org.jdesktop.lg3d.wonderland.darkstar.client.AvatarP2PChannelListener. | | | | |
< < | 6.2.4 The AVATAR_CELL channel | | | | |
< < | The AVATAR_CELL channel is created by an instance of class AvatarCellGLO. The name of the | > > | 6.2.4 AVATAR_CELL channels
An AVATAR_CELL channel is created by an instance of class AvatarCellGLO during its constructor. The name of the | | | channel takes the form: user + AVATAR_CELL, where 'user' is the name of the user.
The server transmits the following messages to the client over this channel: |
| |
| META TOPICPARENT | name="ProjectWonderland" |
Home | Changes | Index | Search | Go <-- This creates the navigation links to : Home | Help | Index | etc. --> | | | The server transmits and receives instances of class org.jdesktop.lg3d.wonderland.darkstar.common.messages.ServerManagerMessage to the client over this channel, of which there are four kinds: STATUS, FULL_STATUS, CHANGE_UPDATE_INTERVAL, and SET_USER_LIMIT.
| |
> > | The only client to the SERVER_MANAGER_CHANNEL communication channel is provided by an instance of class org.jdesktop.lg3d.wonderland.management.ManagerUI which can be opened using the ANT run-manager target.
| | | 7. Summary of Important Code Flow Sequences
This section summarizes the flow of control in the code for two aspects of Project |
| |
| META TOPICPARENT | name="ProjectWonderland" |
Home | Changes | Index | Search | Go <-- This creates the navigation links to : Home | Help | Index | etc. --> | | | 6.2 Publish/Subscribe Communication Channels
The Wonderland server also creates publish/subscribe communication channels, which | |
< < | include: USER_CHANGE, CELL_CACHE, AVATAR_P2P, AVATAR_TILE, and
SERVER_MANAGER_CHANNEL. | > > | include: USER_CHANGE, CELL_CACHE, AVATAR_P2P, AVATAR_CELL, and
SERVER_MANAGER_CHANNEL. | | | 6.2.1 The USER_CHANGE channel | | | 6.2.3 The AVATAR_P2P channel | |
< < | The server creates an AVATAR_P2P channel for each client connected. The name of the
channel takes the form: user + AVATAR_P2P, where 'user' is the name of the user. | > > | The server creates an AVATAR_P2P channel for each client connected. The name of the
channel takes the form: user + AVATAR_P2P, where 'user' is the name of the user. | | | This channel is created by an instance of class AvatarCellGLO during its constructor. Clients request to be joined
to an avatar's P2P? channel via the AvatarCellMessage(JOIN_P2P) message sent on | |
< < | the AVATAR_TILE channel. | > > | the AVATAR_CELL channel (see below). | | | The server transmits the following messages to the client over this channel: | |
< < |
- Instances of class
org.jdesktop.lg3d.wonderland.darkstar.common.messages.AvatarP2PMessage, of which there are three kinds: SETUP, MOVE, and CHAT.
| > > |
- Instances of class
org.jdesktop.lg3d.wonderland.darkstar.common.messages.AvatarP2PMessage, of which there are three kinds: SETUP, MOVE, SPEAKING and CHAT.
| | | | |
< < | The server does not receive any messages from the client on this channel. | > > | The server currently receives messages on this channel via the handleMessage() method of an instance of class org.jdesktop.lg3d.wonderland.darkstar.serverAvatarP2PChannelListenerGLO . (The method is only used for logging purposes.)
The client transmits instances of class AvatarP2PMessage over this channel, though only of kind MOVE and CHAT (see class org.jdesktop.lg3d.wonderland.scenemanager.avatar.Avatar.) | | | | |
< < | 6.2.4 The AVATAR_TILE channel | > > | The client handles messages via the method receivedMessage() of an instance of class org.jdesktop.lg3d.wonderland.darkstar.client.AvatarP2PChannelListener. | | | | |
< < | The AVATAR_TILE channel is created by an instance of class AvatarCellGLO. The name of the
channel takes the form: user + AVATAR_TILE, where 'user' is the name of the user. | > > | 6.2.4 The AVATAR_CELL channel
The AVATAR_CELL channel is created by an instance of class AvatarCellGLO. The name of the
channel takes the form: user + AVATAR_CELL, where 'user' is the name of the user. | | | The server transmits the following messages to the client over this channel: | |
< < |
- An instance of class
AvatarCellMessage, which has one basic kind: SETUP. When a cell first becomes visible.
| > > |
- An instance of class
AvatarCellMessage, which has one basic kind: SETUP. This is sent when a cell first becomes visible.
| | | When a cell becomes visible, the server steps through a list of all cells and
adds the client to the cell's channel if it exists. Currently, only the avatar | |
< < | cell creates a channel for itself. At that point, a SETUP message is sent to | > > | cell creates a channel for itself. At that point, a SETUP message is sent to | | | the client, which stores the channel for future communication. | |
< < | The server received the following messages from the client over this channel: | > > | The server receives the following messages from the client over this channel:
- Instances of
AvatarCellMessage. It handles these messages via method receivedMessage() in an instance of class AvatarCellGLO (for messages that are of kind CELL_MOVE, CELL_ENTER, and CELL_EXIT) and also via the receivedMessage() method of an instance of WonderlandSessionListener (for messages that are of kind AVATAR_MOVE, AVATAR_MUTE and JOIN_P2P.
The client transmits instances of class AvatarCellMessage over this channel (see class org.jdesktop.lg3d.wonderland.darkstar.client.cell.AvatarCell.)
The client receives messages over this channel. It handles them via the receivedMessage() method of an instance of class org.jdesktop.lg3d.wonderland.darkstar.client.cell.AvatarCellChannelListener. | | | | |
< < |
- Instances of
AvatarCellMessage, of which there are four kinds: JOIN_P2P, CELL_MOVE, AVATAR_MOVE, CELL_ENTER, and CELL_EXIT.
| | | 6.2.5 The SERVER_MANAGER_CHANNEL channel | |
< < | The SERVER_MANAGER_CHANNEL communication channel, created by an instance of class org.jdesktop.lg3d.wonderland.darkstar.server.ServerManagerGLO, | > > | The SERVER_MANAGER_CHANNEL communication channel, created by an instance of class org.jdesktop.lg3d.wonderland.darkstar.server.ServerManagerGLO, | | | is used to communication server management information to the client. Currently, the server itself and a special client (hardcoded to name "ServerManager") are
added to this channel. | |
< < | The server transmits and receives instances of class org.jdesktop.lg3d.wonderland.darkstar.common.messages.ServerManagerMessage to the client over this channel, of which there are four kinds: STATUS, FULL_STATUS, CHANGE_UPDATE_INTERVAL, and SET_USER_LIMIT. | > > | The server transmits and receives instances of class org.jdesktop.lg3d.wonderland.darkstar.common.messages.ServerManagerMessage to the client over this channel, of which there are four kinds: STATUS, FULL_STATUS, CHANGE_UPDATE_INTERVAL, and SET_USER_LIMIT. | | |
7. Summary of Important Code Flow Sequences |
| |
| META TOPICPARENT | name="ProjectWonderland" |
Home | Changes | Index | Search | Go <-- This creates the navigation links to : Home | Help | Index | etc. --> | | | 6.2.1 The USER_CHANGE channel | |
< < | The USER_CHANGE communication channel is created by WonderlandBoot, and all new clients | > > | The USER_CHANGE communication channel is created by WonderlandBoot, and all new clients | | | are automatically added to it.
The server transmits the following messages to the client over this channel: | |
< < |
- Instances of class
org.jdesktop.lg3d.wonderland.darkstar.common.messages.UserChangedMessage when users are added (USER_ADD) or when users leave (USER_LEFT).
| > > |
- Instances of class
org.jdesktop.lg3d.wonderland.darkstar.common.messages.UserChangedMessage when users are added (USER_ADD) or when users leave (USER_LEFT).
| | | The server does not receive any messages from the client on this channel. | |
> > | The client does not transmit any messages on this channel.
The client handles these messages via the receivedMessage() method an instance of class org.jdesktop.lg3d.wonderland.darkstar.client.UserChannelListener. | | | 6.2.2 The CELL_CACHE channel | |
< < | The server creates a CELL_CACHE channel for each client connected. The name of the
channel takes the form: user + CELL_CACHE, where 'user' is the name of the user. This | > > | The server creates a CELL_CACHE channel for each client connected. The name of the
channel takes the form: user + CELL_CACHE, where 'user' is the name of the user. This | | | channel is created by an instance of class UserCellCacheGLO. All new clients are automatically
added to this channel.
The server transmits the following messages to the client over this channel: | |
< < |
- Instances of class
CellHiearchyMessage messages, which can be of the kind: LOAD_CELL, MOVE_CELL, CELL_INACTIVE, ADD_PARENT, REMOVE_PARENT, SET_WORLD_ROOT, and DELETE_CELL.
| > > |
- Instances of class
CellHiearchyMessage messages, which can be of the kind: LOAD_CELL, MOVE_CELL, CELL_INACTIVE, ADD_PARENT, REMOVE_PARENT, SET_WORLD_ROOT, and DELETE_CELL.
| | | The server does not receive any messages from the client on this channel. | |
> > | The client does not transmit any messages on this channel.
The client handles these messages via the receivedMessage() method an instance of class org.jdesktop.lg3d.wonderland.darkstar.client.UserCellCacheChannelListener. | | | 6.2.3 The AVATAR_P2P channel
The server creates an AVATAR_P2P channel for each client connected. The name of the |
| |
| META TOPICPARENT | name="ProjectWonderland" |
Home | Changes | Index | Search | Go <-- This creates the navigation links to : Home | Help | Index | etc. --> | | | is implemented by each of the individual server-side cell subclasses.
The CellSetup interface itself is simply an empty interface which extends the | |
< < | java.io.Seriablizable interface so that it may be sent across the wire. Each server-side | > > | java.io.Serializable interface so that it may be sent across the wire. Each server-side | | | cell class defines its own "setup" class that implements the CellSetup interface. Examples (in package org.jdesktop.lg3d.wonderland.darkstar.common)
include AnimatedCellSetup, AvatarCellSetup, ModelViewerCellSetup,
SharedApp2DCellSetup, SimpleCellSetup, and SlideShowCellSetup. The | | | mutable configuration options from an external XML-formatted configuration
file. | |
< < | The initialization of the connection with the server happens via it inner
StartupListener class, which implements the Lg3dStartupListener interface, from | > > | The initialization of the connection with the server happens via it inner class named
StartupListener, which implements the Lg3dStartupListener interface, from | | | Project Looking Glass -- this listener's startupComplete() method is invoked
when the initialization of the graphics is complete. In turn, the implementation
of the startupComplete() method displays a login dialog (see class org.jdesktop.lg3d.wonderland.LoginDialog) | | | the Wonderland server and invokes the method Main.enableMainWindow() to "turn on" the
Wonderland client. | |
< < | All communications with the Darkstar-based Wonderland server is managed by an instance of class | > > | All communication with the Darkstar-based Wonderland server is managed by an instance of class | | | org.jdesktop.lg3d.wonderland.darkstar.client.ChannelController. A new connection to the server is initiated via the
ChannelController.initCommunications() method. See Section 6 below for details
of class ChannelController. | | | the LG3D SceneManagerBase class, an abstract class which implements the LG3D
SceneManager interface. The LG3D SceneManagerBase class handles communication with
the LG3D display server (the moral equivalent of the X Windows Server) via its | |
< < | implementation of the LG3D DisplayServerManagerInterface interface. | > > | implementation of the LG3D interface DisplayServerManagerInterface. | | | The WonderlandSceneManager.initialize() method contains the bulk of the functionality
of this class. It creates an instance of class org.jdesktop.lg3d.wonderland.scenemanager.WorldController with an instance of the | | | which computes the list of visible cells and sends CellHierarchyMessage(LOAD_CELL)
messages for all visible cells on the channel named "user+CELL_CACHE". It also sends
CellHierarchyMessage(DELETE_CELL or CELL_INACTIVE) messages for all newly non- | |
< < | visible cells on the chennel named "user+CELL_CACHE". | > > | visible cells on the channel named "user+CELL_CACHE". | | |
- The
WonderlandSessionListener finally sends UserChangedMessage messages to each of the clients via the USER_CHANGE channel to notify them of the new client.
| | | In this code sequence we consider when the user presses one of the cursor-control keys to move
the position of the avatar. | |
< < |
- The key event is handled by the
.keyPressed() method of class org.jdesktop.lg3d.wonderland.scenemanager.WalkBehavior. The state of the instance of the inner class Stimulus is updated to reflect the key state change.
| > > |
- The key event is handled by the
keyPressed() method of class org.jdesktop.lg3d.wonderland.scenemanager.WalkBehavior. The state of the instance of the inner class Stimulus is updated to reflect the key state change.
| | |
- The method
scheduleUpdate() of the instance of class org.jdesktop.lg3d.wonderland.scenemanager.AvatarControlBehavior is called which tells it that pending updates to the avatar state exists.
- The
AvatarControlBehavior.processStimulus() method wakes up and calls the
|
| |
| META TOPICPARENT | name="ProjectWonderland" |
Home | Changes | Index | Search | Go <-- This creates the navigation links to : Home | Help | Index | etc. --> | | | 4.3 Features of a Cell | |
< < | All cell classes extend the CellGLO class which provides most of the services | > > | All cell classes extend the CellGLO class which provides most of the services | | | necessary for cells. Each cell has a unique ID, generated by a central
facility (see org.jdesktop.lg3d.wonderland.darkstar.server.CellIDGenerator) and also a unique name formed as "CELL_"
plus ID. (see CellGLO.getCellID() and CellGLO.getGLOName() methods). A cell's | | | returns the origin as the cell in the form of an instance of class Matrix4d.
A cell also has a bounds, represented by the Java 3D Bounds class which | |
< < | describes its physical extent. The subclasses of CellGLO manage the cell's | > > | describes its physical extent. The subclasses of CellGLO manage the cell's | | | bounds by overriding the CellGLO.getBounds() method.
4.3.2 Cell parents and children | | | file.
The initialization of the connection with the server happens via it inner | |
< < | StartupListener class, which implements the Lg3dStartupListener? interface, from | > > | StartupListener class, which implements the Lg3dStartupListener interface, from | | | Project Looking Glass -- this listener's startupComplete() method is invoked
when the initialization of the graphics is complete. In turn, the implementation
of the startupComplete() method displays a login dialog (see class org.jdesktop.lg3d.wonderland.LoginDialog) | | | Project Wonderland defines its own scene manager, the equivalent of an X Windows
window manager in Project Looking Glass. Class org.jdesktop.lg3d.wonderland.scenemanager.WonderlandSceneManager extends | |
< < | the LG3D? SceneManagerBase class, an abstract class which implements the LG3D?
SceneManager interface. The LG3D? SceneManagerBase class handles communication with
the LG3D? display server (the moral equivalent of the X Windows Server) via its
implementation of the LG3D? DisplayServerManagerInterface interface. | > > | the LG3D SceneManagerBase class, an abstract class which implements the LG3D
SceneManager interface. The LG3D SceneManagerBase class handles communication with
the LG3D display server (the moral equivalent of the X Windows Server) via its
implementation of the LG3D DisplayServerManagerInterface interface. | | | The WonderlandSceneManager.initialize() method contains the bulk of the functionality
of this class. It creates an instance of class org.jdesktop.lg3d.wonderland.scenemanager.WorldController with an instance of the
Java 3D BranchGroup class to which the WorldController will attach all of the
visual content. It also adds the instance of the Java 3D BranchGroup class as a child | |
< < | of the LG3D? display server's root. | > > | of the LG3D display server's root. | | | | |
< < | The instance of WonderlandSceneManager also creates an instance of an LG3D? StandardAppContainer | > > | The instance of WonderlandSceneManager also creates an instance of an LG3D StandardAppContainer | | | class, using a null-style layout manager. The implementation of the
SceneManager.addFrame3D() and SceneManager.removeFrame3D() methods add and remove frames to
and from the instance of class StandardAppContainer. The usage of this is currently unclear. | |
< < | The instance of class WonderlandSceneManger is installed according to the LG3D? specification as | > > | The instance of class WonderlandSceneManger is installed according to the LG3D specification as | | | follows: the createSceneManager() = method of =org.jdesktop.lg3d.wonderland.scenemanager.WonderlandConfigControl returns an instance of
class WonderlandSceneManager. The Main class sets the "lg.configclass" property
to "org.jdesktop.lg3d.wonderland.scenemanager.WonderlandConfigControl". (Additional
configuration information for the scene manager is also handled by the | |
< < | WonderlandConfigControl? class, which reads an XML-formatted file of configuration | > > | WonderlandConfigControl class, which reads an XML-formatted file of configuration | | | options, by default: "/org/jdesktop/lg3d/wonderland/scenemanager/resources/wonderland.lgcfg".)
5.4 World Controller
The instance of class WorldController handles all of the visible content in the Wonderland world.
As class members, it maintains instances of two important client-side classes: | |
< < | org.jdesktop.lg3d.wonderland.scenemanager.UserCellCache and ChannelController. The WorldController? takes as an argument a Java 3D | > > | org.jdesktop.lg3d.wonderland.scenemanager.UserCellCache and ChannelController. The WorldController takes as an argument a Java 3D | | | BranchGroup to which it adds lighting: an ambient light of color RGB = {0.7, 0.7, 0.7},
and two directional lights. One directional light is white and is down-to-the-left. The
second directional light is RGB = {0.2, 0.2, 0.3} and is up-to-the-left. (TODO: What's | | |
- Instances of classes
NativeApplicationMessage and org.jdesktop.lg3d.wonderland.darkstar.common.messages.SoftphoneMessage as messages from the client.
- Instances of
org.jdesktop.lg3d.wonderland.darkstar.common.messages.AvatarSetupMessage messages from the client
| |
< < |
- CellMessage? messages from the client, dispatched to CellMessageListeners?.
| > > |
- Other instances of some sublcass of
org.jdesktop.lg3d.wonderland.darkstar.common.messages.CellMessage messages from the client, dispatched to instances of class org.jdesktop.lg3d.wonderland.darkstar.server.CellMessageListener.
| | | 6.2 Publish/Subscribe Communication Channels | | | 6.2.1 The USER_CHANGE channel | |
< < | The USER_CHANGE communication channel, created by WonderlandBoot?, and all new clients | > > | The USER_CHANGE communication channel is created by WonderlandBoot, and all new clients | | | are automatically added to it.
The server transmits the following messages to the client over this channel: | |
< < |
- UserChangedMessage? messages when users are added (USER_ADD) or when users leave (USER_LEFT).
| > > |
- Instances of class
org.jdesktop.lg3d.wonderland.darkstar.common.messages.UserChangedMessage when users are added (USER_ADD) or when users leave (USER_LEFT).
| | | The server does not receive any messages from the client on this channel. | | | The server creates a CELL_CACHE channel for each client connected. The name of the
channel takes the form: user + CELL_CACHE, where 'user' is the name of the user. This | |
< < | channel is created by the UserCellCacheGLO? class. All new clients are automatically | > > | channel is created by an instance of class UserCellCacheGLO. All new clients are automatically | | | added to this channel.
The server transmits the following messages to the client over this channel: | |
< < |
- CellHiearchyMessage? messages, which are of the type: LOAD_CELL, MOVE_CELL,
| > > |
- Instances of class
CellHiearchyMessage messages, which can be of the kind: LOAD_CELL, MOVE_CELL,
| | | CELL_INACTIVE, ADD_PARENT, REMOVE_PARENT, SET_WORLD_ROOT, and DELETE_CELL.
The server does not receive any messages from the client on this channel.
6.2.3 The AVATAR_P2P channel | |
< < | The server creates a AVATAR_P2P channel for each client connected. The name of the | > > | The server creates an AVATAR_P2P channel for each client connected. The name of the | | | channel takes the form: user + AVATAR_P2P, where 'user' is the name of the user. | |
< < | This channel is created by the AvatarCellGLO? class. Clients request to be joined
to an avatar's P2P? channel via the AvatarCellMessage? (JOIN_P2P) message sent on | > > | This channel is created by an instance of class AvatarCellGLO during its constructor. Clients request to be joined
to an avatar's P2P? channel via the AvatarCellMessage(JOIN_P2P) message sent on | | | the AVATAR_TILE channel.
The server transmits the following messages to the client over this channel: | |
< < |
- AvatarP2PMessage?, which has three types: SETUP, MOVE, and CHAT.
| > > |
- Instances of class
org.jdesktop.lg3d.wonderland.darkstar.common.messages.AvatarP2PMessage, of which there are three kinds: SETUP, MOVE, and CHAT.
| | | The server does not receive any messages from the client on this channel.
6.2.4 The AVATAR_TILE channel | |
< < | The AVATAR_TILE channel is created by the AvatarCellGLO? class. the name of the | > > | The AVATAR_TILE channel is created by an instance of class AvatarCellGLO. The name of the | | | channel takes the form: user + AVATAR_TILE, where 'user' is the name of the user.
The server transmits the following messages to the client over this channel: | |
< < |
- AvatarCellMessage?, which has one basic type: SETUP. When a cell first becomes visible.
| > > |
- An instance of class
AvatarCellMessage, which has one basic kind: SETUP. When a cell first becomes visible.
| | | | |
< < | When a cell becomes visible, the server steps through a list of all cells as | > > | When a cell becomes visible, the server steps through a list of all cells and | | | adds the client to the cell's channel if it exists. Currently, only the avatar
cell creates a channel for itself. At that point, a SETUP message is sent to | |
< < | the client, which stores away the channel for future communication. | > > | the client, which stores the channel for future communication. | | | | |
< < | The server receives the following messages from the client over this channel: | > > | The server received the following messages from the client over this channel: | | | | |
< < |
- AvatarCellMessage?, which has four basic types: JOIN_P2P, CELL_MOVE, AVATAR_MOVE, CELL_ENTER, and CELL_EXIT.
| > > |
- Instances of
AvatarCellMessage, of which there are four kinds: JOIN_P2P, CELL_MOVE, AVATAR_MOVE, CELL_ENTER, and CELL_EXIT.
| | | 6.2.5 The SERVER_MANAGER_CHANNEL channel | |
< < | The SERVER_MANAGER_CHANNEL communication channel, created by the ServerManagerGLO?
class, is used to communication server management information to the client. Right
now, the server itself and a special client (hardcoded to name "ServerManager") are | > > | The SERVER_MANAGER_CHANNEL communication channel, created by an instance of class org.jdesktop.lg3d.wonderland.darkstar.server.ServerManagerGLO,
is used to communication server management information to the client. Currently, the server itself and a special client (hardcoded to name "ServerManager") are | | | added to this channel. | |
< < | The server transmits and receives the following messages to the client over this channel:
- ServerManagerMessage?, which has four types: STATUS, FULL_STATUS, CHANGE_UPDATE_INTERVAL, and SET_USER_LIMIT.
| > > | The server transmits and receives instances of class org.jdesktop.lg3d.wonderland.darkstar.common.messages.ServerManagerMessage to the client over this channel, of which there are four kinds: STATUS, FULL_STATUS, CHANGE_UPDATE_INTERVAL, and SET_USER_LIMIT. | | |
7. Summary of Important Code Flow Sequences | | | 7.1. Sequence of Code when a Client First Connects | |
< < |
- The Main class creates the main window and adds an LG3D? Lg3dConnector? class to the main window. This, in turn, starts the LG3D? display server. Upon initialization, the L3GD? display server initializes the universe, windowing system, view, creates
| > > |
- The
Main class creates the main window and adds an instance of the LG3D Lg3dConnector class to the main window. This, in turn, starts the LG3D display server. Upon initialization, the L3GD display server initializes the universe, windowing system, view, creates
| | | the root scene graph, and initializes the scene manager. | |
< < |
- The Wonderland Scene Manager creates a new WorldController? class, which creates a new instances of the ChannelController? and UserCellCache? classes.
- Upon completion of the LG3D? initialization, the StartupListener?.startupComplete() method is called which posts the Wonderland Login dialog.
| > > |
- The Wonderland Scene Manager creates a new instance of class
WorldController, which creates a new instances of the ChannelController and UserCellCache classes.
- Upon completion of the LG3D initialization, the
StartupListener.startupComplete() method is called which raises the Wonderland Login dialog.
| | |
- Upon user login confirmation, a connection to the Darkstar server is opened. The client waits for login confirmation, which is sent asynchronously via a call to
| |
< < | WonderlandClientListener?.loggedIn().
- Upon login, the client sends an AvatarSetupMessage? message to the Darkstar server
| > > | WonderlandClientListener.loggedIn().
- Upon login, the client sends an
AvatarSetupMessage message to the Darkstar server
| | | via its client-server communication mechanism with information about the avatar,
such as its visual model.
- Upon the conclusion of login, the main window of the Wonderland client is enabled.
7.2 Sequence of Code upon Initialization of the Server | |
< < |
- The WonderlandBoot?.initialize() method creates new instances of the ServerManagerGLO?, UserManager?, MasterCellCacheGLO?, and ChecksumManagerGLO? classes. A publish/subscribe
| > > |
- The
WonderlandBoot.initialize() method creates new instances of classes ServerManagerGLO, UserManager, MasterCellCacheGLO, and ChecksumManagerGLO. A publish/subscribe
| | | channel is also created named USER_CHANGE. | |
< < |
- The MasterCellCacheGLO? class creates a new WorldRootCellGLO? class. This calls the WorldRootCellGLO?.buildWorld() method which creates all of the cells in the world.
- The WonderlandSessionListener? class receives the AvatarSetupMessage? message from the client. It creates a new UserGLO? class.
- The UserGLO? class creates a new AvatarCellGLO? class, which in turn creates a new UserCellCacheGLO? object.
- The UserCellCacheGLO? class creates a publish/subscribe channel named user+CELL_CACHE,
| > > |
- The
MasterCellCacheGLO instance creates a new instance of class WorldRootCellGLO. In turn this calls the WorldRootCellGLO.buildWorld() method which creates all of the cells in the world.
- An instance of class
WonderlandSessionListener receives an AvatarSetupMessage message from the client. It creates a new instance of class UserGLO.
- The
UserGLO instance creates a new AvatarCellGLO instance, which in turn creates a new UserCellCacheGLO instance.
- The
UserCellCacheGLO instance creates a publish/subscribe channel named user+CELL_CACHE,
| | | where 'user' is the name of the user. | |
< < |
- The AvatarCelLGLO? class then opens a publish/subscribe channel named AVATAR_P2P and
| > > |
- The
AvatarCelLGLO instance then opens a publish/subscribe channel named AVATAR_P2P and
| | | a channel named user+AVATAR_TILE, where 'user' is the name of the user. | |
< < |
- The WonderlandSessionListener? then joins the client to the USER_CHANGE channel and sends a UserChangedMessage? (USER_ADDED) message to the client. It then calls the login() method on UserGLO?.
- The UserGLO?.login() method adds a reference of the user to the hash map relating user ID's to user object references. It calls AvatarCellGLO?.login().
- The AvatarCellGLO?.login() adds itself (the avatar's cell) to the MasterCellCacheGLO? class. It then calls UserCellCacheGLO?.login() which joins the client to the user+CELL_CACHE channel, adds a reference of itself to the MasterCellCacheGLO? class, and sends a CellHierarchyMessage? (LOAD_CELL) to the user+CELL_CACHE channel, and then sends a CellHiearchyMessage? (SET_WORLD_ROOT) to the user+CELL_CACHE channel.
- The UserGLO?.login() method then calls the UserCellCacheGLO?.avatarCellMoved() method, which computes the list of visible cells and sends CellHierarchyMessage? (LOAD_CELL) messages for all visible cells on the user+CELL_CACHE channel. It also sends CellHierarchyMessage? (DELETE_CELL or CELL_INACTIVE) messages for all newly non- visible cells on the user+CELL_CACHE channel.
- The WonderlandSessionListener? finally sends UserChangedMessage? messages to each of the clients via the USER_CHANGE channel to notify of the new client.
| > > |
- The
WonderlandSessionListener instance then joins the client to the USER_CHANGE channel and sends a UserChangedMessage(USER_ADDED) message to the client. It then calls the login() method on the UserGLO instance.
- The
UserGLO.login() method adds a reference of the user to the hash map relating user ID's to user object references. It calls AvatarCellGLO.login().
- The
AvatarCellGLO.login() adds the receiving instance of AvatarCellGLO to the MasterCellCacheGLO instance. It then calls UserCellCacheGLO.login() which joins the client to the user+CELL_CACHE channel, adds itself (the UserCellCacheGLO) to the MasterCellCacheGLO instance, and sends a CellHierarchyMessage(LOAD_CELL) message to the channel named "user+CELL_CACHE", and then sends a CellHiearchyMessage(SET_WORLD_ROOT) message to the channel named "user+CELL_CACHE".
- The
UserGLO.login() method then calls the UserCellCacheGLO.avatarCellMoved() method, which computes the list of visible cells and sends CellHierarchyMessage(LOAD_CELL) messages for all visible cells on the channel named "user+CELL_CACHE". It also sends CellHierarchyMessage(DELETE_CELL or CELL_INACTIVE) messages for all newly non- visible cells on the chennel named "user+CELL_CACHE".
- The
WonderlandSessionListener finally sends UserChangedMessage messages to each of the clients via the USER_CHANGE channel to notify them of the new client.
| | | 7.2 Sequence of Code when an Avatar Moves | |
< < | In this code sequence we consider when the user presses one of the arrow buttons to move | > > | In this code sequence we consider when the user presses one of the cursor-control keys to move | | | the position of the avatar. | |
< < |
- The key event is handled by the WalkBehavior?.keyPressed() event. The Stimulus class is updated to reflect the key state change.
- The AvatarControlBehavior?.scheduleUpdate() method is called which tells it that pending
| > > |
- The key event is handled by the
.keyPressed() method of class org.jdesktop.lg3d.wonderland.scenemanager.WalkBehavior. The state of the instance of the inner class Stimulus is updated to reflect the key state change.
- The method
scheduleUpdate() of the instance of class org.jdesktop.lg3d.wonderland.scenemanager.AvatarControlBehavior is called which tells it that pending
| | | updates to the avatar state exists. | |
< < |
- The AvatarControlBehavior?.processStimulus() method wakes up and calls the WalkBehavior?.updateState() method which updates the position state of the avatar.
| > > |
- The
AvatarControlBehavior.processStimulus() method wakes up and calls the WalkBehavior.updateState() method which updates the position state of the avatar.
| | |
- Collision detection is performed based upon the new position of the Avatar. The position of the camera is then updated.
| |
< < |
- All UserMotionListeners? are notified of the new position of the avatar. One example of a UserMotionListener? is the UserCellCache? class, which calls UserCellCache?.updateCells() method. Another listener is the AvatarCell? class.
- The updateCells() method computes the visible cells based upon the user's viewing frustum.
| > > |
- All implementations of interface
UserMotionListener are notified of the new position of the avatar via the method userMoved(). One example of an implementation of UserMotionListener is class UserCellCache, whose userMoved() method calls the UserCellCache.updateCells() method. (Another example implementation of the interface is class AvatarCell).
- The
updateCells() method computes the visible cells based upon the user's viewing frustum.
| | | It updates the state of each cell and the list of visible cells. For all visible cells, | |
< < | it updates the list of cells the avatar is currently standing in. It sends CellEnterEvent?
and CellExitEvents?, correspondingly within the LG3D? event framework. (At this time the
AvatarCellMessage? CELL_ENTER and CELL_EXIT are not sent to the server, nor does the
server take any action upon receiving these events.
- The AvatarCell?.userMoved() method sends a AvatarCellMessage? (AVATAR_MOVE & CELLMOVE) to the
| > > | it updates the list of cells the avatar is currently standing in. It causes events of type CellEnterEvent
and CellExitEvent to be sent to the appropriate cells (within the LG3D event framework). (At this time the
AvatarCellMessage types CELL_ENTER and CELL_EXIT are not sent to the server, nor does the
server take any action upon receiving these events).
- The
AvatarCell.userMoved() method sends an AvatarCellMessage(AVATAR_MOVE & CELLMOVE) to the
| | | server via the AVATAR_TILE channel. The position of the avatar is updated on the server and | |
< < | the UserCellCacheGLO? is asked to revalidate itself (which computes the list of visible and | > > | the UserCellCacheGLO is asked to revalidate itself (which computes the list of visible and | | | invisible cells, updates its state, and informs the client of such).
8. Future Documentation Work |
| |
| META TOPICPARENT | name="ProjectWonderland" |
Home | Changes | Index | Search | Go <-- This creates the navigation links to : Home | Help | Index | etc. --> | | | been employed in other contexts, namely, herein which is not strictly a
game). | |
< < | Project Darkstar manages a collection of objects (called ManagedObjects?) and | > > | Project Darkstar manages a collection of objects (called ManagedObjects) and | | | provides APIs for the synchronized update of the state of these objects in | |
< < | response to events from multiple clients. Updates to ManagedObjects? are | > > | response to events from multiple clients. Updates to ManagedObjects are | | | themselves transactional -- either a coherent set of state updates happen
across a set of objects or they do not happen at all. All items within a | |
< < | game or virtual world are represented by ManagedObjects? on the server, for | > > | game or virtual world are represented by ManagedObjects on the server, for | | | example, rooms, players, tools, weapons, or any other virtualized real-
world object that exists in the world. Details on Project Darkstar can
be found at http://www.projectdarkstar.com.
The client is a desktop Java application and is based upon two technologies | |
< < | to render the 3D world: Java 3D and Looking Glass 3D (LG3D?). Java 3D, a standard | > > | to render the 3D world: Java 3D and Looking Glass 3D (LG3D). Java 3D, a standard | | | extension to Java SE, renders sets of 3D objects to the screen, making
use of hardware acceleration if possible. Details on Java 3D can be found
at https://java3d.dev.java.net/. Project Looking Glass provides a 3D | | | scenery or objects in the virtual world. Persons, called Avatars, are
also represented by cells. | |
< < | Each cells has a position and bounds inside the virtual world. A cell's | > > | Each cell has a position and bounds inside the virtual world. A cell's | | | origin is given in world coordinates, corresponding to the center of the
cell. A cell also has "cell coordinates", where the cell's center is at
(0, 0, 0). | |
< < | Cells may contain zero of more other cells, and hence there exists the | > > | A cell may contain zero of more other cells, and hence there exists the | | | notion of a "parent" and "children" for each cell -- a single "master" cell
represents the entire world and contains all other cells. A cell may have | |
< < | multiple parents, if it spans the physical bounds of more than one cell. | > > | multiple parents, if it spans the physical bounds of more than one parent cell. | | | Cells, therefore, may overlap with one cell and do not need to be entirely | |
< < | contained within a single cell. | > > | contained within a single cell. (This sounds like it means that the bounds of a cell may overlap the bounds of another cell? Bernard.) | | | 4. Server-side architecture
4.1 Darkstar Boot Class and Data Management
Project Darkstar requires a boot-strapping class to initialize the "game", (which | |
< < | replaces the main() method). The WonderlandBoot? class serves this purpose
by implementing the Darkstar AppListener? interface and the initialize()
method. The implementation of this method performs some very basic tasks | > > | replaces the main() method). The org.jdesktop.lg3d.wonderland.darkstar.server.WonderlandBoot class serves this purpose
by implementing the Darkstar AppListener interface. The implementation of its initialize() method performs some very basic tasks | | | which kick-starts the creation of the Wonderland world. They are: | |
< < |
- Create an instance of the UserManager? class which maintains the list of users (i.e. clients) which connect to the world.
- Create an instance of the MasterCellCacheGLO? class which maintains the list of classes which maintains the cache of cells visible to a user.
- Create an instance of the ChecksumManagerGLO? class which manages a series of checksums for classes representing assets in the world.
- Opens a communication channel named ChannelInfo?.USER_CHANGE which communicates changes in the client's status.
| > > |
- Create an instance of the
org.jdesktop.lg3d.wonderland.darkstar.server.UserManager class which maintains the list of users (i.e. clients) which connect to the server.
- Create an instance of the
org.jdesktop.lg3d.wonderland.darkstar.server.cell.MasterCellCacheGLO class which maintains the list of classes which maintains the cache of cells visible to a user. (Not really sure what this means Bernard.)
- Create an instance of the
org.jdesktop.lg3d.wonderland.darkstar.server.ChecksumManagerGLO class which manages a series of checksums for classes representing assets in the world.
- Open a communication channel named
ChannelInfo.USER_CHANGE which communicates changes in the client's status.
| | | When a new client opens a connection to the Wonderland server, the | |
< < | WonderlandBoot?.loggedIn() method is invoked, which simply creates a new
instance of the WonderlandSessionListener? class. It is this class which | > > | WonderlandBoot.loggedIn() method is invoked, which simply creates a new
instance of the org.jdesktop.lg3d.wonderland.darkstar.server.WonderlandSessionListener class. It is this class which | | | handles future changes in the state of the client, and in particular | |
< < | creates the avatar when a user logs in. | > > | creates the avatar when a user logs in (see WonderlandSessionListener.processAvatarSetupMessage()). | | | 4.2 Cell architecture
Project Wonderland employs the Project Darkstar gaming platform on the
server-side, where each cell is represented by a managed object. The base | |
< < | abstract class for all cell managed objects is the CellGLO? class. (The | > > | abstract class for all cell managed objects is the org.jdesktop.lg3d.wonderland.darkstar.server.cell.CellGLO class. (The | | | suffix "GLO" is a hold-over from an earlier version of Project Darkstar
where managed objects were called "Game Logic Objects" (or GLOs)). | | | cells. Stationary cells represent regions which do not move, while moveable
cells represent graphics which do move. Avatars are the best (and perhaps
only) example of a moveable cell. All stationary cell classes extend | |
< < | StationaryCellGLO? and all moveable cell classes extend MoveableCellGLO?. | > > | org.jdesktop.lg3d.wonderland.darkstar.server.cell.StationaryCellGLO and all moveable cell classes extend org.jdesktop.lg3d.wonderland.darkstar.server.cell.MoveableCellGLO. | | | | |
< < | Various stationary cells are defined within the Wonderland architecture.
The most basic is the "world root" cell (see WorldRootCellGLO? class) which
is the root of all cells in the world and is responsible for creating the
world. At present time, the WorldRootCellGLO? creates its world cells using
hard-coded lines of code. In the future, a more flexible architecture to | > > | Various classes are used to define stationary cells within the Wonderland architecture.
The most basic is the "world root" cell (see org.jdesktop.lg3d.wonderland.darkstar.server.cell.WorldRootCellGLO class) which
is the root of all cells in the world and is also responsible for creating the
world. At present time, the WorldRootCellGLO creates its structure of cells using
hard-coded lines of code. (See for example, WorldRootCellGLO.buildFullWorld().) In the future, a more flexible architecture to | | | build worlds is planned. | |
< < | Currently, the following stationary cells exist: simple terrain, slide show,
model viewer, animated, audio, and shared application. The only moveable
cell that is exists is the avatar cell.
The simple terrain (see SimpleTerrainCellGLO? class) cell is used to define
basic surroundings in the world, taking the name of an external file which
defines the geometry of the surroundings.
A slide show (see SlideShowCellGLO? class) cell is used to define a series of
images which will be shown in sequence, taking a file name pattern, whose
wild-card character ('%') will be expanded into a frame number. Images in
the sequence will be advanced via user input.
A model viewer (see ModelViewerCellGLO? class) cell needs further study. XXX
An animated (see AnimatedCellGLO? class) cell represents a series of images
which are animated in the world, taking an array of file names composing
the animation.
An audio (see AudioCellGLO? class) cell, an extension of the animated cell,
represents audio playing in the world eminating from a certain origin.
A shared application (see SharedApp2DCellGLO? class) represents an X Windows-
based application which is being displayed in the world and can be interacted
with by avatars. | > > | Currently, the following stationary classes exist to represent the following (in package org.jdesktop.lg3d.wonderland.darkstar.server.cell):
simple terrain (SimpleTerrainCellGLO), slide show (SlideShowCellGLO),
model viewer (ModelViewerCellGLO), animated (AnimatedCellGLO), audio (AudioCellGLO), and shared application (SharedApp2DCellGLO). The only moveable
cell that is exists is the avatar cell (AvatarCellGLO).
- The simple terrain cell is used to define basic surroundings in the world, taking the name of an external file which defines the geometry of the surroundings.
- A slide show cell is used to define a series of images which will be shown in sequence, taking a file name pattern, whose wild-card character ('%') will be expanded into a frame number. Images in the sequence will be advanced via user input.
- A model viewer cell needs further study. XXX
- An animated cell represents a series of images which are animated in the world, taking an array of file names composing the animation.
- An audio cell, an extension of the animated cell, represents audio playing in the world eminating from a certain origin.
- A shared application cell represents an X Windows-based application which is being displayed in the world and can be interacted with by avatars.
| | | 4.3 Features of a Cell | |
< < | All cells extend the CellGLO? class which provides most of the services | > > | All cell classes extend the CellGLO class which provides most of the services | | | necessary for cells. Each cell has a unique ID, generated by a central | |
< < | facility (see CellIDGenerator? class) and also a unique name formed as "CELL_"
plus ID. (see CellGLO?.getCellID() and CellGLO?.getGLOName() methods). A cell's
ID is simply a number encapsulated by the CellID? class. | > > | facility (see org.jdesktop.lg3d.wonderland.darkstar.server.CellIDGenerator) and also a unique name formed as "CELL_"
plus ID. (see CellGLO.getCellID() and CellGLO.getGLOName() methods). A cell's
ID is simply a number encapsulated by an instance of the org.jdesktop.lg3d.wonderland.darkstar.common.CellID class. | | | 4.3.1 Cell origin and bounds | | | why a cell's origin cannot be any combination of these transformations,
however, translations and rotations seem to be the only types used in
practice). A cell's origin is stored by the 'cellOrigin' member variable | |
< < | and is set directly by all of the cell subclasses. The CellGLO?.getOrigin()
returns the Matrix4d class origin. | > > | and is set directly by all of the cell subclasses. The CellGLO.getOrigin() method
returns the origin as the cell in the form of an instance of class Matrix4d. | | | A cell also has a bounds, represented by the Java 3D Bounds class which | |
< < | describes its physical extents. The subclasses of CellGLO? manage the cell's
bounds by overwriting the CellGLO?.getBounds() method. | > > | describes its physical extent. The subclasses of CellGLO manage the cell's
bounds by overriding the CellGLO.getBounds() method. | | | 4.3.2 Cell parents and children
A cell's set of zero or more children and parents are stored in hashed sets. | |
< < | Adding and removing a parent cell is done via the CellGLO?.addParentCell() and
CellGLO?.removeParentCell() methods. The CellGLO?.getParentCellIDs() method
returns an array of CellID? classes of each of the registered parent cell. The
methods CellGLO?.addChildCell() and CellGLO?.removeChildCell() add and remove
children to and from the cell, respectively. The CellGLO?.getChildren() returns | > > | Adding and removing a parent cell is done via the CellGLO.addParentCell() and
CellGLO.removeParentCell() methods, respectively. The CellGLO.getParentCellIDs() method
returns an array of instances of class CellID, each of which identifies a parent cell. The
methods CellGLO.addChildCell() and CellGLO.removeChildCell() add and remove
children to and from the cell, respectively. The CellGLO.getChildren() returns | | | a collection of children of the cell. | |
< < | At any time, not all of a cell's children may be visible, which is conditioned
upon some visible bounds. The CellGLO?.getVisibleCells() method returns a | > > | At any time, some of a cell's children may be invisible, which is conditional
upon some visible bounds. The CellGLO.getVisibleCells() method returns a | | | collection of children cells that are visible given a certain bounds. Typically | |
< < | the visible bounds depends upon the viewing frustum of the avatar. | > > | the visible bounds depends upon the viewing frustum of the avatar. | | | 4.3.3 Inter-client communication via a cell | |
< < | Cells also support a communication mechanism between clients, using the | > > | Cells also provide a communication mechanism between clients, using the | | | Project Darkstar channel mechanism. Each cell can have a single communication | |
< < | channel, identified by a unique name and created via CellGLO?.openCellChannel().
The CellGLO?.getCellChannel() method returns the channel. Users are added as
listeners to the channel via the CellGLO?.addUserToCellChannel() and removed
via the CellGLO?.removeUserFromCellChannel() methods. Each of these two methods
takes the unique id of the client server as arguments. See Section 6 below | > > | channel, identified by a unique name and created via the CellGLO.openCellChannel() method.
The CellGLO.getCellChannel() method returns the cell's channel. Clients are added as
listeners to the channel via the =CellGLO.addUserToCellChannel() = method and removed
via the CellGLO.removeUserFromCellChannel() method. Each of these two methods
takes the unique id of the client session as argument. See Section 6 below | | | regarding details of the client-server communication architecture in Project
Wonderland. | |
< < | 4.3.4 Client cell class and setup | > > | 4.3.4 Client-side cell classes and setup | | | | |
< < | Each cell type on the server has a corresponding cell class on the client | > > | Each cell class on the server has a corresponding cell class on the client | | | which is responsible for rendering the cell. The name of the corresponding | |
< < | client cell class is defined by each of the individual cell subclasses which
implement the CellGLO?.getClientCellClassName() method. | > > | client cell class is defined by each of the individual server-side cell subclasses via
the CellGLO.getClientCellClassName() method. | | | | |
< < | The server cell class communicates its visual contents and other setup data
via the CellSetup? class, returned by the CellGLO?.getSetupData() method that
is implemented by each of the individual cell subclasses.
The CellSetup? class itself is simply an empty interface which extends the
java.io.Seriablizable interface so that it may be sent across the wire. Each
cell type defines its own sub-interface of the CellSetup? interface. Examples
include the AnimatedCellSetup?, AvatarCellSetup?, ModelViewerCellSetup?,
SharedApp2DCellSetup?, SimpleCellSetup?, and SlideShowCellSetup? classes. The
SimpleCellSetup? class is used, for example, by the simple terrain cell and | > > | A server-side cell communicates its visual contents and other setup data
via an instance of a class that implements the org.jdesktop.lg3d.wonderland.darkstar.common.CellSetup interface.
This is returned from the CellGLO.getSetupData() method that
is implemented by each of the individual server-side cell subclasses.
The CellSetup interface itself is simply an empty interface which extends the
java.io.Seriablizable interface so that it may be sent across the wire. Each server-side
cell class defines its own "setup" class that implements the CellSetup interface. Examples (in package org.jdesktop.lg3d.wonderland.darkstar.common)
include AnimatedCellSetup, AvatarCellSetup, ModelViewerCellSetup,
SharedApp2DCellSetup, SimpleCellSetup, and SlideShowCellSetup. The
SimpleCellSetup class is used, for example, by the simple terrain cell and | | | has methods which return the name of disk files storing the scene.
4.4 Server-side Cell Caching
The set of cells which should be currently kept in memory by the client is | |
< < | managed by the server via the UserCellCacheGLO? class, an instance of this | > > | managed by the server via an instance of org.jdesktop.lg3d.wonderland.darkstar.server.cell.UserCellCacheGLO class, an instance of this | | | class exists for each user (which is equivalent to saying "client") and | |
< < | is created when the user logs in. All UserCellCacheGLO? classes are maintained
by the MasterCellCacheGLO? class. Both are managed objects within the Project | > > | is created when the user logs in. All instances of UserCellCacheGLO are managed
by the instance of MasterCellCacheGLO class that was created by WonderlandBoot (see section 4.1). They are managed objects within the Project | | | Darkstar infrastructure.
The server-side cell caches support several state changes to cells. They are:
cell created, root cell created, cell moved, cell deleted, and add parent to cell. | |
< < | At the present time, the UserCellCacheGLO?.revalidate() method considers those
cells which are currently visible and add those cells which are new and deletes | > > | At the present time, the UserCellCacheGLO.revalidate() method considers those
cells which are currently visible and adds those cells which are new and deletes | | | from the client's memory those which are no longer visible. Changes in the | |
< < | state of cells are communicated via a dedicated channel associated with the
UserCellCacheGLO? class. At the present, all of these types of messages are
serialized instances of the CellHierarchyMessage? class.
The visible cells are naturally determined by the position of the avatar, and
the its visible domain is determined by the AvatarBoundsManager? class and its
getProximityBounds() method which defines the visible area as a sphere of
a certain radius (AvatarBoundsManager?.PROXIMITY_SIZE = 200.0) from the center | > > | state of cells are communicated via a dedicated channel associated with the instance of
UserCellCacheGLO class. At present, the messages that are communicated on this channel are
serialized instances of the org.jdesktop.lg3d.wonderland.darkstar.common.messages.CellHierarchyMessage class.
The visible cells are determined by the position of the avatar.
Its visible domain is determined by an instance of class org.jdesktop.lg3d.wonderland.darkstar.common.AvatarBoundsManager via its
getProximityBounds() method. This method defines the visible area as a sphere of
a specified radius (AvatarBoundsManager.PROXIMITY_SIZE = 200.0) from the center | | | of the avatar.
5. Client-side Architecture
5.1 The Main class | |
< < | The Main class, as its name implies, implements the static main() method to | > > | The org.jdesktop.lg3d.wonderland.Main class, as its name implies, implements the static main() method to | | | start-up the client. It initializes its user interface and reads in any
mutable configuration options from an external XML-formatted configuration
file. | |
< < | The initialization of the connection with the server happens via the
StartupListener? class, which implements the Lg3dStartupListener? interface, from
Project Looking Glass -- this listener's startupComplete() method is invoked | > > | The initialization of the connection with the server happens via it inner
StartupListener class, which implements the Lg3dStartupListener? interface, from
Project Looking Glass -- this listener's startupComplete() method is invoked | | | when the initialization of the graphics is complete. In turn, the implementation | |
< < | of the startupComplete() method displays a login dialog (see LoginDialog? class) | > > | of the startupComplete() method displays a login dialog (see class org.jdesktop.lg3d.wonderland.LoginDialog) | | | which accepts login information from the user. It initiates a connection to | |
< < | the Wonderland server and invokes Main.enableMainWindow() to "turn on" the | > > | the Wonderland server and invokes the method Main.enableMainWindow() to "turn on" the | | | Wonderland client. | |
< < | All communications with the Darkstar-based Wonderland server are managed by the
ChannelController? class. A new connection to the server is initiated via the
ChannelController?.initCommunications() method. See Section 6 below for details
on the ChannelController? class. | > > | All communications with the Darkstar-based Wonderland server is managed by an instance of class
org.jdesktop.lg3d.wonderland.darkstar.client.ChannelController. A new connection to the server is initiated via the
ChannelController.initCommunications() method. See Section 6 below for details
of class ChannelController. | | | 5.2 Wonderland Universe | |
< < | The "universe", as created by the WonderlandUniverseFactory?, creates the main
drawing canvas and initializes some basic viewing parameters. This class is
created by the WonderlandPlatformConfig? class, which in turn, is specified by
the lg.platformConfigClass property. | > > | The "universe", as created by an instance of class org.jdesktop.lg3d.wonderland.scenemanager.WonderlandUniverseFactory, creates the main
drawing canvas and initializes some basic viewing parameters. This instance is
created by an instance of class org.jdesktop.lg3d.wonderland.scenemanager.WonderlandPlatformConfig, which in turn, is specified by
the lg.platformConfigClass property. | | | 5.3 Scene Manager
Project Wonderland defines its own scene manager, the equivalent of an X Windows | |
< < | window manager in Project Looking Glass. The WonderlandSceneManager? class extends
the LG3D? SceneManagerBase? class, an abstract class which implements the LG3D?
SceneManager? interface. The LG3D? SceneManagerBase? class handles communication with | > > | window manager in Project Looking Glass. Class org.jdesktop.lg3d.wonderland.scenemanager.WonderlandSceneManager extends
the LG3D? SceneManagerBase class, an abstract class which implements the LG3D?
SceneManager interface. The LG3D? SceneManagerBase class handles communication with | | | the LG3D? display server (the moral equivalent of the X Windows Server) via its | |
< < | implements of the LG3D? DisplayServerManagerInterface? interface. | > > | implementation of the LG3D? DisplayServerManagerInterface interface. | | | | |
< < | The WonderlandSceneManager?.initialize() method contains the bulk of the functionality
of this class. It creates an instance of the WorldController? class with a base
Java 3D BranchGroup? class to which the WorldController? class will attach all of the
visual content. It also adds the instance of the Java 3D BranchGroup? class as a child | > > | The WonderlandSceneManager.initialize() method contains the bulk of the functionality
of this class. It creates an instance of class org.jdesktop.lg3d.wonderland.scenemanager.WorldController with an instance of the
Java 3D BranchGroup class to which the WorldController will attach all of the
visual content. It also adds the instance of the Java 3D BranchGroup class as a child | | | of the LG3D? display server's root. | |
< < | The WonderlandSceneManager? class also creates an instance of an LG3D? StandardAppContainer? | > > | The instance of WonderlandSceneManager also creates an instance of an LG3D? StandardAppContainer | | | class, using a null-style layout manager. The implementation of the | |
< < | SceneManager?.addFrame3D() and SceneManager?.removeFrame3D() adds and removes frames to
and from the StandardAppContainer? class. The usage of this is currently unclear. | > > | SceneManager.addFrame3D() and SceneManager.removeFrame3D() methods add and remove frames to
and from the instance of class StandardAppContainer. The usage of this is currently unclear. | | | | |
< < | The WonderlandSceneManger? class is installed according to the LG3D? specification as
follows: the WonderlandConfigControl?.createSceneManager() class returns an instance of
the WonderlandSceneManager? class. The Main class sets the "lg.configclass" property | > > | The instance of class WonderlandSceneManger is installed according to the LG3D? specification as
follows: the createSceneManager() = method of =org.jdesktop.lg3d.wonderland.scenemanager.WonderlandConfigControl returns an instance of
class WonderlandSceneManager. The Main class sets the "lg.configclass" property | | | to "org.jdesktop.lg3d.wonderland.scenemanager.WonderlandConfigControl". (Additional
configuration information for the scene manager is also handled by the
WonderlandConfigControl? class, which reads an XML-formatted file of configuration | | | 5.4 World Controller | |
< < | The WorldController? class handles all of the visible content in the Wonderland world. | > > | The instance of class WorldController handles all of the visible content in the Wonderland world. | | | As class members, it maintains instances of two important client-side classes: | |
< < | UserCellCache? and ChannelController?. The WorldController? takes an argument a Java 3D
BranchGroup? to which it adds lighting: an ambient light of color RGB = {0.7, 0.7, 0.7}, | > > | org.jdesktop.lg3d.wonderland.scenemanager.UserCellCache and ChannelController. The WorldController? takes as an argument a Java 3D
BranchGroup to which it adds lighting: an ambient light of color RGB = {0.7, 0.7, 0.7}, | | | and two directional lights. One directional light is white and is down-to-the-left. The
second directional light is RGB = {0.2, 0.2, 0.3} and is up-to-the-left. (TODO: What's
the effect of this lighting descriptively?) | |
< < | Details of the UserCellCache? (section 5.4) and ChannelController? (section 5.x) classesare found below. | > > | Details of classes UserCellCache (section 5.4) and ChannelController (section 5.x) are found below. | | | 5.5 Client-Side Cell Caching | |
< < | Visible cells are cached and maintained by the UserCellCache? class. The loading/unloading | > > | Visible cells are cached and maintained by an instance of UserCellCache. The loading/unloading | | | of cells and changing their state is controlled entirely by the server through messages | |
< < | send from the server to the client, formatted as instances of the CellHierarchyMessage?
class. The UserCellCache?.handleMessage() method handles these server events, sent over | > > | send from the server to the client, formatted as instances of class CellHierarchyMessage.
The UserCellCache.handleMessage() method handles these server events, sent over | | | a communication channel maintained by the Project Darkstar infrastructure and handled | |
< < | by the UserCellCacheChannelListener? class. | > > | by an instance of class org.jdesktop.lg3d.wonderland.darkstar.client.UserCellCacheChannelListener. | | | | |
< < | A common operation, particular at boot-time, is the creation of new cells on the client
side via a message of type CellHierarchyMessage?.LOAD_CELL. Using the configuration
information embedded in the CellHiearchyMessage?, an instance of the client-side cell
class is create and initialized. The new cell is added to the HashMap? cache of cells,
and the thread (CellUpdateThread? class) is signalled to update the set of visible
cells to render (the UserCellCache?.visibleCells member variable).
The UserCellCache? class also manages the list of cells the avatar is current positioned
in via the UserCellCache?.avatarInCells member variable. This list is updated when the
CellUpdateThread? class is signalled that an update has occurred. Cell enter and exit
events are generated (as represented by the CellEnterEvent? and CellExitEvent? classes,
respectively) and posted. | > > | A common operation, particular at client boot-time, is the request to create new cells on the client
side via a message of type CellHierarchyMessage.LOAD_CELL. Using the configuration
information embedded in the CellHiearchyMessage, an instance of the client-side cell
class is create and initialized. The new cell is added to the HashMap cache of cells,
and the thread (an instance of inner class CellUpdateThread within class UserCellCache) is signalled to update the set of visible
cells to render (the UserCellCache.visibleCells member variable).
The instance of class UserCellCache also manages the list of cells in which the avatar is currently positioned
via the UserCellCache.avatarInCells member variable (a HashSet). This set is updated when the
CellUpdateThread is signalled that an update has occurred. Cell enter and exit
events are generated--as represented by classes CellEnterEvent and CellExitEvent (in package org.jdesktop.lg3d.wonderland.scenemanager.events),
respectively--and posted. | | | | |
< < | The UserCellCache? class currently only implements a subset of the cell states: VISIBLE | > > | Class UserCellCache currently only implements a subset of the cell states: VISIBLE | | | and INACTIVE. The following cell states are currently not handled: ACTIVE, DISK, and
BOUNDS. | |
< < | The UserCellCache? class also implements the UserMotionListener? interface which receives
notification when the avatar moves (via the userMoved() method). The implementation of
the UserCellCache?.userMoved() method is currently basic: it simply updates the status | > > | Class UserCellCache also implements the org.jdesktop.lg3d.wonderland.scenemanager.UserMotionListener interface which receives
notification when the avatar moves (via the userMoved() method). The implementation of
the UserCellCache.userMoved() method is currently basic: it simply updates the status | | | of the visible cells and generates cell enter/exit messages using the updated position
of the avatar. | | | The server transmits the following messages to the client over this channel:
- An initial message giving the version of the communication protocol.
| |
< < |
- Potentially error messages as ErrorMessage? classes.
- NativeApplicationMessage? messages in reply to a "create application cell" message.
| > > |
- Potential error messages as instances of class
org.jdesktop.lg3d.wonderland.darkstar.common.messages.ErrorMessage.
- Instances of class
org.jdesktop.lg3d.wonderland.darkstar.common.messages.NativeApplicationMessage as messages in reply to a "create application cell" message.
| | | The server receives the following messages from the client over this channel: | |
< < |
- NativeApplicationMessage? and SoftphoneMessage? messages from the client.
- AvatarSetupMessage? messages from the client
| > > |
- Instances of classes
NativeApplicationMessage and org.jdesktop.lg3d.wonderland.darkstar.common.messages.SoftphoneMessage as messages from the client.
- Instances of
org.jdesktop.lg3d.wonderland.darkstar.common.messages.AvatarSetupMessage messages from the client
| | |
- CellMessage? messages from the client, dispatched to CellMessageListeners?.
6.2 Publish/Subscribe Communication Channels |
| |
| META TOPICPARENT | name="ProjectWonderland" |
Home | Changes | Index | Search | Go <-- This creates the navigation links to : Home | Help | Index | etc. --> | | | be found at http://www.projectdarkstar.com.
The client is a desktop Java application and is based upon two technologies | |
< < | to render the 3D world: Java 3D and Looking Glass 3D. Java 3D, a standard
extension to Java SE, and renders sets of 3D objects to the screen, making | > > | to render the 3D world: Java 3D and Looking Glass 3D (LG3D?). Java 3D, a standard
extension to Java SE, renders sets of 3D objects to the screen, making | | | use of hardware acceleration if possible. Details on Java 3D can be found
at https://java3d.dev.java.net/. Project Looking Glass provides a 3D
desktop environment. It provides a 3D Windowing environment and a set of | |
< < | API to build 3D applications. Details on the Project Looking Glass project | > > | API to build 3D applications. Details on Project Looking Glass | | | can be found at https://lg3d-core.dev.java.net/.
3. Virtual 3D World | | |
- Create an instance of the ChecksumManagerGLO? class which manages a series of checksums for classes representing assets in the world.
- Opens a communication channel named ChannelInfo?.USER_CHANGE which communicates changes in the client's status.
| |
< < | When a new client opens a connection to the wonderland server, the | > > | When a new client opens a connection to the Wonderland server, the | | | WonderlandBoot?.loggedIn() method is invoked, which simply creates a new
instance of the WonderlandSessionListener? class. It is this class which
handles future changes in the state of the client, and in particular | | | 4.2 Cell architecture
Project Wonderland employs the Project Darkstar gaming platform on the | |
< < | server-side, where each cell is represented by a managed boject. The base | > > | server-side, where each cell is represented by a managed object. The base | | | abstract class for all cell managed objects is the CellGLO? class. (The
suffix "GLO" is a hold-over from an earlier version of Project Darkstar
where managed objects were called "Game Logic Objects" (or GLOs)). |
|
> > |
| META TOPICPARENT | name="ProjectWonderland" |
Home | Changes | Index | Search | Go <-- This creates the navigation links to : Home | Help | Index | etc. -->
ProjectWonderlandArchitecture <-- this automatically adds a header showing the name of this page -->
<-- Your JavaDesktop? article goes here. Please try to include at least one sentence describing this topic. -->
<-- Also please try to include at least one sentence describing where each link goes. -->
<-- Please make sure some other page points to your new article so that others can find it! -->
<-- For more on how to write Javapedia articles please read the WritingArticles? page. -->
Project Wonderland Software Architecture
1. Introduction
Project Wonderland is a software platform for the creation of 3D virtual
worlds, primarily enabling geographically distributed participants to
collaborate with one another. This document describes the software
architecture of Project Wonderland. The primary audience of this document
are software developers wishing to extend or modify Project Wonderland.
Project Wonderland itself is in an early stage of release, and one can
expect that the software architecture, as well as this architecture
document will change significantly over the course of time.
2. Main Components: Client-Server Architecture
Project Wonderland is a Java-based, client-server software platform. The
server software is based upon Project Darkstar, a multi-player "gaming"
technology for the Java SE platform. (The word gaming is placed in quotes
because although Project Darkstar is aimed towards the gaming world, it has
been employed in other contexts, namely, herein which is not strictly a
game).
Project Darkstar manages a collection of objects (called ManagedObjects?) and
provides APIs for the synchronized update of the state of these objects in
response to events from multiple clients. Updates to ManagedObjects? are
themselves transactional -- either a coherent set of state updates happen
across a set of objects or they do not happen at all. All items within a
game or virtual world are represented by ManagedObjects? on the server, for
example, rooms, players, tools, weapons, or any other virtualized real-
world object that exists in the world. Details on Project Darkstar can
be found at http://www.projectdarkstar.com.
The client is a desktop Java application and is based upon two technologies
to render the 3D world: Java 3D and Looking Glass 3D. Java 3D, a standard
extension to Java SE, and renders sets of 3D objects to the screen, making
use of hardware acceleration if possible. Details on Java 3D can be found
at https://java3d.dev.java.net/. Project Looking Glass provides a 3D
desktop environment. It provides a 3D Windowing environment and a set of
API to build 3D applications. Details on the Project Looking Glass project
can be found at https://lg3d-core.dev.java.net/.
3. Virtual 3D World
A virtual world is composed of a collection of "cells", each of which
represents a 3D volume in the world. A world has a single, right-handed, 3D
cartesian coordinate system (hereafter referred to as "world coordinates").
From the viewer's perspective, the +X axis is towards the right, the +Y
axis is gravitationally up, and the +Z axis is towards the user. This
coordinate system is the same as defined by Java 3D. Cells may be
scenery or objects in the virtual world. Persons, called Avatars, are
also represented by cells.
Each cells has a position and bounds inside the virtual world. A cell's
origin is given in world coordinates, corresponding to the center of the
cell. A cell also has "cell coordinates", where the cell's center is at
(0, 0, 0).
Cells may contain zero of more other cells, and hence there exists the
notion of a "parent" and "children" for each cell -- a single "master" cell
represents the entire world and contains all other cells. A cell may have
multiple parents, if it spans the physical bounds of more than one cell.
Cells, therefore, may overlap with one cell and do not need to be entirely
contained within a single cell.
4. Server-side architecture
4.1 Darkstar Boot Class and Data Management
Project Darkstar requires a boot-strapping class to initialize the "game", (which
replaces the main() method). The WonderlandBoot? class serves this purpose
by implementing the Darkstar AppListener? interface and the initialize()
method. The implementation of this method performs some very basic tasks
which kick-starts the creation of the Wonderland world. They are:
- Create an instance of the UserManager? class which maintains the list of users (i.e. clients) which connect to the world.
- Create an instance of the MasterCellCacheGLO? class which maintains the list of classes which maintains the cache of cells visible to a user.
- Create an instance of the ChecksumManagerGLO? class which manages a series of checksums for classes representing assets in the world.
- Opens a communication channel named ChannelInfo?.USER_CHANGE which communicates changes in the client's status.
When a new client opens a connection to the wonderland server, the
WonderlandBoot?.loggedIn() method is invoked, which simply creates a new
instance of the WonderlandSessionListener? class. It is this class which
handles future changes in the state of the client, and in particular
creates the avatar when a user logs in.
4.2 Cell architecture
Project Wonderland employs the Project Darkstar gaming platform on the
server-side, where each cell is represented by a managed boject. The base
abstract class for all cell managed objects is the CellGLO? class. (The
suffix "GLO" is a hold-over from an earlier version of Project Darkstar
where managed objects were called "Game Logic Objects" (or GLOs)).
There are two types of cells in Wonderland: stationary cells and moveable
cells. Stationary cells represent regions which do not move, while moveable
cells represent graphics which do move. Avatars are the best (and perhaps
only) example of a moveable cell. All stationary cell classes extend
StationaryCellGLO? and all moveable cell classes extend MoveableCellGLO?.
Various stationary cells are defined within the Wonderland architecture.
The most basic is the "world root" cell (see WorldRootCellGLO? class) which
is the root of all cells in the world and is responsible for creating the
world. At present time, the WorldRootCellGLO? creates its world cells using
hard-coded lines of code. In the future, a more flexible architecture to
build worlds is planned.
Currently, the following stationary cells exist: simple terrain, slide show,
model viewer, animated, audio, and shared application. The only moveable
cell that is exists is the avatar cell.
The simple terrain (see SimpleTerrainCellGLO? class) cell is used to define
basic surroundings in the world, taking the name of an external file which
defines the geometry of the surroundings.
A slide show (see SlideShowCellGLO? class) cell is used to define a series of
images which will be shown in sequence, taking a file name pattern, whose
wild-card character ('%') will be expanded into a frame number. Images in
the sequence will be advanced via user input.
A model viewer (see ModelViewerCellGLO? class) cell needs further study. XXX
An animated (see AnimatedCellGLO? class) cell represents a series of images
which are animated in the world, taking an array of file names composing
the animation.
An audio (see AudioCellGLO? class) cell, an extension of the animated cell,
represents audio playing in the world eminating from a certain origin.
A shared application (see SharedApp2DCellGLO? class) represents an X Windows-
based application which is being displayed in the world and can be interacted
with by avatars.
4.3 Features of a Cell
All cells extend the CellGLO? class which provides most of the services
necessary for cells. Each cell has a unique ID, generated by a central
facility (see CellIDGenerator? class) and also a unique name formed as "CELL_"
plus ID. (see CellGLO?.getCellID() and CellGLO?.getGLOName() methods). A cell's
ID is simply a number encapsulated by the CellID? class.
4.3.1 Cell origin and bounds
Each cell's position within the world is defined by its origin, as specified
by a 4x4 matrix (see Java 3D's Matrix4d class; the Matrix4d class is used
in Java 3D to define general transformations, such as rotations, scalings,
translations, and shearings. There seems to be no fundamental limitation
why a cell's origin cannot be any combination of these transformations,
however, translations and rotations seem to be the only types used in
practice). A cell's origin is stored by the 'cellOrigin' member variable
and is set directly by all of the cell subclasses. The CellGLO?.getOrigin()
returns the Matrix4d class origin.
A cell also has a bounds, represented by the Java 3D Bounds class which
describes its physical extents. The subclasses of CellGLO? manage the cell's
bounds by overwriting the CellGLO?.getBounds() method.
4.3.2 Cell parents and children
A cell's set of zero or more children and parents are stored in hashed sets.
Adding and removing a parent cell is done via the CellGLO?.addParentCell() and
CellGLO?.removeParentCell() methods. The CellGLO?.getParentCellIDs() method
returns an array of CellID? classes of each of the registered parent cell. The
methods CellGLO?.addChildCell() and CellGLO?.removeChildCell() add and remove
children to and from the cell, respectively. The CellGLO?.getChildren() returns
a collection of children of the cell.
At any time, not all of a cell's children may be visible, which is conditioned
upon some visible bounds. The CellGLO?.getVisibleCells() method returns a
collection of children cells that are visible given a certain bounds. Typically
the visible bounds depends upon the viewing frustum of the avatar.
4.3.3 Inter-client communication via a cell
Cells also support a communication mechanism between clients, using the
Project Darkstar channel mechanism. Each cell can have a single communication
channel, identified by a unique name and created via CellGLO?.openCellChannel().
The CellGLO?.getCellChannel() method returns the channel. Users are added as
listeners to the channel via the CellGLO?.addUserToCellChannel() and removed
via the CellGLO?.removeUserFromCellChannel() methods. Each of these two methods
takes the unique id of the client server as arguments. See Section 6 below
regarding details of the client-server communication architecture in Project
Wonderland.
4.3.4 Client cell class and setup
Each cell type on the server has a corresponding cell class on the client
which is responsible for rendering the cell. The name of the corresponding
client cell class is defined by each of the individual cell subclasses which
implement the CellGLO?.getClientCellClassName() method.
The server cell class communicates its visual contents and other setup data
via the CellSetup? class, returned by the CellGLO?.getSetupData() method that
is implemented by each of the individual cell subclasses.
The CellSetup? class itself is simply an empty interface which extends the
java.io.Seriablizable interface so that it may be sent across the wire. Each
cell type defines its own sub-interface of the CellSetup? interface. Examples
include the AnimatedCellSetup?, AvatarCellSetup?, ModelViewerCellSetup?,
SharedApp2DCellSetup?, SimpleCellSetup?, and SlideShowCellSetup? classes. The
SimpleCellSetup? class is used, for example, by the simple terrain cell and
has methods which return the name of disk files storing the scene.
4.4 Server-side Cell Caching
The set of cells which should be currently kept in memory by the client is
managed by the server via the UserCellCacheGLO? class, an instance of this
class exists for each user (which is equivalent to saying "client") and
is created when the user logs in. All UserCellCacheGLO? classes are maintained
by the MasterCellCacheGLO? class. Both are managed objects within the Project
Darkstar infrastructure.
The server-side cell caches support several state changes to cells. They are:
cell created, root cell created, cell moved, cell deleted, and add parent to cell.
At the present time, the UserCellCacheGLO?.revalidate() method considers those
cells which are currently visible and add those cells which are new and deletes
from the client's memory those which are no longer visible. Changes in the
state of cells are communicated via a dedicated channel associated with the
UserCellCacheGLO? class. At the present, all of these types of messages are
serialized instances of the CellHierarchyMessage? class.
The visible cells are naturally determined by the position of the avatar, and
the its visible domain is determined by the AvatarBoundsManager? class and its
getProximityBounds() method which defines the visible area as a sphere of
a certain radius (AvatarBoundsManager?.PROXIMITY_SIZE = 200.0) from the center
of the avatar.
5. Client-side Architecture
5.1 The Main class
The Main class, as its name implies, implements the static main() method to
start-up the client. It initializes its user interface and reads in any
mutable configuration options from an external XML-formatted configuration
file.
The initialization of the connection with the server happens via the
StartupListener? class, which implements the Lg3dStartupListener? interface, from
Project Looking Glass -- this listener's startupComplete() method is invoked
when the initialization of the graphics is complete. In turn, the implementation
of the startupComplete() method displays a login dialog (see LoginDialog? class)
which accepts login information from the user. It initiates a connection to
the Wonderland server and invokes Main.enableMainWindow() to "turn on" the
Wonderland client.
All communications with the Darkstar-based Wonderland server are managed by the
ChannelController? class. A new connection to the server is initiated via the
ChannelController?.initCommunications() method. See Section 6 below for details
on the ChannelController? class.
5.2 Wonderland Universe
The "universe", as created by the WonderlandUniverseFactory?, creates the main
drawing canvas and initializes some basic viewing parameters. This class is
created by the WonderlandPlatformConfig? class, which in turn, is specified by
the lg.platformConfigClass property.
5.3 Scene Manager
Project Wonderland defines its own scene manager, the equivalent of an X Windows
window manager in Project Looking Glass. The WonderlandSceneManager? class extends
the LG3D? SceneManagerBase? class, an abstract class which implements the LG3D?
SceneManager? interface. The LG3D? SceneManagerBase? class handles communication with
the LG3D? display server (the moral equivalent of the X Windows Server) via its
implements of the LG3D? DisplayServerManagerInterface? interface.
The WonderlandSceneManager?.initialize() method contains the bulk of the functionality
of this class. It creates an instance of the WorldController? class with a base
Java 3D BranchGroup? class to which the WorldController? class will attach all of the
visual content. It also adds the instance of the Java 3D BranchGroup? class as a child
of the LG3D? display server's root.
The WonderlandSceneManager? class also creates an instance of an LG3D? StandardAppContainer?
class, using a null-style layout manager. The implementation of the
SceneManager?.addFrame3D() and SceneManager?.removeFrame3D() adds and removes frames to
and from the StandardAppContainer? class. The usage of this is currently unclear.
The WonderlandSceneManger? class is installed according to the LG3D? specification as
follows: the WonderlandConfigControl?.createSceneManager() class returns an instance of
the WonderlandSceneManager? class. The Main class sets the "lg.configclass" property
to "org.jdesktop.lg3d.wonderland.scenemanager.WonderlandConfigControl". (Additional
configuration information for the scene manager is also handled by the
WonderlandConfigControl? class, which reads an XML-formatted file of configuration
options, by default: "/org/jdesktop/lg3d/wonderland/scenemanager/resources/wonderland.lgcfg".)
5.4 World Controller
The WorldController? class handles all of the visible content in the Wonderland world.
As class members, it maintains instances of two important client-side classes:
UserCellCache? and ChannelController?. The WorldController? takes an argument a Java 3D
BranchGroup? to which it adds lighting: an ambient light of color RGB = {0.7, 0.7, 0.7},
and two directional lights. One directional light is white and is down-to-the-left. The
second directional light is RGB = {0.2, 0.2, 0.3} and is up-to-the-left. (TODO: What's
the effect of this lighting descriptively?)
Details of the UserCellCache? (section 5.4) and ChannelController? (section 5.x) classesare found below.
5.5 Client-Side Cell Caching
Visible cells are cached and maintained by the UserCellCache? class. The loading/unloading
of cells and changing their state is controlled entirely by the server through messages
send from the server to the client, formatted as instances of the CellHierarchyMessage?
class. The UserCellCache?.handleMessage() method handles these server events, sent over
a communication channel maintained by the Project Darkstar infrastructure and handled
by the UserCellCacheChannelListener? class.
A common operation, particular at boot-time, is the creation of new cells on the client
side via a message of type CellHierarchyMessage?.LOAD_CELL. Using the configuration
information embedded in the CellHiearchyMessage?, an instance of the client-side cell
class is create and initialized. The new cell is added to the HashMap? cache of cells,
and the thread (CellUpdateThread? class) is signalled to update the set of visible
cells to render (the UserCellCache?.visibleCells member variable).
The UserCellCache? class also manages the list of cells the avatar is current positioned
in via the UserCellCache?.avatarInCells member variable. This list is updated when the
CellUpdateThread? class is signalled that an update has occurred. Cell enter and exit
events are generated (as represented by the CellEnterEvent? and CellExitEvent? classes,
respectively) and posted.
The UserCellCache? class currently only implements a subset of the cell states: VISIBLE
and INACTIVE. The following cell states are currently not handled: ACTIVE, DISK, and
BOUNDS.
The UserCellCache? class also implements the UserMotionListener? interface which receives
notification when the avatar moves (via the userMoved() method). The implementation of
the UserCellCache?.userMoved() method is currently basic: it simply updates the status
of the visible cells and generates cell enter/exit messages using the updated position
of the avatar.
6. Client-Server Communication
This section outlines all of the communication channels and messages sent between the
Wonderland client and server.
6.1 Client-Server Direct Communication Channel
When a client connects to the server, a direct client-server communication channel is
automatically set up by Project Darkstar.
The server transmits the following messages to the client over this channel:
- An initial message giving the version of the communication protocol.
- Potentially error messages as ErrorMessage? classes.
- NativeApplicationMessage? messages in reply to a "create application cell" message.
The server receives the following messages from the client over this channel:
- NativeApplicationMessage? and SoftphoneMessage? messages from the client.
- AvatarSetupMessage? messages from the client
- CellMessage? messages from the client, dispatched to CellMessageListeners?.
6.2 Publish/Subscribe Communication Channels
The Wonderland server also creates publish/subscribe communication channels, which
include: USER_CHANGE, CELL_CACHE, AVATAR_P2P, AVATAR_TILE, and
SERVER_MANAGER_CHANNEL.
6.2.1 The USER_CHANGE channel
The USER_CHANGE communication channel, created by WonderlandBoot?, and all new clients
are automatically added to it.
The server transmits the following messages to the client over this channel:
- UserChangedMessage? messages when users are added (USER_ADD) or when users leave (USER_LEFT).
The server does not receive any messages from the client on this channel.
6.2.2 The CELL_CACHE channel
The server creates a CELL_CACHE channel for each client connected. The name of the
channel takes the form: user + CELL_CACHE, where 'user' is the name of the user. This
channel is created by the UserCellCacheGLO? class. All new clients are automatically
added to this channel.
The server transmits the following messages to the client over this channel:
- CellHiearchyMessage? messages, which are of the type: LOAD_CELL, MOVE_CELL, CELL_INACTIVE, ADD_PARENT, REMOVE_PARENT, SET_WORLD_ROOT, and DELETE_CELL.
The server does not receive any messages from the client on this channel.
6.2.3 The AVATAR_P2P channel
The server creates a AVATAR_P2P channel for each client connected. The name of the
channel takes the form: user + AVATAR_P2P, where 'user' is the name of the user.
This channel is created by the AvatarCellGLO? class. Clients request to be joined
to an avatar's P2P? channel via the AvatarCellMessage? (JOIN_P2P) message sent on
the AVATAR_TILE channel.
The server transmits the following messages to the client over this channel:
- AvatarP2PMessage?, which has three types: SETUP, MOVE, and CHAT.
The server does not receive any messages from the client on this channel.
6.2.4 The AVATAR_TILE channel
The AVATAR_TILE channel is created by the AvatarCellGLO? class. the name of the
channel takes the form: user + AVATAR_TILE, where 'user' is the name of the user.
The server transmits the following messages to the client over this channel:
- AvatarCellMessage?, which has one basic type: SETUP. When a cell first becomes visible.
When a cell becomes visible, the server steps through a list of all cells as
adds the client to the cell's channel if it exists. Currently, only the avatar
cell creates a channel for itself. At that point, a SETUP message is sent to
the client, which stores away the channel for future communication.
The server receives the following messages from the client over this channel:
- AvatarCellMessage?, which has four basic types: JOIN_P2P, CELL_MOVE, AVATAR_MOVE, CELL_ENTER, and CELL_EXIT.
6.2.5 The SERVER_MANAGER_CHANNEL channel
The SERVER_MANAGER_CHANNEL communication channel, created by the ServerManagerGLO?
class, is used to communication server management information to the client. Right
now, the server itself and a special client (hardcoded to name "ServerManager") are
added to this channel.
The server transmits and receives the following messages to the client over this channel:
- ServerManagerMessage?, which has four types: STATUS, FULL_STATUS, CHANGE_UPDATE_INTERVAL, and SET_USER_LIMIT.
7. Summary of Important Code Flow Sequences
This section summarizes the flow of control in the code for two aspects of Project
Wonderland: when a client first connects and when an avatar moves or changes its
look direction.
7.1. Sequence of Code when a Client First Connects
- The Main class creates the main window and adds an LG3D? Lg3dConnector? class to the main window. This, in turn, starts the LG3D? display server. Upon initialization, the L3GD? display server initializes the universe, windowing system, view, creates the root scene graph, and initializes the scene manager.
- The Wonderland Scene Manager creates a new WorldController? class, which creates a new instances of the ChannelController? and UserCellCache? classes.
- Upon completion of the LG3D? initialization, the StartupListener?.startupComplete() method is called which posts the Wonderland Login dialog.
- Upon user login confirmation, a connection to the Darkstar server is opened. The client waits for login confirmation, which is sent asynchronously via a call to WonderlandClientListener?.loggedIn().
- Upon login, the client sends an AvatarSetupMessage? message to the Darkstar server via its client-server communication mechanism with information about the avatar, such as its visual model.
- Upon the conclusion of login, the main window of the Wonderland client is enabled.
7.2 Sequence of Code upon Initialization of the Server
- The WonderlandBoot?.initialize() method creates new instances of the ServerManagerGLO?, UserManager?, MasterCellCacheGLO?, and ChecksumManagerGLO? classes. A publish/subscribe channel is also created named USER_CHANGE.
- The MasterCellCacheGLO? class creates a new WorldRootCellGLO? class. This calls the WorldRootCellGLO?.buildWorld() method which creates all of the cells in the world.
- The WonderlandSessionListener? class receives the AvatarSetupMessage? message from the client. It creates a new UserGLO? class.
- The UserGLO? class creates a new AvatarCellGLO? class, which in turn creates a new UserCellCacheGLO? object.
- The UserCellCacheGLO? class creates a publish/subscribe channel named user+CELL_CACHE, where 'user' is the name of the user.
- The AvatarCelLGLO? class then opens a publish/subscribe channel named AVATAR_P2P and a channel named user+AVATAR_TILE, where 'user' is the name of the user.
- The WonderlandSessionListener? then joins the client to the USER_CHANGE channel and sends a UserChangedMessage? (USER_ADDED) message to the client. It then calls the login() method on UserGLO?.
- The UserGLO?.login() method adds a reference of the user to the hash map relating user ID's to user object references. It calls AvatarCellGLO?.login().
- The AvatarCellGLO?.login() adds itself (the avatar's cell) to the MasterCellCacheGLO? class. It then calls UserCellCacheGLO?.login() which joins the client to the user+CELL_CACHE channel, adds a reference of itself to the MasterCellCacheGLO? class, and sends a CellHierarchyMessage? (LOAD_CELL) to the user+CELL_CACHE channel, and then sends a CellHiearchyMessage? (SET_WORLD_ROOT) to the user+CELL_CACHE channel.
- The UserGLO?.login() method then calls the UserCellCacheGLO?.avatarCellMoved() method, which computes the list of visible cells and sends CellHierarchyMessage? (LOAD_CELL) messages for all visible cells on the user+CELL_CACHE channel. It also sends CellHierarchyMessage? (DELETE_CELL or CELL_INACTIVE) messages for all newly non- visible cells on the user+CELL_CACHE channel.
- The WonderlandSessionListener? finally sends UserChangedMessage? messages to each of the clients via the USER_CHANGE channel to notify of the new client.
7.2 Sequence of Code when an Avatar Moves
In this code sequence we consider when the user presses one of the arrow buttons to move
the position of the avatar.
- The key event is handled by the WalkBehavior?.keyPressed() event. The Stimulus class is updated to reflect the key state change.
- The AvatarControlBehavior?.scheduleUpdate() method is called which tells it that pending updates to the avatar state exists.
- The AvatarControlBehavior?.processStimulus() method wakes up and calls the WalkBehavior?.updateState() method which updates the position state of the avatar.
- Collision detection is performed based upon the new position of the Avatar. The position of the camera is then updated.
- All UserMotionListeners? are notified of the new position of the avatar. One example of a UserMotionListener? is the UserCellCache? class, which calls UserCellCache?.updateCells() method. Another listener is the AvatarCell? class.
- The updateCells() method computes the visible cells based upon the user's viewing frustum. It updates the state of each cell and the list of visible cells. For all visible cells, it updates the list of cells the avatar is currently standing in. It sends CellEnterEvent? and CellExitEvents?, correspondingly within the LG3D? event framework. (At this time the AvatarCellMessage? CELL_ENTER and CELL_EXIT are not sent to the server, nor does the server take any action upon receiving these events.
- The AvatarCell?.userMoved() method sends a AvatarCellMessage? (AVATAR_MOVE & CELLMOVE) to the server via the AVATAR_TILE channel. The position of the avatar is updated on the server and the UserCellCacheGLO? is asked to revalidate itself (which computes the list of visible and invisible cells, updates its state, and informs the client of such).
8. Future Documentation Work
This software architecture document details just the basics of the Wonderland client-server
software. Noticeably absent is documentation on avatar's and their configuration and control
behavior, application sharing, and audio. |
|