Moved getUnoccupiedLocation() into SpotSceneManager; created SpotSceneUtil
which contains the routines to do it; modified said routines to allow them to be called with the internal location tracking array maintained by the spot scene manager because that is the only thing guaranteed to be truly up to date; made use of where() in spot scene manager's log messages. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1517 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
//
|
||||
// $Id: SpotSceneManager.java,v 1.9 2002/06/19 23:22:51 ray Exp $
|
||||
// $Id: SpotSceneManager.java,v 1.10 2002/06/20 22:14:58 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.spot.server;
|
||||
|
||||
import com.samskivert.util.IntIntMap;
|
||||
import com.samskivert.util.IntListUtil;
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.presents.dobj.DObject;
|
||||
import com.threerings.presents.dobj.Subscriber;
|
||||
@@ -20,6 +21,7 @@ import com.threerings.whirled.spot.Log;
|
||||
import com.threerings.whirled.spot.data.SpotCodes;
|
||||
import com.threerings.whirled.spot.data.SpotOccupantInfo;
|
||||
import com.threerings.whirled.spot.data.SpotSceneModel;
|
||||
import com.threerings.whirled.spot.util.SpotSceneUtil;
|
||||
|
||||
/**
|
||||
* Handles the movement of bodies between locations in the scene and
|
||||
@@ -49,6 +51,17 @@ public class SpotSceneManager extends SceneManager
|
||||
_entering.remove(bodyOid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the locationId of an unoccupied location in this scene
|
||||
* (portals are not included when selecting). If no locations are
|
||||
* unoccupied, this method returns -1.
|
||||
*/
|
||||
public int getUnoccupiedLocation (boolean preferClusters)
|
||||
{
|
||||
return SpotSceneUtil.getUnoccupiedLocation(
|
||||
_sscene.getModel(), _locationOccs, preferClusters);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected void gotSceneData ()
|
||||
{
|
||||
@@ -68,8 +81,8 @@ public class SpotSceneManager extends SceneManager
|
||||
|
||||
public void requestFailed (int oid, ObjectAccessException cause) {
|
||||
Log.warning("Failed to create cluster object " +
|
||||
"[cluster=" + _index + ", oid=" + oid +
|
||||
", cause=" + cause + "].");
|
||||
"[where=" + where() + ", cluster=" + _index +
|
||||
", oid=" + oid + ", cause=" + cause + "].");
|
||||
// skip to the next cluster in case others didn't fail
|
||||
_index++;
|
||||
}
|
||||
@@ -134,8 +147,13 @@ public class SpotSceneManager extends SceneManager
|
||||
int locidx = _sscene.getLocationIndex(locationId);
|
||||
if (locidx == -1 || _locationOccs[locidx] != 0) {
|
||||
Log.info("Ignoring request to change to occupied or " +
|
||||
"non-existent location [user=" + source.username +
|
||||
", locId=" + locationId + ", locidx=" + locidx + "].");
|
||||
"non-existent location [where=" + where() +
|
||||
", user=" + source.username +
|
||||
", locId=" + locationId + ", locidx=" + locidx +
|
||||
", lococcs=" + StringUtil.toString(_locationOccs) +
|
||||
", occinfo=" + StringUtil.listToString(
|
||||
_plobj.occupantInfo.entries(),
|
||||
SpotOccupantInfo.OIDS_AND_LOCS) + "].");
|
||||
throw new ServiceFailedException(LOCATION_OCCUPIED);
|
||||
}
|
||||
|
||||
@@ -145,7 +163,8 @@ public class SpotSceneManager extends SceneManager
|
||||
_plobj.occupantInfo.get(new Integer(bodyOid));
|
||||
if (soi == null) {
|
||||
Log.warning("Aiya! Can't update non-existent occupant info " +
|
||||
"with new location [body=" + source + "].");
|
||||
"with new location [where=" + where() +
|
||||
", body=" + source + "].");
|
||||
throw new ServiceFailedException(INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
@@ -155,7 +174,7 @@ public class SpotSceneManager extends SceneManager
|
||||
if (oldlocidx == -1) {
|
||||
Log.warning("Changing location for body that was " +
|
||||
"previously in an invalid location " +
|
||||
"[info=" + soi + "].");
|
||||
"[where=" + where() + ", info=" + soi + "].");
|
||||
} else {
|
||||
_locationOccs[oldlocidx] = 0;
|
||||
}
|
||||
@@ -164,7 +183,15 @@ public class SpotSceneManager extends SceneManager
|
||||
// stick our new friend into that location, if it's not a portal
|
||||
if (!_isPortal[locidx]) {
|
||||
_locationOccs[locidx] = bodyOid;
|
||||
Log.info("Putting user in location [where=" + where() +
|
||||
", boid=" + source.getOid() +
|
||||
", locId=" + locationId + "].");
|
||||
} else {
|
||||
Log.info("Putting user on portal [where=" + where() +
|
||||
", boid=" + source.getOid() +
|
||||
", locId=" + locationId + "].");
|
||||
}
|
||||
|
||||
// update a clone of their occupant info, we need to clone because
|
||||
// the original could still be in the queue as part of another
|
||||
// event going out to the clients.
|
||||
@@ -190,7 +217,8 @@ public class SpotSceneManager extends SceneManager
|
||||
int locidx = _sscene.getLocationIndex(locationId);
|
||||
if (locidx == -1 || _locationOccs[locidx] != sourceOid) {
|
||||
Log.warning("User not in specified location for CCREQ " +
|
||||
"[body=" + source + ", locId=" + locationId +
|
||||
"[where=" + where() + ", body=" + source +
|
||||
", locId=" + locationId + ", locidx=" + locidx +
|
||||
", message=" + message + "].");
|
||||
return;
|
||||
}
|
||||
@@ -199,7 +227,8 @@ public class SpotSceneManager extends SceneManager
|
||||
int clusterIndex = _sscene.getClusterIndex(locidx);
|
||||
if (clusterIndex == -1) {
|
||||
Log.warning("User in clusterless location sent CCREQ " +
|
||||
"[body=" + source + ", locId=" + locationId +
|
||||
"[where=" + where() + ", body=" + source +
|
||||
", locId=" + locationId +
|
||||
", message=" + message + "].");
|
||||
return;
|
||||
}
|
||||
@@ -211,8 +240,8 @@ public class SpotSceneManager extends SceneManager
|
||||
|
||||
} else {
|
||||
Log.warning("Have no cluster object for CCREQ " +
|
||||
"[cidx=" + clusterIndex + ", chatter=" + source +
|
||||
", message=" + message + "].");
|
||||
"[where=" + where() + ", cidx=" + clusterIndex +
|
||||
", chatter=" + source + ", message=" + message + "].");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
//
|
||||
// $Id: SpotSceneUtil.java,v 1.1 2002/06/20 22:14:58 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.spot.util;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.samskivert.util.ArrayIntSet;
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.util.RandomUtil;
|
||||
|
||||
import com.threerings.presents.dobj.DSet;
|
||||
import com.threerings.whirled.spot.data.SpotOccupantInfo;
|
||||
import com.threerings.whirled.spot.data.SpotSceneModel;
|
||||
|
||||
/**
|
||||
* Spot scene utility functions shared by client and server.
|
||||
*/
|
||||
public class SpotSceneUtil
|
||||
{
|
||||
/**
|
||||
* Returns the locationId of an unoccupied location in the supplied
|
||||
* scene (portals are not included when selecting). If no locations
|
||||
* are unoccupied, this method returns -1.
|
||||
*
|
||||
* @param preferClusters if true, cluster locations (if any are empty)
|
||||
* will be preferred.
|
||||
*/
|
||||
public static int getUnoccupiedLocation (
|
||||
SpotSceneModel model, DSet occupantInfo, boolean preferClusters)
|
||||
{
|
||||
ArrayIntSet locs = getStartSet(model, preferClusters);
|
||||
|
||||
// remove any occupied locations
|
||||
Iterator iter = occupantInfo.entries();
|
||||
while (iter.hasNext()) {
|
||||
SpotOccupantInfo yoi = (SpotOccupantInfo)iter.next();
|
||||
locs.remove(yoi.locationId);
|
||||
}
|
||||
|
||||
// if there are locations left, pick one at random
|
||||
int size = locs.size();
|
||||
if (size > 0) {
|
||||
return locs.get(RandomUtil.getInt(size));
|
||||
|
||||
} else if (preferClusters) {
|
||||
// retry without the preference
|
||||
return getUnoccupiedLocation(model, occupantInfo, false);
|
||||
|
||||
} else {
|
||||
return -1; // we didn't find anything.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the locationId of an unoccupied location in the supplied
|
||||
* scene (portals are not included when selecting). If no locations
|
||||
* are unoccupied, this method returns -1.
|
||||
*
|
||||
* @param preferClusters if true, cluster locations (if any are empty)
|
||||
* will be preferred.
|
||||
*/
|
||||
public static int getUnoccupiedLocation (
|
||||
SpotSceneModel model, int[] occupiedLocs, boolean preferClusters)
|
||||
{
|
||||
ArrayIntSet locs = getStartSet(model, preferClusters);
|
||||
|
||||
// remove any occupied locations
|
||||
for (int ii = 0; ii < model.locationIds.length; ii++) {
|
||||
if (occupiedLocs[ii] != 0) {
|
||||
locs.remove(model.locationIds[ii]);
|
||||
}
|
||||
}
|
||||
|
||||
// if there are locations left, pick one at random
|
||||
int size = locs.size();
|
||||
if (size > 0) {
|
||||
return locs.get(RandomUtil.getInt(size));
|
||||
|
||||
} else if (preferClusters) {
|
||||
// retry without the preference
|
||||
return getUnoccupiedLocation(model, occupiedLocs, false);
|
||||
|
||||
} else {
|
||||
return -1; // we didn't find anything.
|
||||
}
|
||||
}
|
||||
|
||||
/** Used by {@link #getUnoccupiedLocation}. */
|
||||
protected static ArrayIntSet getStartSet (
|
||||
SpotSceneModel model, boolean preferClusters)
|
||||
{
|
||||
ArrayIntSet locs = new ArrayIntSet();
|
||||
|
||||
if (preferClusters) {
|
||||
// only add locations with a valid cluster Id
|
||||
for (int ii=0; ii < model.locationIds.length; ii++) {
|
||||
if (model.locationClusters[ii] != 0) {
|
||||
locs.add(model.locationIds[ii]);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// start with all the locations in the scene
|
||||
locs.add(model.locationIds);
|
||||
|
||||
// remove the portals
|
||||
locs.remove(model.portalIds);
|
||||
}
|
||||
|
||||
return locs;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user