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.BodyObject;
import com.threerings.crowd.data.PlaceConfig; import com.threerings.crowd.data.PlaceConfig;
import com.threerings.crowd.server.LocationManager;
import com.threerings.whirled.client.SceneService; import com.threerings.whirled.client.SceneService;
import com.threerings.whirled.data.SceneModel; 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.SceneManager;
import com.threerings.whirled.server.SceneMoveHandler; import com.threerings.whirled.server.SceneMoveHandler;
import com.threerings.whirled.server.SceneRegistry; import com.threerings.whirled.server.SceneRegistry;
import com.threerings.whirled.server.WhirledServer;
import com.threerings.whirled.zone.client.ZoneService; import com.threerings.whirled.zone.client.ZoneService;
import com.threerings.whirled.zone.data.ZoneCodes; import com.threerings.whirled.zone.data.ZoneCodes;
@@ -48,11 +48,13 @@ import static com.threerings.whirled.zone.Log.log;
public class ZoneMoveHandler extends AbstractSceneMoveHandler public class ZoneMoveHandler extends AbstractSceneMoveHandler
implements ZoneManager.ResolutionListener 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) ZoneService.ZoneMoveListener listener)
{ {
super(body, listener); super(locmgr, body, listener);
_zmgr = zmgr; _zmgr = zmgr;
_screg = screg;
_sceneId = sceneId; _sceneId = sceneId;
_version = sceneVer; _version = sceneVer;
} }
@@ -69,7 +71,7 @@ public class ZoneMoveHandler extends AbstractSceneMoveHandler
_summary = summary; _summary = summary;
// now resolve the target scene // now resolve the target scene
WhirledServer.screg.resolveScene(_sceneId, this); _screg.resolveScene(_sceneId, this);
} }
// from interface ZoneManager.ResolutionListener // from interface ZoneManager.ResolutionListener
@@ -85,7 +87,7 @@ public class ZoneMoveHandler extends AbstractSceneMoveHandler
{ {
// move to the place object associated with this scene // move to the place object associated with this scene
int ploid = scmgr.getPlaceObject().getOid(); 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 // now that we've moved, we can update the user object with the new scene and zone ids
_body.startTransaction(); _body.startTransaction();
@@ -114,6 +116,7 @@ public class ZoneMoveHandler extends AbstractSceneMoveHandler
} }
protected ZoneManager _zmgr; protected ZoneManager _zmgr;
protected SceneRegistry _screg;
protected int _sceneId, _version; protected int _sceneId, _version;
protected ZoneSummary _summary; protected ZoneSummary _summary;
} }
@@ -22,148 +22,18 @@
package com.threerings.whirled.zone.server; package com.threerings.whirled.zone.server;
import com.threerings.presents.data.ClientObject; import com.threerings.presents.data.ClientObject;
import com.threerings.presents.data.InvocationMarshaller;
import com.threerings.presents.server.InvocationException; import com.threerings.presents.server.InvocationException;
import com.threerings.presents.server.InvocationProvider; import com.threerings.presents.server.InvocationProvider;
import com.threerings.whirled.zone.client.ZoneService;
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;
/** /**
* 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 public interface ZoneProvider extends InvocationProvider
implements ZoneCodes, InvocationProvider
{ {
/** /**
* Constructs a zone provider that will interoperate with the supplied zone and scene * Handles a {@link ZoneService#moveTo} request.
* 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.
*/ */
public ZoneProvider (LocationProvider locprov, ZoneRegistry zonereg, SceneRegistry screg) public void moveTo (ClientObject caller, int arg1, int arg2, int arg3, ZoneService.ZoneMoveListener arg4)
{ throws InvocationException;
_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;
} }
@@ -21,14 +21,23 @@
package com.threerings.whirled.zone.server; 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.presents.server.InvocationManager;
import com.threerings.crowd.data.BodyObject;
import com.threerings.crowd.server.LocationManager; import com.threerings.crowd.server.LocationManager;
import com.threerings.whirled.server.SceneRegistry; 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.ZoneCodes;
import com.threerings.whirled.zone.data.ZonedBodyObject;
import com.threerings.whirled.zone.util.ZoneUtil; import com.threerings.whirled.zone.util.ZoneUtil;
import static com.threerings.whirled.zone.Log.log; 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 * The zone registry takes care of mapping zone requests to the appropriate registered zone
* manager. * manager.
*/ */
@Singleton
public class ZoneRegistry 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. * 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 invmgr.registerDispatcher(new ZoneDispatcher(this), ZoneCodes.WHIRLED_GROUP);
zoneprov = new ZoneProvider(locman, this, screg);
invmgr.registerDispatcher(new ZoneDispatcher(zoneprov), ZoneCodes.WHIRLED_GROUP);
} }
/** /**
@@ -60,7 +66,7 @@ public class ZoneRegistry
*/ */
public void registerZoneManager (byte zoneType, ZoneManager manager) public void registerZoneManager (byte zoneType, ZoneManager manager)
{ {
ZoneManager old = (ZoneManager)_managers.get(zoneType); ZoneManager old = _managers.get(zoneType);
if (old != null) { if (old != null) {
log.warning("Zone manager already registered with requested type [type=" + zoneType + log.warning("Zone manager already registered with requested type [type=" + zoneType +
", old=" + old + ", new=" + manager + "]."); ", old=" + old + ", new=" + manager + "].");
@@ -76,10 +82,104 @@ public class ZoneRegistry
*/ */
public ZoneManager getZoneManager (int qualifiedZoneId) public ZoneManager getZoneManager (int qualifiedZoneId)
{ {
int zoneType = ZoneUtil.zoneType(qualifiedZoneId); return _managers.get(ZoneUtil.zoneType(qualifiedZoneId));
return (ZoneManager)_managers.get(zoneType); }
/**
* 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. */ /** 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;
} }