More location management progress.

git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@116 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2001-07-23 22:59:43 +00:00
parent b4d5f76c70
commit 3e5060c7c5
3 changed files with 160 additions and 5 deletions
+2
View File
@@ -8,6 +8,8 @@ Implement object destroyed; finish wiring up oid list tracking.
Ensure at time of OBJECT_ADDED that the object being added exists and has Ensure at time of OBJECT_ADDED that the object being added exists and has
not been destroyed. not been destroyed.
clientWillLogff becomes clientMayLogoff?
* Server-side event concentrator * Server-side event concentrator
The client objects will not subscribe directly, but will subscribe through The client objects will not subscribe directly, but will subscribe through
the concentrator so that, at least, it can create a single the concentrator so that, at least, it can create a single
@@ -1,13 +1,17 @@
// //
// $Id: LocationDirector.java,v 1.3 2001/07/23 21:14:27 mdb Exp $ // $Id: LocationDirector.java,v 1.4 2001/07/23 22:59:43 mdb Exp $
package com.threerings.cocktail.party.client; package com.threerings.cocktail.party.client;
import java.util.ArrayList;
import java.util.List;
import com.threerings.cocktail.cher.client.*; import com.threerings.cocktail.cher.client.*;
import com.threerings.cocktail.cher.dobj.*; import com.threerings.cocktail.cher.dobj.*;
import com.threerings.cocktail.party.Log; import com.threerings.cocktail.party.Log;
import com.threerings.cocktail.party.data.BodyObject; import com.threerings.cocktail.party.data.BodyObject;
import com.threerings.cocktail.party.data.PlaceObject;
import com.threerings.cocktail.party.util.PartyContext; import com.threerings.cocktail.party.util.PartyContext;
/** /**
@@ -18,7 +22,7 @@ import com.threerings.cocktail.party.util.PartyContext;
* before actually issuing the request. * before actually issuing the request.
*/ */
public class LocationManager public class LocationManager
implements ClientObserver implements ClientObserver, Subscriber
{ {
public LocationManager (PartyContext ctx) public LocationManager (PartyContext ctx)
{ {
@@ -36,6 +40,33 @@ public class LocationManager
*/ */
public void moveTo (int placeId) public void moveTo (int placeId)
{ {
// first check to see if our observers are happy with this move
// request
for (int i = 0; i < _observers.size(); i++) {
LocationObserver obs = (LocationObserver)_observers.get(i);
if (!obs.locationMayChange(placeId)) {
Log.info("Location change vetoed by observer " +
"[pid=" + placeId + ", obs=" + obs + "].");
return;
}
}
// complain if we're over-writing a pending request
if (_pendingPlaceId != -1) {
Log.warning("We appear to have a moveTo request outstanding " +
"[ppid=" + _pendingPlaceId +
", npid=" + placeId + "].");
// but we're going to fall through and do it anyway because
// refusing to switch rooms at this point will inevitably
// result in some strange bug causing a move request to be
// dropped by the server and the client that did it to be
// totally hosed because they can no longer move to new
// locations because they still have an outstanding request
}
// make a note of our pending place id
_pendingPlaceId = placeId;
// issue a moveTo request // issue a moveTo request
LocationService.moveTo(_ctx.getClient(), placeId, this); LocationService.moveTo(_ctx.getClient(), placeId, this);
} }
@@ -98,7 +129,21 @@ public class LocationManager
*/ */
public void handleMoveSucceeded () public void handleMoveSucceeded ()
{ {
Log.info("Move succeeded."); DObjectManager omgr = _ctx.getDObjectManager();
// unsubscribe from our old place object
if (_place != null) {
omgr.unsubscribeFromObject(_place.getOid(), this);
_place = null;
}
// make a note that we're now mostly in the new location
_previousPlaceId = _placeId;
_placeId = _pendingPlaceId;
_pendingPlaceId = -1;
// subscribe to our new place object to complete the move
omgr.subscribeToObject(_placeId, this);
} }
/** /**
@@ -106,8 +151,78 @@ public class LocationManager
*/ */
public void handleMoveFailed (String reason) public void handleMoveFailed (String reason)
{ {
Log.info("Move failed [reason=" + reason + "]."); // clear out our pending request oid
int placeId = _pendingPlaceId;
_pendingPlaceId = -1;
// let our observers know that something has gone horribly awry
notifyFailure(placeId, reason);
} }
public void objectAvailable (DObject object)
{
// yay, we have our new place object
_place = (PlaceObject)object;
// let our observers know that all is well on the western front
for (int i = 0; i < _observers.size(); i++) {
LocationObserver obs = (LocationObserver)_observers.get(i);
obs.locationDidChange(_place);
}
}
public void requestFailed (int oid, ObjectAccessException cause)
{
// aiya! we were unable to fetch our new place object; something
// is badly wrong
Log.warning("Aiya! Unable to fetch place object for new location " +
"[plid=" + oid + ", reason=" + cause + "].");
// clear out our half initialized place info
int placeId = _placeId;
_placeId = -1;
// let the kids know shit be fucked
notifyFailure(placeId, "m.unable_to_fetch_place_object");
// if we were previously somewhere, try going back there
if (_previousPlaceId != -1) {
moveTo(_previousPlaceId);
}
}
public boolean handleEvent (DEvent event, DObject target)
{
// nothing to do here, but remain subscribed
return true;
}
protected void notifyFailure (int placeId, String reason)
{
for (int i = 0; i < _observers.size(); i++) {
LocationObserver obs = (LocationObserver)_observers.get(i);
obs.locationChangeFailed(placeId, reason);
}
}
/** The context through which we access needed services. */
protected PartyContext _ctx; protected PartyContext _ctx;
/** Our location observer list. */
protected List _observers = new ArrayList();
/** The oid of the place we currently occupy. */
protected int _placeId = -1;
/** The place object that we currently occupy. */
protected PlaceObject _place;
/**
* The oid of the place for which we have an outstanding moveTo
* request, or -1 if we have no outstanding request.
*/
protected int _pendingPlaceId = -1;
/** The oid of the place we previously occupied. */
protected int _previousPlaceId = -1;
} }
@@ -1,8 +1,46 @@
// //
// $Id: LocationObserver.java,v 1.1 2001/07/20 20:07:37 mdb Exp $ // $Id: LocationObserver.java,v 1.2 2001/07/23 22:59:43 mdb Exp $
package com.threerings.cocktail.party.client; package com.threerings.cocktail.party.client;
import com.threerings.cocktail.party.data.PlaceObject;
/**
* The location observer interface makes it possible for entities to be
* notified when the client moves to a new location. It also provides a
* means for an entity to participate in the ratification process of a new
* location. Observers may opt to reject a request to change to a new
* location, probably because something is going on in the previous
* location that should not be abandoned.
*
* <p> Note that these location callbacks occur on the main thread and
* should execute quickly and not block under any circumstance.
*/
public interface LocationObserver public interface LocationObserver
{ {
/**
* Called when someone has requested that we switch to a new location.
* An observer may choose to veto the location change request for some
* reason or other.
*/
public boolean locationMayChange (int placeId);
/**
* Called when we have switched to a new location.
*
* @param place the place object that represents the new location or
* null if we have switched to no location.
*/
public void locationDidChange (PlaceObject place);
/**
* This is called on all location observers when a location change
* request is rejected by the server or fails for some other reason.
*
* @param placeId the place id to which we attempted to relocate, but
* failed.
* @param reason the reason code that explains why the location change
* request was rejected or otherwise failed.
*/
public void locationChangeFailed (int placeId, String reason);
} }