More progress on table services (can leave a table, things start correctly
now, and much much more). git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@529 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: ParlorCodes.java,v 1.8 2001/10/23 02:22:16 mdb Exp $
|
||||
// $Id: ParlorCodes.java,v 1.9 2001/10/23 20:23:29 mdb Exp $
|
||||
|
||||
package com.threerings.parlor.client;
|
||||
|
||||
@@ -80,6 +80,14 @@ public interface ParlorCodes extends InvocationCodes
|
||||
* TableManager#handleJoinFailed}. */
|
||||
public static final String JOIN_FAILED_RESPONSE = "JoinFailed";
|
||||
|
||||
/** The message identifier for a leave table request. */
|
||||
public static final String LEAVE_TABLE_REQUEST = "LeaveTable";
|
||||
|
||||
/** The response identifier for a leave failed response. This is
|
||||
* mapped by the invocation services to a call to {@link
|
||||
* TableManager#handleLeaveFailed}. */
|
||||
public static final String LEAVE_FAILED_RESPONSE = "LeaveFailed";
|
||||
|
||||
/** An error code returned when a user requests to join a table that
|
||||
* doesn't exist. */
|
||||
public static final String NO_SUCH_TABLE = "m.no_such_table";
|
||||
@@ -93,4 +101,8 @@ public interface ParlorCodes extends InvocationCodes
|
||||
* position that is already occupied. */
|
||||
public static final String TABLE_POSITION_OCCUPIED =
|
||||
"m.table_position_occupied";
|
||||
|
||||
/** An error code returned when a user requests to leave a table that
|
||||
* they were not sitting at in the first place. */
|
||||
public static final String NOT_AT_TABLE = "m.not_at_table";
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: ParlorService.java,v 1.8 2001/10/23 02:22:16 mdb Exp $
|
||||
// $Id: ParlorService.java,v 1.9 2001/10/23 20:23:29 mdb Exp $
|
||||
|
||||
package com.threerings.parlor.client;
|
||||
|
||||
@@ -156,4 +156,28 @@ public class ParlorService implements ParlorCodes
|
||||
return invdir.invoke(
|
||||
MODULE_NAME, JOIN_TABLE_REQUEST, args, rsptarget);
|
||||
}
|
||||
|
||||
/**
|
||||
* You probably don't want to call this directly, but want to call
|
||||
* {@link TableManager#leaveTable}. Requests that the current user
|
||||
* be removed from the specified table.
|
||||
*
|
||||
* @param client a connected, operational client instance.
|
||||
* @param tableId the unique id of the table from which this user
|
||||
* wishes to be removed.
|
||||
* @param rsptarget the object reference that will receive and process
|
||||
* the response.
|
||||
*
|
||||
* @return the invocation request id of the generated request.
|
||||
*/
|
||||
public static int leaveTable (
|
||||
Client client, int tableId, Object rsptarget)
|
||||
{
|
||||
InvocationDirector invdir = client.getInvocationDirector();
|
||||
Object[] args = new Object[] { new Integer(tableId) };
|
||||
Log.info("Sending leave table request " +
|
||||
"[tableId=" + tableId + "].");
|
||||
return invdir.invoke(
|
||||
MODULE_NAME, LEAVE_TABLE_REQUEST, args, rsptarget);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// $Id: SeatednessObserver.java,v 1.1 2001/10/23 20:23:29 mdb Exp $
|
||||
|
||||
package com.threerings.parlor.client;
|
||||
|
||||
/**
|
||||
* Entites that wish to hear about when we sit down at a table or stand up
|
||||
* from a table can implement this interface and register themselves with
|
||||
* the {@link TableManager}.
|
||||
*/
|
||||
public interface SeatednessObserver
|
||||
{
|
||||
/**
|
||||
* Called when this client sits down at or stands up from a table.
|
||||
*
|
||||
* @param isSeated true if the client is now seated at a table, false
|
||||
* if they are now no longer seated at a table.
|
||||
*/
|
||||
public void seatednessDidChange (boolean isSeated);
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
//
|
||||
// $Id: TableDirector.java,v 1.1 2001/10/23 02:22:16 mdb Exp $
|
||||
// $Id: TableDirector.java,v 1.2 2001/10/23 20:23:29 mdb Exp $
|
||||
|
||||
package com.threerings.parlor.client;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.threerings.presents.dobj.ElementAddedEvent;
|
||||
import com.threerings.presents.dobj.ElementUpdatedEvent;
|
||||
import com.threerings.presents.dobj.ElementRemovedEvent;
|
||||
@@ -86,6 +88,35 @@ public class TableManager
|
||||
_lobby = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the specified observer be added to the list of
|
||||
* observers that are notified when this client sits down at or stands
|
||||
* up from a table.
|
||||
*/
|
||||
public void addSeatednessObserver (SeatednessObserver observer)
|
||||
{
|
||||
_seatedObservers.add(observer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the specified observer be removed from to the list of
|
||||
* observers that are notified when this client sits down at or stands
|
||||
* up from a table.
|
||||
*/
|
||||
public void removeSeatednessObserver (SeatednessObserver observer)
|
||||
{
|
||||
_seatedObservers.remove(observer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this client is currently seated at a table, false
|
||||
* if they are not.
|
||||
*/
|
||||
public boolean isSeated ()
|
||||
{
|
||||
return (_ourTable != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a request to create a table with the specified game
|
||||
* configuration. This user will become the owner of this table and
|
||||
@@ -139,15 +170,35 @@ public class TableManager
|
||||
_ctx.getClient(), tableId, position, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a request to leave the specified table at which we are
|
||||
* presumably seated. The response will be communicated via the {@link
|
||||
* TableObserver} interface.
|
||||
*/
|
||||
public void leaveTable (int tableId)
|
||||
{
|
||||
// make sure we're currently in a place
|
||||
if (_lobby == null) {
|
||||
Log.warning("Requested to leave a table but we're not " +
|
||||
"currently in a place [tableId=" + tableId + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
// go ahead and issue the create request
|
||||
ParlorService.leaveTable(_ctx.getClient(), tableId, this);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void elementAdded (ElementAddedEvent event)
|
||||
{
|
||||
if (event.getName().equals(_tableField)) {
|
||||
Table table = (Table)event.getElement();
|
||||
_observer.tableAdded(table);
|
||||
|
||||
// check to see if we just joined a table
|
||||
checkForOurTable(table);
|
||||
checkSeatedness(table);
|
||||
|
||||
// now let the observer know what's up
|
||||
_observer.tableAdded(table);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,10 +207,12 @@ public class TableManager
|
||||
{
|
||||
if (event.getName().equals(_tableField)) {
|
||||
Table table = (Table)event.getElement();
|
||||
_observer.tableUpdated(table);
|
||||
|
||||
// check to see if we just joined or left a table
|
||||
checkForOurTable(table);
|
||||
checkSeatedness(table);
|
||||
|
||||
// now let the observer know what's up
|
||||
_observer.tableUpdated(table);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,12 +221,15 @@ public class TableManager
|
||||
{
|
||||
if (event.getName().equals(_tableField)) {
|
||||
Integer tableId = (Integer)event.getKey();
|
||||
_observer.tableRemoved(tableId.intValue());
|
||||
|
||||
// check to see if our table just disappeared
|
||||
if (_ourTable != null && tableId.equals(_ourTable.tableId)) {
|
||||
_ourTable = null;
|
||||
notifySeatedness(false);
|
||||
}
|
||||
|
||||
// now let the observer know what's up
|
||||
_observer.tableRemoved(tableId.intValue());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,8 +273,10 @@ public class TableManager
|
||||
* Checks to see if we're a member of this table and notes it as our
|
||||
* table, if so.
|
||||
*/
|
||||
protected void checkForOurTable (Table table)
|
||||
protected void checkSeatedness (Table table)
|
||||
{
|
||||
Table oldTable = _ourTable;
|
||||
|
||||
// if this is the same table as our table, clear out our table
|
||||
// reference and allow it to be added back if we are still in the
|
||||
// table
|
||||
@@ -231,7 +289,35 @@ public class TableManager
|
||||
for (int i = 0; i < table.occupants.length; i++) {
|
||||
if (self.username.equals(table.occupants[i])) {
|
||||
_ourTable = table;
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if nothing changed, bail now
|
||||
if (oldTable == _ourTable ||
|
||||
(oldTable != null && oldTable.equals(_ourTable))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise notify the observers
|
||||
notifySeatedness(_ourTable != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the seatedness observers of a seatedness change.
|
||||
*/
|
||||
protected void notifySeatedness (boolean isSeated)
|
||||
{
|
||||
int slength = _seatedObservers.size();
|
||||
for (int i = 0; i < slength; i++) {
|
||||
SeatednessObserver observer = (SeatednessObserver)
|
||||
_seatedObservers.get(i);
|
||||
try {
|
||||
observer.seatednessDidChange(isSeated);
|
||||
} catch (Exception e) {
|
||||
Log.warning("Observer choked in seatednessDidChange() " +
|
||||
"[observer=" + observer + "].");
|
||||
Log.logStackTrace(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -250,4 +336,8 @@ public class TableManager
|
||||
|
||||
/** The table of which we are a member if any. */
|
||||
protected Table _ourTable;
|
||||
|
||||
/** An array of entities that want to hear about when we stand up or
|
||||
* sit down. */
|
||||
protected ArrayList _seatedObservers = new ArrayList();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: Table.java,v 1.4 2001/10/23 02:22:16 mdb Exp $
|
||||
// $Id: Table.java,v 1.5 2001/10/23 20:23:29 mdb Exp $
|
||||
|
||||
package com.threerings.parlor.data;
|
||||
|
||||
@@ -31,7 +31,7 @@ public class Table
|
||||
|
||||
/** The oid of the game that was created from this table or -1 if the
|
||||
* table is still in matchmaking mode. */
|
||||
public int gameOid;
|
||||
public int gameOid = -1;
|
||||
|
||||
/** An array of the usernames of the occupants of this table (some
|
||||
* slots may not be filled. */
|
||||
@@ -143,13 +143,66 @@ public class Table
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the specified user be removed from their seat at this
|
||||
* table.
|
||||
*
|
||||
* @return true if the user was seated at the table and has now been
|
||||
* removed, false if the user was never seated at the table in the
|
||||
* first place.
|
||||
*/
|
||||
public boolean clearOccupant (String username)
|
||||
{
|
||||
for (int i = 0; i < occupants.length; i++) {
|
||||
if (username.equals(occupants[i])) {
|
||||
occupants[i] = "";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this table has occupants in all of the desired
|
||||
* positions and should be started.
|
||||
*/
|
||||
public boolean readyToStart ()
|
||||
{
|
||||
return false;
|
||||
int need = _tconfig.getMinimumPlayers();
|
||||
if (need == -1) {
|
||||
need = _tconfig.getMaximumPlayers();
|
||||
}
|
||||
|
||||
// make sure the first "need" players are filled in
|
||||
for (int i = 0; i < need; i++) {
|
||||
if (StringUtil.blank(occupants[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if there is no one sitting at this table.
|
||||
*/
|
||||
public boolean isEmpty ()
|
||||
{
|
||||
for (int i = 0; i < occupants.length; i++) {
|
||||
if (!StringUtil.blank(occupants[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this table is in play, false if it is still being
|
||||
* matchmade.
|
||||
*/
|
||||
public boolean inPlay ()
|
||||
{
|
||||
return gameOid != -1;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
@@ -174,8 +227,8 @@ public class Table
|
||||
throws IOException
|
||||
{
|
||||
tableId = new Integer(in.readInt());
|
||||
gameOid = in.readInt();
|
||||
lobbyOid = in.readInt();
|
||||
gameOid = in.readInt();
|
||||
occupants = (String[])ValueMarshaller.readFrom(in);
|
||||
config = (GameConfig)ValueMarshaller.readFrom(in);
|
||||
_tconfig = (TableConfig)config;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: TableConfig.java,v 1.1 2001/10/19 02:04:29 mdb Exp $
|
||||
// $Id: TableConfig.java,v 1.2 2001/10/23 20:23:29 mdb Exp $
|
||||
|
||||
package com.threerings.parlor.data;
|
||||
|
||||
@@ -27,4 +27,9 @@ public interface TableConfig
|
||||
* creator any time after the minimum number of players has arrived.
|
||||
*/
|
||||
public int getDesiredPlayers ();
|
||||
|
||||
/**
|
||||
* Sets the desired number of players to the specified value.
|
||||
*/
|
||||
public void setDesiredPlayers (int desiredPlayers);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: ParlorManager.java,v 1.13 2001/10/23 02:22:17 mdb Exp $
|
||||
// $Id: ParlorManager.java,v 1.14 2001/10/23 20:23:29 mdb Exp $
|
||||
|
||||
package com.threerings.parlor.server;
|
||||
|
||||
@@ -208,9 +208,9 @@ public class ParlorManager
|
||||
* will be created.
|
||||
*
|
||||
* @param creator the body object that will own the new table.
|
||||
* @param placeOid the place object id of the place (lobby) in which
|
||||
* this table should be created. The place object specified must
|
||||
* implement the {@link TableLobbyObject} interface.
|
||||
* @param lobbyOid the place object id of the lobby in which this
|
||||
* table should be created. The place object specified must implement
|
||||
* the {@link TableLobbyObject} interface.
|
||||
* @param config the configuration of the game to be created.
|
||||
*
|
||||
* @return the id of the newly created table.
|
||||
@@ -219,26 +219,26 @@ public class ParlorManager
|
||||
* not able processed for some reason. The explanation will be
|
||||
* provided in the message data of the exception.
|
||||
*/
|
||||
public int createTable (BodyObject creator, int placeOid,
|
||||
public int createTable (BodyObject creator, int lobbyOid,
|
||||
GameConfig config)
|
||||
throws ServiceFailedException
|
||||
{
|
||||
// fetch the place object in which we'll be creating a table
|
||||
try {
|
||||
TableLobbyObject tlobj = (TableLobbyObject)
|
||||
CrowdServer.omgr.getObject(placeOid);
|
||||
CrowdServer.omgr.getObject(lobbyOid);
|
||||
|
||||
// make sure the game config implements TableConfig
|
||||
if (!(config instanceof TableConfig)) {
|
||||
Log.warning("Requested to matchmake a non-table game " +
|
||||
"using the table services [creator=" + creator +
|
||||
", ploid=" + placeOid +
|
||||
", loboid=" + lobbyOid +
|
||||
", config=" + config + "].");
|
||||
throw new ServiceFailedException(INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
// create a brand spanking new table
|
||||
Table table = new Table(placeOid, config);
|
||||
Table table = new Table(lobbyOid, config);
|
||||
|
||||
// stick the creator into position zero
|
||||
String error = table.setOccupant(0, creator.username);
|
||||
@@ -261,7 +261,7 @@ public class ParlorManager
|
||||
|
||||
} catch (ClassCastException cce) {
|
||||
Log.warning("Requested to create table in non-table-lobby " +
|
||||
"[creator=" + creator + ", ploid=" + placeOid +
|
||||
"[creator=" + creator + ", loboid=" + lobbyOid +
|
||||
", config=" + config + ", cce=" + cce + "].");
|
||||
throw new ServiceFailedException(INTERNAL_ERROR);
|
||||
}
|
||||
@@ -282,11 +282,9 @@ public class ParlorManager
|
||||
* @param tableId the id of the table to be joined.
|
||||
* @param position the position at which to join the table.
|
||||
*
|
||||
* @return the id of the newly created table.
|
||||
*
|
||||
* @exception ServiceFailedException thrown if the table creation was
|
||||
* not able processed for some reason. The explanation will be
|
||||
* provided in the message data of the exception.
|
||||
* @exception ServiceFailedException thrown if the joining was not
|
||||
* able processed for some reason. The explanation will be provided in
|
||||
* the message data of the exception.
|
||||
*/
|
||||
public void joinTable (BodyObject joiner, int tableId, int position)
|
||||
throws ServiceFailedException
|
||||
@@ -330,6 +328,60 @@ public class ParlorManager
|
||||
tlobj.updateTables(table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the specified user be removed from the specified
|
||||
* table. If the user successfully leaves the table, the function will
|
||||
* return normally. If they are not able to leave for some reason
|
||||
* (they aren't sitting at the table, etc.), a {@link
|
||||
* ServiceFailedException} will be thrown with a message code that
|
||||
* describes the reason for failure.
|
||||
*
|
||||
* @param leaver the body object of the user that wishes to leave the
|
||||
* table.
|
||||
* @param tableId the id of the table to be left.
|
||||
*
|
||||
* @exception ServiceFailedException thrown if the leaving was not
|
||||
* able processed for some reason. The explanation will be provided in
|
||||
* the message data of the exception.
|
||||
*/
|
||||
public void leaveTable (BodyObject leaver, int tableId)
|
||||
throws ServiceFailedException
|
||||
{
|
||||
// look the table up
|
||||
Table table = (Table)_tables.get(tableId);
|
||||
if (table == null) {
|
||||
throw new ServiceFailedException(NO_SUCH_TABLE);
|
||||
}
|
||||
|
||||
// make sure the lobby for this table is still around
|
||||
TableLobbyObject tlobj = (TableLobbyObject)
|
||||
CrowdServer.omgr.getObject(table.lobbyOid);
|
||||
if (tlobj == null) {
|
||||
Log.warning("User tried to leave table whose lobby has " +
|
||||
"disappeared [table=" + table +
|
||||
", leaver=" + leaver + "].");
|
||||
throw new ServiceFailedException(INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
// request that the user be removed from the table
|
||||
if (!table.clearOccupant(leaver.username)) {
|
||||
throw new ServiceFailedException(NOT_AT_TABLE);
|
||||
}
|
||||
|
||||
// check to see if we just removed the last person from the table
|
||||
if (table.isEmpty()) {
|
||||
Log.info("Clearing empty table.");
|
||||
// remove the table from our tables table and from the lobby
|
||||
_tables.remove(tableId);
|
||||
tlobj.removeFromTables(table.tableId);
|
||||
|
||||
} else {
|
||||
Log.info("Updating sparser table.");
|
||||
// update the table in the lobby
|
||||
tlobj.updateTables(table);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when we're ready to create a game (either an invitation has
|
||||
* been accepted or a table is ready to start. If there is a problem
|
||||
@@ -373,7 +425,7 @@ public class ParlorManager
|
||||
public void placeCreated (PlaceObject plobj, PlaceManager pmgr)
|
||||
{
|
||||
// see if this place manager is associated with a table
|
||||
Table table = (Table)_pendingTables.get(pmgr);
|
||||
Table table = (Table)_pendingTables.remove(pmgr);
|
||||
if (table != null) {
|
||||
// update the table with the newly created game object
|
||||
table.gameOid = plobj.getOid();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: ParlorProvider.java,v 1.8 2001/10/19 02:04:29 mdb Exp $
|
||||
// $Id: ParlorProvider.java,v 1.9 2001/10/23 20:23:29 mdb Exp $
|
||||
|
||||
package com.threerings.parlor.server;
|
||||
|
||||
@@ -141,6 +141,31 @@ public class ParlorProvider
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a request from the client to leave an existing table.
|
||||
*/
|
||||
public void handleLeaveTableRequest (
|
||||
BodyObject source, int invid, int tableId)
|
||||
{
|
||||
Log.info("Handling leave table request [source=" + source +
|
||||
", invid=" + invid + ", tableId=" + tableId + "].");
|
||||
|
||||
String rsp = null;
|
||||
|
||||
try {
|
||||
// pass the request on to the table manager
|
||||
_pmgr.leaveTable(source, tableId);
|
||||
// there is normally no response. the client will see
|
||||
// themselves removed from the table they just left
|
||||
|
||||
} catch (ServiceFailedException sfe) {
|
||||
// the exception message is the code indicating the reason for
|
||||
// the creation rejection
|
||||
sendResponse(source, invid, LEAVE_FAILED_RESPONSE,
|
||||
sfe.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/** A reference to the parlor manager we're working with. */
|
||||
protected ParlorManager _pmgr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user