I decided to go hog wild and clean up all the type use in Presents which
required some serious bending and folding of the generic type system, but for the most part we managed to avoid any mutilating. The gendobj task now generates properly typed "addToXXX" and "updateXXX" DSet methods based on the parameterized type of the DSet. This might cause unrecompiled code to break, but I don't think there are many cases in the base toolkit where people call DSet adders or updaters. We'll see and I'll add backwards compatibility versions for cases where we need them to support GG games (everything else we can just recompile). git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4245 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -32,6 +32,7 @@ import com.samskivert.util.DebugChords;
|
||||
import com.samskivert.util.HashIntMap;
|
||||
import com.samskivert.util.Queue;
|
||||
import com.samskivert.util.StringUtil;
|
||||
import com.samskivert.util.IntMap;
|
||||
import com.samskivert.util.Interval;
|
||||
|
||||
import com.threerings.presents.Log;
|
||||
@@ -82,14 +83,16 @@ public class ClientDObjectMgr
|
||||
}
|
||||
|
||||
// inherit documentation from the interface
|
||||
public void createObject (Class dclass, Subscriber target)
|
||||
public <T extends DObject> void createObject (
|
||||
Class<T> dclass, Subscriber<T> target)
|
||||
{
|
||||
// not presently supported
|
||||
throw new RuntimeException("createObject() not supported");
|
||||
}
|
||||
|
||||
// inherit documentation from the interface
|
||||
public void subscribeToObject (int oid, Subscriber target)
|
||||
public <T extends DObject> void subscribeToObject (
|
||||
int oid, Subscriber<T> target)
|
||||
{
|
||||
if (oid <= 0) {
|
||||
target.requestFailed(
|
||||
@@ -100,15 +103,17 @@ public class ClientDObjectMgr
|
||||
}
|
||||
|
||||
// inherit documentation from the interface
|
||||
public void unsubscribeFromObject (int oid, Subscriber target)
|
||||
public <T extends DObject> void unsubscribeFromObject (
|
||||
int oid, Subscriber<T> target)
|
||||
{
|
||||
queueAction(oid, target, false);
|
||||
}
|
||||
|
||||
protected void queueAction (int oid, Subscriber target, boolean subscribe)
|
||||
protected <T extends DObject> void queueAction (
|
||||
int oid, Subscriber<T> target, boolean subscribe)
|
||||
{
|
||||
// queue up an action
|
||||
_actions.append(new ObjectAction(oid, target, subscribe));
|
||||
_actions.append(new ObjectAction<T>(oid, target, subscribe));
|
||||
// and queue up the omgr to get invoked on the invoker thread
|
||||
_client.getRunQueue().postRunnable(this);
|
||||
}
|
||||
@@ -130,14 +135,13 @@ public class ClientDObjectMgr
|
||||
// inherit documentation from the interface
|
||||
public void removedLastSubscriber (DObject obj, boolean deathWish)
|
||||
{
|
||||
// if this object has a registered flush delay, don't can it just
|
||||
// yet, just slip it onto the flush queue
|
||||
Class oclass = obj.getClass();
|
||||
for (Iterator iter = _delays.keySet().iterator(); iter.hasNext(); ) {
|
||||
Class dclass = (Class)iter.next();
|
||||
// if this object has a registered flush delay, don't can it just yet,
|
||||
// just slip it onto the flush queue
|
||||
Class<?> oclass = obj.getClass();
|
||||
for (Class<?> dclass : _delays.keySet()) {
|
||||
if (dclass.isAssignableFrom(oclass)) {
|
||||
long expire = System.currentTimeMillis() +
|
||||
((Long)_delays.get(dclass)).longValue();
|
||||
_delays.get(dclass).longValue();
|
||||
_flushes.put(obj.getOid(), new FlushRecord(obj, expire));
|
||||
// Log.info("Flushing " + obj.getOid() + " at " +
|
||||
// new java.util.Date(expire));
|
||||
@@ -154,7 +158,7 @@ public class ClientDObjectMgr
|
||||
*
|
||||
* @see Client#registerFlushDelay
|
||||
*/
|
||||
public void registerFlushDelay (Class objclass, long delay)
|
||||
public void registerFlushDelay (Class<?> objclass, long delay)
|
||||
{
|
||||
_delays.put(objclass, Long.valueOf(delay));
|
||||
}
|
||||
@@ -191,8 +195,8 @@ public class ClientDObjectMgr
|
||||
// Log.info("Dispatch event: " + evt);
|
||||
dispatchEvent(evt);
|
||||
|
||||
} else if (obj instanceof ObjectResponse) {
|
||||
registerObjectAndNotify(((ObjectResponse)obj).getObject());
|
||||
} else if (obj instanceof ObjectResponse<?>) {
|
||||
registerObjectAndNotify((ObjectResponse<?>)obj);
|
||||
|
||||
} else if (obj instanceof UnsubscribeResponse) {
|
||||
int oid = ((UnsubscribeResponse)obj).getOid();
|
||||
@@ -208,10 +212,10 @@ public class ClientDObjectMgr
|
||||
} else if (obj instanceof PongResponse) {
|
||||
_client.gotPong((PongResponse)obj);
|
||||
|
||||
} else if (obj instanceof ObjectAction) {
|
||||
ObjectAction act = (ObjectAction)obj;
|
||||
} else if (obj instanceof ObjectAction<?>) {
|
||||
ObjectAction<?> act = (ObjectAction<?>)obj;
|
||||
if (act.subscribe) {
|
||||
doSubscribe(act.oid, act.target);
|
||||
doSubscribe(act);
|
||||
} else {
|
||||
doUnsubscribe(act.oid, act.target);
|
||||
}
|
||||
@@ -228,17 +232,17 @@ public class ClientDObjectMgr
|
||||
// if this is a compound event, we need to process its contained
|
||||
// events in order
|
||||
if (event instanceof CompoundEvent) {
|
||||
List events = ((CompoundEvent)event).getEvents();
|
||||
List<DEvent> events = ((CompoundEvent)event).getEvents();
|
||||
int ecount = events.size();
|
||||
for (int i = 0; i < ecount; i++) {
|
||||
dispatchEvent((DEvent)events.get(i));
|
||||
dispatchEvent(events.get(i));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// look up the object on which we're dispatching this event
|
||||
int toid = event.getTargetOid();
|
||||
DObject target = (DObject)_ocache.get(toid);
|
||||
DObject target = _ocache.get(toid);
|
||||
if (target == null) {
|
||||
if (!_dead.containsKey(toid)) {
|
||||
Log.warning("Unable to dispatch event on non-proxied " +
|
||||
@@ -276,16 +280,18 @@ public class ClientDObjectMgr
|
||||
* Registers this object in our proxy cache and notifies the
|
||||
* subscribers that were waiting for subscription to this object.
|
||||
*/
|
||||
protected void registerObjectAndNotify (DObject obj)
|
||||
protected <T extends DObject> void registerObjectAndNotify (
|
||||
ObjectResponse<T> orsp)
|
||||
{
|
||||
// let the object know that we'll be managing it
|
||||
T obj = orsp.getObject();
|
||||
obj.setManager(this);
|
||||
|
||||
// stick the object into the proxy object table
|
||||
_ocache.put(obj.getOid(), obj);
|
||||
|
||||
// let the penders know that the object is available
|
||||
PendingRequest req = (PendingRequest)_penders.remove(obj.getOid());
|
||||
PendingRequest<?> req = _penders.remove(obj.getOid());
|
||||
if (req == null) {
|
||||
Log.warning("Got object, but no one cares?! " +
|
||||
"[oid=" + obj.getOid() + ", obj=" + obj + "].");
|
||||
@@ -293,7 +299,8 @@ public class ClientDObjectMgr
|
||||
}
|
||||
|
||||
for (int i = 0; i < req.targets.size(); i++) {
|
||||
Subscriber target = (Subscriber)req.targets.get(i);
|
||||
@SuppressWarnings("unchecked") Subscriber<T> target =
|
||||
(Subscriber<T>)req.targets.get(i);
|
||||
// add them as a subscriber
|
||||
obj.addSubscriber(target);
|
||||
// and let them know that the object is in
|
||||
@@ -308,7 +315,7 @@ public class ClientDObjectMgr
|
||||
protected void notifyFailure (int oid)
|
||||
{
|
||||
// let the penders know that the object is not available
|
||||
PendingRequest req = (PendingRequest)_penders.remove(oid);
|
||||
PendingRequest<?> req = _penders.remove(oid);
|
||||
if (req == null) {
|
||||
Log.warning("Failed to get object, but no one cares?! " +
|
||||
"[oid=" + oid + "].");
|
||||
@@ -316,9 +323,8 @@ public class ClientDObjectMgr
|
||||
}
|
||||
|
||||
for (int i = 0; i < req.targets.size(); i++) {
|
||||
Subscriber target = (Subscriber)req.targets.get(i);
|
||||
// and let them know that the object is in
|
||||
target.requestFailed(oid, null);
|
||||
req.targets.get(i).requestFailed(oid, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,12 +332,15 @@ public class ClientDObjectMgr
|
||||
* This is guaranteed to be invoked via the invoker and can safely do
|
||||
* main thread type things like call back to the subscriber.
|
||||
*/
|
||||
protected void doSubscribe (int oid, Subscriber target)
|
||||
protected <T extends DObject> void doSubscribe (ObjectAction<T> action)
|
||||
{
|
||||
// Log.info("doSubscribe: " + oid + ": " + target);
|
||||
|
||||
int oid = action.oid;
|
||||
Subscriber<T> target = action.target;
|
||||
|
||||
// first see if we've already got the object in our table
|
||||
DObject obj = (DObject)_ocache.get(oid);
|
||||
@SuppressWarnings("unchecked") T obj = (T)_ocache.get(oid);
|
||||
if (obj != null) {
|
||||
// clear the object out of the flush table if it's in there
|
||||
if (_flushes.remove(oid) != null) {
|
||||
@@ -344,7 +353,8 @@ public class ClientDObjectMgr
|
||||
}
|
||||
|
||||
// see if we've already got an outstanding request for this object
|
||||
PendingRequest req = (PendingRequest)_penders.get(oid);
|
||||
@SuppressWarnings("unchecked") PendingRequest<T> req =
|
||||
(PendingRequest<T>)_penders.get(oid);
|
||||
if (req != null) {
|
||||
// add this subscriber to the list of subscribers to be
|
||||
// notified when the request is satisfied
|
||||
@@ -353,7 +363,7 @@ public class ClientDObjectMgr
|
||||
}
|
||||
|
||||
// otherwise we need to create a new request
|
||||
req = new PendingRequest(oid);
|
||||
req = new PendingRequest<T>(oid);
|
||||
req.addTarget(target);
|
||||
_penders.put(oid, req);
|
||||
// Log.info("Registering pending request [oid=" + oid + "].");
|
||||
@@ -368,7 +378,7 @@ public class ClientDObjectMgr
|
||||
*/
|
||||
protected void doUnsubscribe (int oid, Subscriber target)
|
||||
{
|
||||
DObject dobj = (DObject)_ocache.get(oid);
|
||||
DObject dobj = _ocache.get(oid);
|
||||
if (dobj != null) {
|
||||
dobj.removeSubscriber(target);
|
||||
|
||||
@@ -404,9 +414,11 @@ public class ClientDObjectMgr
|
||||
protected void flushObjects ()
|
||||
{
|
||||
long now = System.currentTimeMillis();
|
||||
for (Iterator iter = _flushes.keySet().iterator(); iter.hasNext(); ) {
|
||||
int oid = ((Integer)iter.next()).intValue();
|
||||
FlushRecord rec = (FlushRecord)_flushes.get(oid);
|
||||
for (Iterator<IntMap.IntEntry<FlushRecord>> iter =
|
||||
_flushes.intEntrySet().iterator(); iter.hasNext(); ) {
|
||||
IntMap.IntEntry<FlushRecord> entry = iter.next();
|
||||
int oid = entry.getIntKey();
|
||||
FlushRecord rec = entry.getValue();
|
||||
if (rec.expire <= now) {
|
||||
iter.remove();
|
||||
flushObject(rec.object);
|
||||
@@ -419,13 +431,13 @@ public class ClientDObjectMgr
|
||||
* The object action is used to queue up a subscribe or unsubscribe
|
||||
* request.
|
||||
*/
|
||||
protected static final class ObjectAction
|
||||
protected static final class ObjectAction<T extends DObject>
|
||||
{
|
||||
public int oid;
|
||||
public Subscriber target;
|
||||
public Subscriber<T> target;
|
||||
public boolean subscribe;
|
||||
|
||||
public ObjectAction (int oid, Subscriber target, boolean subscribe)
|
||||
public ObjectAction (int oid, Subscriber<T> target, boolean subscribe)
|
||||
{
|
||||
this.oid = oid;
|
||||
this.target = target;
|
||||
@@ -438,17 +450,18 @@ public class ClientDObjectMgr
|
||||
}
|
||||
}
|
||||
|
||||
protected static final class PendingRequest
|
||||
protected static final class PendingRequest<T extends DObject>
|
||||
{
|
||||
public int oid;
|
||||
public ArrayList targets = new ArrayList();
|
||||
public ArrayList<Subscriber<T>> targets =
|
||||
new ArrayList<Subscriber<T>>();
|
||||
|
||||
public PendingRequest (int oid)
|
||||
{
|
||||
this.oid = oid;
|
||||
}
|
||||
|
||||
public void addTarget (Subscriber target)
|
||||
public void addTarget (Subscriber<T> target)
|
||||
{
|
||||
targets.add(target);
|
||||
}
|
||||
@@ -478,31 +491,30 @@ public class ClientDObjectMgr
|
||||
protected Client _client;
|
||||
|
||||
/** Our primary dispatch queue. */
|
||||
protected Queue _actions = new Queue();
|
||||
protected Queue<Object> _actions = new Queue<Object>();
|
||||
|
||||
/** All of the distributed objects that are active on this client. */
|
||||
protected HashIntMap _ocache = new HashIntMap();
|
||||
protected HashIntMap<DObject> _ocache = new HashIntMap<DObject>();
|
||||
|
||||
/** Objects that have been marked for death. */
|
||||
protected HashIntMap _dead = new HashIntMap();
|
||||
protected HashIntMap<DObject> _dead = new HashIntMap<DObject>();
|
||||
|
||||
/** Pending object subscriptions. */
|
||||
protected HashIntMap _penders = new HashIntMap();
|
||||
protected HashIntMap<PendingRequest<?>> _penders =
|
||||
new HashIntMap<PendingRequest<?>>();
|
||||
|
||||
/** A mapping from distributed object class to flush delay. */
|
||||
protected HashMap _delays = new HashMap();
|
||||
protected HashMap<Class<?>,Long> _delays = new HashMap<Class<?>,Long>();
|
||||
|
||||
/** A set of objects waiting to be flushed. */
|
||||
protected HashIntMap _flushes = new HashIntMap();
|
||||
protected HashIntMap<FlushRecord> _flushes = new HashIntMap<FlushRecord>();
|
||||
|
||||
/** A debug hook that allows the dumping of all objects in the object
|
||||
* table out to the log. */
|
||||
protected DebugChords.Hook DUMP_OTABLE_HOOK = new DebugChords.Hook() {
|
||||
public void invoke () {
|
||||
Log.info("Dumping " + _ocache.size() + " objects:");
|
||||
Iterator iter = _ocache.values().iterator();
|
||||
while (iter.hasNext()) {
|
||||
DObject obj = (DObject)iter.next();
|
||||
for (DObject obj : _ocache.values()) {
|
||||
Log.info(obj.getClass().getName() + " " + obj);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -597,7 +597,7 @@ public class Communicator
|
||||
protected void iterate ()
|
||||
{
|
||||
// fetch the next message from the queue
|
||||
UpstreamMessage msg = (UpstreamMessage)_msgq.get();
|
||||
UpstreamMessage msg = _msgq.get();
|
||||
|
||||
// if this is a termination message, we're being
|
||||
// requested to exit, so we want to bail now rather
|
||||
@@ -675,7 +675,7 @@ public class Communicator
|
||||
protected Writer _writer;
|
||||
|
||||
protected SocketChannel _channel;
|
||||
protected Queue _msgq = new Queue();
|
||||
protected Queue<UpstreamMessage> _msgq = new Queue<UpstreamMessage>();
|
||||
|
||||
protected long _lastWrite;
|
||||
protected Exception _logonError;
|
||||
|
||||
@@ -81,7 +81,7 @@ public class InvocationDirector
|
||||
clobj.addListener(InvocationDirector.this);
|
||||
|
||||
// clear out our previous registrations
|
||||
clobj.setReceivers(new DSet());
|
||||
clobj.setReceivers(new DSet<Registration>());
|
||||
|
||||
// keep a handle on this bad boy
|
||||
_clobj = clobj;
|
||||
@@ -348,7 +348,7 @@ public class InvocationDirector
|
||||
_omgr.subscribeToObject(newCloid, new Subscriber<ClientObject>() {
|
||||
public void objectAvailable (ClientObject clobj) {
|
||||
// grab a reference to our old receiver registrations
|
||||
DSet receivers = _clobj.receivers;
|
||||
DSet<Registration> receivers = _clobj.receivers;
|
||||
|
||||
// replace the client object
|
||||
_clobj = clobj;
|
||||
@@ -359,10 +359,9 @@ public class InvocationDirector
|
||||
// reregister our receivers
|
||||
_clobj.startTransaction();
|
||||
try {
|
||||
_clobj.setReceivers(new DSet());
|
||||
Iterator iter = receivers.iterator();
|
||||
while (iter.hasNext()) {
|
||||
_clobj.addToReceivers((Registration)iter.next());
|
||||
_clobj.setReceivers(new DSet<Registration>());
|
||||
for (Registration reg : receivers) {
|
||||
_clobj.addToReceivers(reg);
|
||||
}
|
||||
} finally {
|
||||
_clobj.commitTransaction();
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
package com.threerings.presents.data;
|
||||
|
||||
import com.threerings.presents.client.InvocationReceiver;
|
||||
|
||||
import com.threerings.presents.dobj.DObject;
|
||||
import com.threerings.presents.dobj.DSet;
|
||||
|
||||
@@ -43,7 +45,8 @@ public class ClientObject extends DObject
|
||||
|
||||
/** Used to publish all invocation service receivers registered on
|
||||
* this client. */
|
||||
public DSet receivers = new DSet();
|
||||
public DSet<InvocationReceiver.Registration> receivers =
|
||||
new DSet<InvocationReceiver.Registration>();
|
||||
|
||||
/**
|
||||
* Returns a short string identifying this client.
|
||||
@@ -87,7 +90,7 @@ public class ClientObject extends DObject
|
||||
* <code>receivers</code> set. The set will not change until the event is
|
||||
* actually propagated through the system.
|
||||
*/
|
||||
public void addToReceivers (DSet.Entry elem)
|
||||
public void addToReceivers (InvocationReceiver.Registration elem)
|
||||
{
|
||||
requestEntryAdd(RECEIVERS, receivers, elem);
|
||||
}
|
||||
@@ -107,7 +110,7 @@ public class ClientObject extends DObject
|
||||
* <code>receivers</code> set. The set will not change until the event is
|
||||
* actually propagated through the system.
|
||||
*/
|
||||
public void updateReceivers (DSet.Entry elem)
|
||||
public void updateReceivers (InvocationReceiver.Registration elem)
|
||||
{
|
||||
requestEntryUpdate(RECEIVERS, receivers, elem);
|
||||
}
|
||||
@@ -122,7 +125,7 @@ public class ClientObject extends DObject
|
||||
* change. Proxied copies of this object (on clients) will apply the
|
||||
* value change when they received the attribute changed notification.
|
||||
*/
|
||||
public void setReceivers (DSet value)
|
||||
public void setReceivers (DSet<com.threerings.presents.client.InvocationReceiver.Registration> value)
|
||||
{
|
||||
requestAttributeChange(RECEIVERS, value, this.receivers);
|
||||
this.receivers = (value == null) ? null : value.typedClone();
|
||||
|
||||
@@ -56,7 +56,7 @@ public class CompoundEvent extends DEvent
|
||||
|
||||
_omgr = omgr;
|
||||
_target = target;
|
||||
_events = new StreamableArrayList();
|
||||
_events = new StreamableArrayList<DEvent>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,7 +73,7 @@ public class CompoundEvent extends DEvent
|
||||
* Returns the list of events contained within this compound event.
|
||||
* Don't mess with it.
|
||||
*/
|
||||
public List getEvents ()
|
||||
public List<DEvent> getEvents ()
|
||||
{
|
||||
return _events;
|
||||
}
|
||||
@@ -95,7 +95,7 @@ public class CompoundEvent extends DEvent
|
||||
case 0: // nothing doing
|
||||
break;
|
||||
case 1: // no point in being compound
|
||||
_omgr.postEvent((DEvent)_events.get(0));
|
||||
_omgr.postEvent(_events.get(0));
|
||||
break;
|
||||
default: // now we're talking
|
||||
_omgr.postEvent(this);
|
||||
@@ -124,7 +124,7 @@ public class CompoundEvent extends DEvent
|
||||
|
||||
int ecount = _events.size();
|
||||
for (int i = 0; i < ecount; i++) {
|
||||
((DEvent)_events.get(i)).setSourceOid(sourceOid);
|
||||
_events.get(i).setSourceOid(sourceOid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,5 +166,5 @@ public class CompoundEvent extends DEvent
|
||||
protected transient DObject _target;
|
||||
|
||||
/** A list of the events associated with this compound event. */
|
||||
protected StreamableArrayList _events;
|
||||
protected StreamableArrayList<DEvent> _events;
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ public class DObject
|
||||
{
|
||||
public DObject ()
|
||||
{
|
||||
_fields = (Field[])_ftable.get(getClass());
|
||||
_fields = _ftable.get(getClass());
|
||||
if (_fields == null) {
|
||||
_fields = getClass().getFields();
|
||||
Arrays.sort(_fields, FIELD_COMP);
|
||||
@@ -280,10 +280,12 @@ public class DObject
|
||||
/**
|
||||
* Get the DSet with the specified name.
|
||||
*/
|
||||
public final DSet getSet (String setName)
|
||||
public final <T extends DSet.Entry> DSet<T> getSet (String setName)
|
||||
{
|
||||
try {
|
||||
return (DSet) getField(setName).get(this);
|
||||
@SuppressWarnings("unchecked") DSet<T> casted =
|
||||
(DSet<T>)getField(setName).get(this);
|
||||
return casted;
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException("No such set: " + setName);
|
||||
}
|
||||
@@ -292,7 +294,7 @@ public class DObject
|
||||
/**
|
||||
* Request to have the specified item added to the specified DSet.
|
||||
*/
|
||||
public void addToSet (String setName, DSet.Entry entry)
|
||||
public <T extends DSet.Entry> void addToSet (String setName, T entry)
|
||||
{
|
||||
requestEntryAdd(setName, getSet(setName), entry);
|
||||
}
|
||||
@@ -844,7 +846,8 @@ public class DObject
|
||||
/**
|
||||
* Calls by derived instances when a set adder method was called.
|
||||
*/
|
||||
protected void requestEntryAdd (String name, DSet set, DSet.Entry entry)
|
||||
protected <T extends DSet.Entry> void requestEntryAdd (
|
||||
String name, DSet<T> set, T entry)
|
||||
{
|
||||
// if we're on the authoritative server, we update the set immediately
|
||||
boolean alreadyApplied = false;
|
||||
@@ -855,16 +858,17 @@ public class DObject
|
||||
alreadyApplied = true;
|
||||
}
|
||||
// dispatch an entry added event
|
||||
postEvent(new EntryAddedEvent(_oid, name, entry, alreadyApplied));
|
||||
postEvent(new EntryAddedEvent<T>(_oid, name, entry, alreadyApplied));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls by derived instances when a set remover method was called.
|
||||
*/
|
||||
protected void requestEntryRemove (String name, DSet set, Comparable key)
|
||||
protected <T extends DSet.Entry> void requestEntryRemove (
|
||||
String name, DSet<T> set, Comparable key)
|
||||
{
|
||||
// if we're on the authoritative server, we update the set immediately
|
||||
DSet.Entry oldEntry = null;
|
||||
T oldEntry = null;
|
||||
if (_omgr != null && _omgr.isManager(this)) {
|
||||
oldEntry = set.removeKey(key);
|
||||
if (oldEntry == null) {
|
||||
@@ -872,16 +876,17 @@ public class DObject
|
||||
}
|
||||
}
|
||||
// dispatch an entry removed event
|
||||
postEvent(new EntryRemovedEvent(_oid, name, key, oldEntry));
|
||||
postEvent(new EntryRemovedEvent<T>(_oid, name, key, oldEntry));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls by derived instances when a set updater method was called.
|
||||
*/
|
||||
protected void requestEntryUpdate (String name, DSet set, DSet.Entry entry)
|
||||
protected <T extends DSet.Entry> void requestEntryUpdate (
|
||||
String name, DSet<T> set, T entry)
|
||||
{
|
||||
// if we're on the authoritative server, we update the set immediately
|
||||
DSet.Entry oldEntry = null;
|
||||
T oldEntry = null;
|
||||
if (_omgr != null && _omgr.isManager(this)) {
|
||||
oldEntry = set.update(entry);
|
||||
if (oldEntry == null) {
|
||||
@@ -889,7 +894,7 @@ public class DObject
|
||||
}
|
||||
}
|
||||
// dispatch an entry updated event
|
||||
postEvent(new EntryUpdatedEvent(_oid, name, entry, oldEntry));
|
||||
postEvent(new EntryUpdatedEvent<T>(_oid, name, entry, oldEntry));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -955,12 +960,14 @@ public class DObject
|
||||
|
||||
/** Maintains a mapping of sorted field arrays for each distributed
|
||||
* object class. */
|
||||
protected static HashMap _ftable = new HashMap();
|
||||
protected static HashMap<Class,Field[]> _ftable =
|
||||
new HashMap<Class,Field[]>();
|
||||
|
||||
/** Used to sort and search {@link #_fields}. */
|
||||
protected static final Comparator FIELD_COMP = new Comparator() {
|
||||
public int compare (Object o1, Object o2) {
|
||||
return ((Field)o1).getName().compareTo(((Field)o2).getName());
|
||||
protected static final Comparator<Field> FIELD_COMP =
|
||||
new Comparator<Field>() {
|
||||
public int compare (Field f1, Field f2) {
|
||||
return f1.getName().compareTo(f2.getName());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -239,7 +239,8 @@ public class DSet<E extends DSet.Entry>
|
||||
*/
|
||||
public Object[] toArray (Object[] array)
|
||||
{
|
||||
return toArray((E[])array);
|
||||
@SuppressWarnings("unchecked") E[] casted = (E[])array;
|
||||
return toArray(casted);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,7 +32,7 @@ import com.threerings.presents.Log;
|
||||
*
|
||||
* @see DObjectManager#postEvent
|
||||
*/
|
||||
public class EntryAddedEvent extends NamedEvent
|
||||
public class EntryAddedEvent<T extends DSet.Entry> extends NamedEvent
|
||||
{
|
||||
/**
|
||||
* Constructs a new entry added event on the specified target object
|
||||
@@ -44,7 +44,7 @@ public class EntryAddedEvent extends NamedEvent
|
||||
* entry.
|
||||
* @param entry the entry to add to the set attribute.
|
||||
*/
|
||||
public EntryAddedEvent (int targetOid, String name, DSet.Entry entry)
|
||||
public EntryAddedEvent (int targetOid, String name, T entry)
|
||||
{
|
||||
this(targetOid, name, entry, false);
|
||||
}
|
||||
@@ -53,7 +53,7 @@ public class EntryAddedEvent extends NamedEvent
|
||||
* Used when the distributed object already added the entry before
|
||||
* generating the event.
|
||||
*/
|
||||
public EntryAddedEvent (int targetOid, String name, DSet.Entry entry,
|
||||
public EntryAddedEvent (int targetOid, String name, T entry,
|
||||
boolean alreadyApplied)
|
||||
{
|
||||
super(targetOid, name);
|
||||
@@ -72,7 +72,7 @@ public class EntryAddedEvent extends NamedEvent
|
||||
/**
|
||||
* Returns the entry that has been added.
|
||||
*/
|
||||
public DSet.Entry getEntry ()
|
||||
public T getEntry ()
|
||||
{
|
||||
return _entry;
|
||||
}
|
||||
@@ -84,7 +84,7 @@ public class EntryAddedEvent extends NamedEvent
|
||||
throws ObjectAccessException
|
||||
{
|
||||
if (!_alreadyApplied) {
|
||||
boolean added = ((DSet)target.getAttribute(_name)).add(_entry);
|
||||
boolean added = target.getSet(_name).add(_entry);
|
||||
if (!added) {
|
||||
Log.warning("Duplicate entry found [event=" + this + "].");
|
||||
}
|
||||
@@ -109,7 +109,7 @@ public class EntryAddedEvent extends NamedEvent
|
||||
StringUtil.toString(buf, _entry);
|
||||
}
|
||||
|
||||
protected DSet.Entry _entry;
|
||||
protected T _entry;
|
||||
|
||||
/** Used when this event is generated on the authoritative server
|
||||
* where object changes are made immediately. This lets us know not to
|
||||
|
||||
@@ -31,7 +31,7 @@ import com.threerings.presents.Log;
|
||||
*
|
||||
* @see DObjectManager#postEvent
|
||||
*/
|
||||
public class EntryRemovedEvent extends NamedEvent
|
||||
public class EntryRemovedEvent<T extends DSet.Entry> extends NamedEvent
|
||||
{
|
||||
/**
|
||||
* Constructs a new entry removed event on the specified target object
|
||||
@@ -45,7 +45,7 @@ public class EntryRemovedEvent extends NamedEvent
|
||||
* @param oldEntry the previous value of the entry.
|
||||
*/
|
||||
public EntryRemovedEvent (int targetOid, String name, Comparable key,
|
||||
DSet.Entry oldEntry)
|
||||
T oldEntry)
|
||||
{
|
||||
super(targetOid, name);
|
||||
_key = key;
|
||||
@@ -65,13 +65,13 @@ public class EntryRemovedEvent extends NamedEvent
|
||||
*/
|
||||
public Comparable getKey ()
|
||||
{
|
||||
return (Comparable)_key;
|
||||
return _key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entry that was in the set prior to being updated.
|
||||
*/
|
||||
public DSet.Entry getOldEntry ()
|
||||
public T getOldEntry ()
|
||||
{
|
||||
return _oldEntry;
|
||||
}
|
||||
@@ -83,7 +83,7 @@ public class EntryRemovedEvent extends NamedEvent
|
||||
throws ObjectAccessException
|
||||
{
|
||||
if (_oldEntry == UNSET_OLD_ENTRY) {
|
||||
DSet set = (DSet)target.getAttribute(_name);
|
||||
DSet<T> set = target.getSet(_name);
|
||||
// remove, fetch the previous value for interested callers
|
||||
_oldEntry = set.removeKey(_key);
|
||||
if (_oldEntry == null) {
|
||||
@@ -113,5 +113,6 @@ public class EntryRemovedEvent extends NamedEvent
|
||||
}
|
||||
|
||||
protected Comparable _key;
|
||||
protected transient DSet.Entry _oldEntry = UNSET_OLD_ENTRY;
|
||||
@SuppressWarnings("unchecked")
|
||||
protected transient T _oldEntry = (T)UNSET_OLD_ENTRY;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ import com.threerings.presents.Log;
|
||||
*
|
||||
* @see DObjectManager#postEvent
|
||||
*/
|
||||
public class EntryUpdatedEvent extends NamedEvent
|
||||
public class EntryUpdatedEvent<T extends DSet.Entry> extends NamedEvent
|
||||
{
|
||||
/**
|
||||
* Constructs a new entry updated event on the specified target object
|
||||
@@ -45,8 +45,7 @@ public class EntryUpdatedEvent extends NamedEvent
|
||||
* @param entry the entry to update.
|
||||
* @param oldEntry the previous value of the entry.
|
||||
*/
|
||||
public EntryUpdatedEvent (int targetOid, String name, DSet.Entry entry,
|
||||
DSet.Entry oldEntry)
|
||||
public EntryUpdatedEvent (int targetOid, String name, T entry, T oldEntry)
|
||||
{
|
||||
super(targetOid, name);
|
||||
_entry = entry;
|
||||
@@ -64,7 +63,7 @@ public class EntryUpdatedEvent extends NamedEvent
|
||||
/**
|
||||
* Returns the entry that has been updated.
|
||||
*/
|
||||
public DSet.Entry getEntry ()
|
||||
public T getEntry ()
|
||||
{
|
||||
return _entry;
|
||||
}
|
||||
@@ -72,7 +71,7 @@ public class EntryUpdatedEvent extends NamedEvent
|
||||
/**
|
||||
* Returns the entry that was in the set prior to being updated.
|
||||
*/
|
||||
public DSet.Entry getOldEntry ()
|
||||
public T getOldEntry ()
|
||||
{
|
||||
return _oldEntry;
|
||||
}
|
||||
@@ -85,7 +84,7 @@ public class EntryUpdatedEvent extends NamedEvent
|
||||
{
|
||||
// only apply the change if we haven't already
|
||||
if (_oldEntry == UNSET_OLD_ENTRY) {
|
||||
DSet set = (DSet)target.getAttribute(_name);
|
||||
DSet<T> set = target.getSet(_name);
|
||||
// fetch the previous value for interested callers
|
||||
_oldEntry = set.update(_entry);
|
||||
if (_oldEntry == null) {
|
||||
@@ -115,6 +114,7 @@ public class EntryUpdatedEvent extends NamedEvent
|
||||
StringUtil.toString(buf, _entry);
|
||||
}
|
||||
|
||||
protected DSet.Entry _entry;
|
||||
protected transient DSet.Entry _oldEntry = UNSET_OLD_ENTRY;
|
||||
protected T _entry;
|
||||
@SuppressWarnings("unchecked")
|
||||
protected transient T _oldEntry = (T)UNSET_OLD_ENTRY;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,8 @@ package com.threerings.presents.net;
|
||||
|
||||
import com.threerings.presents.dobj.DObject;
|
||||
|
||||
public class ObjectResponse extends DownstreamMessage
|
||||
public class ObjectResponse<T extends DObject>
|
||||
extends DownstreamMessage
|
||||
{
|
||||
/**
|
||||
* Zero argument constructor used when unserializing an instance.
|
||||
@@ -36,12 +37,12 @@ public class ObjectResponse extends DownstreamMessage
|
||||
/**
|
||||
* Constructs an object response with the supplied distributed object.
|
||||
*/
|
||||
public ObjectResponse (DObject dobj)
|
||||
public ObjectResponse (T dobj)
|
||||
{
|
||||
_dobj = dobj;
|
||||
}
|
||||
|
||||
public DObject getObject ()
|
||||
public T getObject ()
|
||||
{
|
||||
return _dobj;
|
||||
}
|
||||
@@ -52,5 +53,5 @@ public class ObjectResponse extends DownstreamMessage
|
||||
}
|
||||
|
||||
/** The object which is associated with this response. */
|
||||
protected DObject _dobj;
|
||||
protected T _dobj;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public class NodeObject extends DObject
|
||||
* <code>clients</code> set. The set will not change until the event is
|
||||
* actually propagated through the system.
|
||||
*/
|
||||
public void addToClients (DSet.Entry elem)
|
||||
public void addToClients (ClientInfo elem)
|
||||
{
|
||||
requestEntryAdd(CLIENTS, clients, elem);
|
||||
}
|
||||
@@ -63,7 +63,7 @@ public class NodeObject extends DObject
|
||||
* <code>clients</code> set. The set will not change until the event is
|
||||
* actually propagated through the system.
|
||||
*/
|
||||
public void updateClients (DSet.Entry elem)
|
||||
public void updateClients (ClientInfo elem)
|
||||
{
|
||||
requestEntryUpdate(CLIENTS, clients, elem);
|
||||
}
|
||||
|
||||
@@ -229,7 +229,9 @@ public class ClientManager
|
||||
|
||||
// request that the appropriate client object be created by the
|
||||
// dobject manager which starts the whole business off
|
||||
PresentsServer.omgr.createObject(clr.getClientObjectClass(), clr);
|
||||
@SuppressWarnings("unchecked") Class<ClientObject> cclass =
|
||||
(Class<ClientObject>)clr.getClientObjectClass();
|
||||
PresentsServer.omgr.createObject(cclass, clr);
|
||||
|
||||
} catch (Exception e) {
|
||||
// let the listener know that we're hosed
|
||||
|
||||
@@ -64,7 +64,7 @@ public class ClientResolver extends Invoker.Unit
|
||||
* Returns the {@link ClientObject} derived class that should be
|
||||
* created to kick off the resolution process.
|
||||
*/
|
||||
public Class getClientObjectClass ()
|
||||
public Class<? extends ClientObject> getClientObjectClass ()
|
||||
{
|
||||
return ClientObject.class;
|
||||
}
|
||||
|
||||
@@ -65,11 +65,12 @@ import com.threerings.presents.dobj.Subscriber;
|
||||
* the client.
|
||||
*/
|
||||
public class InvocationManager
|
||||
implements Subscriber, EventListener
|
||||
implements Subscriber<DObject>, EventListener
|
||||
{
|
||||
/** The list of services that are to be provided to clients at boot
|
||||
* time. Don't mess with this list! */
|
||||
public StreamableArrayList bootlist = new StreamableArrayList();
|
||||
public StreamableArrayList<InvocationMarshaller> bootlist =
|
||||
new StreamableArrayList<InvocationMarshaller>();
|
||||
|
||||
/**
|
||||
* Constructs an invocation manager which will use the supplied
|
||||
@@ -174,8 +175,7 @@ public class InvocationManager
|
||||
|
||||
// let any early registered marshallers know about our invoid
|
||||
while (_lateInitQueue.size() > 0) {
|
||||
InvocationMarshaller marsh = (InvocationMarshaller)
|
||||
_lateInitQueue.remove(0);
|
||||
InvocationMarshaller marsh = _lateInitQueue.remove(0);
|
||||
marsh.setInvocationOid(_invoid);
|
||||
}
|
||||
|
||||
@@ -222,8 +222,7 @@ public class InvocationManager
|
||||
}
|
||||
|
||||
// look up the dispatcher
|
||||
InvocationDispatcher disp = (InvocationDispatcher)
|
||||
_dispatchers.get(invCode);
|
||||
InvocationDispatcher disp = _dispatchers.get(invCode);
|
||||
if (disp == null) {
|
||||
Log.info("Received invocation request but dispatcher " +
|
||||
"registration was already cleared [code=" + invCode +
|
||||
@@ -298,8 +297,8 @@ public class InvocationManager
|
||||
}
|
||||
|
||||
// debugging action...
|
||||
protected static final LRUHashMap _recentRegServices =
|
||||
new LRUHashMap(10000);
|
||||
protected static final LRUHashMap<Integer,String> _recentRegServices =
|
||||
new LRUHashMap<Integer,String>(10000);
|
||||
|
||||
/** The distributed object manager with which we're working. */
|
||||
protected RootDObjectManager _omgr;
|
||||
@@ -312,12 +311,14 @@ public class InvocationManager
|
||||
protected int _invCode;
|
||||
|
||||
/** A table of invocation dispatchers each mapped by a unique code. */
|
||||
protected HashIntMap _dispatchers = new HashIntMap();
|
||||
protected HashIntMap<InvocationDispatcher> _dispatchers =
|
||||
new HashIntMap<InvocationDispatcher>();
|
||||
|
||||
/** Used to keep track of marshallers registered before we had our
|
||||
* invocation object so that we can fill their invocation id in
|
||||
* belatedly. */
|
||||
protected ArrayList _lateInitQueue = new ArrayList();
|
||||
protected ArrayList<InvocationMarshaller> _lateInitQueue =
|
||||
new ArrayList<InvocationMarshaller>();
|
||||
|
||||
/** The text that is appended to the procedure name when automatically
|
||||
* generating a failure response. */
|
||||
|
||||
@@ -764,7 +764,7 @@ public class PresentsClient
|
||||
// documentation inherited from interface
|
||||
public void objectAvailable (DObject object)
|
||||
{
|
||||
if (postMessage(new ObjectResponse(object))) {
|
||||
if (postMessage(new ObjectResponse<DObject>(object))) {
|
||||
// make a note of this new subscription
|
||||
mapSubscrip(object);
|
||||
} else {
|
||||
|
||||
@@ -196,7 +196,7 @@ public class PresentsDObjectMgr
|
||||
*/
|
||||
public DObject getObject (int oid)
|
||||
{
|
||||
return (DObject)_objects.get(oid);
|
||||
return _objects.get(oid);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -324,7 +324,7 @@ public class PresentsDObjectMgr
|
||||
int ecount = events.size();
|
||||
|
||||
// look up the target object
|
||||
DObject target = (DObject)_objects.get(event.getTargetOid());
|
||||
DObject target = _objects.get(event.getTargetOid());
|
||||
if (target == null) {
|
||||
Log.debug("Compound event target no longer exists " +
|
||||
"[event=" + event + "].");
|
||||
@@ -357,7 +357,7 @@ public class PresentsDObjectMgr
|
||||
protected void processEvent (DEvent event)
|
||||
{
|
||||
// look up the target object
|
||||
DObject target = (DObject)_objects.get(event.getTargetOid());
|
||||
DObject target = _objects.get(event.getTargetOid());
|
||||
if (target == null) {
|
||||
Log.debug("Event target no longer exists " +
|
||||
"[event=" + event + "].");
|
||||
@@ -491,7 +491,7 @@ public class PresentsDObjectMgr
|
||||
}
|
||||
|
||||
Reference ref = refs[i];
|
||||
DObject reffer = (DObject)_objects.get(ref.reffingOid);
|
||||
DObject reffer = _objects.get(ref.reffingOid);
|
||||
|
||||
// ensure that the referencing object is still around
|
||||
if (reffer != null) {
|
||||
@@ -857,7 +857,7 @@ public class PresentsDObjectMgr
|
||||
throws ObjectAccessException
|
||||
{
|
||||
// look up the target object
|
||||
T obj = (T)_objects.get(_oid);
|
||||
@SuppressWarnings("unchecked") T obj = (T)_objects.get(_oid);
|
||||
|
||||
// if we're unsubscribing, take care of that and get on out
|
||||
if (_action == UNSUBSCRIBE) {
|
||||
@@ -985,7 +985,7 @@ public class PresentsDObjectMgr
|
||||
protected boolean _running = true;
|
||||
|
||||
/** The event queue via which all events are processed. */
|
||||
protected Queue _evqueue = new Queue();
|
||||
protected Queue<Object> _evqueue = new Queue<Object>();
|
||||
|
||||
/** The managed distributed objects table. */
|
||||
protected HashIntMap<DObject> _objects = new HashIntMap<DObject>();
|
||||
|
||||
@@ -112,7 +112,8 @@ public class PresentsServer
|
||||
SignalManager.registerSignalHandler(SignalManager.SIGHUP, this);
|
||||
|
||||
// create our list of shutdowners
|
||||
_downers = new ObserverList(ObserverList.SAFE_IN_ORDER_NOTIFY);
|
||||
_downers = new ObserverList<Shutdowner>(
|
||||
ObserverList.SAFE_IN_ORDER_NOTIFY);
|
||||
|
||||
// create our distributed object manager
|
||||
omgr = createDObjectManager();
|
||||
@@ -258,7 +259,7 @@ public class PresentsServer
|
||||
report.append(max/1024).append("k max\n");
|
||||
|
||||
for (int ii = 0; ii < _reporters.size(); ii++) {
|
||||
Reporter rptr = (Reporter)_reporters.get(ii);
|
||||
Reporter rptr = _reporters.get(ii);
|
||||
try {
|
||||
rptr.appendReport(report, now, sinceLast, reset);
|
||||
} catch (Throwable t) {
|
||||
@@ -308,7 +309,7 @@ public class PresentsServer
|
||||
*/
|
||||
public void shutdown ()
|
||||
{
|
||||
ObserverList downers = _downers;
|
||||
ObserverList<Shutdowner> downers = _downers;
|
||||
if (downers == null) {
|
||||
Log.warning("Refusing repeat shutdown request.");
|
||||
return;
|
||||
@@ -322,9 +323,9 @@ public class PresentsServer
|
||||
}
|
||||
|
||||
// shut down all shutdown participants
|
||||
downers.apply(new ObserverList.ObserverOp() {
|
||||
public boolean apply (Object observer) {
|
||||
((Shutdowner)observer).shutdown();
|
||||
downers.apply(new ObserverList.ObserverOp<Shutdowner>() {
|
||||
public boolean apply (Shutdowner downer) {
|
||||
downer.shutdown();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@@ -399,10 +400,10 @@ public class PresentsServer
|
||||
protected static long _lastReportStamp = _serverStartTime;
|
||||
|
||||
/** Used to generate "state of server" reports. */
|
||||
protected static ArrayList _reporters = new ArrayList();
|
||||
protected static ArrayList<Reporter> _reporters = new ArrayList<Reporter>();
|
||||
|
||||
/** A list of shutdown participants. */
|
||||
protected static ObserverList _downers;;
|
||||
protected static ObserverList<Shutdowner> _downers;;
|
||||
|
||||
/** The frequency with which we generate "state of server" reports. */
|
||||
protected static final long REPORT_INTERVAL = 15 * 60 * 1000L;
|
||||
|
||||
@@ -69,10 +69,11 @@ public class TimeBaseProvider
|
||||
* base object is created or if the creation fails.
|
||||
*/
|
||||
public static void createTimeBase (
|
||||
final String timeBase, final ResultListener resl)
|
||||
final String timeBase, final ResultListener<TimeBaseObject> resl)
|
||||
{
|
||||
_omgr.createObject(TimeBaseObject.class, new Subscriber () {
|
||||
public void objectAvailable (DObject object) {
|
||||
_omgr.createObject(TimeBaseObject.class,
|
||||
new Subscriber<TimeBaseObject> () {
|
||||
public void objectAvailable (TimeBaseObject object) {
|
||||
// stuff it into our table
|
||||
_timeBases.put(timeBase, object);
|
||||
// and notify the listener
|
||||
@@ -95,7 +96,7 @@ public class TimeBaseProvider
|
||||
*/
|
||||
public static TimeBaseObject getTimeBase (String timeBase)
|
||||
{
|
||||
return (TimeBaseObject)_timeBases.get(timeBase);
|
||||
return _timeBases.get(timeBase);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,7 +117,8 @@ public class TimeBaseProvider
|
||||
}
|
||||
|
||||
/** Used to keep track of our time base objects. */
|
||||
protected static HashMap _timeBases = new HashMap();
|
||||
protected static HashMap<String,TimeBaseObject> _timeBases =
|
||||
new HashMap<String,TimeBaseObject>();
|
||||
|
||||
/** The invocation manager with which we interoperate. */
|
||||
protected static InvocationManager _invmgr;
|
||||
|
||||
@@ -194,7 +194,7 @@ public class ConnectionManager extends LoopingThread
|
||||
* Called by the authenticator to indicate that a connection was
|
||||
* successfully authenticated.
|
||||
*/
|
||||
public void connectionDidAuthenticate (Connection conn)
|
||||
public void connectionDidAuthenticate (AuthingConnection conn)
|
||||
{
|
||||
// slap this sucker onto the authenticated connections queue
|
||||
_authq.append(conn);
|
||||
@@ -360,7 +360,7 @@ public class ConnectionManager extends LoopingThread
|
||||
|
||||
// close any connections that have been queued up to die
|
||||
Connection dconn;
|
||||
while ((dconn = (Connection)_deathq.getNonBlocking()) != null) {
|
||||
while ((dconn = _deathq.getNonBlocking()) != null) {
|
||||
// it's possible that we caught an EOF trying to read from
|
||||
// this connection even after it was queued up for death, so
|
||||
// let's avoid trying to close it twice
|
||||
@@ -396,10 +396,8 @@ public class ConnectionManager extends LoopingThread
|
||||
}
|
||||
|
||||
// send any messages that are waiting on the outgoing queue
|
||||
Object obj;
|
||||
while ((obj = _outq.getNonBlocking()) != null) {
|
||||
@SuppressWarnings("unchecked") Tuple<Connection,byte[]> tup =
|
||||
(Tuple<Connection,byte[]>)obj;
|
||||
Tuple<Connection,byte[]> tup;
|
||||
while ((tup = _outq.getNonBlocking()) != null) {
|
||||
Connection conn = tup.left;
|
||||
|
||||
// if an overflow queue exists for this client, go ahead and
|
||||
@@ -423,7 +421,7 @@ public class ConnectionManager extends LoopingThread
|
||||
|
||||
// check for connections that have completed authentication
|
||||
AuthingConnection conn;
|
||||
while ((conn = (AuthingConnection)_authq.getNonBlocking()) != null) {
|
||||
while ((conn = _authq.getNonBlocking()) != null) {
|
||||
try {
|
||||
// construct a new running connection to handle this
|
||||
// connections network traffic from here on out
|
||||
@@ -893,10 +891,11 @@ public class ConnectionManager extends LoopingThread
|
||||
protected HashMap<SelectionKey,NetEventHandler> _handlers =
|
||||
new HashMap<SelectionKey,NetEventHandler>();
|
||||
|
||||
protected Queue _deathq = new Queue();
|
||||
protected Queue _authq = new Queue();
|
||||
protected Queue<Connection> _deathq = new Queue<Connection>();
|
||||
protected Queue<AuthingConnection> _authq = new Queue<AuthingConnection>();
|
||||
|
||||
protected Queue _outq = new Queue();
|
||||
protected Queue<Tuple<Connection,byte[]>> _outq =
|
||||
new Queue<Tuple<Connection,byte[]>>();
|
||||
protected FramingOutputStream _framer;
|
||||
protected ByteBuffer _outbuf = ByteBuffer.allocateDirect(64 * 1024);
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@ import java.io.StringWriter;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -109,9 +111,7 @@ public class GenDObjectTask extends Task
|
||||
throw new BuildException("Can't resolve InvocationListener", e);
|
||||
}
|
||||
|
||||
ArrayList files = new ArrayList();
|
||||
for (Iterator iter = _filesets.iterator(); iter.hasNext(); ) {
|
||||
FileSet fs = (FileSet)iter.next();
|
||||
for (FileSet fs : _filesets) {
|
||||
DirectoryScanner ds = fs.getDirectoryScanner(getProject());
|
||||
File fromDir = fs.getDir(getProject());
|
||||
String[] srcFiles = ds.getIncludedFiles();
|
||||
@@ -158,7 +158,7 @@ public class GenDObjectTask extends Task
|
||||
}
|
||||
|
||||
// determine which fields we need to deal with
|
||||
ArrayList flist = new ArrayList();
|
||||
ArrayList<Field> flist = new ArrayList<Field>();
|
||||
Field[] fields = oclass.getDeclaredFields();
|
||||
for (int ii = 0; ii < fields.length; ii++) {
|
||||
Field f = fields[ii];
|
||||
@@ -175,12 +175,12 @@ public class GenDObjectTask extends Task
|
||||
String[] lines = null;
|
||||
try {
|
||||
BufferedReader bin = new BufferedReader(new FileReader(source));
|
||||
ArrayList llist = new ArrayList();
|
||||
ArrayList<String> llist = new ArrayList<String>();
|
||||
String line = null;
|
||||
while ((line = bin.readLine()) != null) {
|
||||
llist.add(line);
|
||||
}
|
||||
lines = (String[])llist.toArray(new String[llist.size()]);
|
||||
lines = llist.toArray(new String[llist.size()]);
|
||||
bin.close();
|
||||
} catch (IOException ioe) {
|
||||
System.err.println("Error reading '" + source + "': " + ioe);
|
||||
@@ -249,8 +249,8 @@ public class GenDObjectTask extends Task
|
||||
StringBuilder fsection = new StringBuilder();
|
||||
StringBuilder msection = new StringBuilder();
|
||||
for (int ii = 0; ii < flist.size(); ii++) {
|
||||
Field f = (Field)flist.get(ii);
|
||||
Class ftype = f.getType();
|
||||
Field f = flist.get(ii);
|
||||
Class<?> ftype = f.getType();
|
||||
String fname = f.getName();
|
||||
|
||||
// create our velocity context
|
||||
@@ -262,13 +262,34 @@ public class GenDObjectTask extends Task
|
||||
ctx.put("clonefield", GenUtil.cloneArgument(_dsclass, f, "value"));
|
||||
ctx.put("capfield", StringUtil.unStudlyName(fname).toUpperCase());
|
||||
ctx.put("upfield", StringUtils.capitalize(fname));
|
||||
|
||||
// if this field is an array, we need its component types
|
||||
if (ftype.isArray()) {
|
||||
Class etype = ftype.getComponentType();
|
||||
Class<?> etype = ftype.getComponentType();
|
||||
ctx.put("elemtype", GenUtil.simpleName(etype));
|
||||
ctx.put("wrapelem", GenUtil.boxArgument(etype, "value"));
|
||||
ctx.put("wrapoelem", GenUtil.boxArgument(etype, "ovalue"));
|
||||
}
|
||||
|
||||
// if this field is a generic DSet, we need its bound type
|
||||
if (_dsclass.isAssignableFrom(ftype)) {
|
||||
Type t = f.getGenericType();
|
||||
// we need to walk up the heirarchy until we get to the
|
||||
// parameterized DSet
|
||||
while (t instanceof Class<?>) {
|
||||
t = ((Class<?>)t).getGenericSuperclass();
|
||||
}
|
||||
if (t instanceof ParameterizedType) {
|
||||
ParameterizedType pt = (ParameterizedType)t;
|
||||
if (pt.getActualTypeArguments().length > 0) {
|
||||
ctx.put("etype", GenUtil.simpleName(
|
||||
(Class<?>)pt.getActualTypeArguments()[0]));
|
||||
}
|
||||
} else {
|
||||
ctx.put("etype", "DSet.Entry");
|
||||
}
|
||||
}
|
||||
|
||||
// now figure out which template to use
|
||||
String tname = "field.tmpl";
|
||||
if (_dsclass.isAssignableFrom(ftype)) {
|
||||
@@ -370,7 +391,7 @@ public class GenDObjectTask extends Task
|
||||
}
|
||||
|
||||
/** A list of filesets that contain tile images. */
|
||||
protected ArrayList _filesets = new ArrayList();
|
||||
protected ArrayList<FileSet> _filesets = new ArrayList<FileSet>();
|
||||
|
||||
/** Used to do our own classpath business. */
|
||||
protected ClassLoader _cloader;
|
||||
@@ -380,15 +401,15 @@ public class GenDObjectTask extends Task
|
||||
|
||||
/** {@link DObject} resolved with the proper classloader so that we
|
||||
* can compare it to loaded derived classes. */
|
||||
protected Class _doclass;
|
||||
protected Class<?> _doclass;
|
||||
|
||||
/** {@link DSet} resolved with the proper classloader so that we can
|
||||
* compare it to loaded derived classes. */
|
||||
protected Class _dsclass;
|
||||
protected Class<?> _dsclass;
|
||||
|
||||
/** {@link OidList} resolved with the proper classloader so that we
|
||||
* can compare it to loaded derived classes. */
|
||||
protected Class _olclass;
|
||||
protected Class<?> _olclass;
|
||||
|
||||
/** Specifies the start of the path to our various templates. */
|
||||
protected static final String BASE_TMPL =
|
||||
|
||||
@@ -68,8 +68,9 @@ public class GenReceiverTask extends InvocationTask
|
||||
return;
|
||||
}
|
||||
|
||||
HashMap imports = new HashMap();
|
||||
ComparableArrayList methods = new ComparableArrayList();
|
||||
HashMap<String,Boolean> imports = new HashMap<String,Boolean>();
|
||||
ComparableArrayList<ServiceMethod> methods =
|
||||
new ComparableArrayList<ServiceMethod>();
|
||||
|
||||
// we need to import the receiver itself
|
||||
imports.put(importify(receiver.getName()), Boolean.TRUE);
|
||||
@@ -94,14 +95,14 @@ public class GenReceiverTask extends InvocationTask
|
||||
}
|
||||
|
||||
protected void generateSender (File source, String rname, String rpackage,
|
||||
List methods, Iterator imports)
|
||||
List methods, Iterator<String> imports)
|
||||
{
|
||||
String name = StringUtil.replace(rname, "Receiver", "");
|
||||
String sname = StringUtil.replace(rname, "Receiver", "Sender");
|
||||
String spackage = StringUtil.replace(rpackage, ".client", ".server");
|
||||
|
||||
// construct our imports list
|
||||
ComparableArrayList implist = new ComparableArrayList();
|
||||
ComparableArrayList<String> implist = new ComparableArrayList<String>();
|
||||
CollectionUtil.addAll(implist, imports);
|
||||
checkedAdd(implist, ClientObject.class.getName());
|
||||
checkedAdd(implist, InvocationSender.class.getName());
|
||||
@@ -134,13 +135,13 @@ public class GenReceiverTask extends InvocationTask
|
||||
|
||||
protected void generateDecoder (
|
||||
File source, String rname, String rpackage, List methods,
|
||||
Iterator imports)
|
||||
Iterator<String> imports)
|
||||
{
|
||||
String name = StringUtil.replace(rname, "Receiver", "");
|
||||
String dname = StringUtil.replace(rname, "Receiver", "Decoder");
|
||||
|
||||
// construct our imports list
|
||||
ComparableArrayList implist = new ComparableArrayList();
|
||||
ComparableArrayList<String> implist = new ComparableArrayList<String>();
|
||||
CollectionUtil.addAll(implist, imports);
|
||||
checkedAdd(implist, InvocationDecoder.class.getName());
|
||||
implist.sort();
|
||||
|
||||
@@ -37,13 +37,15 @@ import com.threerings.presents.server.InvocationProvider;
|
||||
public class GenServiceTask extends InvocationTask
|
||||
{
|
||||
/** Used to keep track of custom InvocationListener derivations. */
|
||||
public class ServiceListener implements Comparable
|
||||
public class ServiceListener implements Comparable<ServiceListener>
|
||||
{
|
||||
public Class listener;
|
||||
|
||||
public ComparableArrayList methods = new ComparableArrayList();
|
||||
public ComparableArrayList<ServiceMethod> methods =
|
||||
new ComparableArrayList<ServiceMethod>();
|
||||
|
||||
public ServiceListener (Class service, Class listener, HashMap imports)
|
||||
public ServiceListener (Class service, Class listener,
|
||||
HashMap<String,Boolean> imports)
|
||||
{
|
||||
this.listener = listener;
|
||||
Method[] methdecls = listener.getDeclaredMethods();
|
||||
@@ -59,9 +61,9 @@ public class GenServiceTask extends InvocationTask
|
||||
methods.sort();
|
||||
}
|
||||
|
||||
public int compareTo (Object other)
|
||||
public int compareTo (ServiceListener other)
|
||||
{
|
||||
return getName().compareTo(((ServiceListener)other).getName());
|
||||
return getName().compareTo(other.getName());
|
||||
}
|
||||
|
||||
public boolean equals (Object other)
|
||||
@@ -115,9 +117,11 @@ public class GenServiceTask extends InvocationTask
|
||||
return;
|
||||
}
|
||||
|
||||
HashMap imports = new HashMap();
|
||||
ComparableArrayList methods = new ComparableArrayList();
|
||||
ComparableArrayList listeners = new ComparableArrayList();
|
||||
HashMap<String,Boolean> imports = new HashMap<String,Boolean>();
|
||||
ComparableArrayList<ServiceMethod> methods =
|
||||
new ComparableArrayList<ServiceMethod>();
|
||||
ComparableArrayList<ServiceListener> listeners =
|
||||
new ComparableArrayList<ServiceListener>();
|
||||
|
||||
// we need to import the service itself
|
||||
imports.put(importify(service.getName()), Boolean.TRUE);
|
||||
@@ -158,14 +162,14 @@ public class GenServiceTask extends InvocationTask
|
||||
|
||||
protected void generateMarshaller (
|
||||
File source, String sname, String spackage, List methods,
|
||||
List listeners, Iterator imports)
|
||||
List listeners, Iterator<String> imports)
|
||||
{
|
||||
String name = StringUtil.replace(sname, "Service", "");
|
||||
String mname = StringUtil.replace(sname, "Service", "Marshaller");
|
||||
String mpackage = StringUtil.replace(spackage, ".client", ".data");
|
||||
|
||||
// construct our imports list
|
||||
ComparableArrayList implist = new ComparableArrayList();
|
||||
ComparableArrayList<String> implist = new ComparableArrayList<String>();
|
||||
CollectionUtil.addAll(implist, imports);
|
||||
checkedAdd(implist, Client.class.getName());
|
||||
checkedAdd(implist, InvocationMarshaller.class.getName());
|
||||
@@ -198,14 +202,14 @@ public class GenServiceTask extends InvocationTask
|
||||
|
||||
protected void generateDispatcher (
|
||||
File source, String sname, String spackage, List methods,
|
||||
Iterator imports)
|
||||
Iterator<String> imports)
|
||||
{
|
||||
String name = StringUtil.replace(sname, "Service", "");
|
||||
String dname = StringUtil.replace(sname, "Service", "Dispatcher");
|
||||
String dpackage = StringUtil.replace(spackage, ".client", ".server");
|
||||
|
||||
// construct our imports list
|
||||
ComparableArrayList implist = new ComparableArrayList();
|
||||
ComparableArrayList<String> implist = new ComparableArrayList<String>();
|
||||
CollectionUtil.addAll(implist, imports);
|
||||
checkedAdd(implist, ClientObject.class.getName());
|
||||
checkedAdd(implist, InvocationMarshaller.class.getName());
|
||||
@@ -241,14 +245,14 @@ public class GenServiceTask extends InvocationTask
|
||||
|
||||
protected void generateProvider (
|
||||
File source, String sname, String spackage, List methods,
|
||||
List listeners, Iterator imports)
|
||||
List listeners, Iterator<String> imports)
|
||||
{
|
||||
String name = StringUtil.replace(sname, "Service", "");
|
||||
String mname = StringUtil.replace(sname, "Service", "Provider");
|
||||
String mpackage = StringUtil.replace(spackage, ".client", ".server");
|
||||
|
||||
// construct our imports list
|
||||
ComparableArrayList implist = new ComparableArrayList();
|
||||
ComparableArrayList<String> implist = new ComparableArrayList<String>();
|
||||
CollectionUtil.addAll(implist, imports);
|
||||
checkedAdd(implist, ClientObject.class.getName());
|
||||
checkedAdd(implist, InvocationProvider.class.getName());
|
||||
@@ -280,7 +284,7 @@ public class GenServiceTask extends InvocationTask
|
||||
}
|
||||
|
||||
/** Services for which we should not generate provider interfaces. */
|
||||
protected HashSet _providerless = new HashSet();
|
||||
protected HashSet<String> _providerless = new HashSet<String>();
|
||||
|
||||
/** Specifies the path to the marshaller template. */
|
||||
protected static final String MARSHALLER_TMPL =
|
||||
|
||||
@@ -46,7 +46,7 @@ public abstract class InvocationTask extends Task
|
||||
|
||||
public Class listener;
|
||||
|
||||
public ListenerArgument (int index, Class listener)
|
||||
public ListenerArgument (int index, Class<?> listener)
|
||||
{
|
||||
this.index = index+1;
|
||||
this.listener = listener;
|
||||
@@ -65,21 +65,23 @@ public abstract class InvocationTask extends Task
|
||||
}
|
||||
|
||||
/** Used to keep track of invocation service methods. */
|
||||
public class ServiceMethod implements Comparable
|
||||
public class ServiceMethod implements Comparable<ServiceMethod>
|
||||
{
|
||||
public Method method;
|
||||
|
||||
public ArrayList listenerArgs = new ArrayList();
|
||||
public ArrayList<ListenerArgument> listenerArgs =
|
||||
new ArrayList<ListenerArgument>();
|
||||
|
||||
public ServiceMethod (Class service, Method method, HashMap imports)
|
||||
public ServiceMethod (Class<?> service, Method method,
|
||||
HashMap<String,Boolean> imports)
|
||||
{
|
||||
this.method = method;
|
||||
|
||||
// we need to look through our arguments and note any needed
|
||||
// imports in the supplied table
|
||||
Class[] args = method.getParameterTypes();
|
||||
Class<?>[] args = method.getParameterTypes();
|
||||
for (int ii = 0; ii < args.length; ii++) {
|
||||
Class arg = args[ii];
|
||||
Class<?> arg = args[ii];
|
||||
while (arg.isArray()) {
|
||||
arg = arg.getComponentType();
|
||||
}
|
||||
@@ -132,7 +134,7 @@ public abstract class InvocationTask extends Task
|
||||
public String getArgList (boolean skipFirst)
|
||||
{
|
||||
StringBuilder buf = new StringBuilder();
|
||||
Class[] args = method.getParameterTypes();
|
||||
Class<?>[] args = method.getParameterTypes();
|
||||
for (int ii = skipFirst ? 1 : 0; ii < args.length; ii++) {
|
||||
if (buf.length() > 0) {
|
||||
buf.append(", ");
|
||||
@@ -146,7 +148,7 @@ public abstract class InvocationTask extends Task
|
||||
public String getWrappedArgList (boolean skipFirst)
|
||||
{
|
||||
StringBuilder buf = new StringBuilder();
|
||||
Class[] args = method.getParameterTypes();
|
||||
Class<?>[] args = method.getParameterTypes();
|
||||
for (int ii = (skipFirst ? 1 : 0); ii < args.length; ii++) {
|
||||
if (buf.length() > 0) {
|
||||
buf.append(", ");
|
||||
@@ -161,15 +163,15 @@ public abstract class InvocationTask extends Task
|
||||
return (method.getParameterTypes().length > (skipFirst ? 1 : 0));
|
||||
}
|
||||
|
||||
public int compareTo (Object other)
|
||||
public int compareTo (ServiceMethod other)
|
||||
{
|
||||
return getCode().compareTo(((ServiceMethod)other).getCode());
|
||||
return getCode().compareTo(other.getCode());
|
||||
}
|
||||
|
||||
public String getUnwrappedArgList (boolean listenerMode)
|
||||
{
|
||||
StringBuilder buf = new StringBuilder();
|
||||
Class[] args = method.getParameterTypes();
|
||||
Class<?>[] args = method.getParameterTypes();
|
||||
for (int ii = (listenerMode ? 0 : 1); ii < args.length; ii++) {
|
||||
if (buf.length() > 0) {
|
||||
buf.append(", ");
|
||||
@@ -180,7 +182,7 @@ public abstract class InvocationTask extends Task
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
protected String boxArgument (Class clazz, int index)
|
||||
protected String boxArgument (Class<?> clazz, int index)
|
||||
{
|
||||
if (_ilistener.isAssignableFrom(clazz)) {
|
||||
return GenUtil.boxArgument(clazz, "listener" + index);
|
||||
@@ -190,7 +192,7 @@ public abstract class InvocationTask extends Task
|
||||
}
|
||||
|
||||
protected String unboxArgument (
|
||||
Class clazz, int index, boolean listenerMode)
|
||||
Class<?> clazz, int index, boolean listenerMode)
|
||||
{
|
||||
if (listenerMode && _ilistener.isAssignableFrom(clazz)) {
|
||||
return "listener" + index;
|
||||
@@ -252,8 +254,7 @@ public abstract class InvocationTask extends Task
|
||||
throw new BuildException("Can't resolve InvocationListener", e);
|
||||
}
|
||||
|
||||
for (Iterator iter = _filesets.iterator(); iter.hasNext(); ) {
|
||||
FileSet fs = (FileSet)iter.next();
|
||||
for (FileSet fs : _filesets) {
|
||||
DirectoryScanner ds = fs.getDirectoryScanner(getProject());
|
||||
File fromDir = fs.getDir(getProject());
|
||||
String[] srcFiles = ds.getIncludedFiles();
|
||||
@@ -302,7 +303,7 @@ public abstract class InvocationTask extends Task
|
||||
FileUtils.writeStringToFile(new File(path), data, "UTF-8");
|
||||
}
|
||||
|
||||
protected static void checkedAdd (List list, Object value)
|
||||
protected static <T> void checkedAdd (List<T> list, T value)
|
||||
{
|
||||
if (!list.contains(value)) {
|
||||
list.add(value);
|
||||
@@ -324,7 +325,7 @@ public abstract class InvocationTask extends Task
|
||||
}
|
||||
|
||||
/** A list of filesets that contain tile images. */
|
||||
protected ArrayList _filesets = new ArrayList();
|
||||
protected ArrayList<FileSet> _filesets = new ArrayList<FileSet>();
|
||||
|
||||
/** A header to put on all generated source files. */
|
||||
protected String _header;
|
||||
@@ -337,5 +338,5 @@ public abstract class InvocationTask extends Task
|
||||
|
||||
/** {@link InvocationListener} resolved with the proper classloader so
|
||||
* that we can compare it to loaded derived classes. */
|
||||
protected Class _ilistener;
|
||||
protected Class<?> _ilistener;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* <code>$field</code> set. The set will not change until the event is
|
||||
* actually propagated through the system.
|
||||
*/
|
||||
public void addTo$upfield (DSet.Entry elem)
|
||||
public void addTo$upfield ($etype elem)
|
||||
{
|
||||
requestEntryAdd($capfield, $field, elem);
|
||||
}
|
||||
@@ -23,7 +23,7 @@
|
||||
* <code>$field</code> set. The set will not change until the event is
|
||||
* actually propagated through the system.
|
||||
*/
|
||||
public void update$upfield (DSet.Entry elem)
|
||||
public void update$upfield ($etype elem)
|
||||
{
|
||||
requestEntryUpdate($capfield, $field, elem);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,8 @@ public class ClassUtil
|
||||
* @return the method with the specified name or null if no method
|
||||
* with that name could be found.
|
||||
*/
|
||||
public static Method getMethod (String name, Object target, HashMap cache)
|
||||
public static Method getMethod (
|
||||
String name, Object target, HashMap<String,Method> cache)
|
||||
{
|
||||
Class tclass = target.getClass();
|
||||
String key = tclass.getName() + ":" + name;
|
||||
|
||||
@@ -35,14 +35,14 @@ import com.threerings.presents.dobj.Subscriber;
|
||||
* complete before the subscriber decides they no longer wish to be
|
||||
* subscribed.
|
||||
*/
|
||||
public class SafeSubscriber
|
||||
implements Subscriber
|
||||
public class SafeSubscriber<T extends DObject>
|
||||
implements Subscriber<T>
|
||||
{
|
||||
/**
|
||||
* Creates a safe subscriber for the specified distributed object
|
||||
* which will interact with the specified subscriber.
|
||||
*/
|
||||
public SafeSubscriber (int oid, Subscriber subscriber)
|
||||
public SafeSubscriber (int oid, Subscriber<T> subscriber)
|
||||
{
|
||||
// make sure they're not fucking us around
|
||||
if (oid <= 0) {
|
||||
@@ -157,7 +157,7 @@ public class SafeSubscriber
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void objectAvailable (DObject object)
|
||||
public void objectAvailable (T object)
|
||||
{
|
||||
// make sure life is not too cruel
|
||||
if (_object != null) {
|
||||
@@ -224,8 +224,8 @@ public class SafeSubscriber
|
||||
}
|
||||
|
||||
protected int _oid;
|
||||
protected Subscriber _subscriber;
|
||||
protected DObject _object;
|
||||
protected Subscriber<T> _subscriber;
|
||||
protected T _object;
|
||||
protected boolean _active;
|
||||
protected boolean _pending;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user