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:
Michael Bayne
2002-06-20 22:14:58 +00:00
parent cb14ec144c
commit eb3a4909d6
2 changed files with 154 additions and 11 deletions
@@ -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;
}
}