Perception Messaging
From Multiverse
| Multiverse Servers |
|
Installing • Installing on Linux • Running • Troubleshooting • FAQ • Release Notes • Updating • JMX Monitoring & Mgmt. |
| Infrastructure |
|
Platform Architecture • Registering a World • Proxy Server • Event Handling • World Manager • Voice Server |
| Messaging System |
|
Perception Messaging • Using Extension Messages • Message Marshalling • Multi-subject Messaging • Message Catalog |
| Object Architecture |
|
World Instancing • Server Object Search • Server Regions • Server Markers |
| Scalability and Performance |
| Reference |
|
File Layout • Property File • Logging • API |
Contents |
Overview
The Multiverse perception system controls what objects can perceive ("see") in the world. The perception system is exercised hundreds of times a second in a busy world, so efficiency is important. The world manager quad tree plays an important role in making the system fast. Also important is the communication of perception information from the world manager to the client and other plugins. The server uses custom perception messaging to make this as efficient as possible.
Perception messaging is implemented by three classes:
-
multiverse.server.messages.PerceptionMessage
ThePerceptionMessagecommunicates perception changes for a single object. The message contains a list of gained objects (newly perceived) and lost objects (no longer perceivable). -
multiverse.server.messages.PerceptionFilter
ThePerceptionFilteris used by the subscriber to get perception messages for some set of objects (the target set). The filter is also used to get other messages for the target objects, and for objects perceived by those targets (the subject set). -
multiverse.server.messages.PerceptionTrigger
ThePerceptionTriggerautomatically updates aPerceptionFiltersubject set to keep it in-sync with the set of object perceivable by the filter's target set.
As of Multiverse 1.1, perception messaging is used by the proxy plugin and the ObjectTracker.
PerceptionMessage
The PerceptionMessage Javadoc contains a good description of the information contained in
a PerceptionMessage. However, it does not describe the "object info" returned by ObjectNote.getObjectInfo().
If you subscribe to WorldManagerClient.MSG_TYPE_PERCEPTION then the object info is null. If you
subscribe to WorldManagerClient.MSG_TYPE_PERCEPTION_INFO, then the object info is a
WorldManagerClient.PerceptionInfo
The PerceptionInfo contains a WorldManagerClient.ObjectInfo and optionally, a DisplayContext. The ObjectInfo contains basic world information such as name, object type, location, direction, and orientation.
PerceptionFilter
Creating a PerceptionFilter subscription is the first step in using perception messaging. The
PerceptionFilter message types should include one of WorldManagerClient.MSG_TYPE_PERCEPTION or
WorldManagerClient.MSG_TYPE_PERCEPTION_INFO. Set the filter's target set to the object you
want to track. If the target set changes, add or remove the targets from the filter using
addTarget() or removeTarget(). If these methods return true, then
you should apply a FilterUpdate to the subscription to notify publishers of the target set change.
The subscription should be created with a
PerceptionTrigger instance if you want more than just the perception messages. For example,
if you want location updates for the perceived objects, then add WorldManagerClient.MSG_TYPE_UPDATEWNODE
to the filter's message types. The PerceptionTrigger will cause the world manager to keep the
PerceptionFilter's subject set in-sync with the union of objects perceived by the filter's
target set. Note that this is only done on the world manager's copy of the PerceptionFilter.
The PerceptionFilter in the subscriber's process will have an empty subject set. You could
keep the subject set updated manually, but it's easier to just call PerceptionFilter.setMatchAllSubjects(true) on the subscriber. This setting
is transient; it's not replicated when the subscription if forwarded.
The preceding description applies if the additional message types only originate from the world manager. The example uses MSG_TYPE_UPDATEWNODE which should only be published by the world manager. If you add message types originating from other plugins, then extra work is needed to keep their filter's subject set in-sync with the world manager's subject set. The subscriber should apply a filter update to the subscription when the subject set changes. The subscriber will need to track the subject set via PerceptionMessage gains and losses and only apply a FilterUpdate when a subject is first perceived by any target or when a subject is no longer perceived by any target.
PerceptionTrigger
The PerceptionTrigger doesn't have any configuration or require any manipulation. Simply instantiate one when creating a PerceptionFilter subscription.
PerceptionUpdateTrigger
The PerceptionUpdateTrigger gives you a means to run code just before and after a remote PerceptionFilter receives a FilterUpdate. The trigger is called once for each FilterUpdate instruction.
The set of PerceptionUpdateTriggers is global for a process.
PerceptionUpdateTriggers implement the following interface:
public interface PerceptionUpdateTrigger
{
public void preUpdate(PerceptionFilter filter,
FilterUpdate.Instruction instruction,
AgentHandle sender,
SubscriptionHandle sub);
public void postUpdate(PerceptionFilter filter,
FilterUpdate.Instruction instruction,
AgentHandle sender,
SubscriptionHandle sub);
}
preUpdate() is called once for each FilterUpdate instruction before any of the instructions have been applied. postUpdate() is called once for each FilterUpdate instruction after all of the instructions have been applied.
The sender is the agent who sent the FilterUpdate. The sub is the filter's subscription. These values can be used with the method MessageAgent.sendDirect(message,sender,sub)
Simple example
Simple perception messaging example. Monitor the location of objects perceived by some set of objects. Contains methods to dynamically change the set of perceiving objects.
import java.util.ArrayList;
import multiverse.msgsys.*;
import multiverse.server.messages.*;
import multiverse.server.plugins.WorldManagerClient;
import multiverse.server.engine.Engine;
/** Simple perception messaging example. Monitor the location of
objects perceived by some set of objects. Contains methods to
dynamically change the set of perceiving objects.
*/
public class PerceptionExample implements MessageCallback
{
public PerceptionExample()
{
perceptionFilter = new PerceptionFilter();
perceptionFilter.addType(WorldManagerClient.MSG_TYPE_PERCEPTION);
perceptionFilter.addType(WorldManagerClient.MSG_TYPE_UPDATEWNODE);
perceptionFilter.setMatchAllSubjects(true);
PerceptionTrigger perceptionTrigger = new PerceptionTrigger();
perceptionSubId = Engine.getAgent().createSubscription(
perceptionFilter, this, MessageAgent.NO_FLAGS, perceptionTrigger);
}
public synchronized void addObjectMonitoring(long oid) {
if (perceptionFilter.addTarget(oid)) {
FilterUpdate filterUpdate = new FilterUpdate(1);
filterUpdate.addFieldValue(PerceptionFilter.FIELD_TARGETS,
new Long(oid));
Engine.getAgent().applyFilterUpdate(perceptionSubId,
filterUpdate);
}
}
public synchronized void removeObjectMonitoring(long oid) {
if (perceptionFilter.removeTarget(oid)) {
FilterUpdate filterUpdate = new FilterUpdate(1);
filterUpdate.removeFieldValue(PerceptionFilter.FIELD_TARGETS,
new Long(oid));
Engine.getAgent().applyFilterUpdate(perceptionSubId,
filterUpdate);
}
}
public void handleMessage(Message msg, int flags) {
if (msg.getMsgType() == WorldManagerClient.MSG_TYPE_PERCEPTION) {
handlePerception((PerceptionMessage)msg);
}
else if (msg.getMsgType() == WorldManagerClient.MSG_TYPE_UPDATEWNODE) {
handleUpdateWorldNode((WorldManagerClient.UpdateWorldNodeMessage)msg);
}
}
void handlePerception(PerceptionMessage message)
{
}
void handleUpdateWorldNode(
WorldManagerClient.UpdateWorldNodeMessage message)
{
}
PerceptionFilter perceptionFilter;
PerceptionTrigger perceptionTrigger;
long perceptionSubId;
}
