Got cluster chat support working. Made it an invocation service rather

than a place service (which may be changed back when place services
improve or I may change the main chat stuff to be an invocation service).


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@803 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2001-12-16 21:02:18 +00:00
parent 4f716cd540
commit 1c02c2d6f4
6 changed files with 151 additions and 68 deletions
@@ -1,5 +1,5 @@
//
// $Id: SpotCodes.java,v 1.2 2001/12/14 23:12:39 mdb Exp $
// $Id: SpotCodes.java,v 1.3 2001/12/16 21:02:18 mdb Exp $
package com.threerings.whirled.spot.client;
@@ -41,6 +41,6 @@ public interface SpotCodes extends ChatCodes, SceneCodes
* generated by a failed changeLoc request. */
public static final String LOCATION_OCCUPIED = "m.location_occupied";
/** The message identifier for a cluster speak request message. */
public static final String CLUSTER_SPEAK_REQUEST = "cspkreq";
/** The message identifier for a cluster speak request. */
public static final String CLUSTER_SPEAK_REQUEST = "ClusterSpeak";
}
@@ -1,11 +1,18 @@
//
// $Id: SpotSceneDirector.java,v 1.4 2001/12/16 05:18:20 mdb Exp $
// $Id: SpotSceneDirector.java,v 1.5 2001/12/16 21:02:18 mdb Exp $
package com.threerings.whirled.spot.client;
import java.util.Iterator;
import com.samskivert.util.StringUtil;
import com.threerings.presents.dobj.DObject;
import com.threerings.presents.dobj.DObjectManager;
import com.threerings.presents.dobj.ObjectAccessException;
import com.threerings.presents.dobj.Subscriber;
import com.threerings.crowd.chat.ChatDirector;
import com.threerings.whirled.client.SceneDirector;
import com.threerings.whirled.data.SceneModel;
import com.threerings.whirled.util.WhirledContext;
@@ -19,7 +26,7 @@ import com.threerings.whirled.spot.data.Portal;
* locations within a scene.
*/
public class SpotSceneDirector
implements SpotCodes
implements SpotCodes, Subscriber
{
/**
* This is used to communicate back to the caller of {@link
@@ -52,6 +59,15 @@ public class SpotSceneDirector
_scdir = scdir;
}
/**
* Configures this spot scene director with a chat director, with
* which it will coordinate to implement cluster chatting.
*/
public void setChatDirector (ChatDirector chatdir)
{
_chatdir = chatdir;
}
/**
* Requests that this client move to the location specified by the
* supplied portal id. A request will be made and when the response is
@@ -157,21 +173,64 @@ public class SpotSceneDirector
locationId, this);
}
/**
* Sends a chat message to the other users in the cluster to which the
* location that we currently occupy belongs.
*/
public void requestClusterSpeak (String message)
{
// make sure we're currently in a scene
DisplaySpotScene scene = (DisplaySpotScene)_scdir.getScene();
if (scene == null) {
Log.warning("Requested to speak to cluster, but we're not " +
"currently in any scene [message=" + message + "].");
return;
}
// make sure we're in a location
if (_locationId > 0) {
SpotService.clusterSpeak(
_ctx.getClient(), scene.getId(), _locationId, message, this);
} else {
Log.info("Ignoring cluster speak as we're not in a location.");
}
}
/**
* Called in response to a successful <code>changeLoc</code> request.
*/
public void handleChangeLocSucceeded (int invid)
public void handleChangeLocSucceeded (int invid, int clusterOid)
{
ChangeObserver obs = _changeObserver;
int locId = _pendingLocId;
_locationId = _pendingLocId;
// clear out our pending location info
_pendingLocId = -1;
_changeObserver = null;
// determine if our cluster oid changed (which we only care about
// if we're doing cluster chat)
if (_chatdir != null) {
int oldOid = (_clobj == null) ? -1 : _clobj.getOid();
if (clusterOid != oldOid) {
DObjectManager omgr = _ctx.getDObjectManager();
// remove our old subscription if necessary
if (_clobj != null) {
_chatdir.removeAuxilliarySource(_clobj);
// unsubscribe from our old object
omgr.unsubscribeFromObject(_clobj.getOid(), this);
_clobj = null;
}
// create a new subscription (we'll wire it up to the chat
// director when the subscription completes
omgr.subscribeToObject(clusterOid, this);
}
}
// if we had an observer, let them know things went well
if (obs != null) {
obs.locationChangeSucceeded(locId);
obs.locationChangeSucceeded(_locationId);
}
}
@@ -193,16 +252,43 @@ public class SpotSceneDirector
}
}
// documentation inherited
public void objectAvailable (DObject object)
{
// we've got our cluster chat object, configure the chat director
// with it and keep a reference ourselves
if (_chatdir != null) {
_chatdir.addAuxilliarySource(object);
_clobj = object;
}
}
// documentation inherited
public void requestFailed (int oid, ObjectAccessException cause)
{
Log.warning("Unable to subscribe to cluster chat object " +
"[oid=" + oid + ",, cause=" + cause + "].");
}
/** The active client context. */
protected WhirledContext _ctx;
/** The scene director with which we are cooperating. */
protected SceneDirector _scdir;
/** A reference to the chat director with which we coordinate. */
protected ChatDirector _chatdir;
/** The location id of the location we currently occupy. */
protected int _locationId = -1;
/** The location id on which we have an outstanding change location
* request. */
protected int _pendingLocId = -1;
/** The cluster chat object for the cluster we currently occupy. */
protected DObject _clobj;
/** An entity that wants to know if a requested location change
* succeded or failed. */
protected ChangeObserver _changeObserver;
@@ -1,5 +1,5 @@
//
// $Id: SpotService.java,v 1.3 2001/12/16 05:18:20 mdb Exp $
// $Id: SpotService.java,v 1.4 2001/12/16 21:02:18 mdb Exp $
package com.threerings.whirled.spot.client;
@@ -48,4 +48,20 @@ public class SpotService implements SpotCodes
Log.info("Sent changeLoc request [sceneId=" + sceneId +
", locId=" + locationId + "].");
}
/**
* Requests that the supplied message be delivered to listeners in the
* cluster to which the specified location belongs.
*/
public static void clusterSpeak (
Client client, int sceneId, int locationId, String message,
SpotSceneDirector rsptarget)
{
InvocationDirector invdir = client.getInvocationDirector();
Object[] args = new Object[] {
new Integer(sceneId), new Integer(locationId), message };
invdir.invoke(MODULE_NAME, CLUSTER_SPEAK_REQUEST, args, rsptarget);
Log.info("Sent clusterSpeak request [sceneId=" + sceneId +
", locId=" + locationId + ", message=" + message + "].");
}
}
@@ -1,51 +0,0 @@
//
// $Id: ClusterChatMessageHandler.java,v 1.1 2001/12/14 00:12:32 mdb Exp $
package com.threerings.whirled.spot.server;
import com.threerings.presents.dobj.MessageEvent;
import com.threerings.crowd.data.BodyObject;
import com.threerings.crowd.data.PlaceObject;
import com.threerings.crowd.server.PlaceManager;
import com.threerings.whirled.server.WhirledServer;
import com.threerings.whirled.spot.Log;
/**
* The cluster chat message handler handles chat messages that are issued
* to the cluster associated with a particular location, with the
* intention of speaking only to bodies in that cluster.
*/
public class ClusterChatMessageHandler
implements PlaceManager.MessageHandler
{
/**
* Handles {@link SpotCodes#CLUSTER_SPEAK_REQUEST} messages.
*/
public void handleEvent (MessageEvent event, PlaceManager pmgr)
{
// presently we do no ratification of chat messages, so we just
// generate a chat notification with the message and name of the
// speaker
int soid = event.getSourceOid();
BodyObject source = (BodyObject)WhirledServer.omgr.getObject(soid);
if (source == null) {
Log.info("Chatter went away. Dropping cluster chat request " +
"[req=" + event + "].");
return;
}
// parse our incoming arguments
Object[] inargs = event.getArgs();
int reqid = ((Integer)inargs[0]).intValue();
int locid = ((Integer)inargs[1]).intValue();
String message = (String)inargs[2];
// pass this request on to the spot scene manager as it will need
// to check that the location exists and that the requester
// occupies it and so on
((SpotSceneManager)pmgr).handleClusterChatRequest(
source, locid, message);
}
}
@@ -1,5 +1,5 @@
//
// $Id: SpotProvider.java,v 1.4 2001/12/16 05:38:26 mdb Exp $
// $Id: SpotProvider.java,v 1.5 2001/12/16 21:02:18 mdb Exp $
package com.threerings.whirled.spot.server;
@@ -200,8 +200,9 @@ public class SpotProvider extends InvocationProvider
throw new ServiceFailedException(INTERNAL_ERROR);
}
smgr.handleChangeLocRequest(source, locationId);
sendResponse(source, invid, CHANGE_LOC_SUCCEEDED_RESPONSE);
int locOid = smgr.handleChangeLocRequest(source, locationId);
sendResponse(source, invid, CHANGE_LOC_SUCCEEDED_RESPONSE,
new Integer(locOid));
} catch (ServiceFailedException sfe) {
sendResponse(source, invid, CHANGE_LOC_FAILED_RESPONSE,
@@ -209,6 +210,29 @@ public class SpotProvider extends InvocationProvider
}
}
/**
* Handles {@link SpotCodes#CLUSTER_SPEAK_REQUEST} messages.
*/
public void handleClusterSpeakRequest (
BodyObject source, int invid, int sceneId, int locId, String message)
{
// look up the scene manager for the specified scene
SpotSceneManager smgr = (SpotSceneManager)
_screg.getSceneManager(sceneId);
if (smgr == null) {
Log.warning("User requested cluster chat in " +
"non-existent scene [user=" + source.username +
", sceneId=" + sceneId + ", locId=" + locId +
", message=" + message + "].");
} else {
// pass this request on to the spot scene manager as it will
// need to check that the location exists and that the
// requester occupies it and so on
smgr.handleClusterSpeakRequest(source, locId, message);
}
}
/**
* Looks up the specified place object, obtains the occupant info for
* the specified body object and updates the location id in said
@@ -1,5 +1,5 @@
//
// $Id: SpotSceneManager.java,v 1.3 2001/12/16 08:07:53 mdb Exp $
// $Id: SpotSceneManager.java,v 1.4 2001/12/16 21:02:18 mdb Exp $
package com.threerings.whirled.spot.server;
@@ -110,11 +110,15 @@ public class SpotSceneManager extends SceneManager
* Called by the {@link SpotProvider} when we receive a request by a
* user to occupy a particular location.
*
* @return the oid of the chat object associated with the cluster to
* which this location belongs or -1 if the location is not part of a
* cluster.
*
* @exception ServiceFailedException thrown with a reason code
* explaining the location change failure if there is a problem
* processing the location change request.
*/
protected void handleChangeLocRequest (BodyObject source, int locationId)
protected int handleChangeLocRequest (BodyObject source, int locationId)
throws ServiceFailedException
{
// make sure no one is already in the requested location
@@ -154,13 +158,17 @@ public class SpotSceneManager extends SceneManager
soi.locationId = locationId;
// and broadcast the update to the place
_plobj.updateOccupantInfo(soi);
// figure out the cluster chat oid
int clusterIdx = _sscene.getClusterIndex(locidx);
return (clusterIdx == -1) ? -1 : _clusterOids[clusterIdx];
}
/**
* Called by the {@link ClusterChatMessageHandler} when we receive a
* cluster chat request.
* Called by the {@link SpotProvider} when we receive a cluster speak
* request.
*/
protected void handleClusterChatRequest (
protected void handleClusterSpeakRequest (
BodyObject source, int locationId, String message)
{
// make sure this user occupies the specified location