From b71007a9099542c3a0e2a55f51bc3aeabab23e71 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Wed, 21 Mar 2007 21:38:31 +0000 Subject: [PATCH] Yay for rabbit holes. Revamped the table services to decouple them from places. While I was in there, I extracted the communication between the client and the TableManager into a new-style "embedded in the TableLobbyObject" service instead of wonkily routing everything through the global ParlorService and the ParlorProvider (which got merged into the ParlorManager as a part of this rabbit holery). The GG build will break... I will fix it. git-svn-id: svn+ssh://src.earth.threerings.net/vilya/trunk@255 c613c5cb-e716-0410-b11b-feb51c14d237 --- build.xml | 1 - .../threerings/parlor/client/ParlorService.as | 15 - .../client/ParlorService_InviteListener.as | 3 - .../threerings/parlor/client/TableService.as | 51 ++++ .../client/TableService_TableListener.as | 44 +++ .../parlor/data/ParlorMarshaller.as | 61 +--- .../data/ParlorMarshaller_InviteMarshaller.as | 1 - .../threerings/parlor/data/TableMarshaller.as | 99 +++++++ .../data/TableMarshaller_TableMarshaller.as | 59 ++++ .../micasa/lobby/table/TableLobbyManager.java | 9 +- .../micasa/lobby/table/TableLobbyObject.java | 43 ++- .../parlor/client/ParlorService.java | 126 ++------- .../parlor/client/TableDirector.java | 196 +++++-------- .../parlor/client/TableService.java | 71 +++++ .../parlor/data/ParlorMarshaller.java | 94 +------ .../parlor/data/TableLobbyObject.java | 11 + .../parlor/data/TableMarshaller.java | 93 +++++++ .../parlor/server/ParlorDispatcher.java | 29 -- .../parlor/server/ParlorManager.java | 81 +++++- .../parlor/server/ParlorProvider.java | 214 ++------------ .../parlor/server/TableDispatcher.java | 94 +++++++ .../parlor/server/TableManager.java | 262 ++++++++---------- .../parlor/server/TableManagerProvider.java | 11 +- .../parlor/server/TableProvider.java | 61 ++++ 24 files changed, 936 insertions(+), 793 deletions(-) create mode 100644 src/as/com/threerings/parlor/client/TableService.as create mode 100644 src/as/com/threerings/parlor/client/TableService_TableListener.as create mode 100644 src/as/com/threerings/parlor/data/TableMarshaller.as create mode 100644 src/as/com/threerings/parlor/data/TableMarshaller_TableMarshaller.as create mode 100644 src/java/com/threerings/parlor/client/TableService.java create mode 100644 src/java/com/threerings/parlor/data/TableMarshaller.java create mode 100644 src/java/com/threerings/parlor/server/TableDispatcher.java create mode 100644 src/java/com/threerings/parlor/server/TableProvider.java diff --git a/build.xml b/build.xml index ee275bbe..1aa635e1 100644 --- a/build.xml +++ b/build.xml @@ -61,7 +61,6 @@ - diff --git a/src/as/com/threerings/parlor/client/ParlorService.as b/src/as/com/threerings/parlor/client/ParlorService.as index 30d21c1f..65fdfa5e 100644 --- a/src/as/com/threerings/parlor/client/ParlorService.as +++ b/src/as/com/threerings/parlor/client/ParlorService.as @@ -24,10 +24,7 @@ package com.threerings.parlor.client { import flash.utils.ByteArray; import com.threerings.parlor.client.ParlorService; import com.threerings.parlor.client.ParlorService_InviteListener; -import com.threerings.parlor.client.ParlorService_TableListener; import com.threerings.parlor.data.ParlorMarshaller_InviteMarshaller; -import com.threerings.parlor.data.ParlorMarshaller_TableMarshaller; -import com.threerings.parlor.data.TableConfig; import com.threerings.parlor.game.data.GameConfig; import com.threerings.presents.client.Client; import com.threerings.presents.client.InvocationService; @@ -44,25 +41,13 @@ public interface ParlorService extends InvocationService // from Java interface ParlorService function cancel (arg1 :Client, arg2 :int, arg3 :InvocationService_InvocationListener) :void; - // from Java interface ParlorService - function createTable (arg1 :Client, arg2 :int, arg3 :TableConfig, arg4 :GameConfig, arg5 :ParlorService_TableListener) :void; - // from Java interface ParlorService function invite (arg1 :Client, arg2 :Name, arg3 :GameConfig, arg4 :ParlorService_InviteListener) :void; - // from Java interface ParlorService - function joinTable (arg1 :Client, arg2 :int, arg3 :int, arg4 :int, arg5 :InvocationService_InvocationListener) :void; - - // from Java interface ParlorService - function leaveTable (arg1 :Client, arg2 :int, arg3 :int, arg4 :InvocationService_InvocationListener) :void; - // from Java interface ParlorService function respond (arg1 :Client, arg2 :int, arg3 :int, arg4 :Object, arg5 :InvocationService_InvocationListener) :void; // from Java interface ParlorService function startSolitaire (arg1 :Client, arg2 :GameConfig, arg3 :InvocationService_ConfirmListener) :void; - - // from Java interface ParlorService - function startTableNow (arg1 :Client, arg2 :int, arg3 :int, arg4 :InvocationService_InvocationListener) :void; } } diff --git a/src/as/com/threerings/parlor/client/ParlorService_InviteListener.as b/src/as/com/threerings/parlor/client/ParlorService_InviteListener.as index 39ccf502..0c291c68 100644 --- a/src/as/com/threerings/parlor/client/ParlorService_InviteListener.as +++ b/src/as/com/threerings/parlor/client/ParlorService_InviteListener.as @@ -26,10 +26,7 @@ import com.threerings.util.*; // for Float, Integer, etc. import com.threerings.parlor.client.ParlorService; import com.threerings.parlor.client.ParlorService_InviteListener; -import com.threerings.parlor.client.ParlorService_TableListener; import com.threerings.parlor.data.ParlorMarshaller_InviteMarshaller; -import com.threerings.parlor.data.ParlorMarshaller_TableMarshaller; -import com.threerings.parlor.data.TableConfig; import com.threerings.parlor.game.data.GameConfig; import com.threerings.presents.client.Client; import com.threerings.presents.client.InvocationService_ConfirmListener; diff --git a/src/as/com/threerings/parlor/client/TableService.as b/src/as/com/threerings/parlor/client/TableService.as new file mode 100644 index 00000000..849413f7 --- /dev/null +++ b/src/as/com/threerings/parlor/client/TableService.as @@ -0,0 +1,51 @@ +// +// $Id$ +// +// Vilya library - tools for developing networked games +// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/vilya/ +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.parlor.client { + +import flash.utils.ByteArray; +import com.threerings.parlor.client.TableService; +import com.threerings.parlor.data.TableConfig; +import com.threerings.parlor.game.data.GameConfig; +import com.threerings.presents.client.Client; +import com.threerings.presents.client.InvocationService; +import com.threerings.presents.client.InvocationService_InvocationListener; +import com.threerings.presents.client.InvocationService_ResultListener; +import com.threerings.presents.data.InvocationMarshaller_ResultMarshaller; + +/** + * An ActionScript version of the Java TableService interface. + */ +public interface TableService extends InvocationService +{ + // from Java interface TableService + function createTable (arg1 :Client, arg2 :TableConfig, arg3 :GameConfig, arg4 :InvocationService_ResultListener) :void; + + // from Java interface TableService + function joinTable (arg1 :Client, arg2 :int, arg3 :int, arg4 :InvocationService_InvocationListener) :void; + + // from Java interface TableService + function leaveTable (arg1 :Client, arg2 :int, arg3 :InvocationService_InvocationListener) :void; + + // from Java interface TableService + function startTableNow (arg1 :Client, arg2 :int, arg3 :InvocationService_InvocationListener) :void; +} +} diff --git a/src/as/com/threerings/parlor/client/TableService_TableListener.as b/src/as/com/threerings/parlor/client/TableService_TableListener.as new file mode 100644 index 00000000..ee714b5d --- /dev/null +++ b/src/as/com/threerings/parlor/client/TableService_TableListener.as @@ -0,0 +1,44 @@ +// +// $Id$ +// +// Vilya library - tools for developing networked games +// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/vilya/ +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.parlor.client { + +import flash.utils.ByteArray; +import com.threerings.util.*; // for Float, Integer, etc. + +import com.threerings.parlor.client.TableService; +import com.threerings.parlor.client.TableService_TableListener; +import com.threerings.parlor.data.TableConfig; +import com.threerings.parlor.data.TableMarshaller_TableMarshaller; +import com.threerings.parlor.game.data.GameConfig; +import com.threerings.presents.client.Client; +import com.threerings.presents.client.InvocationService_InvocationListener; + +/** + * An ActionScript version of the Java TableService_TableListener interface. + */ +public interface TableService_TableListener + extends InvocationService_InvocationListener +{ + // from Java TableService_TableListener + function tableCreated (arg1 :int) :void +} +} diff --git a/src/as/com/threerings/parlor/data/ParlorMarshaller.as b/src/as/com/threerings/parlor/data/ParlorMarshaller.as index 61aa4fe8..cafca25b 100644 --- a/src/as/com/threerings/parlor/data/ParlorMarshaller.as +++ b/src/as/com/threerings/parlor/data/ParlorMarshaller.as @@ -26,10 +26,7 @@ import com.threerings.util.*; // for Float, Integer, etc. import com.threerings.parlor.client.ParlorService; import com.threerings.parlor.client.ParlorService_InviteListener; -import com.threerings.parlor.client.ParlorService_TableListener; import com.threerings.parlor.data.ParlorMarshaller_InviteMarshaller; -import com.threerings.parlor.data.ParlorMarshaller_TableMarshaller; -import com.threerings.parlor.data.TableConfig; import com.threerings.parlor.game.data.GameConfig; import com.threerings.presents.client.Client; import com.threerings.presents.client.InvocationService_ConfirmListener; @@ -62,21 +59,8 @@ public class ParlorMarshaller extends InvocationMarshaller ]); } - /** The method id used to dispatch {@link #createTable} requests. */ - public static const CREATE_TABLE :int = 2; - - // from interface ParlorService - public function createTable (arg1 :Client, arg2 :int, arg3 :TableConfig, arg4 :GameConfig, arg5 :ParlorService_TableListener) :void - { - var listener5 :ParlorMarshaller_TableMarshaller = new ParlorMarshaller_TableMarshaller(); - listener5.listener = arg5; - sendRequest(arg1, CREATE_TABLE, [ - Integer.valueOf(arg2), arg3, arg4, listener5 - ]); - } - /** The method id used to dispatch {@link #invite} requests. */ - public static const INVITE :int = 3; + public static const INVITE :int = 2; // from interface ParlorService public function invite (arg1 :Client, arg2 :Name, arg3 :GameConfig, arg4 :ParlorService_InviteListener) :void @@ -88,34 +72,8 @@ public class ParlorMarshaller extends InvocationMarshaller ]); } - /** The method id used to dispatch {@link #joinTable} requests. */ - public static const JOIN_TABLE :int = 4; - - // from interface ParlorService - public function joinTable (arg1 :Client, arg2 :int, arg3 :int, arg4 :int, arg5 :InvocationService_InvocationListener) :void - { - var listener5 :InvocationMarshaller_ListenerMarshaller = new InvocationMarshaller_ListenerMarshaller(); - listener5.listener = arg5; - sendRequest(arg1, JOIN_TABLE, [ - Integer.valueOf(arg2), Integer.valueOf(arg3), Integer.valueOf(arg4), listener5 - ]); - } - - /** The method id used to dispatch {@link #leaveTable} requests. */ - public static const LEAVE_TABLE :int = 5; - - // from interface ParlorService - public function leaveTable (arg1 :Client, arg2 :int, arg3 :int, arg4 :InvocationService_InvocationListener) :void - { - var listener4 :InvocationMarshaller_ListenerMarshaller = new InvocationMarshaller_ListenerMarshaller(); - listener4.listener = arg4; - sendRequest(arg1, LEAVE_TABLE, [ - Integer.valueOf(arg2), Integer.valueOf(arg3), listener4 - ]); - } - /** The method id used to dispatch {@link #respond} requests. */ - public static const RESPOND :int = 6; + public static const RESPOND :int = 3; // from interface ParlorService public function respond (arg1 :Client, arg2 :int, arg3 :int, arg4 :Object, arg5 :InvocationService_InvocationListener) :void @@ -128,7 +86,7 @@ public class ParlorMarshaller extends InvocationMarshaller } /** The method id used to dispatch {@link #startSolitaire} requests. */ - public static const START_SOLITAIRE :int = 7; + public static const START_SOLITAIRE :int = 4; // from interface ParlorService public function startSolitaire (arg1 :Client, arg2 :GameConfig, arg3 :InvocationService_ConfirmListener) :void @@ -139,18 +97,5 @@ public class ParlorMarshaller extends InvocationMarshaller arg2, listener3 ]); } - - /** The method id used to dispatch {@link #startTableNow} requests. */ - public static const START_TABLE_NOW :int = 8; - - // from interface ParlorService - public function startTableNow (arg1 :Client, arg2 :int, arg3 :int, arg4 :InvocationService_InvocationListener) :void - { - var listener4 :InvocationMarshaller_ListenerMarshaller = new InvocationMarshaller_ListenerMarshaller(); - listener4.listener = arg4; - sendRequest(arg1, START_TABLE_NOW, [ - Integer.valueOf(arg2), Integer.valueOf(arg3), listener4 - ]); - } } } diff --git a/src/as/com/threerings/parlor/data/ParlorMarshaller_InviteMarshaller.as b/src/as/com/threerings/parlor/data/ParlorMarshaller_InviteMarshaller.as index 620f4833..39d62a9a 100644 --- a/src/as/com/threerings/parlor/data/ParlorMarshaller_InviteMarshaller.as +++ b/src/as/com/threerings/parlor/data/ParlorMarshaller_InviteMarshaller.as @@ -26,7 +26,6 @@ import com.threerings.util.*; // for Float, Integer, etc. import com.threerings.parlor.client.ParlorService; import com.threerings.parlor.client.ParlorService_InviteListener; -import com.threerings.parlor.data.TableConfig; import com.threerings.parlor.game.data.GameConfig; import com.threerings.presents.client.Client; import com.threerings.presents.client.InvocationService; diff --git a/src/as/com/threerings/parlor/data/TableMarshaller.as b/src/as/com/threerings/parlor/data/TableMarshaller.as new file mode 100644 index 00000000..70ab1446 --- /dev/null +++ b/src/as/com/threerings/parlor/data/TableMarshaller.as @@ -0,0 +1,99 @@ +// +// $Id$ +// +// Vilya library - tools for developing networked games +// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/vilya/ +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.parlor.data { + +import flash.utils.ByteArray; +import com.threerings.util.*; // for Float, Integer, etc. + +import com.threerings.parlor.client.TableService; +import com.threerings.parlor.data.TableConfig; +import com.threerings.parlor.game.data.GameConfig; +import com.threerings.presents.client.Client; +import com.threerings.presents.client.InvocationService_InvocationListener; +import com.threerings.presents.client.InvocationService_ResultListener; +import com.threerings.presents.data.InvocationMarshaller; +import com.threerings.presents.data.InvocationMarshaller_ListenerMarshaller; +import com.threerings.presents.data.InvocationMarshaller_ResultMarshaller; + +/** + * Provides the implementation of the {@link TableService} interface + * that marshalls the arguments and delivers the request to the provider + * on the server. Also provides an implementation of the response listener + * interfaces that marshall the response arguments and deliver them back + * to the requesting client. + */ +public class TableMarshaller extends InvocationMarshaller + implements TableService +{ + /** The method id used to dispatch {@link #createTable} requests. */ + public static const CREATE_TABLE :int = 1; + + // from interface TableService + public function createTable (arg1 :Client, arg2 :TableConfig, arg3 :GameConfig, arg4 :InvocationService_ResultListener) :void + { + var listener4 :InvocationMarshaller_ResultMarshaller = new InvocationMarshaller_ResultMarshaller(); + listener4.listener = arg4; + sendRequest(arg1, CREATE_TABLE, [ + arg2, arg3, listener4 + ]); + } + + /** The method id used to dispatch {@link #joinTable} requests. */ + public static const JOIN_TABLE :int = 2; + + // from interface TableService + public function joinTable (arg1 :Client, arg2 :int, arg3 :int, arg4 :InvocationService_InvocationListener) :void + { + var listener4 :InvocationMarshaller_ListenerMarshaller = new InvocationMarshaller_ListenerMarshaller(); + listener4.listener = arg4; + sendRequest(arg1, JOIN_TABLE, [ + Integer.valueOf(arg2), Integer.valueOf(arg3), listener4 + ]); + } + + /** The method id used to dispatch {@link #leaveTable} requests. */ + public static const LEAVE_TABLE :int = 3; + + // from interface TableService + public function leaveTable (arg1 :Client, arg2 :int, arg3 :InvocationService_InvocationListener) :void + { + var listener3 :InvocationMarshaller_ListenerMarshaller = new InvocationMarshaller_ListenerMarshaller(); + listener3.listener = arg3; + sendRequest(arg1, LEAVE_TABLE, [ + Integer.valueOf(arg2), listener3 + ]); + } + + /** The method id used to dispatch {@link #startTableNow} requests. */ + public static const START_TABLE_NOW :int = 4; + + // from interface TableService + public function startTableNow (arg1 :Client, arg2 :int, arg3 :InvocationService_InvocationListener) :void + { + var listener3 :InvocationMarshaller_ListenerMarshaller = new InvocationMarshaller_ListenerMarshaller(); + listener3.listener = arg3; + sendRequest(arg1, START_TABLE_NOW, [ + Integer.valueOf(arg2), listener3 + ]); + } +} +} diff --git a/src/as/com/threerings/parlor/data/TableMarshaller_TableMarshaller.as b/src/as/com/threerings/parlor/data/TableMarshaller_TableMarshaller.as new file mode 100644 index 00000000..58353ad0 --- /dev/null +++ b/src/as/com/threerings/parlor/data/TableMarshaller_TableMarshaller.as @@ -0,0 +1,59 @@ +// +// $Id$ +// +// Vilya library - tools for developing networked games +// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/vilya/ +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.parlor.data { + +import flash.utils.ByteArray; +import com.threerings.util.*; // for Float, Integer, etc. + +import com.threerings.parlor.client.TableService; +import com.threerings.parlor.client.TableService_TableListener; +import com.threerings.parlor.data.TableConfig; +import com.threerings.parlor.game.data.GameConfig; +import com.threerings.presents.client.Client; +import com.threerings.presents.client.InvocationService; +import com.threerings.presents.data.InvocationMarshaller_ListenerMarshaller; + +/** + * Marshalls instances of the TableService_TableMarshaller interface. + */ +public class TableMarshaller_TableMarshaller + extends InvocationMarshaller_ListenerMarshaller +{ + /** The method id used to dispatch {@link #tableCreated} responses. */ + public static const TABLE_CREATED :int = 1; + + // from InvocationMarshaller_ListenerMarshaller + override public function dispatchResponse (methodId :int, args :Array) :void + { + switch (methodId) { + case TABLE_CREATED: + (listener as TableService_TableListener).tableCreated( + (args[0] as int)); + return; + + default: + super.dispatchResponse(methodId, args); + return; + } + } +} +} diff --git a/src/java/com/threerings/micasa/lobby/table/TableLobbyManager.java b/src/java/com/threerings/micasa/lobby/table/TableLobbyManager.java index 86650359..082c4d8a 100644 --- a/src/java/com/threerings/micasa/lobby/table/TableLobbyManager.java +++ b/src/java/com/threerings/micasa/lobby/table/TableLobbyManager.java @@ -27,8 +27,7 @@ import com.threerings.parlor.server.TableManagerProvider; import com.threerings.micasa.lobby.LobbyManager; /** - * Extends lobby manager only to ensure that a table lobby object is used - * for table lobbies. + * Extends lobby manager only to ensure that a table lobby object is used for table lobbies. */ public class TableLobbyManager extends LobbyManager implements TableManagerProvider @@ -37,10 +36,8 @@ public class TableLobbyManager protected void didStartup () { super.didStartup(); - - // now that we have our place object, we can create our table - // manager - _tmgr = new TableManager(this); + // now that we have our place object, we can create our table manager + _tmgr = new TableManager(getPlaceObject()); } // documentation inherited diff --git a/src/java/com/threerings/micasa/lobby/table/TableLobbyObject.java b/src/java/com/threerings/micasa/lobby/table/TableLobbyObject.java index 383ebe3c..1eccf985 100644 --- a/src/java/com/threerings/micasa/lobby/table/TableLobbyObject.java +++ b/src/java/com/threerings/micasa/lobby/table/TableLobbyObject.java @@ -21,46 +21,59 @@ package com.threerings.micasa.lobby.table; -import com.threerings.presents.dobj.DSet; import com.threerings.parlor.data.Table; +import com.threerings.parlor.data.TableMarshaller; +import com.threerings.presents.dobj.DSet; + import com.threerings.micasa.lobby.LobbyObject; -public class TableLobbyObject - extends LobbyObject +public class TableLobbyObject extends LobbyObject implements com.threerings.parlor.data.TableLobbyObject { // AUTO-GENERATED: FIELDS START /** The field name of the tableSet field. */ public static final String TABLE_SET = "tableSet"; + + /** The field name of the tableService field. */ + public static final String TABLE_SERVICE = "tableService"; // AUTO-GENERATED: FIELDS END /** A set containing all of the tables being managed by this lobby. */ public DSet tableSet = new DSet(); - // documentation inherited + /** Handles our table services. */ + public TableMarshaller tableService; + + // from interface TableLobbyObject public DSet getTables () { return tableSet; } - // documentation inherited from interface + // from interface TableLobbyObject public void addToTables (Table table) { addToTableSet(table); } - // documentation inherited from interface + // from interface TableLobbyObject public void updateTables (Table table) { updateTableSet(table); } - // documentation inherited from interface + // from interface TableLobbyObject public void removeFromTables (Comparable key) { removeFromTableSet(key); } + // from interface TableLobbyObject + public TableMarshaller getTableService () + { + return tableService; + } + // AUTO-GENERATED: METHODS START /** * Requests that the specified entry be added to the @@ -109,5 +122,21 @@ public class TableLobbyObject (value == null) ? null : value.typedClone(); this.tableSet = clone; } + + /** + * Requests that the tableService field be set to the + * specified value. The local value will be updated immediately and an + * event will be propagated through the system to notify all listeners + * that the attribute did change. Proxied copies of this object (on + * clients) will apply the value change when they received the + * attribute changed notification. + */ + public void setTableService (TableMarshaller value) + { + TableMarshaller ovalue = this.tableService; + requestAttributeChange( + TABLE_SERVICE, value, ovalue); + this.tableService = value; + } // AUTO-GENERATED: METHODS END } diff --git a/src/java/com/threerings/parlor/client/ParlorService.java b/src/java/com/threerings/parlor/client/ParlorService.java index 964aacdf..e29ebcec 100644 --- a/src/java/com/threerings/parlor/client/ParlorService.java +++ b/src/java/com/threerings/parlor/client/ParlorService.java @@ -26,16 +26,13 @@ import com.threerings.util.Name; import com.threerings.presents.client.Client; import com.threerings.presents.client.InvocationService; -import com.threerings.parlor.data.TableConfig; - import com.threerings.parlor.game.data.GameConfig; /** - * Provides an interface to the various parlor invocation services. - * Presently these services are limited to the various matchmaking - * mechanisms. It is unlikely that client code will want to make direct - * use of this class, instead they would make use of the programmatic - * interface provided by the {@link ParlorDirector}. + * Provides an interface to the various parlor invocation services. Presently these services are + * limited to the various matchmaking mechanisms. It is unlikely that client code will want to make + * direct use of this class, instead they would make use of the programmatic interface provided by + * the {@link ParlorDirector}. */ public interface ParlorService extends InvocationService { @@ -51,124 +48,49 @@ public interface ParlorService extends InvocationService } /** - * You probably don't want to call this directly, but want to generate - * your invitation request via {@link ParlorDirector#invite}. Requests - * that an invitation be delivered to the named user, requesting that - * they join the inviting user in a game, the details of which are + * You probably don't want to call this directly, but want to generate your invitation request + * via {@link ParlorDirector#invite}. Requests that an invitation be delivered to the named + * user, requesting that they join the inviting user in a game, the details of which are * specified in the supplied game config object. * * @param client a connected, operational client instance. * @param invitee the username of the user to be invited. - * @param config a game config object detailing the type and - * configuration of the game to be created. + * @param config a game config object detailing the type and configuration of the game to be + * created. * @param listener will receive and process the response. */ public void invite (Client client, Name invitee, GameConfig config, InviteListener listener); /** - * You probably don't want to call this directly, but want to call one - * of {@link Invitation#accept}, {@link Invitation#refuse}, or {@link - * Invitation#counter}. Requests that an invitation response be - * delivered with the specified parameters. + * You probably don't want to call this directly, but want to call one of {@link + * Invitation#accept}, {@link Invitation#refuse}, or {@link Invitation#counter}. Requests that + * an invitation response be delivered with the specified parameters. * * @param client a connected, operational client instance. - * @param inviteId the unique id previously assigned by the server to - * this invitation. - * @param code the response code to use in responding to the - * invitation. - * @param arg the argument associated with the response (a string - * message from the player explaining why the response was refused in - * the case of an invitation refusal or an updated game configuration - * object in the case of a counter-invitation, or null in the case of - * an accepted invitation). + * @param inviteId the unique id previously assigned by the server to this invitation. + * @param code the response code to use in responding to the invitation. + * @param arg the argument associated with the response (a string message from the player + * explaining why the response was refused in the case of an invitation refusal or an updated + * game configuration object in the case of a counter-invitation, or null in the case of an + * accepted invitation). * @param listener will receive and process the response. */ public void respond (Client client, int inviteId, int code, Object arg, InvocationListener listener); /** - * You probably don't want to call this directly, but want to call - * {@link Invitation#cancel}. Requests that an outstanding - * invitation be cancelled. + * You probably don't want to call this directly, but want to call {@link + * Invitation#cancel}. Requests that an outstanding invitation be cancelled. * * @param client a connected, operational client instance. - * @param inviteId the unique id previously assigned by the server to - * this invitation. + * @param inviteId the unique id previously assigned by the server to this invitation. * @param listener will receive and process the response. */ - public void cancel (Client client, int inviteId, - InvocationListener listener); + public void cancel (Client client, int inviteId, InvocationListener listener); /** - * Used to communicate responses to {@link #createTable}, {@link - * #joinTable}, and {@link #leaveTable} requests. + * Requests to start a single player game with the specified game configuration. */ - public static interface TableListener extends InvocationListener - { - public void tableCreated (int tableId); - } - - /** - * You probably don't want to call this directly, but want to call - * {@link TableDirector#createTable}. Requests that a new table be - * created. - * - * @param client a connected, operational client instance. - * @param lobbyOid the oid of the lobby that will contain the newly - * created table. - * @param tableConfig the table configuration parameters. - * @param config the game config for the game to be matchmade by the - * table. - * @param listener will receive and process the response. - */ - public void createTable (Client client, int lobbyOid, - TableConfig tableConfig, GameConfig config, TableListener listener); - - /** - * You probably don't want to call this directly, but want to call - * {@link TableDirector#joinTable}. Requests that the current user - * be added to the specified table at the specified position. - * - * @param client a connected, operational client instance. - * @param lobbyOid the oid of the lobby that contains the table. - * @param tableId the unique id of the table to which this user wishes - * to be added. - * @param position the position at the table to which this user desires - * to be added. - * @param listener will receive and process the response. - */ - public void joinTable (Client client, int lobbyOid, int tableId, - int position, InvocationListener listener); - - /** - * You probably don't want to call this directly, but want to call - * {@link TableDirector#leaveTable}. Requests that the current user be - * removed from the specified table. - * - * @param client a connected, operational client instance. - * @param lobbyOid the oid of the lobby that contains the table. - * @param tableId the unique id of the table from which this user - * wishes to be removed. - * @param listener will receive and process the response. - */ - public void leaveTable (Client client, int lobbyOid, int tableId, - InvocationListener listener); - - /** - * You probably don't want to call this directly, but want to call - * {@link TableDirector#startTableNow}. Requests that the specified - * table be started now, even if all seats are not occupied. This - * will always fail if called by any other player than that seated - * in position 0 (usually the creator). - */ - public void startTableNow (Client client, int lobbyOid, int tableId, - InvocationListener listener); - - /** - * Requests to start a single player game with the specified game - * configuration. - */ - public void startSolitaire (Client client, GameConfig config, - ConfirmListener listener); + public void startSolitaire (Client client, GameConfig config, ConfirmListener listener); } diff --git a/src/java/com/threerings/parlor/client/TableDirector.java b/src/java/com/threerings/parlor/client/TableDirector.java index 38edf82b..706cba5e 100644 --- a/src/java/com/threerings/parlor/client/TableDirector.java +++ b/src/java/com/threerings/parlor/client/TableDirector.java @@ -44,39 +44,32 @@ import com.threerings.parlor.game.data.GameConfig; import com.threerings.parlor.util.ParlorContext; /** - * As tables are created and managed within the scope of a place (a - * lobby), we want to fold the table management functionality into the - * standard hierarchy of place controllers that deal with place-related - * functionality on the client. Thus, instead of forcing places that - * expect to have tables to extend a TableLobbyController or - * something similar, we instead provide the table director which can be - * instantiated by the place controller (or specific table related views) - * to handle the table matchmaking services. + * As tables are created and managed within the scope of a place (a lobby), we want to fold the + * table management functionality into the standard hierarchy of place controllers that deal with + * place-related functionality on the client. Thus, instead of forcing places that expect to have + * tables to extend a TableLobbyController or something similar, we instead provide + * the table director which can be instantiated by the place controller (or specific table related + * views) to handle the table matchmaking services. * - *

