Have the ZoneRegistry implement ZoneService instead of using a concrete

provider. Other injection and cleanup.


git-svn-id: svn+ssh://src.earth.threerings.net/vilya/trunk@640 c613c5cb-e716-0410-b11b-feb51c14d237
This commit is contained in:
Michael Bayne
2008-06-29 14:18:10 +00:00
parent 10bdbaa2f3
commit d3b227a13b
3 changed files with 126 additions and 153 deletions
@@ -25,6 +25,7 @@ import com.threerings.presents.server.InvocationException;
import com.threerings.crowd.data.BodyObject;
import com.threerings.crowd.data.PlaceConfig;
import com.threerings.crowd.server.LocationManager;
import com.threerings.whirled.client.SceneService;
import com.threerings.whirled.data.SceneModel;
@@ -33,7 +34,6 @@ import com.threerings.whirled.server.AbstractSceneMoveHandler;
import com.threerings.whirled.server.SceneManager;
import com.threerings.whirled.server.SceneMoveHandler;
import com.threerings.whirled.server.SceneRegistry;
import com.threerings.whirled.server.WhirledServer;
import com.threerings.whirled.zone.client.ZoneService;
import com.threerings.whirled.zone.data.ZoneCodes;
@@ -48,11 +48,13 @@ import static com.threerings.whirled.zone.Log.log;
public class ZoneMoveHandler extends AbstractSceneMoveHandler
implements ZoneManager.ResolutionListener
{
public ZoneMoveHandler (ZoneManager zmgr, BodyObject body, int sceneId, int sceneVer,
public ZoneMoveHandler (LocationManager locmgr, ZoneManager zmgr, SceneRegistry screg,
BodyObject body, int sceneId, int sceneVer,
ZoneService.ZoneMoveListener listener)
{
super(body, listener);
super(locmgr, body, listener);
_zmgr = zmgr;
_screg = screg;
_sceneId = sceneId;
_version = sceneVer;
}
@@ -69,7 +71,7 @@ public class ZoneMoveHandler extends AbstractSceneMoveHandler
_summary = summary;
// now resolve the target scene
WhirledServer.screg.resolveScene(_sceneId, this);
_screg.resolveScene(_sceneId, this);
}
// from interface ZoneManager.ResolutionListener
@@ -85,7 +87,7 @@ public class ZoneMoveHandler extends AbstractSceneMoveHandler
{
// move to the place object associated with this scene
int ploid = scmgr.getPlaceObject().getOid();
PlaceConfig config = WhirledServer.locman.moveTo(_body, ploid);
PlaceConfig config = _locman.moveTo(_body, ploid);
// now that we've moved, we can update the user object with the new scene and zone ids
_body.startTransaction();
@@ -114,6 +116,7 @@ public class ZoneMoveHandler extends AbstractSceneMoveHandler
}
protected ZoneManager _zmgr;
protected SceneRegistry _screg;
protected int _sceneId, _version;
protected ZoneSummary _summary;
}
@@ -22,148 +22,18 @@
package com.threerings.whirled.zone.server;
import com.threerings.presents.data.ClientObject;
import com.threerings.presents.data.InvocationMarshaller;
import com.threerings.presents.server.InvocationException;
import com.threerings.presents.server.InvocationProvider;
import com.threerings.crowd.data.BodyObject;
import com.threerings.crowd.data.PlaceConfig;
import com.threerings.crowd.data.PlaceObject;
import com.threerings.crowd.server.LocationProvider;
import com.threerings.whirled.data.SceneModel;
import com.threerings.whirled.data.SceneUpdate;
import com.threerings.whirled.server.SceneManager;
import com.threerings.whirled.server.SceneRegistry;
import com.threerings.whirled.zone.client.ZoneService.ZoneMoveListener;
import com.threerings.whirled.zone.data.ZoneCodes;
import com.threerings.whirled.zone.data.ZoneSummary;
import com.threerings.whirled.zone.data.ZonedBodyObject;
import static com.threerings.whirled.zone.Log.log;
import com.threerings.whirled.zone.client.ZoneService;
/**
* Provides zone related services which are presently the ability to move from zone to zone.
* Defines the server-side of the {@link ZoneService}.
*/
public class ZoneProvider
implements ZoneCodes, InvocationProvider
public interface ZoneProvider extends InvocationProvider
{
/**
* Constructs a zone provider that will interoperate with the supplied zone and scene
* registries. The zone provider will automatically be constructed and registered by the {@link
* ZoneRegistry}, which a zone-using system must create and initialize in their server.
* Handles a {@link ZoneService#moveTo} request.
*/
public ZoneProvider (LocationProvider locprov, ZoneRegistry zonereg, SceneRegistry screg)
{
_locprov = locprov;
_zonereg = zonereg;
_screg = screg;
}
/**
* Processes a request from a client to move to a scene in a new zone.
*
* @param caller the user requesting the move.
* @param zoneId the qualified zone id of the new zone.
* @param sceneId the identifier of the new scene.
* @param sceneVer the version of the scene model currently held by the client.
* @param listener the entity to inform of success or failure.
*/
public void moveTo (ClientObject caller, int zoneId, int sceneId,
int sceneVer, ZoneMoveListener listener)
throws InvocationException
{
if (!(caller instanceof ZonedBodyObject)) {
log.warning("Request to switch zones by non-ZonedBodyObject " +
"[clobj=" + caller.getClass() + "].");
throw new InvocationException(INTERNAL_ERROR);
}
// look up the caller's current zone id and make sure it is happy about their departure
// from the current zone
BodyObject body = (BodyObject)caller;
ZoneManager ozmgr = _zonereg.getZoneManager(((ZonedBodyObject)caller).getZoneId());
if (ozmgr != null) {
String msg = ozmgr.ratifyBodyExit(body);
if (msg != null) {
throw new InvocationException(msg);
}
}
// look up the zone manager for the zone
ZoneManager zmgr = _zonereg.getZoneManager(zoneId);
if (zmgr == null) {
log.warning("Requested to enter a zone for which we have no manager " +
"[user=" + body.who() + ", zoneId=" + zoneId + "].");
throw new InvocationException(NO_SUCH_ZONE);
}
// resolve the zone and move the user
zmgr.resolveZone(zoneId, new ZoneMoveHandler(
zmgr, (BodyObject)caller, sceneId, sceneVer, listener));
}
/**
* Ejects the specified body from their current scene and sends them a request to move to the
* specified new zone and scene. This is the zone-equivalent to {@link
* LocationProvider#moveBody}.
*
* @return null if the user was forcibly moved, or a string indicating the reason for denial of
* departure of their current zone (from {@link ZoneManager#ratifyBodyExit}).
*/
public String moveBody (ZonedBodyObject source, int zoneId, int sceneId)
{
if (source.getZoneId() == zoneId) {
// handle the case of moving somewhere in the same zone
_screg.moveBody((BodyObject) source, sceneId);
} else {
// first remove them from their old location
String reason = leaveOccupiedZone(source);
if (reason != null) {
return reason;
}
// then send a forced move notification
ZoneSender.forcedMove((BodyObject)source, zoneId, sceneId);
}
return null;
}
/**
* Ejects the specified body from their current scene and zone. This is the zone equivalent to
* {@link LocationProvider#leaveOccupiedPlace}.
*
* @return null if the user was forcibly moved, or a string indicating the reason for denial of
* departure of their current zone (from {@link ZoneManager#ratifyBodyExit}).
*/
public String leaveOccupiedZone (ZonedBodyObject source)
{
// look up the caller's current zone id and make sure it is happy about their departure
// from the current zone
ZoneManager zmgr = _zonereg.getZoneManager(source.getZoneId());
String msg;
if (zmgr != null &&
(msg = zmgr.ratifyBodyExit((BodyObject)source)) != null) {
return msg;
}
// remove them from their occupied scene
_screg.leaveOccupiedScene((BodyObject)source);
// and clear out their zone information
source.setZoneId(-1);
return null;
}
/** The entity that handles basic location changes. */
protected LocationProvider _locprov;
/** The zone registry with which we communicate. */
protected ZoneRegistry _zonereg;
/** The scene registry with which we communicate. */
protected SceneRegistry _screg;
public void moveTo (ClientObject caller, int arg1, int arg2, int arg3, ZoneService.ZoneMoveListener arg4)
throws InvocationException;
}
@@ -21,14 +21,23 @@
package com.threerings.whirled.zone.server;
import com.samskivert.util.HashIntMap;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.samskivert.util.IntMap;
import com.samskivert.util.IntMaps;
import com.threerings.presents.data.ClientObject;
import com.threerings.presents.server.InvocationException;
import com.threerings.presents.server.InvocationManager;
import com.threerings.crowd.data.BodyObject;
import com.threerings.crowd.server.LocationManager;
import com.threerings.whirled.server.SceneRegistry;
import com.threerings.whirled.zone.client.ZoneService;
import com.threerings.whirled.zone.data.ZoneCodes;
import com.threerings.whirled.zone.data.ZonedBodyObject;
import com.threerings.whirled.zone.util.ZoneUtil;
import static com.threerings.whirled.zone.Log.log;
@@ -37,19 +46,16 @@ import static com.threerings.whirled.zone.Log.log;
* The zone registry takes care of mapping zone requests to the appropriate registered zone
* manager.
*/
@Singleton
public class ZoneRegistry
implements ZoneProvider
{
/** Implements the server-side of the zone-related services. */
public ZoneProvider zoneprov;
/**
* Creates a zone manager with the supplied configuration.
*/
public ZoneRegistry (InvocationManager invmgr, LocationManager locman, SceneRegistry screg)
@Inject public ZoneRegistry (InvocationManager invmgr)
{
// create a zone provider and register it with the invocation services
zoneprov = new ZoneProvider(locman, this, screg);
invmgr.registerDispatcher(new ZoneDispatcher(zoneprov), ZoneCodes.WHIRLED_GROUP);
invmgr.registerDispatcher(new ZoneDispatcher(this), ZoneCodes.WHIRLED_GROUP);
}
/**
@@ -60,7 +66,7 @@ public class ZoneRegistry
*/
public void registerZoneManager (byte zoneType, ZoneManager manager)
{
ZoneManager old = (ZoneManager)_managers.get(zoneType);
ZoneManager old = _managers.get(zoneType);
if (old != null) {
log.warning("Zone manager already registered with requested type [type=" + zoneType +
", old=" + old + ", new=" + manager + "].");
@@ -76,10 +82,104 @@ public class ZoneRegistry
*/
public ZoneManager getZoneManager (int qualifiedZoneId)
{
int zoneType = ZoneUtil.zoneType(qualifiedZoneId);
return (ZoneManager)_managers.get(zoneType);
return _managers.get(ZoneUtil.zoneType(qualifiedZoneId));
}
/**
* Ejects the specified body from their current scene and sends them a request to move to the
* specified new zone and scene. This is the zone-equivalent to {@link
* LocationProvider#moveBody}.
*
* @return null if the user was forcibly moved, or a string indicating the reason for denial of
* departure of their current zone (from {@link ZoneManager#ratifyBodyExit}).
*/
public String moveBody (ZonedBodyObject source, int zoneId, int sceneId)
{
if (source.getZoneId() == zoneId) {
// handle the case of moving somewhere in the same zone
_screg.moveBody((BodyObject) source, sceneId);
} else {
// first remove them from their old location
String reason = leaveOccupiedZone(source);
if (reason != null) {
return reason;
}
// then send a forced move notification
ZoneSender.forcedMove((BodyObject)source, zoneId, sceneId);
}
return null;
}
/**
* Ejects the specified body from their current scene and zone. This is the zone equivalent to
* {@link LocationProvider#leaveOccupiedPlace}.
*
* @return null if the user was forcibly moved, or a string indicating the reason for denial of
* departure of their current zone (from {@link ZoneManager#ratifyBodyExit}).
*/
public String leaveOccupiedZone (ZonedBodyObject source)
{
// look up the caller's current zone id and make sure it is happy about their departure
// from the current zone
ZoneManager zmgr = getZoneManager(source.getZoneId());
String msg;
if (zmgr != null &&
(msg = zmgr.ratifyBodyExit((BodyObject)source)) != null) {
return msg;
}
// remove them from their occupied scene
_screg.leaveOccupiedScene((BodyObject)source);
// and clear out their zone information
source.setZoneId(-1);
return null;
}
// from interface ZoneProvider
public void moveTo (ClientObject caller, int zoneId, int sceneId,
int sceneVer, ZoneService.ZoneMoveListener listener)
throws InvocationException
{
if (!(caller instanceof ZonedBodyObject)) {
log.warning("Request to switch zones by non-ZonedBodyObject " +
"[clobj=" + caller.getClass() + "].");
throw new InvocationException(ZoneCodes.INTERNAL_ERROR);
}
// look up the caller's current zone id and make sure it is happy about their departure
// from the current zone
BodyObject body = (BodyObject)caller;
ZoneManager ozmgr = getZoneManager(((ZonedBodyObject)caller).getZoneId());
if (ozmgr != null) {
String msg = ozmgr.ratifyBodyExit(body);
if (msg != null) {
throw new InvocationException(msg);
}
}
// look up the zone manager for the zone
ZoneManager zmgr = getZoneManager(zoneId);
if (zmgr == null) {
log.warning("Requested to enter a zone for which we have no manager " +
"[user=" + body.who() + ", zoneId=" + zoneId + "].");
throw new InvocationException(ZoneCodes.NO_SUCH_ZONE);
}
// resolve the zone and move the user
zmgr.resolveZone(zoneId, new ZoneMoveHandler(_locman, zmgr, _screg, (BodyObject)caller,
sceneId, sceneVer, listener));
}
/** A table of zone managers. */
protected HashIntMap _managers = new HashIntMap();
protected IntMap<ZoneManager> _managers = IntMaps.newHashIntMap();
/** Provides access to scene managers by scene. */
@Inject protected SceneRegistry _screg;
/** Provides location services. */
@Inject protected LocationManager _locman;
}