If we're going to do this, I guess we're going to do it properly. Nixed the
notion of a global group (though we implicitly define one in InvocationCodes) added a mechanism for directors (which generally handle the client side of invocation services) to register their interest in bootstrap service groups so that the whole goddamned complex business can happen magically behind the scenes. If you instantiate a director, it will automatically register interest in the service group it needs and everything will work. If you don't use the director code, you don't get the services and you can safely exclude all of that code from your client even though the services are still in use on the server (and presumably used by some other types of clients). This is going to break all the builds, which I'll soon fix. Then I'll go write all this in ActionScript. Yay! git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4552 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -24,19 +24,17 @@ package com.threerings.presents.client;
|
||||
import com.threerings.presents.util.PresentsContext;
|
||||
|
||||
/**
|
||||
* Handles functionality common to nearly all client directors. They
|
||||
* generally need to be session observers so that they can set themselves
|
||||
* up when the client logs on (by overriding {@link #clientDidLogon}) and
|
||||
* clean up after themselves when the client logs off (by overriding
|
||||
* {@link #clientDidLogoff}).
|
||||
* Handles functionality common to nearly all client directors. They generally need to be session
|
||||
* observers so that they can set themselves up when the client logs on (by overriding {@link
|
||||
* #clientDidLogon}) and clean up after themselves when the client logs off (by overriding {@link
|
||||
* #clientDidLogoff}).
|
||||
*/
|
||||
public class BasicDirector
|
||||
implements SessionObserver
|
||||
{
|
||||
/**
|
||||
* Derived directors will need to provide the basic director with a
|
||||
* context that it can use to register itself with the necessary
|
||||
* entities.
|
||||
* Derived directors will need to provide the basic director with a context that it can use to
|
||||
* register itself with the necessary entities.
|
||||
*/
|
||||
protected BasicDirector (PresentsContext ctx)
|
||||
{
|
||||
@@ -56,6 +54,12 @@ public class BasicDirector
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void clientWillLogon (Client client)
|
||||
{
|
||||
registerServices(client);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void clientDidLogon (Client client)
|
||||
{
|
||||
@@ -85,8 +89,7 @@ public class BasicDirector
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether or not this director is available in standalone mode
|
||||
* (defaults to false).
|
||||
* Checks whether or not this director is available in standalone mode (defaults to false).
|
||||
*/
|
||||
public boolean isAvailableInStandalone ()
|
||||
{
|
||||
@@ -102,8 +105,7 @@ public class BasicDirector
|
||||
}
|
||||
|
||||
/**
|
||||
* If this director is not currently available, throws a
|
||||
* {@link RuntimeException}.
|
||||
* If this director is not currently available, throws a {@link RuntimeException}.
|
||||
*/
|
||||
protected void assertAvailable ()
|
||||
{
|
||||
@@ -114,20 +116,27 @@ public class BasicDirector
|
||||
}
|
||||
|
||||
/**
|
||||
* Called in three circumstances: when a director is created and we've
|
||||
* already logged on; when we first log on and when the client object
|
||||
* changes after we've already logged on.
|
||||
* Called in three circumstances: when a director is created and we've already logged on; when
|
||||
* we first log on and when the client object changes after we've already logged on.
|
||||
*/
|
||||
protected void clientObjectUpdated (Client client)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Derived directors can override this method and obtain any services
|
||||
* they'll need during their operation via calls to {@link
|
||||
* Client#getService}. If the director is available, it will automatically
|
||||
* be called when the client logs on or when the director is constructed
|
||||
* if it is constructed after the client is already logged on.
|
||||
* If a director makes use of bootstrap invocation services which are part of a bootstrap
|
||||
* service group, it should register interest in that group here with a call to {@link
|
||||
* Client#addServiceGroup}.
|
||||
*/
|
||||
protected void registerServices (Client client)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Derived directors can override this method and obtain any services they'll need during their
|
||||
* operation via calls to {@link Client#getService}. If the director is available, it will
|
||||
* automatically be called when the client logs on or when the director is constructed if it is
|
||||
* constructed after the client is already logged on.
|
||||
*/
|
||||
protected void fetchServices (Client client)
|
||||
{
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.samskivert.util.RunQueue;
|
||||
|
||||
import com.threerings.presents.Log;
|
||||
import com.threerings.presents.data.ClientObject;
|
||||
import com.threerings.presents.data.InvocationCodes;
|
||||
import com.threerings.presents.dobj.DObjectManager;
|
||||
import com.threerings.presents.net.AuthResponseData;
|
||||
import com.threerings.presents.net.BootstrapData;
|
||||
@@ -44,8 +45,7 @@ import com.threerings.presents.net.PongResponse;
|
||||
*/
|
||||
public class Client
|
||||
{
|
||||
/** The default ports on which the server listens for client
|
||||
* connections. */
|
||||
/** The default ports on which the server listens for client connections. */
|
||||
public static final int[] DEFAULT_SERVER_PORTS = { 47624 };
|
||||
|
||||
/**
|
||||
@@ -193,16 +193,6 @@ public class Client
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks this client as interested in the specified bootstrap services group. Any services
|
||||
* registered as bootstrap services with the supplied group name will be included in this
|
||||
* clients bootstrap services set. This must be called before {@link #logon}.
|
||||
*/
|
||||
public void addBootstrapGroup (String group)
|
||||
{
|
||||
_bootGroups.add(group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data associated with our authentication response. Users of the Presents system
|
||||
* may wish to communicate authentication related information to their client by extending and
|
||||
@@ -269,6 +259,16 @@ public class Client
|
||||
return _invdir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks this client as interested in the specified bootstrap services group. Any services
|
||||
* registered as bootstrap services with the supplied group name will be included in this
|
||||
* clients bootstrap services set. This must be called before {@link #logon}.
|
||||
*/
|
||||
public void addServiceGroup (String group)
|
||||
{
|
||||
_bootGroups.add(group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first bootstrap service that could be located that implements the supplied
|
||||
* {@link InvocationService} derivation. <code>null</code> is returned if no such service
|
||||
@@ -281,8 +281,7 @@ public class Client
|
||||
}
|
||||
int scount = _bstrap.services.size();
|
||||
for (int ii = 0; ii < scount; ii++) {
|
||||
InvocationService service = (InvocationService)
|
||||
_bstrap.services.get(ii);
|
||||
InvocationService service = (InvocationService)_bstrap.services.get(ii);
|
||||
if (sclass.isInstance(service)) {
|
||||
return service;
|
||||
}
|
||||
@@ -300,8 +299,7 @@ public class Client
|
||||
InvocationService isvc = getService(sclass);
|
||||
if (isvc == null) {
|
||||
throw new RuntimeException(
|
||||
sclass.getName() + " isn't available. " +
|
||||
"I can't bear to go on.");
|
||||
sclass.getName() + " isn't available. I can't bear to go on.");
|
||||
}
|
||||
return isvc;
|
||||
}
|
||||
@@ -744,7 +742,9 @@ public class Client
|
||||
protected BootstrapData _bstrap;
|
||||
|
||||
/** The set of bootstrap service groups this client cares about. */
|
||||
protected HashSet<String> _bootGroups = new HashSet<String>();
|
||||
protected HashSet<String> _bootGroups = new HashSet<String>(); {
|
||||
_bootGroups.add(InvocationCodes.GLOBAL_GROUP);
|
||||
}
|
||||
|
||||
/** Manages invocation services. */
|
||||
protected InvocationDirector _invdir = new InvocationDirector();
|
||||
|
||||
@@ -32,6 +32,11 @@ package com.threerings.presents.client;
|
||||
*/
|
||||
public class ClientAdapter implements ClientObserver
|
||||
{
|
||||
// documentation inherited
|
||||
public void clientWillLogon (Client client)
|
||||
{
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void clientDidLogon (Client client)
|
||||
{
|
||||
|
||||
@@ -30,6 +30,11 @@ package com.threerings.presents.client;
|
||||
*/
|
||||
public interface SessionObserver
|
||||
{
|
||||
/**
|
||||
* Called immediately before a logon is attempted.
|
||||
*/
|
||||
public void clientWillLogon (Client client);
|
||||
|
||||
/**
|
||||
* Called after the client successfully connected to and authenticated
|
||||
* with the server. The entire object system is up and running by the
|
||||
|
||||
@@ -29,6 +29,10 @@ package com.threerings.presents.data;
|
||||
*/
|
||||
public interface InvocationCodes
|
||||
{
|
||||
/** Defines a global invocation services group that can be used by clients and services that do
|
||||
* not care to make a distinction between groups of invocation services. */
|
||||
public static final String GLOBAL_GROUP = "presents";
|
||||
|
||||
/** An error code returned to clients when a service cannot be performed because of some
|
||||
* internal server error that we couldn't explain in any meaningful way (things like null
|
||||
* pointer exceptions). */
|
||||
|
||||
@@ -160,8 +160,7 @@ public class PeerManager
|
||||
|
||||
// set the invocation service
|
||||
_nodeobj.setPeerService(
|
||||
(PeerMarshaller)PresentsServer.invmgr.registerDispatcher(
|
||||
new PeerDispatcher(this), false));
|
||||
(PeerMarshaller)PresentsServer.invmgr.registerDispatcher(new PeerDispatcher(this)));
|
||||
|
||||
// register ourselves as a client observer
|
||||
PresentsServer.clmgr.addClientObserver(this);
|
||||
@@ -668,6 +667,12 @@ public class PeerManager
|
||||
log.warning("Peer connection failed " + _record + ": " + cause);
|
||||
}
|
||||
|
||||
// documentation inherited from interface ClientObserver
|
||||
public void clientWillLogon (Client client)
|
||||
{
|
||||
// nothing doing
|
||||
}
|
||||
|
||||
// documentation inherited from interface ClientObserver
|
||||
public void clientDidLogon (Client client)
|
||||
{
|
||||
|
||||
@@ -62,9 +62,6 @@ import java.util.HashMap;
|
||||
public class InvocationManager
|
||||
implements EventListener
|
||||
{
|
||||
/** Defines the name of the global bootstrap group. */
|
||||
public static final String GLOBAL_BOOTSTRAP_GROUP = "global";
|
||||
|
||||
/** A mapping from bootstrap group to lists of services that are to be provided to clients at
|
||||
* boot time. Don't mess with these lists! */
|
||||
public HashMap<String,StreamableArrayList<InvocationMarshaller>> bootlists =
|
||||
@@ -100,13 +97,10 @@ public class InvocationManager
|
||||
* send requests to the provider for whom the dispatcher is proxying.
|
||||
*
|
||||
* @param dispatcher the dispatcher to be registered.
|
||||
* @param bootstrap if true, the service instance will be added to the list of invocation
|
||||
* service objects provided to the client in the bootstrap data.
|
||||
*/
|
||||
public InvocationMarshaller registerDispatcher (
|
||||
InvocationDispatcher dispatcher, boolean bootstrap)
|
||||
public InvocationMarshaller registerDispatcher (InvocationDispatcher dispatcher)
|
||||
{
|
||||
return registerDispatcher(dispatcher, bootstrap ? GLOBAL_BOOTSTRAP_GROUP : null);
|
||||
return registerDispatcher(dispatcher, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,8 +134,7 @@ public class InvocationManager
|
||||
list.add(marsh);
|
||||
}
|
||||
|
||||
_recentRegServices.put(Integer.valueOf(invCode),
|
||||
marsh.getClass().getName());
|
||||
_recentRegServices.put(Integer.valueOf(invCode), marsh.getClass().getName());
|
||||
|
||||
// Log.info("Registered service [marsh=" + marsh + "].");
|
||||
return marsh;
|
||||
@@ -292,8 +285,7 @@ public class InvocationManager
|
||||
/** The distributed object manager with which we're working. */
|
||||
protected RootDObjectManager _omgr;
|
||||
|
||||
/** The object id of the object on which we receive invocation service
|
||||
* requests. */
|
||||
/** The object id of the object on which we receive invocation service requests. */
|
||||
protected int _invoid = -1;
|
||||
|
||||
/** Used to generate monotonically increasing provider ids. */
|
||||
@@ -303,7 +295,7 @@ public class InvocationManager
|
||||
protected HashIntMap<InvocationDispatcher> _dispatchers =
|
||||
new HashIntMap<InvocationDispatcher>();
|
||||
|
||||
/** The text that is appended to the procedure name when automatically
|
||||
* generating a failure response. */
|
||||
/** The text that is appended to the procedure name when automatically generating a failure
|
||||
* response. */
|
||||
protected static final String FAILED_SUFFIX = "Failed";
|
||||
}
|
||||
|
||||
@@ -651,13 +651,9 @@ public class PresentsClient
|
||||
|
||||
// fill in the list of bootstrap services
|
||||
data.services = new StreamableArrayList<InvocationMarshaller>();
|
||||
StreamableArrayList<InvocationMarshaller> list =
|
||||
PresentsServer.invmgr.bootlists.get(InvocationManager.GLOBAL_BOOTSTRAP_GROUP);
|
||||
if (list != null) {
|
||||
data.services.addAll(list);
|
||||
}
|
||||
for (String group : _areq.getBootGroups()) {
|
||||
list = PresentsServer.invmgr.bootlists.get(group);
|
||||
StreamableArrayList<InvocationMarshaller> list =
|
||||
PresentsServer.invmgr.bootlists.get(group);
|
||||
if (list != null) {
|
||||
data.services.addAll(list);
|
||||
}
|
||||
|
||||
@@ -34,17 +34,16 @@ import com.threerings.presents.data.TimeBaseObject;
|
||||
import com.threerings.presents.dobj.RootDObjectManager;
|
||||
|
||||
/**
|
||||
* Provides the server-side of the time base services. The time base
|
||||
* services provide a means by which delta times can be sent over the
|
||||
* network which are expanded based on a shared base time into full time
|
||||
* stamps.
|
||||
* Provides the server-side of the time base services. The time base services provide a means by
|
||||
* which delta times can be sent over the network which are expanded based on a shared base time
|
||||
* into full time stamps.
|
||||
*/
|
||||
public class TimeBaseProvider
|
||||
implements InvocationProvider, TimeBaseCodes
|
||||
{
|
||||
/**
|
||||
* Registers the time provider with the appropriate managers. Called
|
||||
* by the presents server at startup.
|
||||
* Registers the time provider with the appropriate managers. Called by the presents server at
|
||||
* startup.
|
||||
*/
|
||||
public static void init (InvocationManager invmgr, RootDObjectManager omgr)
|
||||
{
|
||||
@@ -53,13 +52,12 @@ public class TimeBaseProvider
|
||||
_omgr = omgr;
|
||||
|
||||
// register a provider instance
|
||||
invmgr.registerDispatcher(
|
||||
new TimeBaseDispatcher(new TimeBaseProvider()), true);
|
||||
invmgr.registerDispatcher(new TimeBaseDispatcher(new TimeBaseProvider()), GLOBAL_GROUP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a time base object which can subsequently be fetched by the
|
||||
* client and used to send delta times.
|
||||
* Creates a time base object which can subsequently be fetched by the client and used to send
|
||||
* delta times.
|
||||
*
|
||||
* @param timeBase the name of the time base to create.
|
||||
*
|
||||
@@ -73,8 +71,8 @@ public class TimeBaseProvider
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the named timebase object, or null if no time base object
|
||||
* has been created with that name.
|
||||
* Returns the named timebase object, or null if no time base object has been created with that
|
||||
* name.
|
||||
*/
|
||||
public static TimeBaseObject getTimeBase (String timeBase)
|
||||
{
|
||||
@@ -82,11 +80,9 @@ public class TimeBaseProvider
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a request from a client to fetch the oid of the specified
|
||||
* time object.
|
||||
* Processes a request from a client to fetch the oid of the specified time object.
|
||||
*/
|
||||
public void getTimeOid (
|
||||
ClientObject source, String timeBase, GotTimeBaseListener listener)
|
||||
public void getTimeOid (ClientObject source, String timeBase, GotTimeBaseListener listener)
|
||||
throws InvocationException
|
||||
{
|
||||
// look up the time base object in question
|
||||
|
||||
Reference in New Issue
Block a user