We've always been at war with Eurasia. Changed InvocationManager to

InvocationDirector (please god let the renaming be done). Removed IntMap
and modified code to use samskivert's HashIntMap. Also more progress on
invitations and all that.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@376 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2001-10-02 02:09:06 +00:00
parent 6620936a04
commit e08ea92b23
5 changed files with 217 additions and 32 deletions
@@ -1,5 +1,5 @@
// //
// $Id: ParlorCodes.java,v 1.1 2001/10/01 22:17:34 mdb Exp $ // $Id: ParlorCodes.java,v 1.2 2001/10/02 02:09:06 mdb Exp $
package com.threerings.parlor.client; package com.threerings.parlor.client;
@@ -17,6 +17,16 @@ public interface ParlorCodes extends InvocationCodes
* notification. */ * notification. */
public static final String INVITE_ID = "Invite"; public static final String INVITE_ID = "Invite";
/** The response identifier for an accepted invite request. This is
* mapped by the invocation services to a call to {@link
* ParlorDirector#handleInviteReceived}. */
public static final String INVITE_RECEIVED_RESPONSE = "InviteReceived";
/** The response identifier for a rejceted invite request. This is
* mapped by the invocation services to a call to {@link
* ParlorDirector#handleInviteFailed}. */
public static final String INVITE_FAILED_RESPONSE = "InviteFailed";
/** The message identifier for an invitation cancellation request or /** The message identifier for an invitation cancellation request or
* notification. */ * notification. */
public static final String CANCEL_INVITE_ID = "CancelInvite"; public static final String CANCEL_INVITE_ID = "CancelInvite";
@@ -33,4 +43,9 @@ public interface ParlorCodes extends InvocationCodes
/** The response code for a countered invitation. */ /** The response code for a countered invitation. */
public static final int INVITATION_COUNTERED = 2; public static final int INVITATION_COUNTERED = 2;
/** An error code explaining that an invitation was rejected because
* the invited user was not online at the time the invitation was
* received. */
public static final String INVITEE_NOT_ONLINE = "m.invitee_not_online";
} }
@@ -1,5 +1,5 @@
// //
// $Id: ParlorDirector.java,v 1.4 2001/10/01 22:17:34 mdb Exp $ // $Id: ParlorDirector.java,v 1.5 2001/10/02 02:09:06 mdb Exp $
package com.threerings.parlor.client; package com.threerings.parlor.client;
@@ -7,6 +7,8 @@ import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import com.samskivert.util.HashIntMap; import com.samskivert.util.HashIntMap;
import com.threerings.cocktail.cher.client.InvocationReceiver;
import com.threerings.parlor.Log; import com.threerings.parlor.Log;
import com.threerings.parlor.data.GameConfig; import com.threerings.parlor.data.GameConfig;
import com.threerings.parlor.util.ParlorContext; import com.threerings.parlor.util.ParlorContext;
@@ -19,7 +21,7 @@ import com.threerings.parlor.util.ParlorContext;
* that started. * that started.
*/ */
public class ParlorDirector public class ParlorDirector
implements ParlorCodes implements ParlorCodes, InvocationReceiver
{ {
/** /**
* Constructs a parlor director and provides it with the parlor * Constructs a parlor director and provides it with the parlor
@@ -1,10 +1,10 @@
// //
// $Id: ParlorService.java,v 1.4 2001/10/01 22:17:34 mdb Exp $ // $Id: ParlorService.java,v 1.5 2001/10/02 02:09:06 mdb Exp $
package com.threerings.parlor.client; package com.threerings.parlor.client;
import com.threerings.cocktail.cher.client.Client; import com.threerings.cocktail.cher.client.Client;
import com.threerings.cocktail.cher.client.InvocationManager; import com.threerings.cocktail.cher.client.InvocationDirector;
import com.threerings.parlor.Log; import com.threerings.parlor.Log;
import com.threerings.parlor.data.GameConfig; import com.threerings.parlor.data.GameConfig;
@@ -40,11 +40,11 @@ public class ParlorService implements ParlorCodes
public static int invite (Client client, String invitee, public static int invite (Client client, String invitee,
GameConfig config, Object rsptarget) GameConfig config, Object rsptarget)
{ {
InvocationManager invmgr = client.getInvocationManager(); InvocationDirector invdir = client.getInvocationDirector();
Object[] args = new Object[] { invitee, config }; Object[] args = new Object[] { invitee, config };
Log.info("Sending invite request [to=" + invitee + Log.info("Sending invite request [to=" + invitee +
", cfg=" + config + "]."); ", cfg=" + config + "].");
return invmgr.invoke(MODULE_NAME, INVITE_ID, args, rsptarget); return invdir.invoke(MODULE_NAME, INVITE_ID, args, rsptarget);
} }
/** /**
@@ -71,14 +71,14 @@ public class ParlorService implements ParlorCodes
public static int respond (Client client, int inviteId, int code, public static int respond (Client client, int inviteId, int code,
Object arg, Object rsptarget) Object arg, Object rsptarget)
{ {
InvocationManager invmgr = client.getInvocationManager(); InvocationDirector invdir = client.getInvocationDirector();
Object[] args = new Object[] { Object[] args = new Object[] {
new Integer(inviteId), new Integer(code), null }; new Integer(inviteId), new Integer(code), null };
// we can't have a null argument so we use the empty string // we can't have a null argument so we use the empty string
args[2] = (arg == null) ? "" : arg; args[2] = (arg == null) ? "" : arg;
Log.info("Sending invitation response [inviteId=" + inviteId + Log.info("Sending invitation response [inviteId=" + inviteId +
", code=" + code + ", arg=" + arg + "]."); ", code=" + code + ", arg=" + arg + "].");
return invmgr.invoke( return invdir.invoke(
MODULE_NAME, RESPOND_INVITE_ID, args, rsptarget); MODULE_NAME, RESPOND_INVITE_ID, args, rsptarget);
} }
@@ -97,10 +97,10 @@ public class ParlorService implements ParlorCodes
*/ */
public static int cancel (Client client, int inviteId, Object rsptarget) public static int cancel (Client client, int inviteId, Object rsptarget)
{ {
InvocationManager invmgr = client.getInvocationManager(); InvocationDirector invdir = client.getInvocationDirector();
Object[] args = new Object[] { new Integer(inviteId) }; Object[] args = new Object[] { new Integer(inviteId) };
Log.info("Sending invitation cancellation " + Log.info("Sending invitation cancellation " +
"[inviteId=" + inviteId + "]."); "[inviteId=" + inviteId + "].");
return invmgr.invoke(MODULE_NAME, CANCEL_INVITE_ID, args, rsptarget); return invdir.invoke(MODULE_NAME, CANCEL_INVITE_ID, args, rsptarget);
} }
} }
@@ -1,13 +1,17 @@
// //
// $Id: ParlorManager.java,v 1.2 2001/10/01 22:17:34 mdb Exp $ // $Id: ParlorManager.java,v 1.3 2001/10/02 02:09:06 mdb Exp $
package com.threerings.parlor.server; package com.threerings.parlor.server;
import com.samskivert.util.Config; import com.samskivert.util.Config;
import com.samskivert.util.HashIntMap;
import com.threerings.cocktail.cher.server.InvocationManager; import com.threerings.cocktail.cher.server.InvocationManager;
import com.threerings.cocktail.cher.server.ServiceFailedException;
import com.threerings.cocktail.party.data.BodyObject; import com.threerings.cocktail.party.data.BodyObject;
import com.threerings.parlor.Log;
import com.threerings.parlor.client.ParlorCodes; import com.threerings.parlor.client.ParlorCodes;
import com.threerings.parlor.data.GameConfig; import com.threerings.parlor.data.GameConfig;
@@ -35,6 +39,9 @@ public class ParlorManager
// register our invocation provider // register our invocation provider
ParlorProvider pprov = new ParlorProvider(this); ParlorProvider pprov = new ParlorProvider(this);
invmgr.registerProvider(MODULE_NAME, pprov); invmgr.registerProvider(MODULE_NAME, pprov);
// keep this around for later
_invmgr = invmgr;
} }
/** /**
@@ -46,13 +53,168 @@ public class ParlorManager
* @param invitee the player being invited. * @param invitee the player being invited.
* @param config the configuration of the game being proposed. * @param config the configuration of the game being proposed.
* *
* @return the <code>SUCCESS</code> constant if the invitation was * @return the invitation identifier for the newly created invitation
* accepted and delivered, or a string describing the reason for * record.
* failure if it was rejected. *
* @exception ServiceFailedException thrown if the invitation was not
* able to be processed for some reason (like the invited player has
* requested not to be disturbed). The explanation will be provided in
* the message data of the exception.
*/ */
public String invite (BodyObject inviter, BodyObject invitee, public int invite (BodyObject inviter, BodyObject invitee,
GameConfig config) GameConfig config)
throws ServiceFailedException
{ {
return SUCCESS; // here we should check to make sure the invitee hasn't muted the
// inviter, and that the inviter isn't shunned and all that other
// access control type stuff
// create a new invitation record for this invitation
Invitation invite = new Invitation(inviter, invitee, config);
// stick it in the pending invites table
_invites.put(invite.inviteId, invite);
// deliver an invite notification to the invitee
Object[] args = new Object[] {
new Integer(invite.inviteId), inviter.username, config };
_invmgr.sendNotification(
invitee.getOid(), MODULE_NAME, INVITE_ID, args);
// and let the caller know the invite id we assigned
return invite.inviteId;
} }
/**
* Effects a response to an invitation (accept, refuse or counter),
* made by the specified source user with the specified arguments.
*
* @param source the body object of the user that is issuing this
* response.
* @param inviteId the identifier of the invitation to which we are
* responding.
* @param code the response code (either {@link
* #INVITATION_ACCEPTED}, {@link #INVITATION_REFUSED} or {@link
* #INVITATION_COUNTERED}).
* @param arg the argument that goes along with the response: an
* explanatory message in the case of a refusal (the empty string, not
* null, if no message was provided) or the new game configuration in
* the case of a counter-invitation.
*/
public void respondToInvite (BodyObject source, int inviteId, int code,
Object arg)
{
// look up the invitation
Invitation invite = (Invitation)_invites.get(inviteId);
if (invite == null) {
Log.warning("Requested to respond to non-existent invitation " +
"[source=" + source + ", inviteId=" + inviteId +
", code=" + code + ", arg=" + arg + "].");
return;
}
// make sure this response came from the proper person
if (source != invite.invitee) {
Log.warning("Got response from non-invitee [source=" + source +
", invite=" + invite + ", code=" + code +
", arg=" + arg + "].");
return;
}
// let the other user know that a response was made to this
// invitation
Object[] args = new Object[] {
new Integer(invite.inviteId), new Integer(code), arg };
_invmgr.sendNotification(
invite.inviter.getOid(), MODULE_NAME, RESPOND_INVITE_ID, args);
switch (code) {
case INVITATION_ACCEPTED:
// the invitation was accepted, so we'll need to start up the
// game and get the necessary balls rolling
processAcceptedInvitation(invite);
// and remove the invitation from the pending table
_invites.remove(inviteId);
break;
case INVITATION_REFUSED:
// remove the invitation record from the pending table as it
// is no longer pending
_invites.remove(inviteId);
break;
case INVITATION_COUNTERED:
// swap control of the invitation to the invitee
invite.swapControl();
break;
default:
Log.warning("Requested to respond to invitation with " +
"unknown response code [source=" + source +
", invite=" + invite + ", code=" + code +
", arg=" + arg + "].");
break;
}
}
public void cancelInvite (BodyObject source, int inviteId)
{
}
protected void processAcceptedInvitation (Invitation invite)
{
// start up the game and all that...
}
/**
* The invitation record is used by the parlor manager to keep track
* of pending invitations.
*/
protected static class Invitation
{
/** The unique identifier for this inviation. */
public int inviteId = _nextInviteId++;
/** The person proposing the invitation. */
public BodyObject inviter;
/** The person to whom the invitation is proposed. */
public BodyObject invitee;
/** The configuration of the game being proposed. */
public GameConfig config;
/**
* Constructs a new invitation with the specified participants and
* configuration.
*/
public Invitation (BodyObject inviter, BodyObject invitee,
GameConfig config)
{
this.inviter = inviter;
this.invitee = invitee;
this.config = config;
}
/**
* Swaps the inviter and invitee which is necessary when the
* invitee responds with a counter-invitation.
*/
public void swapControl ()
{
BodyObject tmp = inviter;
inviter = invitee;
invitee = tmp;
}
}
/** A reference to the invocation manager in operation on this server. */
protected InvocationManager _invmgr;
/** The table of pending invitations. */
protected HashIntMap _invites = new HashIntMap();
/** A counter used to generate unique identifiers for invitation
* records. */
protected static int _nextInviteId = 0;
} }
@@ -1,9 +1,10 @@
// //
// $Id: ParlorProvider.java,v 1.3 2001/10/01 22:17:34 mdb Exp $ // $Id: ParlorProvider.java,v 1.4 2001/10/02 02:09:06 mdb Exp $
package com.threerings.parlor.server; package com.threerings.parlor.server;
import com.threerings.cocktail.cher.server.InvocationProvider; import com.threerings.cocktail.cher.server.InvocationProvider;
import com.threerings.cocktail.cher.server.ServiceFailedException;
import com.threerings.cocktail.party.data.BodyObject; import com.threerings.cocktail.party.data.BodyObject;
import com.threerings.cocktail.party.server.PartyServer; import com.threerings.cocktail.party.server.PartyServer;
@@ -42,21 +43,22 @@ public class ParlorProvider
String rsp = null; String rsp = null;
// ensure that the invitee is online at present // ensure that the invitee is online at present
BodyObject target = PartyServer.lookupBody(invitee); try {
if (target == null) { BodyObject target = PartyServer.lookupBody(invitee);
rsp = "m.not_online\t" + invitee; if (target == null) {
throw new ServiceFailedException(INVITEE_NOT_ONLINE);
}
} else { // submit the invite request to the parlor manager
// if they are, submit the invite request to the parlor int inviteId = _pmgr.invite(source, target, config);
// manager sendResponse(source, invid, INVITE_RECEIVED_RESPONSE,
rsp = _pmgr.invite(source, target, config); new Integer(inviteId));
}
// now send the response } catch (ServiceFailedException sfe) {
if (rsp.equals(SUCCESS)) { // the exception message is the code indicating the reason
sendResponse(source, invid, "InviteReceived"); // for the invitation rejection
} else { sendResponse(source, invid, INVITE_FAILED_RESPONSE,
sendResponse(source, invid, "InviteReceived"); sfe.getMessage());
} }
} }
@@ -67,6 +69,8 @@ public class ParlorProvider
public void handleRepsondInviteRequest ( public void handleRepsondInviteRequest (
BodyObject source, int invid, int inviteId, int code, Object arg) BodyObject source, int invid, int inviteId, int code, Object arg)
{ {
// pass this on to the parlor manager
_pmgr.respondToInvite(source, inviteId, code, arg);
} }
/** /**
@@ -76,6 +80,8 @@ public class ParlorProvider
public void handleCancelInviteRequest ( public void handleCancelInviteRequest (
BodyObject source, int invid, int inviteId) BodyObject source, int invid, int inviteId)
{ {
// pass this on to the parlor manager
_pmgr.cancelInvite(source, inviteId);
} }
/** A reference to the parlor manager we're working with. */ /** A reference to the parlor manager we're working with. */