Convert Narya (most of the way) over to a Maven Ant task based build. The
ActionScript bits remain belligerent, but the Java stuff is mostly shipshape. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6222 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
/**
|
||||
* Used to validate distributed object subscription requests and event
|
||||
* dispatches.
|
||||
*
|
||||
* @see DObject#setAccessController
|
||||
*/
|
||||
public interface AccessController
|
||||
{
|
||||
/**
|
||||
* Should return true if the supplied subscriber is allowed to
|
||||
* subscribe to the specified object.
|
||||
*/
|
||||
boolean allowSubscribe (DObject object, Subscriber<?> subscriber);
|
||||
|
||||
/**
|
||||
* Should return true if the supplied event is legal for dispatch on
|
||||
* the specified distributed object.
|
||||
*/
|
||||
boolean allowDispatch (DObject object, DEvent event);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
/**
|
||||
* Implemented by entities which wish to hear about attribute changes that take place for a
|
||||
* particular distributed object.
|
||||
*
|
||||
* @see DObject#addListener
|
||||
*/
|
||||
public interface AttributeChangeListener extends ChangeListener
|
||||
{
|
||||
/**
|
||||
* Called when an attribute changed event has been dispatched on an object. This will be
|
||||
* called <em>after</em> the event has been applied to the object. So fetching the attribute
|
||||
* during this call will provide the new value for the attribute.
|
||||
*
|
||||
* @param event The event that was dispatched on the object.
|
||||
*/
|
||||
void attributeChanged (AttributeChangedEvent event);
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.presents.net.Transport;
|
||||
|
||||
/**
|
||||
* An attribute changed event is dispatched when a single attribute of a distributed object has
|
||||
* changed. It can also be constructed to request an attribute change on an object and posted to
|
||||
* the dobjmgr.
|
||||
*
|
||||
* @see DObjectManager#postEvent
|
||||
*/
|
||||
public class AttributeChangedEvent extends NamedEvent
|
||||
{
|
||||
/**
|
||||
* Constructs a blank instance of this event in preparation for unserialization from the
|
||||
* network.
|
||||
*/
|
||||
public AttributeChangedEvent ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the new value of the attribute.
|
||||
*/
|
||||
public Object getValue ()
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the attribute prior to the application of this event.
|
||||
*/
|
||||
public Object getOldValue ()
|
||||
{
|
||||
return _oldValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the new value of the attribute as a byte. This will fail if the attribute in
|
||||
* question is not a byte.
|
||||
*/
|
||||
public byte getByteValue ()
|
||||
{
|
||||
return ((Byte)_value).byteValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the new value of the attribute as a short. This will fail if the attribute in
|
||||
* question is not a short.
|
||||
*/
|
||||
public short getShortValue ()
|
||||
{
|
||||
return ((Short)_value).shortValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the new value of the attribute as an int. This will fail if the attribute in
|
||||
* question is not an int.
|
||||
*/
|
||||
public int getIntValue ()
|
||||
{
|
||||
return ((Integer)_value).intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the new value of the attribute as a long. This will fail if the attribute in
|
||||
* question is not a long.
|
||||
*/
|
||||
public long getLongValue ()
|
||||
{
|
||||
return ((Long)_value).longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the new value of the attribute as a float. This will fail if the attribute in
|
||||
* question is not a float.
|
||||
*/
|
||||
public float getFloatValue ()
|
||||
{
|
||||
return ((Float)_value).floatValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the new value of the attribute as a double. This will fail if the attribute in
|
||||
* question is not a double.
|
||||
*/
|
||||
public double getDoubleValue ()
|
||||
{
|
||||
return ((Double)_value).doubleValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean alreadyApplied ()
|
||||
{
|
||||
// if we have an old value, that means we're running on the master server and we have
|
||||
// already applied this attribute change to the object
|
||||
return (_oldValue != UNSET_OLD_VALUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyToObject (DObject target)
|
||||
throws ObjectAccessException
|
||||
{
|
||||
// if we're not already applied, grab the previous value and apply the attribute change
|
||||
if (!alreadyApplied()) {
|
||||
_oldValue = target.getAttribute(_name);
|
||||
Object value = _value;
|
||||
if (value != null) {
|
||||
Class<?> vclass = value.getClass();
|
||||
if (vclass.isPrimitive()) {
|
||||
// do nothing; we check this to avoid the more expensive isAssignableFrom check
|
||||
// on primitives which are far and away the most common case
|
||||
} else if (vclass.isArray()) {
|
||||
int length = Array.getLength(value);
|
||||
Object clone = Array.newInstance(vclass.getComponentType(), length);
|
||||
System.arraycopy(value, 0, clone, 0, length);
|
||||
value = clone;
|
||||
} else if (DSet.class.isAssignableFrom(vclass)) {
|
||||
value = ((DSet<?>)value).clone();
|
||||
}
|
||||
}
|
||||
// pass the new value on to the object
|
||||
target.setAttribute(_name, value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new attribute changed event on the specified target object with the supplied
|
||||
* attribute name and value. <em>Do not construct these objects by hand.</em> Use {@link
|
||||
* DObject#changeAttribute} instead.
|
||||
*
|
||||
* @param targetOid the object id of the object whose attribute has changed.
|
||||
* @param name the name of the attribute (data member) that has changed.
|
||||
* @param value the new value of the attribute (in the case of primitive types, the
|
||||
* reflection-defined object-alternative is used).
|
||||
*/
|
||||
protected AttributeChangedEvent (int targetOid, String name, Object value, Object oldValue)
|
||||
{
|
||||
this(targetOid, name, value, oldValue, Transport.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new attribute changed event on the specified target object with the supplied
|
||||
* attribute name and value. <em>Do not construct these objects by hand.</em> Use {@link
|
||||
* DObject#changeAttribute} instead.
|
||||
*
|
||||
* @param targetOid the object id of the object whose attribute has changed.
|
||||
* @param name the name of the attribute (data member) that has changed.
|
||||
* @param value the new value of the attribute (in the case of primitive types, the
|
||||
* reflection-defined object-alternative is used).
|
||||
* @param transport a hint as to the type of transport desired for the event.
|
||||
*/
|
||||
protected AttributeChangedEvent (
|
||||
int targetOid, String name, Object value, Object oldValue, Transport transport)
|
||||
{
|
||||
super(targetOid, name, transport);
|
||||
_value = value;
|
||||
_oldValue = oldValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void notifyListener (Object listener)
|
||||
{
|
||||
if (listener instanceof AttributeChangeListener) {
|
||||
((AttributeChangeListener)listener).attributeChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toString (StringBuilder buf)
|
||||
{
|
||||
buf.append("CHANGE:");
|
||||
super.toString(buf);
|
||||
buf.append(", value=");
|
||||
StringUtil.toString(buf, _value);
|
||||
}
|
||||
|
||||
protected Object _value;
|
||||
protected transient Object _oldValue = UNSET_OLD_VALUE;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
/**
|
||||
* The various listener interfaces (e.g. {@link EventListener}, {@link AttributeChangeListener},
|
||||
* etc.) all extend this base interface so that the distributed object can check to make sure when
|
||||
* an object is adding itself as a listener of some sort that it actually implements at least one
|
||||
* of the listener interfaces. Thus, all listener interfaces must extend this one.
|
||||
*/
|
||||
public interface ChangeListener
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.threerings.util.StreamableArrayList;
|
||||
|
||||
import com.threerings.presents.net.Transport;
|
||||
|
||||
/**
|
||||
* Used to manage and submit groups of events on a collection of distributed objects in a single
|
||||
* transaction.
|
||||
*
|
||||
* @see DObject#startTransaction
|
||||
*/
|
||||
public class CompoundEvent extends DEvent
|
||||
{
|
||||
/**
|
||||
* Constructs a blank compound event in preparation for unserialization.
|
||||
*/
|
||||
public CompoundEvent ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a compound event and prepares it for operation.
|
||||
*/
|
||||
public CompoundEvent (DObject target, DObjectManager omgr)
|
||||
{
|
||||
super(target.getOid());
|
||||
|
||||
// sanity check
|
||||
if (omgr == null) {
|
||||
String errmsg = "Must receive non-null object manager reference";
|
||||
throw new IllegalArgumentException(errmsg);
|
||||
}
|
||||
|
||||
_omgr = omgr;
|
||||
_target = target;
|
||||
_events = StreamableArrayList.newList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Posts an event to this transaction. The event will be delivered as part of the entire
|
||||
* transaction if it is committed or discarded if the transaction is cancelled.
|
||||
*/
|
||||
public void postEvent (DEvent event)
|
||||
{
|
||||
_events.add(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of events contained within this compound event.
|
||||
*
|
||||
* Don't mess with it.
|
||||
*/
|
||||
public List<DEvent> getEvents ()
|
||||
{
|
||||
return _events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits this transaction by posting this event to the distributed object event queue. All
|
||||
* participating dobjects will have their transaction references cleared and will go back to
|
||||
* normal operation.
|
||||
*/
|
||||
public void commit ()
|
||||
{
|
||||
// first clear our target
|
||||
clearTarget();
|
||||
|
||||
// then post this event onto the queue (but only if we actually
|
||||
// accumulated some events)
|
||||
int size = _events.size();
|
||||
switch (size) {
|
||||
case 0: // nothing doing
|
||||
break;
|
||||
case 1: // no point in being compound
|
||||
_omgr.postEvent(_events.get(0));
|
||||
break;
|
||||
default: // now we're talking
|
||||
_transport = _events.get(0).getTransport();
|
||||
for (int ii = 1; ii < size; ii++) {
|
||||
_transport = _events.get(ii).getTransport().combine(_transport);
|
||||
}
|
||||
_omgr.postEvent(this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels this transaction. All events posted to this transaction will be discarded.
|
||||
*/
|
||||
public void cancel ()
|
||||
{
|
||||
// clear our target
|
||||
clearTarget();
|
||||
// clear our event queue in case someone holds onto us
|
||||
_events.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSourceOid (int sourceOid)
|
||||
{
|
||||
super.setSourceOid(sourceOid);
|
||||
|
||||
// we need to propagate our source oid to our constituent events
|
||||
int ecount = _events.size();
|
||||
for (int ii = 0; ii < ecount; ii++) {
|
||||
_events.get(ii).setSourceOid(sourceOid);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTargetOid (int targetOid)
|
||||
{
|
||||
super.setTargetOid(targetOid);
|
||||
|
||||
// we need to propagate our target oid to our constituent events
|
||||
int ecount = _events.size();
|
||||
for (int ii = 0; ii < ecount; ii++) {
|
||||
_events.get(ii).setTargetOid(targetOid);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTransport (Transport transport)
|
||||
{
|
||||
super.setTransport(transport);
|
||||
for (int ii = 0, nn = _events.size(); ii < nn; ii++) {
|
||||
_events.get(ii).setTransport(transport);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyToObject (DObject target)
|
||||
throws ObjectAccessException
|
||||
{
|
||||
// nothing to apply here
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls out to our target object, clearing its transaction reference.
|
||||
*/
|
||||
protected void clearTarget ()
|
||||
{
|
||||
if (_target != null) {
|
||||
_target.clearTransaction();
|
||||
_target = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toString (StringBuilder buf)
|
||||
{
|
||||
buf.append("COMPOUND:");
|
||||
super.toString(buf);
|
||||
for (int ii = 0; ii < _events.size(); ii++) {
|
||||
buf.append(", ").append(_events.get(ii));
|
||||
}
|
||||
}
|
||||
|
||||
/** The object manager that we'll post ourselves to when we're committed. */
|
||||
protected transient DObjectManager _omgr;
|
||||
|
||||
/** The object for which we're managing a transaction. */
|
||||
protected transient DObject _target;
|
||||
|
||||
/** A list of the events associated with this compound event. */
|
||||
protected StreamableArrayList<DEvent> _events;
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
import com.threerings.io.Streamable;
|
||||
|
||||
import com.threerings.presents.net.Transport;
|
||||
|
||||
/**
|
||||
* A distributed object event is dispatched whenever any modification is made to a distributed
|
||||
* object. It can also be dispatched purely for notification purposes, without making any
|
||||
* modifications to the object that defines the delivery group (the object's subscribers).
|
||||
*/
|
||||
public abstract class DEvent implements Streamable
|
||||
{
|
||||
/** This event's "number". Every event dispatched by the server is numbered in monotonically
|
||||
* increasing fashion when the event is posted to the event dispatch queue. */
|
||||
public transient long eventId;
|
||||
|
||||
/**
|
||||
* A zero argument constructor for unserialization from yon network.
|
||||
*/
|
||||
public DEvent ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new distributed object event that pertains to the specified distributed object.
|
||||
*/
|
||||
public DEvent (int targetOid)
|
||||
{
|
||||
this(targetOid, Transport.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new distributed object event that pertains to the specified distributed object.
|
||||
*
|
||||
* @param transport a hint as to the type of transport desired for the event.
|
||||
*/
|
||||
public DEvent (int targetOid, Transport transport)
|
||||
{
|
||||
_toid = targetOid;
|
||||
_transport = transport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the oid of the object that is the target of this event.
|
||||
*/
|
||||
public int getTargetOid ()
|
||||
{
|
||||
return _toid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Some events are used only internally on the server and need not be broadcast to subscribers,
|
||||
* proxy or otherwise. Such events can return true here and short-circuit the normal proxy
|
||||
* event dispatch mechanism.
|
||||
*/
|
||||
public boolean isPrivate ()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this event applies itself immediately to the distributed object on the server and then
|
||||
* NOOPs later when {@link #applyToObject} is called, it should return true from this method.
|
||||
* If it will modify the object during its {@link #applyToObject} call, it should return false.
|
||||
*/
|
||||
public boolean alreadyApplied ()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the attribute modifications represented by this event to the specified target
|
||||
* object. This is called by the distributed object manager in the course of dispatching events
|
||||
* and should not be called directly.
|
||||
*
|
||||
* @exception ObjectAccessException thrown if there is any problem applying the event to the
|
||||
* object (invalid attribute, etc.).
|
||||
*
|
||||
* @return true if the object manager should go on to notify the object's listeners of this
|
||||
* event, false if the event should be treated silently and the listeners should not be
|
||||
* notified.
|
||||
*/
|
||||
public abstract boolean applyToObject (DObject target)
|
||||
throws ObjectAccessException;
|
||||
|
||||
/**
|
||||
* Returns the object id of the client that generated this event. If the event was generated by
|
||||
* the server, the value returned will be -1. This is not valid on the client, it will return
|
||||
* -1 for all events there (it is primarily provided to allow for event-level access control).
|
||||
*/
|
||||
public int getSourceOid ()
|
||||
{
|
||||
return _soid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not call this method. Sets the oid of the object on which this event operates. It is only
|
||||
* used when rewriting events during object proxying.
|
||||
*/
|
||||
public void setTargetOid (int targetOid)
|
||||
{
|
||||
_toid = targetOid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not call this method. Sets the source oid of the client that generated this event. It is
|
||||
* automatically called by the client management code when a client forwards an event to the
|
||||
* server.
|
||||
*/
|
||||
public void setSourceOid (int sourceOid)
|
||||
{
|
||||
_soid = sourceOid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the transport parameters. For events received over the network, these indicate the
|
||||
* mode of transport over which the event was received. When an event is sent over the
|
||||
* network, these act as a hint as to the type of transport desired.
|
||||
*/
|
||||
public void setTransport (Transport transport)
|
||||
{
|
||||
_transport = transport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the transport parameters.
|
||||
*/
|
||||
public Transport getTransport ()
|
||||
{
|
||||
return _transport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes the actual transport with which the event was transmitted.
|
||||
*/
|
||||
public void noteActualTransport (Transport transport)
|
||||
{
|
||||
_actualTransport = transport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the actual transport with which the event was transmitted, or <code>null</code> if
|
||||
* not yet known.
|
||||
*/
|
||||
public Transport getActualTransport ()
|
||||
{
|
||||
return _actualTransport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Events with associated listener interfaces should implement this function and notify the
|
||||
* supplied listener if it implements their event listening interface. For example, the {@link
|
||||
* AttributeChangedEvent} will notify listeners that implement {@link AttributeChangeListener}.
|
||||
*/
|
||||
protected void notifyListener (Object listener)
|
||||
{
|
||||
// the default is to do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString ()
|
||||
{
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("[");
|
||||
toString(buf);
|
||||
buf.append("]");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* This should be overridden by derived classes (which should be sure to call
|
||||
* <code>super.toString()</code>) to append the derived class specific event information to the
|
||||
* string buffer.
|
||||
*/
|
||||
protected void toString (StringBuilder buf)
|
||||
{
|
||||
buf.append("targetOid=").append(_toid);
|
||||
buf.append(", sourceOid=").append(_soid);
|
||||
if (_transport != Transport.DEFAULT) {
|
||||
buf.append(", transport=").append(_transport);
|
||||
}
|
||||
}
|
||||
|
||||
/** The oid of the object that is the target of this event. */
|
||||
protected int _toid;
|
||||
|
||||
/** The oid of the client that generated this event. */
|
||||
protected transient int _soid = -1;
|
||||
|
||||
/** The transport parameters. */
|
||||
protected transient Transport _transport = Transport.DEFAULT;
|
||||
|
||||
/** The actual transport with which the event was transmitted (null if as yet unknown). */
|
||||
protected transient Transport _actualTransport;
|
||||
|
||||
/** Used to differentiate between null meaning we haven't initialized our old value and null
|
||||
* being the actual old value. */
|
||||
protected static final Object UNSET_OLD_VALUE = new Object();
|
||||
|
||||
/** Used to differentiate between null meaning we haven't initialized our old entry and null
|
||||
* being the actual old entry. */
|
||||
protected static final DSet.Entry UNSET_OLD_ENTRY = new DSet.Entry() {
|
||||
public Comparable<?> getKey () {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,82 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
/**
|
||||
* The distributed object manager is responsible for managing the creation and destruction of
|
||||
* distributed objects and propagating dobj events to the appropriate subscribers. On the client,
|
||||
* objects are managed as proxies to the real objects managed by the server, so attribute change
|
||||
* requests are forwarded to the server and events coming down from the server are delivered to the
|
||||
* local subscribers. On the server, the objects are managed directly.
|
||||
*/
|
||||
public interface DObjectManager
|
||||
{
|
||||
/**
|
||||
* Returns true if this distributed object manager is the authoritative manager for the
|
||||
* specified distributed object, or fals if we are only providing a proxy to the object.
|
||||
*/
|
||||
boolean isManager (DObject object);
|
||||
|
||||
/**
|
||||
* Requests that the specified subscriber be subscribed to the object identified by the
|
||||
* supplied object id. That subscriber will be notified when the object is available or if the
|
||||
* subscription request failed.
|
||||
*
|
||||
* @param oid The object id of the distributed object to which subscription is desired.
|
||||
* @param target The subscriber to be subscribed.
|
||||
*
|
||||
* @see Subscriber#objectAvailable
|
||||
* @see Subscriber#requestFailed
|
||||
*/
|
||||
<T extends DObject> void subscribeToObject (int oid, Subscriber<T> target);
|
||||
|
||||
/**
|
||||
* Requests that the specified subscriber be unsubscribed from the object identified by the
|
||||
* supplied object id.
|
||||
*
|
||||
* @param oid The object id of the distributed object from which unsubscription is desired.
|
||||
* @param target The subscriber to be unsubscribed.
|
||||
*/
|
||||
<T extends DObject> void unsubscribeFromObject (int oid, Subscriber<T> target);
|
||||
|
||||
/**
|
||||
* Posts a distributed object event into the system. Instead of requesting the modification of
|
||||
* a distributed object attribute by calling the setter for that attribute on the object
|
||||
* itself, an <code>AttributeChangedEvent</code> can be constructed and posted directly. This
|
||||
* is true for all event types and is useful for situations where one doesn't have access to
|
||||
* the object in question, but needs to affect some event.
|
||||
*
|
||||
* <p> This event will be forwarded to the ultimate manager of the object (on the client, this
|
||||
* means it will be forwarded to the server) where it will be checked for validity and then
|
||||
* applied to the object and dispatched to all its subscribers.
|
||||
*
|
||||
* @param event The event to be dispatched.
|
||||
*/
|
||||
void postEvent (DEvent event);
|
||||
|
||||
/**
|
||||
* When a distributed object removes its last subscriber, it will call this function to let the
|
||||
* object manager know. The manager might then choose to flush this object from the system or
|
||||
* unregister from some upstream manager whose object it was proxying, for example.
|
||||
*/
|
||||
void removedLastSubscriber (DObject obj, boolean deathWish);
|
||||
}
|
||||
@@ -0,0 +1,530 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
import java.util.AbstractSet;
|
||||
import java.util.Comparator;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.samskivert.util.ArrayUtil;
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
import com.threerings.io.Streamable;
|
||||
|
||||
import static com.threerings.presents.Log.log;
|
||||
|
||||
/**
|
||||
* The distributed set class provides a means by which an unordered set of objects can be
|
||||
* maintained as a distributed object field. Entries can be added to and removed from the set,
|
||||
* requests for which will generate events much like other distributed object fields.
|
||||
*
|
||||
* <p> Classes that wish to act as set entries must implement the {@link Entry} interface which
|
||||
* extends {@link Streamable} and adds the requirement that the object provide a key which will be
|
||||
* used to identify entry equality. Thus an entry is declared to be in a set of the object returned
|
||||
* by that entry's {@link Entry#getKey} method is equal (using {@link Object#equals}) to the entry
|
||||
* returned by the {@link Entry#getKey} method of some other entry in the set. Additionally, in the
|
||||
* case of entry removal, only the key for the entry to be removed will be transmitted with the
|
||||
* removal event to save network bandwidth. Lastly, the object returned by {@link Entry#getKey}
|
||||
* must be a {@link Streamable} type.
|
||||
*
|
||||
* @param <E> the type of entry stored in this set.
|
||||
*/
|
||||
public class DSet<E extends DSet.Entry>
|
||||
implements Iterable<E>, Streamable, Cloneable
|
||||
{
|
||||
/**
|
||||
* Entries of the set must implement this interface.
|
||||
*/
|
||||
public static interface Entry extends Streamable
|
||||
{
|
||||
/**
|
||||
* Each entry provide an associated key which is used to determine its uniqueness in the
|
||||
* set. See the {@link DSet} class documentation for further information.
|
||||
*/
|
||||
Comparable<?> getKey ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new DSet of the appropriate generic type.
|
||||
*/
|
||||
public static <E extends DSet.Entry> DSet<E> newDSet ()
|
||||
{
|
||||
return new DSet<E>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new DSet of the appropriate generic type.
|
||||
*/
|
||||
public static <E extends DSet.Entry> DSet<E> newDSet (Iterable<E> source)
|
||||
{
|
||||
return new DSet<E>(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the first comparable to the second. This is useful to avoid type safety warnings
|
||||
* when dealing with the keys of {@link DSet.Entry} values.
|
||||
*/
|
||||
public static int compare (Comparable<?> c1, Comparable<?> c2)
|
||||
{
|
||||
@SuppressWarnings("unchecked") Comparable<Object> cc1 = (Comparable<Object>)c1;
|
||||
@SuppressWarnings("unchecked") Comparable<Object> cc2 = (Comparable<Object>)c2;
|
||||
return cc1.compareTo(cc2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a distributed set and populates it with values from the supplied iterator. This
|
||||
* should be done before the set is unleashed into the wild distributed object world because no
|
||||
* associated entry added events will be generated. Additionally, this operation does not check
|
||||
* for duplicates when adding entries, so one should be sure that the iterator contains only
|
||||
* unique entries.
|
||||
*
|
||||
* @param source an iterator from which we will initially populate the set.
|
||||
*/
|
||||
public DSet (Iterable<E> source)
|
||||
{
|
||||
for (E e : source) {
|
||||
add(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a distributed set and populates it with values from the supplied iterator. This
|
||||
* should be done before the set is unleashed into the wild distributed object world because no
|
||||
* associated entry added events will be generated. Additionally, this operation does not check
|
||||
* for duplicates when adding entries, so one should be sure that the iterator contains only
|
||||
* unique entries.
|
||||
*
|
||||
* @param source an iterator from which we will initially populate the set.
|
||||
*/
|
||||
public DSet (Iterator<E> source)
|
||||
{
|
||||
while (source.hasNext()) {
|
||||
add(source.next());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a distributed set and populates it with values from the supplied array. This should
|
||||
* be done before the set is unleashed into the wild distributed object world because no
|
||||
* associated entry added events will be generated. Additionally, this operation does not check
|
||||
* for duplicates when adding entries, so one should be sure that the iterator contains only
|
||||
* unique entries.
|
||||
*
|
||||
* @param source an array from which we will initially populate the set.
|
||||
*/
|
||||
public DSet (E[] source)
|
||||
{
|
||||
for (E element : source) {
|
||||
if (element != null) {
|
||||
add(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an empty distributed set.
|
||||
*/
|
||||
public DSet ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of entries in this set.
|
||||
*/
|
||||
public int size ()
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the set contains an entry whose <code>getKey()</code> method returns a key
|
||||
* that <code>equals()</code> the key returned by <code>getKey()</code> of the supplied
|
||||
* entry. Returns false otherwise.
|
||||
*/
|
||||
public boolean contains (E elem)
|
||||
{
|
||||
return containsKey(elem.getKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if an entry in the set has a key that <code>equals()</code> the supplied
|
||||
* key. Returns false otherwise.
|
||||
*/
|
||||
public boolean containsKey (Comparable<?> key)
|
||||
{
|
||||
return get(key) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entry that matches (<code>getKey().equals(key)</code>) the specified key or null
|
||||
* if no entry could be found that matches the key.
|
||||
*/
|
||||
public E get (Comparable<?> key)
|
||||
{
|
||||
// determine where we'll be adding the new element
|
||||
int eidx = ArrayUtil.binarySearch(
|
||||
_entries, 0, _size, new SimpleEntry<Comparable<?>>(key), ENTRY_COMP);
|
||||
return (eidx < 0) ? null : _entries[eidx];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator over the entries of this set. It does not support modification (nor
|
||||
* iteration while modifications are being made to the set). It should not be kept around as it
|
||||
* can quickly become out of date.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public Iterator<E> entries ()
|
||||
{
|
||||
return iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator over the entries of this set. It does not support modification (nor
|
||||
* iteration while modifications are being made to the set). It should not be kept around as it
|
||||
* can quickly become out of date.
|
||||
*/
|
||||
public Iterator<E> iterator ()
|
||||
{
|
||||
// the crazy sanity checks
|
||||
if (_size < 0 || _size > _entries.length || (_size > 0 && _entries[_size-1] == null)) {
|
||||
log.warning("DSet in a bad way", "size", _size, "entries", _entries, new Exception());
|
||||
}
|
||||
|
||||
return new Iterator<E>() {
|
||||
public boolean hasNext () {
|
||||
checkComodification();
|
||||
return (_index < _size);
|
||||
}
|
||||
public E next () {
|
||||
checkComodification();
|
||||
return _entries[_index++];
|
||||
}
|
||||
public void remove () {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
protected void checkComodification () {
|
||||
if (_modCount != _expectedModCount) {
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
if (_ssize != _size) {
|
||||
log.warning("Size changed during iteration", "ssize", _ssize, "nsize", _size,
|
||||
"entries", _entries, new Exception());
|
||||
}
|
||||
}
|
||||
protected int _index = 0;
|
||||
protected int _ssize = _size;
|
||||
protected int _expectedModCount = _modCount;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the elements of this distributed set into the supplied array. If the array is not
|
||||
* large enough to hold all of the elements, as many as fit into the array will be copied. If
|
||||
* the <code>array</code> argument is null, an object array of sufficient size to contain all
|
||||
* of the elements of this set will be created and returned.
|
||||
*/
|
||||
public E[] toArray (E[] array)
|
||||
{
|
||||
if (array == null) {
|
||||
@SuppressWarnings("unchecked") E[] copy = (E[])new Entry[size()];
|
||||
array = copy;
|
||||
}
|
||||
System.arraycopy(_entries, 0, array, 0, array.length);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an <b>immutable</b> view of this distributed set as a Java set.
|
||||
*/
|
||||
public Set<E> asSet ()
|
||||
{
|
||||
return new AbstractSet<E>() {
|
||||
@Override public boolean add (E o) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
@Override public boolean remove (Object o) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
@Override public boolean contains (Object o) {
|
||||
if (!(o instanceof DSet.Entry)) {
|
||||
return false;
|
||||
}
|
||||
@SuppressWarnings("unchecked") E elem = (E)o;
|
||||
return DSet.this.contains(elem);
|
||||
}
|
||||
@Override public Iterator<E> iterator () {
|
||||
return DSet.this.iterator();
|
||||
}
|
||||
@Override public int size () {
|
||||
return DSet.this.size();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #toArray(Entry[])}.
|
||||
*/
|
||||
@Deprecated
|
||||
public Object[] toArray (Object[] array)
|
||||
{
|
||||
@SuppressWarnings("unchecked") E[] casted = (E[])array;
|
||||
return toArray(casted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified entry to the set. This should not be called directly, instead the
|
||||
* associated <code>addTo{Set}()</code> method should be called on the distributed object that
|
||||
* contains the set in question.
|
||||
*
|
||||
* @return true if the entry was added, false if it was already in the set.
|
||||
*/
|
||||
protected boolean add (E elem)
|
||||
{
|
||||
// determine where we'll be adding the new element
|
||||
int eidx = ArrayUtil.binarySearch(_entries, 0, _size, elem, ENTRY_COMP);
|
||||
|
||||
// if the element is already in the set, bail now
|
||||
if (eidx >= 0) {
|
||||
log.warning("Refusing to add duplicate entry", "entry", elem, "set", this,
|
||||
new Exception());
|
||||
return false;
|
||||
}
|
||||
|
||||
// convert the index into happy positive land
|
||||
eidx = (eidx+1)*-1;
|
||||
|
||||
// expand our entries array if necessary
|
||||
int elength = _entries.length;
|
||||
if (_size >= elength) {
|
||||
// sanity check
|
||||
if (elength > getWarningSize()) {
|
||||
log.warning("Requested to expand to questionably large size", "l", elength,
|
||||
new Exception());
|
||||
}
|
||||
|
||||
// create a new array and copy our data into it
|
||||
@SuppressWarnings("unchecked") E[] elems = (E[])new Entry[elength*2];
|
||||
System.arraycopy(_entries, 0, elems, 0, elength);
|
||||
_entries = elems;
|
||||
}
|
||||
|
||||
// if the entry doesn't go at the end, shift the elements down to accomodate it
|
||||
if (eidx < _size) {
|
||||
System.arraycopy(_entries, eidx, _entries, eidx+1, _size-eidx);
|
||||
}
|
||||
|
||||
// stuff the entry into the array and note that we're bigger
|
||||
_entries[eidx] = elem;
|
||||
_size++;
|
||||
_modCount++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified entry from the set. This should not be called directly, instead the
|
||||
* associated <code>removeFrom{Set}()</code> method should be called on the distributed object
|
||||
* that contains the set in question.
|
||||
*
|
||||
* @return true if the entry was removed, false if it was not in the set.
|
||||
*/
|
||||
protected boolean remove (E elem)
|
||||
{
|
||||
return (null != removeKey(elem.getKey()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes from the set the entry whose key matches the supplied key. This should not be called
|
||||
* directly, instead the associated <code>removeFrom{Set}()</code> method should be called on
|
||||
* the distributed object that contains the set in question.
|
||||
*
|
||||
* @return the old matching entry if found and removed, null if not found.
|
||||
*/
|
||||
protected E removeKey (Comparable<?> key)
|
||||
{
|
||||
// don't fail, but generate a warning if we're passed a null key
|
||||
if (key == null) {
|
||||
log.warning("Requested to remove null key.", new Exception());
|
||||
return null;
|
||||
}
|
||||
|
||||
// look up this entry's position in our set
|
||||
int eidx = ArrayUtil.binarySearch(
|
||||
_entries, 0, _size, new SimpleEntry<Comparable<?>>(key), ENTRY_COMP);
|
||||
|
||||
// if we found it, remove it
|
||||
if (eidx >= 0) {
|
||||
// extract the old entry
|
||||
E oldEntry = _entries[eidx];
|
||||
_size--;
|
||||
if ((_entries.length > INITIAL_CAPACITY) && (_size < _entries.length/8)) {
|
||||
// if we're using less than 1/8 of our capacity, shrink by half
|
||||
@SuppressWarnings("unchecked") E[] newEnts = (E[])new Entry[_entries.length/2];
|
||||
System.arraycopy(_entries, 0, newEnts, 0, eidx);
|
||||
System.arraycopy(_entries, eidx+1, newEnts, eidx, _size-eidx);
|
||||
_entries = newEnts;
|
||||
|
||||
} else {
|
||||
// shift entries past the removed one downwards
|
||||
System.arraycopy(_entries, eidx+1, _entries, eidx, _size-eidx);
|
||||
_entries[_size] = null;
|
||||
}
|
||||
_modCount++;
|
||||
return oldEntry;
|
||||
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the specified entry by locating an entry whose key matches the key of the supplied
|
||||
* entry and overwriting it. This should not be called directly, instead the associated
|
||||
* <code>update{Set}()</code> method should be called on the distributed object that contains
|
||||
* the set in question.
|
||||
*
|
||||
* @return the old entry that was replaced, or null if it was not found (in which case nothing
|
||||
* is updated).
|
||||
*/
|
||||
protected E update (E elem)
|
||||
{
|
||||
// look up this entry's position in our set
|
||||
int eidx = ArrayUtil.binarySearch(_entries, 0, _size, elem, ENTRY_COMP);
|
||||
|
||||
// if we found it, update it
|
||||
if (eidx >= 0) {
|
||||
E oldEntry = _entries[eidx];
|
||||
_entries[eidx] = elem;
|
||||
_modCount++;
|
||||
return oldEntry;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum size where we should warn that we're getting a bit large.
|
||||
*/
|
||||
protected int getWarningSize ()
|
||||
{
|
||||
return 2048;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a shallow copy of this object in a type safe manner.
|
||||
*
|
||||
* @deprecated clone() works just fine now.
|
||||
*/
|
||||
@Deprecated
|
||||
public DSet<E> typedClone ()
|
||||
{
|
||||
return clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a shallow copy of this object.
|
||||
*/
|
||||
@Override
|
||||
public DSet<E> clone ()
|
||||
{
|
||||
try {
|
||||
@SuppressWarnings("unchecked") DSet<E> nset = (DSet<E>)super.clone();
|
||||
@SuppressWarnings("unchecked") E[] copy = (E[])new Entry[_entries.length];
|
||||
nset._entries = copy;
|
||||
System.arraycopy(_entries, 0, nset._entries, 0, _entries.length);
|
||||
nset._modCount = 0;
|
||||
return nset;
|
||||
} catch (CloneNotSupportedException cnse) {
|
||||
throw new AssertionError(cnse);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString ()
|
||||
{
|
||||
StringBuilder buf = new StringBuilder("(");
|
||||
String prefix = "";
|
||||
for (E elem : _entries) {
|
||||
if (elem != null) {
|
||||
buf.append(prefix);
|
||||
prefix = ", ";
|
||||
buf.append(elem);
|
||||
}
|
||||
}
|
||||
buf.append(")");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/** Custom writer method. @see Streamable. */
|
||||
public void writeObject (ObjectOutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.writeInt(_size);
|
||||
for (int ii = 0; ii < _size; ii++) {
|
||||
out.writeObject(_entries[ii]);
|
||||
}
|
||||
}
|
||||
|
||||
/** Custom reader method. @see Streamable. */
|
||||
public void readObject (ObjectInputStream in)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
_size = in.readInt();
|
||||
// ensure our capacity is a power of 2 (for consistency)
|
||||
int capacity = INITIAL_CAPACITY;
|
||||
while (capacity < _size) {
|
||||
capacity <<= 1;
|
||||
}
|
||||
@SuppressWarnings("unchecked") E[] entries = (E[])new Entry[capacity];
|
||||
_entries = entries;
|
||||
for (int ii = 0; ii < _size; ii++) {
|
||||
@SuppressWarnings("unchecked") E entry = (E)in.readObject();
|
||||
_entries[ii] = entry;
|
||||
}
|
||||
}
|
||||
|
||||
/** The entries of the set (in a sparse array). */
|
||||
@SuppressWarnings("unchecked") protected E[] _entries = (E[])new Entry[INITIAL_CAPACITY];
|
||||
|
||||
/** The number of entries in this set. */
|
||||
protected int _size;
|
||||
|
||||
/** Used to check for concurrent modification. */
|
||||
protected transient int _modCount;
|
||||
|
||||
/** The default capacity of a set instance. */
|
||||
protected static final int INITIAL_CAPACITY = 2;
|
||||
|
||||
/** Used for lookups and to keep the set contents sorted on insertions. */
|
||||
protected static Comparator<Entry> ENTRY_COMP = new Comparator<Entry>() {
|
||||
public int compare (Entry e1, Entry e2) {
|
||||
return DSet.compare(e1.getKey(), e2.getKey());
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import com.samskivert.util.MethodFinder;
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import static com.threerings.presents.Log.log;
|
||||
|
||||
/**
|
||||
* Maps distributed object events to methods using reflection.
|
||||
*/
|
||||
public class DynamicListener<T extends DSet.Entry>
|
||||
implements AttributeChangeListener, ElementUpdateListener, SetListener<T>
|
||||
{
|
||||
/**
|
||||
* Creates a listener that dynamically dispatches events on the supplied
|
||||
* target.
|
||||
*/
|
||||
public DynamicListener (Object target)
|
||||
{
|
||||
this(target, new MethodFinder(target.getClass()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a listener that dynamically dispatches events on the supplied
|
||||
* target using the methods in finder.
|
||||
*/
|
||||
public DynamicListener (Object target, MethodFinder finder)
|
||||
{
|
||||
_target = target;
|
||||
_finder = finder;
|
||||
}
|
||||
|
||||
// from interface AttributeChangeListener
|
||||
public void attributeChanged (AttributeChangedEvent event)
|
||||
{
|
||||
dispatchMethod(event.getName() + "Changed",
|
||||
new Object[] { event.getValue() });
|
||||
}
|
||||
|
||||
// from interface ElementUpdateListener
|
||||
public void elementUpdated (ElementUpdatedEvent event)
|
||||
{
|
||||
dispatchMethod(event.getName() + "Updated",
|
||||
new Object[] { event.getIndex(), event.getValue() });
|
||||
}
|
||||
|
||||
// from interface SetListener
|
||||
public void entryAdded (EntryAddedEvent<T> event)
|
||||
{
|
||||
dispatchMethod(event.getName() + "Added",
|
||||
new Object[] { event.getEntry() });
|
||||
}
|
||||
|
||||
// from interface SetListener
|
||||
public void entryUpdated (EntryUpdatedEvent<T> event)
|
||||
{
|
||||
dispatchMethod(event.getName() + "Updated",
|
||||
new Object[] { event.getEntry() });
|
||||
}
|
||||
|
||||
// from interface SetListener
|
||||
public void entryRemoved (EntryRemovedEvent<T> event)
|
||||
{
|
||||
dispatchMethod(event.getName() + "Removed",
|
||||
new Object[] { event.getKey() });
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically looks up the method in question on our target and dispatches
|
||||
* an event if it does.
|
||||
*/
|
||||
public void dispatchMethod (String name, Object[] arguments)
|
||||
{
|
||||
// first check the cache
|
||||
Method method = _mcache.get(name);
|
||||
if (method == null) {
|
||||
// if we haven't already determined this method doesn't exist, try
|
||||
// to resolve it
|
||||
if (!_mcache.containsKey(name)) {
|
||||
_mcache.put(name, method = resolveMethod(name, arguments));
|
||||
}
|
||||
}
|
||||
if (method != null) {
|
||||
try {
|
||||
method.invoke(_target, arguments);
|
||||
} catch (Exception e) {
|
||||
log.warning("Failed to dispatch event callback " +
|
||||
name + "(" + StringUtil.toString(arguments) + ").", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for a method that matches the supplied signature.
|
||||
*/
|
||||
protected Method resolveMethod (String name, Object[] arguments)
|
||||
{
|
||||
Class<?>[] ptypes = new Class<?>[arguments.length];
|
||||
for (int ii = 0; ii < arguments.length; ii++) {
|
||||
ptypes[ii] = arguments[ii] == null ?
|
||||
null : arguments[ii].getClass();
|
||||
}
|
||||
try {
|
||||
return _finder.findMethod(name, ptypes);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** The object on which we will dynamically dispatch events. */
|
||||
protected Object _target;
|
||||
|
||||
/** Used to look up methods. */
|
||||
protected MethodFinder _finder;
|
||||
|
||||
/** A cache of already resolved methods. */
|
||||
protected HashMap<String, Method> _mcache = Maps.newHashMap();
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
/**
|
||||
* Implemented by entities which wish to hear about element updates that take place for a
|
||||
* particular distributed object.
|
||||
*
|
||||
* @see DObject#addListener
|
||||
*/
|
||||
public interface ElementUpdateListener extends ChangeListener
|
||||
{
|
||||
/**
|
||||
* Called when an element updated event has been dispatched on an object. This will be called
|
||||
* <em>after</em> the event has been applied to the object. So fetching the element during
|
||||
* this call will provide the new value for the element.
|
||||
*
|
||||
* @param event The event that was dispatched on the object.
|
||||
*/
|
||||
void elementUpdated (ElementUpdatedEvent event);
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.presents.net.Transport;
|
||||
|
||||
/**
|
||||
* An element updated event is dispatched when an element of an array field in a distributed object
|
||||
* is updated. It can also be constructed to request the update of an entry and posted to the
|
||||
* dobjmgr.
|
||||
*
|
||||
* @see DObjectManager#postEvent
|
||||
*/
|
||||
public class ElementUpdatedEvent extends NamedEvent
|
||||
{
|
||||
/**
|
||||
* Constructs a new element updated event on the specified target object with the supplied
|
||||
* attribute name, element and index.
|
||||
*
|
||||
* @param targetOid the object id of the object whose attribute has changed.
|
||||
* @param name the name of the attribute (data member) for which an element has changed.
|
||||
* @param value the new value of the element (in the case of primitive types, the
|
||||
* reflection-defined object-alternative is used).
|
||||
* @param ovalue the previous value of the element (in the case of primitive types, the
|
||||
* reflection-defined object-alternative is used).
|
||||
* @param index the index in the array of the updated element.
|
||||
*/
|
||||
public ElementUpdatedEvent (int targetOid, String name, Object value, Object ovalue, int index)
|
||||
{
|
||||
this(targetOid, name, value, ovalue, index, Transport.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new element updated event on the specified target object with the supplied
|
||||
* attribute name, element and index.
|
||||
*
|
||||
* @param targetOid the object id of the object whose attribute has changed.
|
||||
* @param name the name of the attribute (data member) for which an element has changed.
|
||||
* @param value the new value of the element (in the case of primitive types, the
|
||||
* reflection-defined object-alternative is used).
|
||||
* @param ovalue the previous value of the element (in the case of primitive types, the
|
||||
* reflection-defined object-alternative is used).
|
||||
* @param index the index in the array of the updated element.
|
||||
* @param transport a hint as to the type of transport desired for the event.
|
||||
*/
|
||||
public ElementUpdatedEvent (
|
||||
int targetOid, String name, Object value, Object ovalue, int index, Transport transport)
|
||||
{
|
||||
super(targetOid, name, transport);
|
||||
_value = value;
|
||||
_oldValue = ovalue;
|
||||
_index = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a blank instance of this event in preparation for unserialization from the
|
||||
* network.
|
||||
*/
|
||||
public ElementUpdatedEvent ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the new value of the element.
|
||||
*/
|
||||
public Object getValue ()
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the element prior to the application of this event.
|
||||
*/
|
||||
public Object getOldValue ()
|
||||
{
|
||||
return _oldValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the element.
|
||||
*/
|
||||
public int getIndex ()
|
||||
{
|
||||
return _index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the new value of the element as a short. This will fail if the element in question
|
||||
* is not a short.
|
||||
*/
|
||||
public short getShortValue ()
|
||||
{
|
||||
return ((Short)_value).shortValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the new value of the element as an int. This will fail if the element in question is
|
||||
* not an int.
|
||||
*/
|
||||
public int getIntValue ()
|
||||
{
|
||||
return ((Integer)_value).intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the new value of the element as a long. This will fail if the element in question is
|
||||
* not a long.
|
||||
*/
|
||||
public long getLongValue ()
|
||||
{
|
||||
return ((Long)_value).longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the new value of the element as a float. This will fail if the element in question
|
||||
* is not a float.
|
||||
*/
|
||||
public float getFloatValue ()
|
||||
{
|
||||
return ((Float)_value).floatValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the new value of the element as a double. This will fail if the element in question
|
||||
* is not a double.
|
||||
*/
|
||||
public double getDoubleValue ()
|
||||
{
|
||||
return ((Double)_value).doubleValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean alreadyApplied ()
|
||||
{
|
||||
return (_oldValue != UNSET_OLD_VALUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyToObject (DObject target)
|
||||
throws ObjectAccessException
|
||||
{
|
||||
if (!alreadyApplied()) {
|
||||
try {
|
||||
// fetch the array field from the object
|
||||
Field field = target.getClass().getField(_name);
|
||||
Class<?> ftype = field.getType();
|
||||
|
||||
// sanity check
|
||||
if (!ftype.isArray()) {
|
||||
String msg = "Requested to set element on non-array field.";
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
// grab the previous value to provide to interested parties
|
||||
_oldValue = Array.get(field.get(target), _index);
|
||||
|
||||
// we don't do any magical expansion or any funny business; the array should be big
|
||||
// enough to contain the value being updated or we'll throw an
|
||||
// ArrayIndexOutOfBoundsException
|
||||
Array.set(field.get(target), _index, _value);
|
||||
|
||||
} catch (Exception e) {
|
||||
String msg = "Error updating element [field=" + _name + ", index=" + _index + "]";
|
||||
throw new ObjectAccessException(msg, e);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void notifyListener (Object listener)
|
||||
{
|
||||
if (listener instanceof ElementUpdateListener) {
|
||||
((ElementUpdateListener)listener).elementUpdated(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toString (StringBuilder buf)
|
||||
{
|
||||
buf.append("UPDATE:");
|
||||
super.toString(buf);
|
||||
buf.append(", value=");
|
||||
StringUtil.toString(buf, _value);
|
||||
buf.append(", index=").append(_index);
|
||||
}
|
||||
|
||||
protected Object _value;
|
||||
protected int _index;
|
||||
protected transient Object _oldValue = UNSET_OLD_VALUE;
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
/**
|
||||
* An entry added event is dispatched when an entry is added to a {@link DSet} attribute of a
|
||||
* distributed entry. It can also be constructed to request the addition of an entry to a set and
|
||||
* posted to the dobjmgr.
|
||||
*
|
||||
* @see DObjectManager#postEvent
|
||||
*
|
||||
* @param <T> the type of entry being handled by this event. This must match the type on the set
|
||||
* that generated this event.
|
||||
*/
|
||||
public class EntryAddedEvent<T extends DSet.Entry> extends NamedEvent
|
||||
{
|
||||
/**
|
||||
* Constructs a new entry added event on the specified target object with the supplied set
|
||||
* attribute name and entry to add.
|
||||
*
|
||||
* @param targetOid the object id of the object to whose set we will add an entry.
|
||||
* @param name the name of the attribute to which to add the specified entry.
|
||||
* @param entry the entry to add to the set attribute.
|
||||
*/
|
||||
public EntryAddedEvent (int targetOid, String name, T entry)
|
||||
{
|
||||
this(targetOid, name, entry, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used when the distributed object already added the entry before generating the event.
|
||||
*/
|
||||
public EntryAddedEvent (int targetOid, String name, T entry, boolean alreadyApplied)
|
||||
{
|
||||
super(targetOid, name);
|
||||
_entry = entry;
|
||||
_alreadyApplied = alreadyApplied;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a blank instance of this event in preparation for unserialization from the
|
||||
* network.
|
||||
*/
|
||||
public EntryAddedEvent ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entry that has been added.
|
||||
*/
|
||||
public T getEntry ()
|
||||
{
|
||||
return _entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean alreadyApplied ()
|
||||
{
|
||||
return _alreadyApplied;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyToObject (DObject target)
|
||||
throws ObjectAccessException
|
||||
{
|
||||
if (!_alreadyApplied) {
|
||||
if (!target.getSet(_name).add(_entry)) {
|
||||
return false; // DSet will have already complained
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void notifyListener (Object listener)
|
||||
{
|
||||
if (listener instanceof SetListener<?>) {
|
||||
@SuppressWarnings("unchecked") SetListener<T> setlist = (SetListener<T>)listener;
|
||||
setlist.entryAdded(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toString (StringBuilder buf)
|
||||
{
|
||||
buf.append("ELADD:");
|
||||
super.toString(buf);
|
||||
buf.append(", entry=");
|
||||
StringUtil.toString(buf, _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 apply ourselves when we're actually dispatched. */
|
||||
protected transient boolean _alreadyApplied;
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
import static com.threerings.presents.Log.log;
|
||||
|
||||
/**
|
||||
* An entry removed event is dispatched when an entry is removed from a {@link DSet} attribute of a
|
||||
* distributed object. It can also be constructed to request the removal of an entry from a set and
|
||||
* posted to the dobjmgr.
|
||||
*
|
||||
* @see DObjectManager#postEvent
|
||||
*
|
||||
* @param <T> the type of entry being handled by this event. This must match the type on the set
|
||||
* that generated this event.
|
||||
*/
|
||||
public class EntryRemovedEvent<T extends DSet.Entry> extends NamedEvent
|
||||
{
|
||||
/**
|
||||
* Constructs a new entry removed event on the specified target object with the supplied set
|
||||
* attribute name and entry key to remove.
|
||||
*
|
||||
* @param targetOid the object id of the object from whose set we will remove an entry.
|
||||
* @param name the name of the attribute from which to remove the specified entry.
|
||||
* @param key the entry key that identifies the entry to remove.
|
||||
* @param oldEntry the previous value of the entry.
|
||||
*/
|
||||
public EntryRemovedEvent (int targetOid, String name, Comparable<?> key, T oldEntry)
|
||||
{
|
||||
super(targetOid, name);
|
||||
_key = key;
|
||||
_oldEntry = oldEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a blank instance of this event in preparation for unserialization from the
|
||||
* network.
|
||||
*/
|
||||
public EntryRemovedEvent ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key that identifies the entry that has been removed.
|
||||
*/
|
||||
public Comparable<?> getKey ()
|
||||
{
|
||||
return _key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entry that was in the set prior to being updated.
|
||||
*/
|
||||
public T getOldEntry ()
|
||||
{
|
||||
return _oldEntry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean alreadyApplied ()
|
||||
{
|
||||
return (_oldEntry != UNSET_OLD_ENTRY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyToObject (DObject target)
|
||||
throws ObjectAccessException
|
||||
{
|
||||
if (!alreadyApplied()) {
|
||||
DSet<T> set = target.getSet(_name);
|
||||
// remove, fetch the previous value for interested callers
|
||||
_oldEntry = set.removeKey(_key);
|
||||
if (_oldEntry == null) {
|
||||
// complain if there was actually nothing there
|
||||
log.warning("No matching entry to remove", "key", _key, "set", set);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void notifyListener (Object listener)
|
||||
{
|
||||
if (listener instanceof SetListener<?>) {
|
||||
@SuppressWarnings("unchecked") SetListener<T> setlist = (SetListener<T>)listener;
|
||||
setlist.entryRemoved(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toString (StringBuilder buf)
|
||||
{
|
||||
buf.append("ELREM:");
|
||||
super.toString(buf);
|
||||
buf.append(", key=").append(_key);
|
||||
}
|
||||
|
||||
protected Comparable<?> _key;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected transient T _oldEntry = (T)UNSET_OLD_ENTRY;
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.presents.net.Transport;
|
||||
|
||||
import static com.threerings.presents.Log.log;
|
||||
|
||||
/**
|
||||
* An entry updated event is dispatched when an entry of a {@link DSet} is updated. It can also be
|
||||
* constructed to request the update of an entry and posted to the dobjmgr.
|
||||
*
|
||||
* @see DObjectManager#postEvent
|
||||
*
|
||||
* @param <T> the type of entry being handled by this event. This must match the type on the set
|
||||
* that generated this event.
|
||||
*/
|
||||
public class EntryUpdatedEvent<T extends DSet.Entry> extends NamedEvent
|
||||
{
|
||||
/**
|
||||
* Constructs a new entry updated event on the specified target object for the specified set
|
||||
* name and with the supplied updated entry.
|
||||
*
|
||||
* @param targetOid the object id of the object to whose set we will add an entry.
|
||||
* @param name the name of the attribute in which to update the specified entry.
|
||||
* @param entry the entry to update.
|
||||
* @param oldEntry the previous value of the entry.
|
||||
*/
|
||||
public EntryUpdatedEvent (int targetOid, String name, T entry, T oldEntry)
|
||||
{
|
||||
this(targetOid, name, entry, oldEntry, Transport.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new entry updated event on the specified target object for the specified set
|
||||
* name and with the supplied updated entry.
|
||||
*
|
||||
* @param targetOid the object id of the object to whose set we will add an entry.
|
||||
* @param name the name of the attribute in which to update the specified entry.
|
||||
* @param entry the entry to update.
|
||||
* @param oldEntry the previous value of the entry.
|
||||
* @param transport a hint as to the type of transport desired for the event.
|
||||
*/
|
||||
public EntryUpdatedEvent (int targetOid, String name, T entry, T oldEntry, Transport transport)
|
||||
{
|
||||
super(targetOid, name, transport);
|
||||
_entry = entry;
|
||||
_oldEntry = oldEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a blank instance of this event in preparation for unserialization from the
|
||||
* network.
|
||||
*/
|
||||
public EntryUpdatedEvent ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entry that has been updated.
|
||||
*/
|
||||
public T getEntry ()
|
||||
{
|
||||
return _entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entry that was in the set prior to being updated.
|
||||
*/
|
||||
public T getOldEntry ()
|
||||
{
|
||||
return _oldEntry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean alreadyApplied ()
|
||||
{
|
||||
return (_oldEntry != UNSET_OLD_ENTRY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyToObject (DObject target)
|
||||
throws ObjectAccessException
|
||||
{
|
||||
// only apply the change if we haven't already
|
||||
if (!alreadyApplied()) {
|
||||
DSet<T> set = target.getSet(_name);
|
||||
// fetch the previous value for interested callers
|
||||
_oldEntry = set.update(_entry);
|
||||
if (_oldEntry == null) {
|
||||
// complain if we didn't update anything
|
||||
log.warning("No matching entry to update", "entry", this, "set", set);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void notifyListener (Object listener)
|
||||
{
|
||||
if (listener instanceof SetListener<?>) {
|
||||
@SuppressWarnings("unchecked") SetListener<T> setlist = (SetListener<T>)listener;
|
||||
setlist.entryUpdated(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toString (StringBuilder buf)
|
||||
{
|
||||
buf.append("ELUPD:");
|
||||
super.toString(buf);
|
||||
buf.append(", entry=");
|
||||
StringUtil.toString(buf, _entry);
|
||||
}
|
||||
|
||||
protected T _entry;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected transient T _oldEntry = (T)UNSET_OLD_ENTRY;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
/**
|
||||
* Implemented by entities which wish to hear about all events being dispatched on a particular
|
||||
* distributed object.
|
||||
*
|
||||
* @see DObject#addListener
|
||||
*/
|
||||
public interface EventListener extends ChangeListener
|
||||
{
|
||||
/**
|
||||
* Called when any event has been dispatched on an object. The event will be of the derived
|
||||
* class that corresponds to the kind of event that occurred on the object. This will be
|
||||
* called <em>after</em> the event has been applied to the object. So fetching an attribute
|
||||
* upon receiving an attribute changed event will provide the new value for the attribute.
|
||||
*
|
||||
* @param event The event that was dispatched on the object.
|
||||
*/
|
||||
void eventReceived (DEvent event);
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.presents.net.Transport;
|
||||
|
||||
/**
|
||||
* Used to dispatch an invocation notification from the server to a
|
||||
* client.
|
||||
*
|
||||
* @see DObjectManager#postEvent
|
||||
*/
|
||||
public class InvocationNotificationEvent extends DEvent
|
||||
{
|
||||
/**
|
||||
* Constructs a new invocation notification event on the specified
|
||||
* target object with the supplied receiver id, method id and
|
||||
* arguments.
|
||||
*
|
||||
* @param targetOid the object id of the object on which the event is
|
||||
* to be dispatched.
|
||||
* @param receiverId identifies the receiver to which this notification
|
||||
* is being dispatched.
|
||||
* @param methodId the id of the method to be invoked.
|
||||
* @param args the arguments for the method. This array should contain
|
||||
* only values of valid distributed object types.
|
||||
*/
|
||||
public InvocationNotificationEvent (
|
||||
int targetOid, short receiverId, int methodId, Object[] args)
|
||||
{
|
||||
this(targetOid, receiverId, methodId, args, Transport.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new invocation notification event on the specified
|
||||
* target object with the supplied receiver id, method id and
|
||||
* arguments.
|
||||
*
|
||||
* @param targetOid the object id of the object on which the event is
|
||||
* to be dispatched.
|
||||
* @param receiverId identifies the receiver to which this notification
|
||||
* is being dispatched.
|
||||
* @param methodId the id of the method to be invoked.
|
||||
* @param args the arguments for the method. This array should contain
|
||||
* only values of valid distributed object types.
|
||||
* @param transport a hint as to the type of transport desired for the event.
|
||||
*/
|
||||
public InvocationNotificationEvent (
|
||||
int targetOid, short receiverId, int methodId, Object[] args, Transport transport)
|
||||
{
|
||||
super(targetOid, transport);
|
||||
_receiverId = receiverId;
|
||||
_methodId = (byte)methodId;
|
||||
_args = args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a blank instance of this event in preparation for
|
||||
* unserialization from the network.
|
||||
*/
|
||||
public InvocationNotificationEvent ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the receiver id associated with this notification.
|
||||
*/
|
||||
public int getReceiverId ()
|
||||
{
|
||||
return _receiverId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the id of the method associated with this notification.
|
||||
*/
|
||||
public int getMethodId ()
|
||||
{
|
||||
return _methodId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the arguments associated with this notification.
|
||||
*/
|
||||
public Object[] getArgs ()
|
||||
{
|
||||
return _args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyToObject (DObject target)
|
||||
throws ObjectAccessException
|
||||
{
|
||||
// nothing to do here
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void notifyListener (Object listener)
|
||||
{
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toString (StringBuilder buf)
|
||||
{
|
||||
buf.append("INOT:");
|
||||
super.toString(buf);
|
||||
buf.append(", rcvId=").append(_receiverId);
|
||||
buf.append(", methodId=").append(_methodId);
|
||||
buf.append(", args=").append(StringUtil.toString(_args));
|
||||
}
|
||||
|
||||
/** Identifies the receiver to which this notification is being
|
||||
* dispatched. */
|
||||
protected short _receiverId;
|
||||
|
||||
/** The id of the receiver method being invoked. */
|
||||
protected byte _methodId;
|
||||
|
||||
/** The arguments to the receiver method being invoked. */
|
||||
protected Object[] _args;
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.presents.net.Transport;
|
||||
|
||||
/**
|
||||
* Used to dispatch an invocation request from the client to the server.
|
||||
*
|
||||
* @see DObjectManager#postEvent
|
||||
*/
|
||||
public class InvocationRequestEvent extends DEvent
|
||||
{
|
||||
/**
|
||||
* Constructs a new invocation request event on the specified target
|
||||
* object with the supplied code, method and arguments.
|
||||
*
|
||||
* @param targetOid the object id of the object on which the event is
|
||||
* to be dispatched.
|
||||
* @param invCode the invocation provider identification code.
|
||||
* @param methodId the id of the method to be invoked.
|
||||
* @param args the arguments for the method. This array should contain
|
||||
* only values of valid distributed object types.
|
||||
*/
|
||||
public InvocationRequestEvent (
|
||||
int targetOid, int invCode, int methodId, Object[] args)
|
||||
{
|
||||
this(targetOid, invCode, methodId, args, Transport.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new invocation request event on the specified target
|
||||
* object with the supplied code, method and arguments.
|
||||
*
|
||||
* @param targetOid the object id of the object on which the event is
|
||||
* to be dispatched.
|
||||
* @param invCode the invocation provider identification code.
|
||||
* @param methodId the id of the method to be invoked.
|
||||
* @param args the arguments for the method. This array should contain
|
||||
* only values of valid distributed object types.
|
||||
* @param transport a hint as to the type of transport desired for the event.
|
||||
*/
|
||||
public InvocationRequestEvent (
|
||||
int targetOid, int invCode, int methodId, Object[] args, Transport transport)
|
||||
{
|
||||
super(targetOid, transport);
|
||||
_invCode = invCode;
|
||||
_methodId = (byte)methodId;
|
||||
_args = args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a blank instance of this event in preparation for
|
||||
* unserialization from the network.
|
||||
*/
|
||||
public InvocationRequestEvent ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the invocation code associated with this request.
|
||||
*/
|
||||
public int getInvCode ()
|
||||
{
|
||||
return _invCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the id of the method associated with this request.
|
||||
*/
|
||||
public int getMethodId ()
|
||||
{
|
||||
return _methodId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the arguments associated with this request.
|
||||
*/
|
||||
public Object[] getArgs ()
|
||||
{
|
||||
return _args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyToObject (DObject target)
|
||||
throws ObjectAccessException
|
||||
{
|
||||
// nothing to do here
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void notifyListener (Object listener)
|
||||
{
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toString (StringBuilder buf)
|
||||
{
|
||||
buf.append("IREQ:");
|
||||
super.toString(buf);
|
||||
buf.append(", code=").append(_invCode);
|
||||
buf.append(", methodId=").append(_methodId);
|
||||
buf.append(", args=").append(StringUtil.toString(_args));
|
||||
}
|
||||
|
||||
/** The code identifying which invocation provider to which this
|
||||
* request is directed. */
|
||||
protected int _invCode;
|
||||
|
||||
/** The id of the method being invoked. */
|
||||
protected byte _methodId;
|
||||
|
||||
/** The arguments to the method being invoked. */
|
||||
protected Object[] _args;
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.presents.net.Transport;
|
||||
|
||||
/**
|
||||
* Used to dispatch an invocation response from the server to the client.
|
||||
*
|
||||
* @see DObjectManager#postEvent
|
||||
*/
|
||||
public class InvocationResponseEvent extends DEvent
|
||||
{
|
||||
/**
|
||||
* Constructs a new invocation response event on the specified target
|
||||
* object with the supplied code, method and arguments.
|
||||
*
|
||||
* @param targetOid the object id of the object on which the event is
|
||||
* to be dispatched.
|
||||
* @param requestId the id of the request to which we are responding.
|
||||
* @param methodId the method to be invoked.
|
||||
* @param args the arguments for the method. This array should contain
|
||||
* only values of valid distributed object types.
|
||||
*/
|
||||
public InvocationResponseEvent (
|
||||
int targetOid, int requestId, int methodId, Object[] args)
|
||||
{
|
||||
this(targetOid, requestId, methodId, args, Transport.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new invocation response event on the specified target
|
||||
* object with the supplied code, method and arguments.
|
||||
*
|
||||
* @param targetOid the object id of the object on which the event is
|
||||
* to be dispatched.
|
||||
* @param requestId the id of the request to which we are responding.
|
||||
* @param methodId the method to be invoked.
|
||||
* @param args the arguments for the method. This array should contain
|
||||
* only values of valid distributed object types.
|
||||
* @param transport a hint as to the type of transport desired for the event.
|
||||
*/
|
||||
public InvocationResponseEvent (
|
||||
int targetOid, int requestId, int methodId, Object[] args, Transport transport)
|
||||
{
|
||||
super(targetOid, transport);
|
||||
_requestId = (short)requestId;
|
||||
_methodId = (byte)methodId;
|
||||
_args = args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a blank instance of this event in preparation for
|
||||
* unserialization from the network.
|
||||
*/
|
||||
public InvocationResponseEvent ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the invocation request id associated with this response.
|
||||
*/
|
||||
public int getRequestId ()
|
||||
{
|
||||
return _requestId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the method associated with this response.
|
||||
*/
|
||||
public int getMethodId ()
|
||||
{
|
||||
return _methodId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the arguments associated with this response.
|
||||
*/
|
||||
public Object[] getArgs ()
|
||||
{
|
||||
return _args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyToObject (DObject target)
|
||||
throws ObjectAccessException
|
||||
{
|
||||
// nothing to do here
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void notifyListener (Object listener)
|
||||
{
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toString (StringBuilder buf)
|
||||
{
|
||||
buf.append("IRSP:");
|
||||
super.toString(buf);
|
||||
buf.append(", reqid=").append(_requestId);
|
||||
buf.append(", methodId=").append(_methodId);
|
||||
buf.append(", args=").append(StringUtil.toString(_args));
|
||||
}
|
||||
|
||||
/** The id of the request with which this response is associated. */
|
||||
protected short _requestId;
|
||||
|
||||
/** The id of the method being invoked. */
|
||||
protected byte _methodId;
|
||||
|
||||
/** The arguments to the method being invoked. */
|
||||
protected Object[] _args;
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.presents.net.Transport;
|
||||
|
||||
/**
|
||||
* A message event is used to dispatch a message to all subscribers of a
|
||||
* distributed object without actually changing any of the fields of the
|
||||
* object. A message has a name, by which different subscribers of the
|
||||
* same object can distinguish their different messages, and an array of
|
||||
* arguments by which any contents of the message can be delivered.
|
||||
*
|
||||
* @see DObjectManager#postEvent
|
||||
*/
|
||||
public class MessageEvent extends NamedEvent
|
||||
{
|
||||
/**
|
||||
* Constructs a new message event on the specified target object with
|
||||
* the supplied name and arguments.
|
||||
*
|
||||
* @param targetOid the object id of the object whose attribute has
|
||||
* changed.
|
||||
* @param name the name of the message event.
|
||||
* @param args the arguments for this message. This array should
|
||||
* contain only values of valid distributed object types.
|
||||
*/
|
||||
public MessageEvent (int targetOid, String name, Object[] args)
|
||||
{
|
||||
this(targetOid, name, args, Transport.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new message event on the specified target object with
|
||||
* the supplied name and arguments.
|
||||
*
|
||||
* @param targetOid the object id of the object whose attribute has
|
||||
* changed.
|
||||
* @param name the name of the message event.
|
||||
* @param args the arguments for this message. This array should
|
||||
* contain only values of valid distributed object types.
|
||||
* @param transport a hint as to the type of transport desired for the event.
|
||||
*/
|
||||
public MessageEvent (int targetOid, String name, Object[] args, Transport transport)
|
||||
{
|
||||
super(targetOid, name, transport);
|
||||
_args = args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a blank instance of this event in preparation for
|
||||
* unserialization from the network.
|
||||
*/
|
||||
public MessageEvent ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the arguments to this message.
|
||||
*/
|
||||
public Object[] getArgs ()
|
||||
{
|
||||
return _args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the arguments associated with this message event.
|
||||
* <em>Note:</em> this should only be called on events that have not
|
||||
* yet been dispatched into the distributed object system.
|
||||
*/
|
||||
public void setArgs (Object[] args)
|
||||
{
|
||||
_args = args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyToObject (DObject target)
|
||||
throws ObjectAccessException
|
||||
{
|
||||
// nothing to do here
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void notifyListener (Object listener)
|
||||
{
|
||||
if (listener instanceof MessageListener) {
|
||||
((MessageListener)listener).messageReceived(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toString (StringBuilder buf)
|
||||
{
|
||||
buf.append("MSG:");
|
||||
super.toString(buf);
|
||||
buf.append(", args=").append(StringUtil.toString(_args));
|
||||
}
|
||||
|
||||
protected Object[] _args;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
/**
|
||||
* Implemented by entities which wish to hear about message events that are dispatched on a
|
||||
* particular distributed object.
|
||||
*
|
||||
* @see DObject#addListener
|
||||
*/
|
||||
public interface MessageListener extends ChangeListener
|
||||
{
|
||||
/**
|
||||
* Called when an message event has been dispatched on an object.
|
||||
*
|
||||
* @param event The event that was dispatched on the object.
|
||||
*/
|
||||
void messageReceived (MessageEvent event);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
import com.threerings.presents.dobj.AttributeChangeListener;
|
||||
import com.threerings.presents.dobj.AttributeChangedEvent;
|
||||
|
||||
/**
|
||||
* A AttributeChangeListener that listens for changes with a given name and calls
|
||||
* <code>namedAttributeChanged</code> when they occur.
|
||||
*/
|
||||
public abstract class NamedAttributeListener
|
||||
implements AttributeChangeListener
|
||||
{
|
||||
/**
|
||||
* Listen for AttributeChangedEvent events with the given name.
|
||||
*/
|
||||
public NamedAttributeListener (String name)
|
||||
{
|
||||
_name = name;
|
||||
}
|
||||
|
||||
final public void attributeChanged (AttributeChangedEvent event)
|
||||
{
|
||||
if (event.getName().equals(_name)) {
|
||||
namedAttributeChanged(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The attribute this listener is watching has changed.
|
||||
*/
|
||||
public abstract void namedAttributeChanged (AttributeChangedEvent event);
|
||||
|
||||
protected final String _name;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
/**
|
||||
* An ElementUpdateListener that listens for changes with a given name and calls
|
||||
* namedElementUpdated when they occur.
|
||||
*/
|
||||
public abstract class NamedElementUpdateListener
|
||||
implements ElementUpdateListener
|
||||
{
|
||||
/**
|
||||
* Listen for element updates with the given name.
|
||||
*/
|
||||
public NamedElementUpdateListener (String name)
|
||||
{
|
||||
_name = name;
|
||||
}
|
||||
|
||||
final public void elementUpdated (ElementUpdatedEvent event)
|
||||
{
|
||||
if (event.getName().equals(_name)) {
|
||||
namedElementUpdated(event);
|
||||
}
|
||||
}
|
||||
|
||||
abstract protected void namedElementUpdated (ElementUpdatedEvent event);
|
||||
|
||||
protected final String _name;
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
import com.threerings.presents.net.Transport;
|
||||
|
||||
/**
|
||||
* A common parent class for all events that are associated with a name
|
||||
* (in some cases a field name, in other cases just an identifying name).
|
||||
*/
|
||||
public abstract class NamedEvent extends DEvent
|
||||
{
|
||||
/**
|
||||
* Constructs a new named event for the specified target object with
|
||||
* the supplied attribute name.
|
||||
*
|
||||
* @param targetOid the object id of the object in question.
|
||||
* @param name the name associated with this event.
|
||||
*/
|
||||
public NamedEvent (int targetOid, String name)
|
||||
{
|
||||
this(targetOid, name, Transport.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new named event for the specified target object with
|
||||
* the supplied attribute name.
|
||||
*
|
||||
* @param targetOid the object id of the object in question.
|
||||
* @param name the name associated with this event.
|
||||
* @param transport a hint as to the type of transport desired for the event.
|
||||
*/
|
||||
public NamedEvent (int targetOid, String name, Transport transport)
|
||||
{
|
||||
super(targetOid, transport);
|
||||
_name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a blank instance of this event in preparation for
|
||||
* unserialization from the network.
|
||||
*/
|
||||
public NamedEvent ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the attribute to which this event pertains.
|
||||
*/
|
||||
public String getName ()
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toString (StringBuilder buf)
|
||||
{
|
||||
super.toString(buf);
|
||||
buf.append(", name=").append(_name);
|
||||
}
|
||||
|
||||
protected String _name;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
/**
|
||||
* A SetAdapter that listens for changes with a given name and calls the 'named' version of the
|
||||
* SetListener methods when they occur.
|
||||
*/
|
||||
public class NamedSetAdapter<T extends DSet.Entry> extends SetAdapter<T>
|
||||
{
|
||||
/**
|
||||
* Listen for DSet events with the given name.
|
||||
*/
|
||||
public NamedSetAdapter (String name)
|
||||
{
|
||||
_name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
final public void entryAdded (EntryAddedEvent<T> event)
|
||||
{
|
||||
if (event.getName().equals(_name)) {
|
||||
namedEntryAdded(event);
|
||||
}
|
||||
}
|
||||
|
||||
public void namedEntryAdded (EntryAddedEvent<T> event)
|
||||
{
|
||||
// Override to provide functionality
|
||||
}
|
||||
|
||||
@Override
|
||||
final public void entryRemoved (EntryRemovedEvent<T> event)
|
||||
{
|
||||
if (event.getName().equals(_name)) {
|
||||
namedEntryRemoved(event);
|
||||
}
|
||||
}
|
||||
|
||||
public void namedEntryRemoved (EntryRemovedEvent<T> event)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
final public void entryUpdated (EntryUpdatedEvent<T> event)
|
||||
{
|
||||
if (event.getName().equals(_name)) {
|
||||
namedEntryUpdated(event);
|
||||
}
|
||||
}
|
||||
|
||||
public void namedEntryUpdated (EntryUpdatedEvent<T> event)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected final String _name;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
/**
|
||||
* A no such object exception is delivered when a subscriber requests
|
||||
* access to an object that does not exist.
|
||||
*/
|
||||
public class NoSuchObjectException extends ObjectAccessException
|
||||
{
|
||||
public NoSuchObjectException (int oid)
|
||||
{
|
||||
super("m.no_such_object\t" + oid);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
/**
|
||||
* An object access exception is delivered when an object is not accessible to a requesting
|
||||
* subscriber for some reason or other. For some access exceptions, special derived classes exist
|
||||
* to communicate the error. For others, a message string explaining the access failure is
|
||||
* provided.
|
||||
*/
|
||||
public class ObjectAccessException extends Exception
|
||||
{
|
||||
/**
|
||||
* Constructs a object access exception with the specified error message.
|
||||
*/
|
||||
public ObjectAccessException (String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a object access exception with the specified error message and the chained
|
||||
* causing event.
|
||||
*/
|
||||
public ObjectAccessException (String message, Exception cause)
|
||||
{
|
||||
super(message);
|
||||
initCause(cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a object access exception with the specified chained causing event.
|
||||
*/
|
||||
public ObjectAccessException (Exception cause)
|
||||
{
|
||||
initCause(cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
/**
|
||||
* An object added event is dispatched when an object is added to an
|
||||
* <code>OidList</code> attribute of a distributed object. It can also be
|
||||
* constructed to request the addition of an oid to an
|
||||
* <code>OidList</code> attribute of an object and posted to the dobjmgr.
|
||||
*
|
||||
* @see DObjectManager#postEvent
|
||||
*/
|
||||
public class ObjectAddedEvent extends NamedEvent
|
||||
{
|
||||
/**
|
||||
* Constructs a new object added event on the specified target object
|
||||
* with the supplied oid list attribute name and object id to add.
|
||||
*
|
||||
* @param targetOid the object id of the object to whose oid list we
|
||||
* will add an oid.
|
||||
* @param name the name of the attribute (data member) to which to add
|
||||
* the specified oid.
|
||||
* @param oid the oid to add to the oid list attribute.
|
||||
*/
|
||||
public ObjectAddedEvent (int targetOid, String name, int oid)
|
||||
{
|
||||
super(targetOid, name);
|
||||
_oid = oid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a blank instance of this event in preparation for
|
||||
* unserialization from the network.
|
||||
*/
|
||||
public ObjectAddedEvent ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the oid that has been added.
|
||||
*/
|
||||
public int getOid ()
|
||||
{
|
||||
return _oid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyToObject (DObject target)
|
||||
throws ObjectAccessException
|
||||
{
|
||||
OidList list = (OidList)target.getAttribute(_name);
|
||||
list.add(_oid);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void notifyListener (Object listener)
|
||||
{
|
||||
if (listener instanceof OidListListener) {
|
||||
((OidListListener)listener).objectAdded(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toString (StringBuilder buf)
|
||||
{
|
||||
buf.append("OBJADD:");
|
||||
super.toString(buf);
|
||||
buf.append(", oid=").append(_oid);
|
||||
}
|
||||
|
||||
protected int _oid;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
/**
|
||||
* Implemented by entities which wish to hear about object destruction events.
|
||||
*
|
||||
* @see DObject#addListener
|
||||
*/
|
||||
public interface ObjectDeathListener extends ChangeListener
|
||||
{
|
||||
/**
|
||||
* Called when this object has been destroyed. This will be called <em>after</em> the event has
|
||||
* been applied to the object.
|
||||
*
|
||||
* @param event The event that was dispatched on the object.
|
||||
*/
|
||||
void objectDestroyed (ObjectDestroyedEvent event);
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
/**
|
||||
* An object destroyed event is dispatched when an object has been removed
|
||||
* from the distributed object system. It can also be constructed to
|
||||
* request an attribute change on an object and posted to the dobjmgr.
|
||||
*
|
||||
* @see DObjectManager#postEvent
|
||||
*/
|
||||
public class ObjectDestroyedEvent extends DEvent
|
||||
{
|
||||
/**
|
||||
* Constructs a new object destroyed event for the specified
|
||||
* distributed object.
|
||||
*
|
||||
* @param targetOid the object id of the object that will be destroyed.
|
||||
*/
|
||||
public ObjectDestroyedEvent (int targetOid)
|
||||
{
|
||||
super(targetOid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a blank instance of this event in preparation for
|
||||
* unserialization from the network.
|
||||
*/
|
||||
public ObjectDestroyedEvent ()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyToObject (DObject target)
|
||||
throws ObjectAccessException
|
||||
{
|
||||
// nothing to do in preparation for destruction, the omgr will
|
||||
// have to recognize this type of event and do the right thing
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void notifyListener (Object listener)
|
||||
{
|
||||
if (listener instanceof ObjectDeathListener) {
|
||||
((ObjectDeathListener)listener).objectDestroyed(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toString (StringBuilder buf)
|
||||
{
|
||||
buf.append("DESTROY:");
|
||||
super.toString(buf);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
/**
|
||||
* An object removed event is dispatched when an object is removed from an
|
||||
* <code>OidList</code> attribute of a distributed object. It can also be
|
||||
* constructed to request the removal of an oid from an
|
||||
* <code>OidList</code> attribute of an object and posted to the dobjmgr.
|
||||
*
|
||||
* @see DObjectManager#postEvent
|
||||
*/
|
||||
public class ObjectRemovedEvent extends NamedEvent
|
||||
{
|
||||
/**
|
||||
* Constructs a new object removed event on the specified target
|
||||
* object with the supplied oid list attribute name and object id to
|
||||
* remove.
|
||||
*
|
||||
* @param targetOid the object id of the object from whose oid list we
|
||||
* will remove an oid.
|
||||
* @param name the name of the attribute (data member) from which to
|
||||
* remove the specified oid.
|
||||
* @param oid the oid to remove from the oid list attribute.
|
||||
*/
|
||||
public ObjectRemovedEvent (int targetOid, String name, int oid)
|
||||
{
|
||||
super(targetOid, name);
|
||||
_oid = oid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a blank instance of this event in preparation for
|
||||
* unserialization from the network.
|
||||
*/
|
||||
public ObjectRemovedEvent ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the oid that has been removed.
|
||||
*/
|
||||
public int getOid ()
|
||||
{
|
||||
return _oid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyToObject (DObject target)
|
||||
throws ObjectAccessException
|
||||
{
|
||||
OidList list = (OidList)target.getAttribute(_name);
|
||||
list.remove(_oid);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void notifyListener (Object listener)
|
||||
{
|
||||
if (listener instanceof OidListListener) {
|
||||
((OidListListener)listener).objectRemoved(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toString (StringBuilder buf)
|
||||
{
|
||||
buf.append("OBJREM:");
|
||||
super.toString(buf);
|
||||
buf.append(", oid=").append(_oid);
|
||||
}
|
||||
|
||||
protected int _oid;
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
import com.threerings.io.Streamable;
|
||||
|
||||
/**
|
||||
* An oid list is used to store lists of object ids. The list will not
|
||||
* allow duplicate ids. This class is not synchronized, with the
|
||||
* expectation that all modifications of instances will take place on the
|
||||
* dobjmgr thread.
|
||||
*
|
||||
* <ul>
|
||||
* <li> Do not use an OidList to store a set of ints. OidList has special meaning inside
|
||||
* of the dobj system, namely:
|
||||
* <li> When an object is destroyed, its oid is automagically removed from any OidLists.
|
||||
* </ul>
|
||||
*/
|
||||
public class OidList implements Streamable
|
||||
{
|
||||
/**
|
||||
* Creates an empty oid list.
|
||||
*/
|
||||
public OidList ()
|
||||
{
|
||||
this(DEFAULT_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an empty oid list with space for at least
|
||||
* <code>initialSize</code> object ids before it will need to expand.
|
||||
*/
|
||||
public OidList (int initialSize)
|
||||
{
|
||||
// ensure that we have at least two slots or the expansion code
|
||||
// won't work
|
||||
_oids = new int[Math.max(initialSize, 2)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of object ids in the list.
|
||||
*/
|
||||
public int size ()
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified object id to the list if it is not already
|
||||
* there.
|
||||
*
|
||||
* @return true if the object was added, false if it was already in
|
||||
* the list.
|
||||
*/
|
||||
public boolean add (int oid)
|
||||
{
|
||||
// check for existence
|
||||
for (int ii = 0; ii < _size; ii++) {
|
||||
if (_oids[ii] == oid) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// make room if necessary
|
||||
if (_size+1 >= _oids.length) {
|
||||
expand();
|
||||
}
|
||||
|
||||
// add the oid
|
||||
_oids[_size++] = oid;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified oid from the list.
|
||||
*
|
||||
* @return true if the oid was in the list and was removed, false
|
||||
* otherwise.
|
||||
*/
|
||||
public boolean remove (int oid)
|
||||
{
|
||||
// scan for the oid in question
|
||||
for (int ii = 0; ii < _size; ii++) {
|
||||
if (_oids[ii] == oid) {
|
||||
// shift the rest of the list back one
|
||||
System.arraycopy(_oids, ii+1, _oids, ii, --_size-ii);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified oid is in the list, false if not.
|
||||
*/
|
||||
public boolean contains (int oid)
|
||||
{
|
||||
for (int ii = 0; ii < _size; ii++) {
|
||||
if (_oids[ii] == oid) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the object id at the specified index. This does no boundary
|
||||
* checking.
|
||||
*/
|
||||
public int get (int index)
|
||||
{
|
||||
return _oids[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString ()
|
||||
{
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("{");
|
||||
for (int ii = 0; ii < _size; ii++) {
|
||||
if (ii > 0) {
|
||||
buf.append(", ");
|
||||
}
|
||||
buf.append(_oids[ii]);
|
||||
}
|
||||
buf.append("}");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private void expand ()
|
||||
{
|
||||
int[] oids = new int[_oids.length*2];
|
||||
System.arraycopy(_oids, 0, oids, 0, _oids.length);
|
||||
_oids = oids;
|
||||
}
|
||||
|
||||
private int[] _oids;
|
||||
private int _size;
|
||||
|
||||
protected static final int DEFAULT_SIZE = 4;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
/**
|
||||
* Implemented by entities which wish to hear about changes that occur to oid list attributes of a
|
||||
* particular distributed object.
|
||||
*
|
||||
* @see DObject#addListener
|
||||
*/
|
||||
public interface OidListListener extends ChangeListener
|
||||
{
|
||||
/**
|
||||
* Called when an object added event has been dispatched on an object. This will be called
|
||||
* <em>after</em> the event has been applied to the object.
|
||||
*
|
||||
* @param event The event that was dispatched on the object.
|
||||
*/
|
||||
void objectAdded (ObjectAddedEvent event);
|
||||
|
||||
/**
|
||||
* Called when an object removed event has been dispatched on an object. This will be called
|
||||
* <em>after</em> the event has been applied to the object.
|
||||
*
|
||||
* @param event The event that was dispatched on the object.
|
||||
*/
|
||||
void objectRemoved (ObjectRemovedEvent event);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
import com.threerings.presents.data.ClientObject;
|
||||
|
||||
/**
|
||||
* Defines a special kind of subscriber that proxies events for a subordinate distributed object
|
||||
* manager. All events dispatched on objects with which this subscriber is registered are passed
|
||||
* along to the subscriber for delivery to its subordinate manager.
|
||||
*
|
||||
* @see DObject#addListener
|
||||
*/
|
||||
public interface ProxySubscriber extends Subscriber<DObject>
|
||||
{
|
||||
/**
|
||||
* Called when any event has been dispatched on an object.
|
||||
*
|
||||
* @param event The event that was dispatched on the object.
|
||||
*/
|
||||
void eventReceived (DEvent event);
|
||||
|
||||
/**
|
||||
* Returns the client object that represents the subscriber for whom we are proxying.
|
||||
*/
|
||||
ClientObject getClientObject ();
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
/**
|
||||
* A release lock event is dispatched at the end of a chain of events to
|
||||
* release a lock that is intended to prevent some application defined
|
||||
* activity from happening until those events have been processed. This is
|
||||
* an entirely cooperative locking system, meaning that the application
|
||||
* will have to explicitly attempt acquisition of the lock to find out if
|
||||
* the lock has yet been released. These locks don't actually prevent any
|
||||
* of the distributed object machinery from functioning.
|
||||
*
|
||||
* @see DObjectManager#postEvent
|
||||
*/
|
||||
public class ReleaseLockEvent extends NamedEvent
|
||||
{
|
||||
/**
|
||||
* Constructs a new release lock event for the specified target object
|
||||
* with the supplied lock name.
|
||||
*
|
||||
* @param targetOid the object id of the object in question.
|
||||
* @param name the name of the lock to release.
|
||||
*/
|
||||
public ReleaseLockEvent (int targetOid, String name)
|
||||
{
|
||||
super(targetOid, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a blank instance of this event in preparation for
|
||||
* unserialization from the network.
|
||||
*/
|
||||
public ReleaseLockEvent ()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrivate ()
|
||||
{
|
||||
// we need only run on the server; no need to propagate to proxies
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies this lock release to the object.
|
||||
*/
|
||||
@Override
|
||||
public boolean applyToObject (DObject target)
|
||||
throws ObjectAccessException
|
||||
{
|
||||
// clear this lock from the target object
|
||||
target.clearLock(_name);
|
||||
// no need to notify subscribers about these sorts of events
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toString (StringBuilder buf)
|
||||
{
|
||||
buf.append("UNLOCK:");
|
||||
super.toString(buf);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import com.samskivert.util.Interval;
|
||||
import com.samskivert.util.RunQueue;
|
||||
|
||||
/**
|
||||
* The root distributed object manager extends the basic distributed object manager interface with
|
||||
* methods that can only be guaranteed to work in the virtual machine that is hosting the
|
||||
* distributed objects in question. VMs that operate proxies of objects can only implement the
|
||||
* basic distributed object manager interface.
|
||||
*/
|
||||
public interface RootDObjectManager extends DObjectManager, RunQueue, Executor
|
||||
{
|
||||
/**
|
||||
* Looks up and returns the requested distributed object in the dobj table, returning null if
|
||||
* no object exists with that oid.
|
||||
*/
|
||||
DObject getObject (int oid);
|
||||
|
||||
/**
|
||||
* Registers a distributed object instance of the supplied class with the system and assigns it
|
||||
* an oid. When the call returns the object will be registered with the system and its oid will
|
||||
* have been assigned.
|
||||
*
|
||||
* @return the registered object for the caller's convenience.
|
||||
*/
|
||||
<T extends DObject> T registerObject (T object);
|
||||
|
||||
/**
|
||||
* Requests that the specified object be destroyed. Once destroyed an object is removed from
|
||||
* the runtime system and may no longer have events dispatched on it.
|
||||
*
|
||||
* @param oid The object id of the distributed object to be destroyed.
|
||||
*/
|
||||
void destroyObject (int oid);
|
||||
|
||||
/**
|
||||
* Creates an {@link Interval} that runs the supplied runnable. If the root omgr is shutdown
|
||||
* before the interval expires (or if the interval is scheduled to repeat), it will be
|
||||
* automatically cancelled. This makes it easy to schedule fire-and-forget intervals:
|
||||
*
|
||||
* <pre>
|
||||
* _omgr.newInterval(someRunnable).schedule(500); // one shot
|
||||
* Interval ival = _omgr.newInterval(someRunnable).schedule(500, true); // repeater
|
||||
* </pre>
|
||||
*/
|
||||
Interval newInterval (Runnable action);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
/**
|
||||
* A message event that only goes to the server. If generated on the server then it never leaves
|
||||
* the server.
|
||||
*/
|
||||
public class ServerMessageEvent extends MessageEvent
|
||||
{
|
||||
/**
|
||||
* Constructs a new message event on the specified target object with
|
||||
* the supplied name and arguments.
|
||||
*
|
||||
* @param targetOid the object id of the object whose attribute has
|
||||
* changed.
|
||||
* @param name the name of the message event.
|
||||
* @param args the arguments for this message. This array should
|
||||
* contain only values of valid distributed object types.
|
||||
*/
|
||||
public ServerMessageEvent (int targetOid, String name, Object[] args)
|
||||
{
|
||||
super(targetOid, name, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Suitable for unserialization.
|
||||
*/
|
||||
public ServerMessageEvent ()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrivate ()
|
||||
{
|
||||
// this is what makes us server-only
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
/**
|
||||
* Implements the methods in SetListener so that you don't have to implement the ones you don't
|
||||
* want to.
|
||||
*
|
||||
* <p> <b>NOTE:</b> This adapter will receive <em>all</em> Entry events from a DObject it's
|
||||
* listening to, so it should check that the event's name matches the field it's interested in
|
||||
* before acting on the event.
|
||||
*
|
||||
* @param <T> the type of entry being handled by this listener. This must match the type on the set
|
||||
* that generates the events.
|
||||
*/
|
||||
public class SetAdapter<T extends DSet.Entry> implements SetListener<T>
|
||||
{
|
||||
// documentation inherited from interface SetListener
|
||||
public void entryAdded (EntryAddedEvent<T> event)
|
||||
{
|
||||
// override to provide functionality
|
||||
}
|
||||
|
||||
// documentation inherited from interface SetListener
|
||||
public void entryUpdated (EntryUpdatedEvent<T> event)
|
||||
{
|
||||
// override to provide functionality
|
||||
}
|
||||
|
||||
// documentation inherited from interface SetListener
|
||||
public void entryRemoved (EntryRemovedEvent<T> event)
|
||||
{
|
||||
// override to provide functionality
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
/**
|
||||
* Implemented by entities which wish to hear about changes that occur to set attributes of a
|
||||
* particular distributed object.
|
||||
*
|
||||
* <p> <b>NOTE:</b> This listener will receive <em>all</em> Entry events from a DObject it's
|
||||
* listening to, so it should check that the event's name matches the field it's interested in
|
||||
* before acting on the event.
|
||||
*
|
||||
* @see DObject#addListener
|
||||
*
|
||||
* @param <T> the type of entry being handled by this listener. This must match the type on the set
|
||||
* that generates the events.
|
||||
*/
|
||||
public interface SetListener<T extends DSet.Entry> extends ChangeListener
|
||||
{
|
||||
/**
|
||||
* Called when an entry added event has been dispatched on an
|
||||
* object. This will be called <em>after</em> the event has been
|
||||
* applied to the object.
|
||||
*
|
||||
* @param event The event that was dispatched on the object.
|
||||
*/
|
||||
void entryAdded (EntryAddedEvent<T> event);
|
||||
|
||||
/**
|
||||
* Called when an entry updated event has been dispatched on an
|
||||
* object. This will be called <em>after</em> the event has been
|
||||
* applied to the object.
|
||||
*
|
||||
* @param event The event that was dispatched on the object.
|
||||
*/
|
||||
void entryUpdated (EntryUpdatedEvent<T> event);
|
||||
|
||||
/**
|
||||
* Called when an entry removed event has been dispatched on an
|
||||
* object. This will be called <em>after</em> the event has been
|
||||
* applied to the object.
|
||||
*
|
||||
* @param event The event that was dispatched on the object.
|
||||
*/
|
||||
void entryRemoved (EntryRemovedEvent<T> event);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
import com.threerings.io.Streamable;
|
||||
|
||||
/**
|
||||
* A quick and easy DSet.Entry that holds some sort of Comparable.
|
||||
*
|
||||
* Remember: this type must also be {@link Streamable}.
|
||||
*/
|
||||
public class SimpleEntry<T extends Comparable<?>>
|
||||
implements DSet.Entry
|
||||
{
|
||||
// Zero arg constructor for unserialization
|
||||
public SimpleEntry () { }
|
||||
|
||||
public SimpleEntry (T key) {
|
||||
_key = key;
|
||||
}
|
||||
|
||||
public T getKey () {
|
||||
return _key;
|
||||
}
|
||||
|
||||
protected T _key;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://code.google.com/p/narya/
|
||||
//
|
||||
// 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.presents.dobj;
|
||||
|
||||
/**
|
||||
* A subscriber is an entity that has access to a distributed object. The
|
||||
* process of obtaining access to a distributed object is an asynchronous
|
||||
* one, and changes made to an object are delivered asynchronously. By
|
||||
* registering as a subscriber to an object, an entity can react to
|
||||
* changes made to an object and ensure that their object is kept up to
|
||||
* date.
|
||||
*
|
||||
* <p> To actually receive callbacks when events are dispatched on a
|
||||
* distributed object, an entity should register itself as a listener on
|
||||
* the object once it has received its object reference.
|
||||
*
|
||||
* @see EventListener
|
||||
* @see AttributeChangeListener
|
||||
* @see SetListener
|
||||
* @see OidListListener
|
||||
*
|
||||
* @param <T> the type object being subscribed to.
|
||||
*/
|
||||
public interface Subscriber<T extends DObject>
|
||||
{
|
||||
/**
|
||||
* Called when a subscription request has succeeded and the object is
|
||||
* available. If the object was requested for subscription, the
|
||||
* subscriber can subsequently receive notifications by registering
|
||||
* itself as a listener of some sort (see {@link
|
||||
* DObject#addListener}).
|
||||
*
|
||||
* @see DObjectManager#subscribeToObject
|
||||
*/
|
||||
void objectAvailable (T object);
|
||||
|
||||
/**
|
||||
* Called when a subscription request has failed. The nature of the
|
||||
* failure will be communicated via the supplied
|
||||
* <code>ObjectAccessException</code>.
|
||||
*
|
||||
* @see DObjectManager#subscribeToObject
|
||||
*/
|
||||
void requestFailed (int oid, ObjectAccessException cause);
|
||||
}
|
||||
Reference in New Issue
Block a user