Entites that do so, will need to implement the {@link - * TableObserver} interface so that the table director can notify them - * when table related things happen. + *

Entites that do so, will need to implement the {@link TableObserver} interface so that the + * table director can notify them when table related things happen. * - *

The table services expect that the place object being used as a - * lobby in which the table matchmaking takes place implements the {@link - * TableLobbyObject} interface. + *

The table services expect that the place object being used as a lobby in which the table + * matchmaking takes place implements the {@link TableLobbyObject} interface. */ public class TableDirector extends BasicDirector - implements SetListener, ParlorService.TableListener + implements SetListener, TableService.ResultListener { /** - * Creates a new table director to manage tables with the specified - * observer which will receive callbacks when interesting table - * related things happen. + * Creates a new table director to manage tables with the specified observer which will receive + * callbacks when interesting table related things happen. * * @param ctx the parlor context in use by the client. - * @param tableField the field name of the distributed set that - * contains the tables we will be managing. - * @param observer the entity that will receive callbacks when things - * happen to the tables. + * @param tableField the field name of the distributed set that contains the tables we will be + * managing. + * @param observer the entity that will receive callbacks when things happen to the tables. */ - public TableDirector ( - ParlorContext ctx, String tableField, TableObserver observer) + public TableDirector (ParlorContext ctx, String tableField, TableObserver observer) { super(ctx); @@ -87,39 +80,33 @@ public class TableDirector extends BasicDirector } /** - * This must be called by the entity that uses the table director when - * the using entity prepares to enter and display a place. It is - * assumed that the client is already subscribed to the provided place - * object. + * This must be called by the entity that uses the table director when the using entity + * prepares to enter and display a place. It is assumed that the client is already subscribed + * to the provided place object. */ public void willEnterPlace (PlaceObject place) { // the place should be a TableLobbyObject - _tlobj = (TableLobbyObject) place; - _lobby = place; - + _tlobj = (TableLobbyObject)place; // add ourselves as a listener to the place object place.addListener(this); } /** - * This must be called by the entity that uses the table director when - * the using entity has left and is done displaying a place. + * This must be called by the entity that uses the table director when the using entity has + * left and is done displaying a place. */ public void didLeavePlace (PlaceObject place) { // remove our listenership place.removeListener(this); - - // clear out our lobby reference - _lobby = null; + // clear out our reference _tlobj = 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. + * 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) { @@ -127,9 +114,8 @@ public class TableDirector extends BasicDirector } /** - * 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. + * 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) { @@ -137,8 +123,7 @@ public class TableDirector extends BasicDirector } /** - * Returns true if this client is currently seated at a table, false - * if they are not. + * Returns true if this client is currently seated at a table, false if they are not. */ public boolean isSeated () { @@ -146,117 +131,100 @@ public class TableDirector extends BasicDirector } /** - * Sends a request to create a table with the specified game - * configuration. This user will become the owner of this table and - * will be added to the first position in the table. The response will - * be communicated via the {@link TableObserver} interface. + * Sends a request to create a table with the specified game configuration. This user will + * become the owner of this table and will be added to the first position in the table. The + * response will be communicated via the {@link TableObserver} interface. */ public void createTable (TableConfig tableConfig, GameConfig config) { // if we're already in a table, refuse the request if (_ourTable != null) { - Log.warning("Ignoring request to create table as we're " + - "already in a table [table=" + _ourTable + "]."); + Log.warning("Ignoring request to create table as we're already in a table " + + "[table=" + _ourTable + "]."); return; } // make sure we're currently in a place - if (_lobby == null) { - Log.warning("Requested to create a table but we're not " + - "currently in a place [config=" + config + "]."); + if (_tlobj == null) { + Log.warning("Requested to create a table but we're not currently in a place " + + "[config=" + config + "]."); return; } // go ahead and issue the create request - _pservice.createTable(_ctx.getClient(), _lobby.getOid(), tableConfig, - config, this); + _tlobj.getTableService().createTable(_ctx.getClient(), tableConfig, config, this); } /** - * Sends a request to join the specified table at the specified - * position. The response will be communicated via the {@link - * TableObserver} interface. + * Sends a request to join the specified table at the specified position. The response will be + * communicated via the {@link TableObserver} interface. */ public void joinTable (int tableId, int position) { // if we're already in a table, refuse the request if (_ourTable != null) { - Log.warning("Ignoring request to join table as we're " + - "already in a table [table=" + _ourTable + "]."); + Log.warning("Ignoring request to join table as we're already in a table " + + "[table=" + _ourTable + "]."); return; } // make sure we're currently in a place - if (_lobby == null) { - Log.warning("Requested to join a table but we're not " + - "currently in a place [tableId=" + tableId + "]."); + if (_tlobj == null) { + Log.warning("Requested to join a table but we're not currently in a place " + + "[tableId=" + tableId + "]."); return; } // issue the join request - _pservice.joinTable(_ctx.getClient(), _lobby.getOid(), tableId, - position, this); + _tlobj.getTableService().joinTable(_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. + * 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 + "]."); + if (_tlobj == null) { + Log.warning("Requested to leave a table but we're not currently in a place " + + "[tableId=" + tableId + "]."); return; } // issue the leave request - _pservice.leaveTable(_ctx.getClient(), _lobby.getOid(), tableId, this); + _tlobj.getTableService().leaveTable(_ctx.getClient(), tableId, this); } /** - * Sends a request to have the specified table start now, even if - * all the seats have not yet been filled. + * Sends a request to have the specified table start now, even if all the seats have not yet + * been filled. */ public void startTableNow (int tableId) { - if (_lobby == null) { - Log.warning("Requested to start a table but we're not " + - "currently in a place [tableId=" + tableId + "]."); + if (_tlobj == null) { + Log.warning("Requested to start a table but we're not currently in a place " + + "[tableId=" + tableId + "]."); return; } - _pservice.startTableNow(_ctx.getClient(), _lobby.getOid(), - tableId, this); + _tlobj.getTableService().startTableNow(_ctx.getClient(), tableId, this); } // documentation inherited public void clientDidLogoff (Client client) { super.clientDidLogoff(client); - _pservice = null; - _lobby = null; _ourTable = null; } - // documentation inherited - protected void fetchServices (Client client) - { - // get a handle on our parlor services - _pservice = (ParlorService)client.requireService(ParlorService.class); - } - // documentation inherited public void entryAdded (EntryAddedEvent event) { if (event.getName().equals(_tableField)) { Table table = (Table)event.getEntry(); - // check to see if we just joined a table checkSeatedness(table); - // now let the observer know what's up _observer.tableAdded(table); } @@ -267,10 +235,8 @@ public class TableDirector extends BasicDirector { if (event.getName().equals(_tableField)) { Table table = (Table)event.getEntry(); - // check to see if we just joined or left a table checkSeatedness(table); - // now let the observer know what's up _observer.tableUpdated(table); } @@ -281,43 +247,42 @@ public class TableDirector extends BasicDirector { if (event.getName().equals(_tableField)) { int tableId = ((Integer) event.getKey()).intValue(); - // check to see if our table just disappeared if (_ourTable != null && tableId == _ourTable.tableId) { _ourTable = null; notifySeatedness(false); } - // now let the observer know what's up _observer.tableRemoved(tableId); } } - // documentation inherited from interface - public void tableCreated (int tableId) + // from interface TableService.ResultListener + public void requestProcessed (Object result) { - if (_lobby == null) { + int tableId = (Integer)result; + if (_tlobj == null) { // we've left, it's none of our concern anymore Log.info("Table created, but no lobby. [tableId=" + tableId + "]."); return; } - // All this to check to see if we created a party game (and should now enter). Table table = (Table) _tlobj.getTables().get(tableId); if (table == null) { Log.warning("Table created, but where is it? [tableId=" + tableId + "]"); return; } + + // All this to check to see if we created a party game (and should now enter). if (table.gameOid != -1 && table.occupants.length == 0) { - // let's boogie! - _ctx.getParlorDirector().gameIsReady(table.gameOid); + _ctx.getParlorDirector().gameIsReady(table.gameOid); // let's boogie! } } // documentation inherited from interface public void requestFailed (String reason) { - Log.warning("Table creation failed [reason=" + reason + "]."); + Log.warning("Table action failed [reason=" + reason + "]."); } /** @@ -328,9 +293,8 @@ public class TableDirector extends BasicDirector { 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 + // 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 if (table.equals(_ourTable)) { _ourTable = null; } @@ -355,25 +319,18 @@ public class TableDirector extends BasicDirector */ protected void notifySeatedness (final boolean isSeated) { - _seatedObservers.apply( - new ObserverList.ObserverOp() { - public boolean apply (SeatednessObserver so) { - so.seatednessDidChange(isSeated); - return true; - } - }); + _seatedObservers.apply(new ObserverList.ObserverOp() { + public boolean apply (SeatednessObserver so) { + so.seatednessDidChange(isSeated); + return true; + } + }); } /** A context by which we can access necessary client services. */ protected ParlorContext _ctx; - /** Parlor server-side services. */ - protected ParlorService _pservice; - - /** The place object in which we're currently managing tables. */ - protected PlaceObject _lobby; - - /** The place object, cast as a TableLobbyObject. */ + /** Our TableLobbyObject. */ protected TableLobbyObject _tlobj; /** The field name of the distributed set that contains our tables. */ @@ -385,8 +342,7 @@ public class TableDirector extends BasicDirector /** 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. */ + /** An array of entities that want to hear about when we stand up or sit down. */ protected ObserverList _seatedObservers = new ObserverList(ObserverList.FAST_UNSAFE_NOTIFY); } diff --git a/src/java/com/threerings/parlor/client/TableService.java b/src/java/com/threerings/parlor/client/TableService.java new file mode 100644 index 00000000..0d436bdb --- /dev/null +++ b/src/java/com/threerings/parlor/client/TableService.java @@ -0,0 +1,71 @@ +// +// $Id$ +// +// Vilya library - tools for developing networked games +// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/vilya/ +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.parlor.client; + +import com.threerings.presents.client.Client; +import com.threerings.presents.client.InvocationService; + +import com.threerings.parlor.data.TableConfig; +import com.threerings.parlor.game.data.GameConfig; + +/** + * Provides table lobbying services. + */ +public interface TableService extends InvocationService +{ + /** + * Requests that a new table be created. + * + * @param client a connected, operational client instance. + * @param tableConfig the table configuration parameters. + * @param config the game config for the game to be matchmade by the table. + * @param listener will receive and process the response. + */ + public void createTable (Client client, TableConfig tableConfig, GameConfig config, + ResultListener listener); + + /** + * Requests that the current user be added to the specified table at the specified position. + * + * @param client a connected, operational client instance. + * @param tableId the unique id of the table to which this user wishes to be added. + * @param position the position at the table to which this user desires to be added. + * @param listener will receive and process the response. + */ + public void joinTable (Client client, int tableId, int position, InvocationListener listener); + + /** + * 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 listener will receive and process the response. + */ + public void leaveTable (Client client, int tableId, InvocationListener listener); + + /** + * Requests that the specified table be started now, even if all seats are not occupied. This + * will always fail if called by any other player than that seated in position 0 (usually the + * creator). + */ + public void startTableNow (Client client, int tableId, InvocationListener listener); +} diff --git a/src/java/com/threerings/parlor/data/ParlorMarshaller.java b/src/java/com/threerings/parlor/data/ParlorMarshaller.java index d986a7fa..4f5db2fd 100644 --- a/src/java/com/threerings/parlor/data/ParlorMarshaller.java +++ b/src/java/com/threerings/parlor/data/ParlorMarshaller.java @@ -22,7 +22,6 @@ package com.threerings.parlor.data; import com.threerings.parlor.client.ParlorService; -import com.threerings.parlor.data.TableConfig; import com.threerings.parlor.game.data.GameConfig; import com.threerings.presents.client.Client; import com.threerings.presents.client.InvocationService; @@ -75,41 +74,6 @@ public class ParlorMarshaller extends InvocationMarshaller } } - /** - * Marshalls results to implementations of {@link TableListener}. - */ - public static class TableMarshaller extends ListenerMarshaller - implements TableListener - { - /** The method id used to dispatch {@link #tableCreated} - * responses. */ - public static final int TABLE_CREATED = 1; - - // from interface TableMarshaller - public void tableCreated (int arg1) - { - _invId = null; - omgr.postEvent(new InvocationResponseEvent( - callerOid, requestId, TABLE_CREATED, - new Object[] { Integer.valueOf(arg1) })); - } - - @Override // from InvocationMarshaller - public void dispatchResponse (int methodId, Object[] args) - { - switch (methodId) { - case TABLE_CREATED: - ((TableListener)listener).tableCreated( - ((Integer)args[0]).intValue()); - return; - - default: - super.dispatchResponse(methodId, args); - return; - } - } - } - /** The method id used to dispatch {@link #cancel} requests. */ public static final int CANCEL = 1; @@ -123,21 +87,8 @@ public class ParlorMarshaller extends InvocationMarshaller }); } - /** The method id used to dispatch {@link #createTable} requests. */ - public static final int CREATE_TABLE = 2; - - // from interface ParlorService - public void createTable (Client arg1, int arg2, TableConfig arg3, GameConfig arg4, ParlorService.TableListener arg5) - { - ParlorMarshaller.TableMarshaller listener5 = new ParlorMarshaller.TableMarshaller(); - listener5.listener = arg5; - sendRequest(arg1, CREATE_TABLE, new Object[] { - Integer.valueOf(arg2), arg3, arg4, listener5 - }); - } - /** The method id used to dispatch {@link #invite} requests. */ - public static final int INVITE = 3; + public static final int INVITE = 2; // from interface ParlorService public void invite (Client arg1, Name arg2, GameConfig arg3, ParlorService.InviteListener arg4) @@ -149,34 +100,8 @@ public class ParlorMarshaller extends InvocationMarshaller }); } - /** The method id used to dispatch {@link #joinTable} requests. */ - public static final int JOIN_TABLE = 4; - - // from interface ParlorService - public void joinTable (Client arg1, int arg2, int arg3, int arg4, InvocationService.InvocationListener arg5) - { - ListenerMarshaller listener5 = new ListenerMarshaller(); - listener5.listener = arg5; - sendRequest(arg1, JOIN_TABLE, new Object[] { - Integer.valueOf(arg2), Integer.valueOf(arg3), Integer.valueOf(arg4), listener5 - }); - } - - /** The method id used to dispatch {@link #leaveTable} requests. */ - public static final int LEAVE_TABLE = 5; - - // from interface ParlorService - public void leaveTable (Client arg1, int arg2, int arg3, InvocationService.InvocationListener arg4) - { - ListenerMarshaller listener4 = new ListenerMarshaller(); - listener4.listener = arg4; - sendRequest(arg1, LEAVE_TABLE, new Object[] { - Integer.valueOf(arg2), Integer.valueOf(arg3), listener4 - }); - } - /** The method id used to dispatch {@link #respond} requests. */ - public static final int RESPOND = 6; + public static final int RESPOND = 3; // from interface ParlorService public void respond (Client arg1, int arg2, int arg3, Object arg4, InvocationService.InvocationListener arg5) @@ -189,7 +114,7 @@ public class ParlorMarshaller extends InvocationMarshaller } /** The method id used to dispatch {@link #startSolitaire} requests. */ - public static final int START_SOLITAIRE = 7; + public static final int START_SOLITAIRE = 4; // from interface ParlorService public void startSolitaire (Client arg1, GameConfig arg2, InvocationService.ConfirmListener arg3) @@ -200,17 +125,4 @@ public class ParlorMarshaller extends InvocationMarshaller arg2, listener3 }); } - - /** The method id used to dispatch {@link #startTableNow} requests. */ - public static final int START_TABLE_NOW = 8; - - // from interface ParlorService - public void startTableNow (Client arg1, int arg2, int arg3, InvocationService.InvocationListener arg4) - { - ListenerMarshaller listener4 = new ListenerMarshaller(); - listener4.listener = arg4; - sendRequest(arg1, START_TABLE_NOW, new Object[] { - Integer.valueOf(arg2), Integer.valueOf(arg3), listener4 - }); - } } diff --git a/src/java/com/threerings/parlor/data/TableLobbyObject.java b/src/java/com/threerings/parlor/data/TableLobbyObject.java index 58390949..a46cd044 100644 --- a/src/java/com/threerings/parlor/data/TableLobbyObject.java +++ b/src/java/com/threerings/parlor/data/TableLobbyObject.java @@ -53,4 +53,15 @@ public interface TableLobbyObject * tables set (using the appropriate distributed object mechanisms). */ public void removeFromTables (Comparable key); + + /** + * Returns a reference to the table service configured in this object. + */ + public TableMarshaller getTableService (); + + /** + * Configures the table service that clients should use to communicate table requests back to + * the table manager handling these tables. + */ + public void setTableService (TableMarshaller service); } diff --git a/src/java/com/threerings/parlor/data/TableMarshaller.java b/src/java/com/threerings/parlor/data/TableMarshaller.java new file mode 100644 index 00000000..432d05e4 --- /dev/null +++ b/src/java/com/threerings/parlor/data/TableMarshaller.java @@ -0,0 +1,93 @@ +// +// $Id$ +// +// Vilya library - tools for developing networked games +// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/vilya/ +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.parlor.data; + +import com.threerings.parlor.client.TableService; +import com.threerings.parlor.data.TableConfig; +import com.threerings.parlor.game.data.GameConfig; +import com.threerings.presents.client.Client; +import com.threerings.presents.client.InvocationService; +import com.threerings.presents.data.InvocationMarshaller; +import com.threerings.presents.dobj.InvocationResponseEvent; + +/** + * Provides the implementation of the {@link TableService} interface + * that marshalls the arguments and delivers the request to the provider + * on the server. Also provides an implementation of the response listener + * interfaces that marshall the response arguments and deliver them back + * to the requesting client. + */ +public class TableMarshaller extends InvocationMarshaller + implements TableService +{ + /** The method id used to dispatch {@link #createTable} requests. */ + public static final int CREATE_TABLE = 1; + + // from interface TableService + public void createTable (Client arg1, TableConfig arg2, GameConfig arg3, InvocationService.ResultListener arg4) + { + InvocationMarshaller.ResultMarshaller listener4 = new InvocationMarshaller.ResultMarshaller(); + listener4.listener = arg4; + sendRequest(arg1, CREATE_TABLE, new Object[] { + arg2, arg3, listener4 + }); + } + + /** The method id used to dispatch {@link #joinTable} requests. */ + public static final int JOIN_TABLE = 2; + + // from interface TableService + public void joinTable (Client arg1, int arg2, int arg3, InvocationService.InvocationListener arg4) + { + ListenerMarshaller listener4 = new ListenerMarshaller(); + listener4.listener = arg4; + sendRequest(arg1, JOIN_TABLE, new Object[] { + Integer.valueOf(arg2), Integer.valueOf(arg3), listener4 + }); + } + + /** The method id used to dispatch {@link #leaveTable} requests. */ + public static final int LEAVE_TABLE = 3; + + // from interface TableService + public void leaveTable (Client arg1, int arg2, InvocationService.InvocationListener arg3) + { + ListenerMarshaller listener3 = new ListenerMarshaller(); + listener3.listener = arg3; + sendRequest(arg1, LEAVE_TABLE, new Object[] { + Integer.valueOf(arg2), listener3 + }); + } + + /** The method id used to dispatch {@link #startTableNow} requests. */ + public static final int START_TABLE_NOW = 4; + + // from interface TableService + public void startTableNow (Client arg1, int arg2, InvocationService.InvocationListener arg3) + { + ListenerMarshaller listener3 = new ListenerMarshaller(); + listener3.listener = arg3; + sendRequest(arg1, START_TABLE_NOW, new Object[] { + Integer.valueOf(arg2), listener3 + }); + } +} diff --git a/src/java/com/threerings/parlor/server/ParlorDispatcher.java b/src/java/com/threerings/parlor/server/ParlorDispatcher.java index c549c3b4..e57cfa62 100644 --- a/src/java/com/threerings/parlor/server/ParlorDispatcher.java +++ b/src/java/com/threerings/parlor/server/ParlorDispatcher.java @@ -23,7 +23,6 @@ package com.threerings.parlor.server; import com.threerings.parlor.client.ParlorService; import com.threerings.parlor.data.ParlorMarshaller; -import com.threerings.parlor.data.TableConfig; import com.threerings.parlor.game.data.GameConfig; import com.threerings.presents.client.Client; import com.threerings.presents.client.InvocationService; @@ -66,13 +65,6 @@ public class ParlorDispatcher extends InvocationDispatcher ); return; - case ParlorMarshaller.CREATE_TABLE: - ((ParlorProvider)provider).createTable( - source, - ((Integer)args[0]).intValue(), (TableConfig)args[1], (GameConfig)args[2], (ParlorService.TableListener)args[3] - ); - return; - case ParlorMarshaller.INVITE: ((ParlorProvider)provider).invite( source, @@ -80,20 +72,6 @@ public class ParlorDispatcher extends InvocationDispatcher ); return; - case ParlorMarshaller.JOIN_TABLE: - ((ParlorProvider)provider).joinTable( - source, - ((Integer)args[0]).intValue(), ((Integer)args[1]).intValue(), ((Integer)args[2]).intValue(), (InvocationService.InvocationListener)args[3] - ); - return; - - case ParlorMarshaller.LEAVE_TABLE: - ((ParlorProvider)provider).leaveTable( - source, - ((Integer)args[0]).intValue(), ((Integer)args[1]).intValue(), (InvocationService.InvocationListener)args[2] - ); - return; - case ParlorMarshaller.RESPOND: ((ParlorProvider)provider).respond( source, @@ -108,13 +86,6 @@ public class ParlorDispatcher extends InvocationDispatcher ); return; - case ParlorMarshaller.START_TABLE_NOW: - ((ParlorProvider)provider).startTableNow( - source, - ((Integer)args[0]).intValue(), ((Integer)args[1]).intValue(), (InvocationService.InvocationListener)args[2] - ); - return; - default: super.dispatchRequest(source, methodId, args); return; diff --git a/src/java/com/threerings/parlor/server/ParlorManager.java b/src/java/com/threerings/parlor/server/ParlorManager.java index edb363b7..49bc21a6 100644 --- a/src/java/com/threerings/parlor/server/ParlorManager.java +++ b/src/java/com/threerings/parlor/server/ParlorManager.java @@ -24,14 +24,18 @@ package com.threerings.parlor.server; import com.samskivert.util.HashIntMap; import com.threerings.util.Name; +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.CrowdServer; import com.threerings.crowd.server.PlaceRegistry; import com.threerings.parlor.Log; +import com.threerings.parlor.client.ParlorService; import com.threerings.parlor.data.ParlorCodes; +import com.threerings.parlor.data.TableConfig; import com.threerings.parlor.game.data.GameConfig; import com.threerings.parlor.game.server.GameManager; @@ -42,11 +46,8 @@ import com.threerings.parlor.game.server.GameManager; * game. */ public class ParlorManager - implements ParlorCodes + implements ParlorCodes, ParlorProvider { - /** Provides the server-side implementation of the parlor services. */ - public ParlorProvider parprov; - /** * Initializes the parlor manager. This should be called by the server that is making use of * the parlor services on the single instance of parlor manager that it has created. @@ -58,13 +59,78 @@ public class ParlorManager public void init (InvocationManager invmgr, PlaceRegistry plreg) { // create and register our invocation provider - parprov = new ParlorProvider(this); - invmgr.registerDispatcher(new ParlorDispatcher(parprov), PARLOR_GROUP); + invmgr.registerDispatcher(new ParlorDispatcher(this), PARLOR_GROUP); // keep this for later _plreg = plreg; } + // from interface ParlorProvider + public void invite (ClientObject caller, Name invitee, GameConfig config, + ParlorService.InviteListener listener) + throws InvocationException + { +// Log.info("Handling invite request [source=" + source + ", invitee=" + invitee + +// ", config=" + config + "]."); + + BodyObject source = (BodyObject)caller; + String rsp = null; + + // ensure that the invitee is online at present + BodyObject target = CrowdServer.lookupBody(invitee); + if (target == null) { + throw new InvocationException(INVITEE_NOT_ONLINE); + } + + int inviteId = invite(source, target, config); + listener.inviteReceived(inviteId); + } + + // from interface ParlorProvider + public void respond (ClientObject caller, int inviteId, int code, Object arg, + ParlorService.InvocationListener listener) + { + // pass this on to the parlor manager + respondToInvite((BodyObject)caller, inviteId, code, arg); + } + + // from interface ParlorProvider + public void cancel (ClientObject caller, int inviteId, + ParlorService.InvocationListener listener) + { + cancelInvite((BodyObject)caller, inviteId); + } + + // from interface ParlorProvider + public void startSolitaire (ClientObject caller, GameConfig config, + ParlorService.ConfirmListener listener) + throws InvocationException + { + BodyObject user = (BodyObject)caller; + + Log.debug("Processing start solitaire [caller=" + user.who() + ", config=" + config + "]."); + + try { + // just this fellow will be playing + if (config.players == null || config.players.length == 0) { + config.players = new Name[] { user.getVisibleName() }; + } + + // create the game manager and begin its initialization process + CrowdServer.plreg.createPlace(config); + + // the game manager will notify the player that their game is + // "ready", but tell the caller that we processed their request + listener.requestProcessed(); + + } catch (InstantiationException ie) { + Log.warning("Error instantiating game manager " + + "[for=" + caller.who() + ", config=" + config + "]."); + Log.logStackTrace(ie); + throw new InvocationException(INTERNAL_ERROR); + } + } + /** * Issues an invitation from the inviter to the invitee for a game as * described by the supplied config object. @@ -79,8 +145,7 @@ public class ParlorManager * 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 int invite (BodyObject inviter, BodyObject invitee, - GameConfig config) + public int invite (BodyObject inviter, BodyObject invitee, GameConfig config) throws InvocationException { // Log.info("Received invitation request [inviter=" + inviter + diff --git a/src/java/com/threerings/parlor/server/ParlorProvider.java b/src/java/com/threerings/parlor/server/ParlorProvider.java index 4e75143e..eb22cba6 100644 --- a/src/java/com/threerings/parlor/server/ParlorProvider.java +++ b/src/java/com/threerings/parlor/server/ParlorProvider.java @@ -21,221 +21,41 @@ package com.threerings.parlor.server; -import com.threerings.util.Name; - +import com.threerings.parlor.client.ParlorService; +import com.threerings.parlor.game.data.GameConfig; +import com.threerings.presents.client.Client; import com.threerings.presents.client.InvocationService; -import com.threerings.presents.client.InvocationService.InvocationListener; import com.threerings.presents.data.ClientObject; import com.threerings.presents.server.InvocationException; import com.threerings.presents.server.InvocationProvider; - -import com.threerings.crowd.data.BodyObject; -import com.threerings.crowd.server.CrowdServer; -import com.threerings.crowd.server.PlaceManager; - -import com.threerings.parlor.Log; -import com.threerings.parlor.client.ParlorService; -import com.threerings.parlor.data.ParlorCodes; -import com.threerings.parlor.data.TableConfig; -import com.threerings.parlor.game.data.GameConfig; -import com.threerings.parlor.game.server.GameManager; +import com.threerings.util.Name; /** - * The parlor provider handles the server side of the various Parlor - * services that are made available for direct invocation by the client. - * Primarily these are the matchmaking mechanisms. + * Defines the server-side of the {@link ParlorService}. */ -public class ParlorProvider - implements InvocationProvider, ParlorCodes +public interface ParlorProvider extends InvocationProvider { /** - * Constructs a parlor provider instance which will be used to handle - * all parlor-related invocation service requests. This is - * automatically taken care of by the parlor manager, so no other - * entity need instantiate and register a parlor provider. - * - * @param pmgr a reference to the parlor manager active in this - * server. + * Handles a {@link ParlorService#cancel} request. */ - public ParlorProvider (ParlorManager pmgr) - { - _pmgr = pmgr; - } + public void cancel (ClientObject caller, int arg1, InvocationService.InvocationListener arg2) + throws InvocationException; /** - * Processes a request from the client to invite another user to play - * a game. + * Handles a {@link ParlorService#invite} request. */ - public void invite (ClientObject caller, Name invitee, GameConfig config, - ParlorService.InviteListener listener) - throws InvocationException - { -// Log.info("Handling invite request [source=" + source + -// ", invitee=" + invitee + ", config=" + config + "]."); - - BodyObject source = (BodyObject)caller; - String rsp = null; - - // ensure that the invitee is online at present - BodyObject target = CrowdServer.lookupBody(invitee); - if (target == null) { - throw new InvocationException(INVITEE_NOT_ONLINE); - } - - // submit the invite request to the parlor manager - int inviteId = _pmgr.invite(source, target, config); - listener.inviteReceived(inviteId); - } + public void invite (ClientObject caller, Name arg1, GameConfig arg2, ParlorService.InviteListener arg3) + throws InvocationException; /** - * Processes a request from the client to respond to an outstanding - * invitation by accepting, refusing, or countering it. + * Handles a {@link ParlorService#respond} request. */ - public void respond (ClientObject caller, int inviteId, int code, - Object arg, InvocationListener listener) - { - // pass this on to the parlor manager - _pmgr.respondToInvite((BodyObject)caller, inviteId, code, arg); - } - - /** - * Processes a request from the client to cancel an outstanding - * invitation. - */ - public void cancel (ClientObject caller, int inviteId, - InvocationListener listener) - { - // pass this on to the parlor manager - _pmgr.cancelInvite((BodyObject)caller, inviteId); - } - - /** - * Processes a request from the client to create a new table. - */ - public void createTable ( - ClientObject caller, int lobbyOid, TableConfig tableConfig, - GameConfig config, ParlorService.TableListener listener) - throws InvocationException - { - Log.info("Handling create table request [caller=" + caller.who() + - ", lobbyOid=" + lobbyOid + ", config=" + config + "]."); - - // pass the creation request on to the table manager - TableManager tmgr = getTableManager(lobbyOid); - int tableId = tmgr.createTable((BodyObject)caller, tableConfig, config); - listener.tableCreated(tableId); - } - - /** - * Processes a request from the client to join an existing table. - */ - public void joinTable (ClientObject caller, int lobbyOid, int tableId, - int position, InvocationListener listener) - throws InvocationException - { - Log.info("Handling join table request [caller=" + caller.who() + - ", lobbyOid=" + lobbyOid + ", tableId=" + tableId + - ", position=" + position + "]."); - - // pass the join request on to the table manager - TableManager tmgr = getTableManager(lobbyOid); - tmgr.joinTable((BodyObject)caller, tableId, position); - - // there is normally no success response. the client will see - // themselves show up in the table that they joined - } - - /** - * Processes a request from the client to leave an existing table. - */ - public void leaveTable (ClientObject caller, int lobbyOid, int tableId, - InvocationListener listener) - throws InvocationException - { - Log.info("Handling leave table request [caller=" + caller.who() + - ", lobbyOid=" + lobbyOid + ", tableId=" + tableId + "]."); - - // pass the join request on to the table manager - TableManager tmgr = getTableManager(lobbyOid); - tmgr.leaveTable((BodyObject)caller, tableId); - - // there is normally no success response. the client will see - // themselves removed from the table they just left - } + public void respond (ClientObject caller, int arg1, int arg2, Object arg3, InvocationService.InvocationListener arg4) + throws InvocationException; /** * Handles a {@link ParlorService#startSolitaire} request. */ - public void startTableNow (ClientObject caller, int lobbyOid, int tableId, - InvocationService.InvocationListener listener) - throws InvocationException - { - TableManager tmgr = getTableManager(lobbyOid); - tmgr.startTableNow((BodyObject) caller, tableId); - } - - /** - * Handles a {@link ParlorService#startSolitaire} request. - */ - public void startSolitaire (ClientObject caller, GameConfig config, - InvocationService.ConfirmListener listener) - throws InvocationException - { - BodyObject user = (BodyObject)caller; - - Log.debug("Processing start puzzle [caller=" + user.who() + - ", config=" + config + "]."); - - try { - // just this fellow will be playing - if (config.players == null || config.players.length == 0) { - config.players = new Name[] { user.getVisibleName() }; - } - - // create the game manager and begin its initialization process - CrowdServer.plreg.createPlace(config); - - // the game manager will notify the player that their game is - // "ready", but tell the caller that we processed their request - listener.requestProcessed(); - - } catch (InstantiationException ie) { - Log.warning("Error instantiating game manager " + - "[for=" + caller.who() + ", config=" + config + "]."); - Log.logStackTrace(ie); - throw new InvocationException(INTERNAL_ERROR); - } - } - - /** - * Looks up the place manager associated with the supplied lobby oid, - * casts it to a table lobby manager and obtains the associated table - * manager reference. - * - * @exception InvocationException thrown if something goes wrong - * along the way like no place manager exists or the place manager - * that does exist doesn't implement table lobby manager. - */ - protected TableManager getTableManager (int lobbyOid) - throws InvocationException - { - PlaceManager plmgr = CrowdServer.plreg.getPlaceManager(lobbyOid); - if (plmgr == null) { - Log.warning("No place manager exists from which to obtain " + - "table manager reference [ploid=" + lobbyOid + "]."); - throw new InvocationException(INTERNAL_ERROR); - } - - // sanity check - if (!(plmgr instanceof TableManagerProvider)) { - Log.warning("Place manager not a table lobby manager " + - "[plmgr=" + plmgr + "]."); - throw new InvocationException(INTERNAL_ERROR); - } - - return ((TableManagerProvider)plmgr).getTableManager(); - } - - /** A reference to the parlor manager we're working with. */ - protected ParlorManager _pmgr; + public void startSolitaire (ClientObject caller, GameConfig arg1, InvocationService.ConfirmListener arg2) + throws InvocationException; } diff --git a/src/java/com/threerings/parlor/server/TableDispatcher.java b/src/java/com/threerings/parlor/server/TableDispatcher.java new file mode 100644 index 00000000..6ee19eb8 --- /dev/null +++ b/src/java/com/threerings/parlor/server/TableDispatcher.java @@ -0,0 +1,94 @@ +// +// $Id$ +// +// Vilya library - tools for developing networked games +// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/vilya/ +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.parlor.server; + +import com.threerings.parlor.client.TableService; +import com.threerings.parlor.data.TableConfig; +import com.threerings.parlor.data.TableMarshaller; +import com.threerings.parlor.game.data.GameConfig; +import com.threerings.presents.client.Client; +import com.threerings.presents.client.InvocationService; +import com.threerings.presents.data.ClientObject; +import com.threerings.presents.data.InvocationMarshaller; +import com.threerings.presents.server.InvocationDispatcher; +import com.threerings.presents.server.InvocationException; + +/** + * Dispatches requests to the {@link TableProvider}. + */ +public class TableDispatcher extends InvocationDispatcher +{ + /** + * Creates a dispatcher that may be registered to dispatch invocation + * service requests for the specified provider. + */ + public TableDispatcher (TableProvider provider) + { + this.provider = provider; + } + + // from InvocationDispatcher + public InvocationMarshaller createMarshaller () + { + return new TableMarshaller(); + } + + @SuppressWarnings("unchecked") // from InvocationDispatcher + public void dispatchRequest ( + ClientObject source, int methodId, Object[] args) + throws InvocationException + { + switch (methodId) { + case TableMarshaller.CREATE_TABLE: + ((TableProvider)provider).createTable( + source, + (TableConfig)args[0], (GameConfig)args[1], (InvocationService.ResultListener)args[2] + ); + return; + + case TableMarshaller.JOIN_TABLE: + ((TableProvider)provider).joinTable( + source, + ((Integer)args[0]).intValue(), ((Integer)args[1]).intValue(), (InvocationService.InvocationListener)args[2] + ); + return; + + case TableMarshaller.LEAVE_TABLE: + ((TableProvider)provider).leaveTable( + source, + ((Integer)args[0]).intValue(), (InvocationService.InvocationListener)args[1] + ); + return; + + case TableMarshaller.START_TABLE_NOW: + ((TableProvider)provider).startTableNow( + source, + ((Integer)args[0]).intValue(), (InvocationService.InvocationListener)args[1] + ); + return; + + default: + super.dispatchRequest(source, methodId, args); + return; + } + } +} diff --git a/src/java/com/threerings/parlor/server/TableManager.java b/src/java/com/threerings/parlor/server/TableManager.java index 59913580..5a1437d5 100644 --- a/src/java/com/threerings/parlor/server/TableManager.java +++ b/src/java/com/threerings/parlor/server/TableManager.java @@ -28,7 +28,8 @@ import com.samskivert.util.HashIntMap; import com.samskivert.util.StringUtil; import com.threerings.util.Name; -import com.threerings.presents.dobj.ChangeListener; +import com.threerings.presents.data.ClientObject; +import com.threerings.presents.dobj.DObject; import com.threerings.presents.dobj.NamedEvent; import com.threerings.presents.dobj.ObjectAddedEvent; import com.threerings.presents.dobj.ObjectDeathListener; @@ -44,39 +45,43 @@ import com.threerings.crowd.server.CrowdServer; import com.threerings.crowd.server.PlaceManager; import com.threerings.parlor.Log; +import com.threerings.parlor.client.TableService; import com.threerings.parlor.data.ParlorCodes; import com.threerings.parlor.data.Table; import com.threerings.parlor.data.TableConfig; import com.threerings.parlor.data.TableLobbyObject; +import com.threerings.parlor.data.TableMarshaller; import com.threerings.parlor.game.data.GameConfig; import com.threerings.parlor.game.data.GameObject; import com.threerings.parlor.game.server.GameManager; /** - * A table manager can be used by a place manager to take care of the - * management of a table matchmaking service in the place managed by the - * place manager. The place manager need instantiate a table manager and - * implement the {@link TableManagerProvider} interface to provide access - * to the table manager for the associated invocation services. + * A table manager can be used by a place manager (or other entity) to take care of the management + * of a table matchmaking service in the place managed by the place manager (or on some other + * distributed object). The place manager need instantiate a table manager and implement the {@link + * TableManagerProvider} interface to provide access to the table manager for the associated + * invocation services. */ public class TableManager - implements ParlorCodes, OidListListener + implements ParlorCodes, OidListListener, TableProvider { /** - * Creates a table manager that will work in tandem with the specified - * place manager to manage a table matchmaking service in this place. + * Creates a table manager that will manage tables in the supplied distributed object (which + * must implement {@link TableLobbyObject}. */ - public TableManager (PlaceManager plmgr) + public TableManager (DObject tableObject) { - // get a reference to our place object - _plobj = plmgr.getPlaceObject(); + // set up our object references + _tlobj = (TableLobbyObject)tableObject; + _tlobj.setTableService( + (TableMarshaller)CrowdServer.invmgr.registerDispatcher(new TableDispatcher(this))); + _dobj = tableObject; - // add ourselves as an oidlist listener to this lobby so that we - // can tell if a user leaves the lobby without leaving their table - _plobj.addListener(this); - - // make sure it implements table lobby object - _tlobj = (TableLobbyObject)_plobj; + // if our table is in a "place" add ourselves as a listener so that we can tell if a user + // leaves the place without leaving their table + if (_dobj instanceof PlaceObject) { + _dobj.addListener(this); + } } /** @@ -87,33 +92,19 @@ public class TableManager _tableClass = tableClass; } - /** - * Requests that a new table be created to matchmake the game - * described by the supplied game config instance. The config instance - * provided must implement the {@link TableConfig} interface so that - * the parlor services can determine how to configure the table that - * will be created. - * - * @param creator the body object that will own the new table. - * @param tableConfig the configuration parameters for the table. - * @param config the configuration of the game to be created. - * - * @return the id of the newly created table. - * - * @exception InvocationException thrown if the table creation was - * not able processed for some reason. The explanation will be - * provided in the message data of the exception. - */ - public int createTable (BodyObject creator, TableConfig tableConfig, - GameConfig config) + // from interface ParlorProvider + public void createTable (ClientObject caller, TableConfig tableConfig, GameConfig config, + TableService.ResultListener listener) throws InvocationException { - // make sure the creator is an occupant of the lobby in which - // they are requesting to create a table - if (!_plobj.occupants.contains(creator.getOid())) { - Log.warning("Requested to create a table in a lobby not " + - "occupied by the creator [creator=" + creator + - ", loboid=" + _plobj.getOid() + "]."); + BodyObject creator = (BodyObject)caller; + + // if we're managing tables in a place, make sure the creator is an occupant of the place + // in which they are requesting to create a table + if (_dobj instanceof PlaceObject && + !((PlaceObject)_dobj).occupants.contains(creator.getOid())) { + Log.warning("Requested to create a table in a place not occupied by the creator " + + "[creator=" + creator + ", ploid=" + _dobj.getOid() + "]."); throw new InvocationException(INTERNAL_ERROR); } @@ -122,26 +113,25 @@ public class TableManager try { table = _tableClass.newInstance(); } catch (Exception e) { - Log.warning("Unable to create a new table instance! " + - "[tableClass=" + _tableClass + ", error=" + e + "]."); + Log.warning("Unable to create a new table instance! [tableClass=" + _tableClass + + ", error=" + e + "]."); throw new InvocationException(INTERNAL_ERROR); } - table.init(_plobj.getOid(), tableConfig, config); + table.init(_dobj.getOid(), tableConfig, config); if (table.bodyOids != null && table.bodyOids.length > 0) { // stick the creator into the first non-AI position int cpos = (config.ais == null) ? 0 : config.ais.length; String error = table.setOccupant(cpos, creator); if (error != null) { - Log.warning("Unable to add creator to position zero of " + - "table!? [table=" + table + ", creator=" + creator + - ", error=" + error + "]."); + Log.warning("Unable to add creator to position zero of table!? [table=" + table + + ", creator=" + creator + ", error=" + error + "]."); // bail out now and abort the table creation process throw new InvocationException(error); } // make a mapping from the creator to this table - _boidMap.put(creator.getOid(), table); + notePlayerAdded(table, creator.getOid()); } // stick the table into the table lobby object @@ -155,32 +145,16 @@ public class TableManager int oid = createGame(table); } - // finally let the caller know what the new table id is - return table.tableId; + listener.requestProcessed(table.tableId); } - /** - * Requests that the specified user be added to the specified table at - * the specified position. If the user successfully joins the table, - * the function will return normally. If they are not able to join for - * some reason (the slot is already full, etc.), a {@link - * InvocationException} will be thrown with a message code that - * describes the reason for failure. If the user does successfully - * join, they will be added to the table entry in the tables set in - * the place object that is hosting the table. - * - * @param joiner the body object of the user that wishes to join the - * table. - * @param tableId the id of the table to be joined. - * @param position the position at which to join the table. - * - * @exception InvocationException 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) + // from interface ParlorProvider + public void joinTable (ClientObject caller, int tableId, int position, + TableService.InvocationListener listener) throws InvocationException { + BodyObject joiner = (BodyObject)caller; + // look the table up Table table = _tables.get(tableId); if (table == null) { @@ -199,32 +173,23 @@ public class TableManager createGame(table); } else { // make a mapping from this occupant to this table - _boidMap.put(joiner.getOid(), table); + notePlayerAdded(table, joiner.getOid()); } // update the table in the lobby _tlobj.updateTables(table); + + // there is normally no success response. the client will see + // themselves show up in the table that they joined } - /** - * 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 - * InvocationException} 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 InvocationException 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) + // from interface ParlorProvider + public void leaveTable (ClientObject caller, int tableId, + TableService.InvocationListener listener) throws InvocationException { + BodyObject leaver = (BodyObject)caller; + // look the table up Table table = _tables.get(tableId); if (table == null) { @@ -237,57 +202,42 @@ public class TableManager } // remove the mapping from this user to the table - if (_boidMap.remove(leaver.getOid()) == null) { - Log.warning("No body to table mapping to clear? " + - "[leaver=" + leaver + ", table=" + table + "]."); + if (!notePlayerRemoved(table, leaver.getOid())) { + Log.warning("No body to table mapping to clear? [leaver=" + leaver + + ", table=" + table + "]."); } - // either update or delete the table depending on whether or not - // we just removed the last occupant + // either update or delete the table depending on whether or not we just removed the last + // occupant if (table.isEmpty()) { purgeTable(table); } else { _tlobj.updateTables(table); } + + // there is normally no success response. the client will see + // themselves removed from the table they just left } - /** - * Requests that the specified table be started now, even if there are - * some vacant seats. This may only be done if the minimum number of - * players are already present at the table. By convention, only the - * player at seat 0 may request to have the game start early, as they - * are usually the creator. - * - * @param requester the body object of the user that wishes to start - * the table. - * @param tableId the id of the table to be started. - * - * @exception InvocationException thrown if the starting was not able - * processed for some reason. The explanation will be provided in the - * message data of the exception. - */ - public void startTableNow (BodyObject requester, int tableId) + // from interface ParlorProvider + public void startTableNow (ClientObject caller, int tableId, + TableService.InvocationListener listener) throws InvocationException { - // look the table up + BodyObject starter = (BodyObject)caller; Table table = _tables.get(tableId); if (table == null) { throw new InvocationException(NO_SUCH_TABLE); - - } else if (requester.getOid() != table.bodyOids[0]) { + } else if (starter.getOid() != table.bodyOids[0]) { throw new InvocationException(INVALID_TABLE_POSITION); - } else if (!table.mayBeStarted()) { throw new InvocationException(INTERNAL_ERROR); } - - // I guess we're ready to go! createGame(table); } /** - * Removes the table from all of our internal tables and from its - * lobby's distributed object. + * Removes the table from all of our internal tables and from its lobby's distributed object. */ protected void purgeTable (Table table) { @@ -297,7 +247,7 @@ public class TableManager // clear out all matching entries in the boid map if (table.bodyOids != null) { for (int ii = 0; ii < table.bodyOids.length; ii++) { - _boidMap.remove(table.bodyOids[ii]); + notePlayerRemoved(table, table.bodyOids[ii]); } } @@ -309,9 +259,30 @@ public class TableManager } /** - * 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 - * creating the game manager, it should be reported in the logs. + * Called when a player is added to a table to set up our mappings. + */ + protected void notePlayerAdded (Table table, int playerOid) + { + _boidMap.put(playerOid, table); + + // TODO: if we're not in a place, listen to the player's BodyObject for object death so + // that we remove them from their table if they logoff + } + + /** + * Called when a player leaves a table to clear our mappings. + */ + protected boolean notePlayerRemoved (Table table, int playerOid) + { + boolean removed = (_boidMap.remove(playerOid) != null); + // TODO: remove our BodyObject death listener + return removed; + } + + /** + * 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 creating the game manager, it should be reported in + * the logs. * * @return the oid of the newly-created game. */ @@ -325,8 +296,7 @@ public class TableManager return gobj.getOid(); } catch (Throwable t) { - Log.warning("Failed to create manager for game " + - "[config=" + table.config + "]: " + t); + Log.warning("Failed to create manager for game [config=" + table.config + "]: " + t); throw new InvocationException(INTERNAL_ERROR); } } @@ -344,8 +314,8 @@ public class TableManager } /** - * Called when our game has been created, we take this opportunity to clean - * up the table and transition it to "in play" mode. + * Called when our game has been created, we take this opportunity to clean up the table and + * transition it to "in play" mode. */ protected void gameCreated (Table table, GameObject gameobj) { @@ -365,8 +335,7 @@ public class TableManager } } - // add an object death listener to unmap the table when the game - // finally goes away + // add an object death listener to unmap the table when the game finally goes away gameobj.addListener(_gameListener); // and then update the lobby object that contains the table @@ -374,18 +343,16 @@ public class TableManager } /** - * Called when a game created from a table managed by this table - * manager was destroyed. We remove the associated table. + * Called when a game created from a table managed by this table manager was destroyed. We + * remove the associated table. */ protected void unmapTable (int gameOid) { Table table = _goidMap.get(gameOid); if (table != null) { purgeTable(table); - } else { - Log.warning("Requested to unmap table that wasn't mapped " + - "[gameOid=" + gameOid + "]."); + Log.warning("Requested to unmap table that wasn't mapped [gameOid=" + gameOid + "]."); } } @@ -396,8 +363,7 @@ public class TableManager { Table table = _goidMap.get(gameOid); if (table == null) { - Log.warning("Unable to find table for running game " + - "[gameOid=" + gameOid + "]."); + Log.warning("Unable to find table for running game [gameOid=" + gameOid + "]."); return; } @@ -437,13 +403,13 @@ public class TableManager // remove this occupant from the table if (!pender.clearOccupantByOid(bodyOid)) { - Log.warning("Attempt to remove body from mapped table failed " + - "[table=" + pender + ", bodyOid=" + bodyOid + "]."); + Log.warning("Attempt to remove body from mapped table failed [table=" + pender + + ", bodyOid=" + bodyOid + "]."); return; } - // either update or delete the table depending on whether or not - // we just removed the last occupant + // either update or delete the table depending on whether or not we just removed the last + // occupant if (pender.isEmpty()) { purgeTable(pender); } else { @@ -451,15 +417,15 @@ public class TableManager } } - /** A reference to the place object in which we're managing tables. */ - protected PlaceObject _plobj; + /** A reference to the distributed object in which we're managing tables. */ + protected DObject _dobj; + + /** A reference to our distributed object casted to a table lobby object. */ + protected TableLobbyObject _tlobj; /** The class of table we instantiate. */ protected Class _tableClass = Table.class; - /** A reference to our place object casted to a table lobby object. */ - protected TableLobbyObject _tlobj; - /** The table of pending tables. */ protected HashIntMap _tables = new HashIntMap
(); @@ -488,9 +454,7 @@ public class TableManager maybeCheckOccupants(event); } - /** - * Check to see if the set event causes us to update the table. - */ + /** Check to see if the set event causes us to update the table. */ protected void maybeCheckOccupants (NamedEvent event) { if (GameObject.OCCUPANTS.equals(event.getName())) { updateOccupants(event.getTargetOid()); @@ -499,5 +463,5 @@ public class TableManager } // END: class GameDeathListener /** A listener that prunes tables after the game dies. */ - protected ChangeListener _gameListener = new GameListener(); + protected GameListener _gameListener = new GameListener(); } diff --git a/src/java/com/threerings/parlor/server/TableManagerProvider.java b/src/java/com/threerings/parlor/server/TableManagerProvider.java index f2f294ec..acd6577f 100644 --- a/src/java/com/threerings/parlor/server/TableManagerProvider.java +++ b/src/java/com/threerings/parlor/server/TableManagerProvider.java @@ -22,16 +22,15 @@ package com.threerings.parlor.server; /** - * A place manager that wishes to provide table matchmaking services in - * its place needs to create a table manager and make it available by - * implementing this interface. The table invocation services and the - * table manager will take care of the rest. + * A place manager that wishes to provide table matchmaking services in its place needs to create a + * table manager and make it available by implementing this interface. The table invocation + * services and the table manager will take care of the rest. */ public interface TableManagerProvider { /** - * Returns a reference to the table manager that is responsible for - * table management in this lobby. + * Returns a reference to the table manager that is responsible for table management in this + * lobby. */ public TableManager getTableManager (); } diff --git a/src/java/com/threerings/parlor/server/TableProvider.java b/src/java/com/threerings/parlor/server/TableProvider.java new file mode 100644 index 00000000..a7f345bc --- /dev/null +++ b/src/java/com/threerings/parlor/server/TableProvider.java @@ -0,0 +1,61 @@ +// +// $Id$ +// +// Vilya library - tools for developing networked games +// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/vilya/ +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.parlor.server; + +import com.threerings.parlor.client.TableService; +import com.threerings.parlor.data.TableConfig; +import com.threerings.parlor.game.data.GameConfig; +import com.threerings.presents.client.Client; +import com.threerings.presents.client.InvocationService; +import com.threerings.presents.data.ClientObject; +import com.threerings.presents.server.InvocationException; +import com.threerings.presents.server.InvocationProvider; + +/** + * Defines the server-side of the {@link TableService}. + */ +public interface TableProvider extends InvocationProvider +{ + /** + * Handles a {@link TableService#createTable} request. + */ + public void createTable (ClientObject caller, TableConfig arg1, GameConfig arg2, InvocationService.ResultListener arg3) + throws InvocationException; + + /** + * Handles a {@link TableService#joinTable} request. + */ + public void joinTable (ClientObject caller, int arg1, int arg2, InvocationService.InvocationListener arg3) + throws InvocationException; + + /** + * Handles a {@link TableService#leaveTable} request. + */ + public void leaveTable (ClientObject caller, int arg1, InvocationService.InvocationListener arg2) + throws InvocationException; + + /** + * Handles a {@link TableService#startTableNow} request. + */ + public void startTableNow (ClientObject caller, int arg1, InvocationService.InvocationListener arg2) + throws InvocationException; +}