More progress on the distributed object stuff.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@19 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
//
|
||||
// $Id: AttributeChangedEvent.java,v 1.1 2001/06/01 07:12:13 mdb Exp $
|
||||
// $Id: AttributeChangedEvent.java,v 1.2 2001/06/01 19:56:13 mdb Exp $
|
||||
|
||||
package com.threerings.cocktail.cher.dobj;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import com.threerings.cocktail.cher.Log;
|
||||
|
||||
/**
|
||||
* An attribute changed event is dispatched when a single attribute of a
|
||||
* distributed object has changed. It can also be constructed to request
|
||||
@@ -92,6 +95,24 @@ public class AttributeChangedEvent extends DEvent
|
||||
return ((Double)_value).doubleValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies this attribute change to the object.
|
||||
*/
|
||||
public boolean applyToObject (DObject target)
|
||||
throws ObjectAccessException
|
||||
{
|
||||
// look up the setter for this object
|
||||
Method setter = DEventUtil.getSetter(target.getClass(), _name);
|
||||
|
||||
try {
|
||||
setter.invoke(target, new Object[] { _value });
|
||||
} catch (Exception e) {
|
||||
throw new ObjectAccessException("Reflection error: " + e);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected String _name;
|
||||
protected Object _value;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: DEvent.java,v 1.2 2001/06/01 07:12:13 mdb Exp $
|
||||
// $Id: DEvent.java,v 1.3 2001/06/01 19:56:13 mdb Exp $
|
||||
|
||||
package com.threerings.cocktail.cher.dobj;
|
||||
|
||||
@@ -9,7 +9,7 @@ package com.threerings.cocktail.cher.dobj;
|
||||
* notification purposes, without making any modifications to the object
|
||||
* that defines the delivery group (the object's subscribers).
|
||||
*/
|
||||
public class DEvent
|
||||
public abstract class DEvent
|
||||
{
|
||||
/**
|
||||
* Returns the oid of the object that is the target of this event.
|
||||
@@ -19,6 +19,22 @@ public class DEvent
|
||||
return _toid;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 subscribers of this event, false if the event should be
|
||||
* treated silently and the subscribers should not be notified.
|
||||
*/
|
||||
public abstract boolean applyToObject (DObject target)
|
||||
throws ObjectAccessException;
|
||||
|
||||
/**
|
||||
* Constructs a new distributed object event that pertains to the
|
||||
* specified distributed object.
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
//
|
||||
// $Id: DEventUtil.java,v 1.1 2001/06/01 19:56:13 mdb Exp $
|
||||
|
||||
package com.threerings.cocktail.cher.dobj;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* A repository for distributed object event related utility functions.
|
||||
*/
|
||||
public class DEventUtil
|
||||
{
|
||||
/**
|
||||
* Looks up and returns the method used to set an attribute of the
|
||||
* specified name on an instance of the specified distributed object
|
||||
* class.
|
||||
*/
|
||||
public static Method getSetter (Class clazz, String name)
|
||||
throws ObjectAccessException
|
||||
{
|
||||
// first see if it's cached
|
||||
Method setter = (Method)_setterCache.get(name);
|
||||
if (setter != null) {
|
||||
return setter;
|
||||
}
|
||||
|
||||
// convert the attribute name into a setter name
|
||||
String sname = setterName(name);
|
||||
try {
|
||||
// look up that method (we don't have the parameter types, so
|
||||
// we have to do our own name matching)
|
||||
Method[] methods = clazz.getMethods();
|
||||
for (int i = 0; i < methods.length; i++) {
|
||||
if (methods[i].getName().equals(sname)) {
|
||||
setter = methods[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (SecurityException se) {
|
||||
throw new ObjectAccessException("Reflection error: " + se);
|
||||
}
|
||||
|
||||
// make sure we found a matching method
|
||||
if (setter == null) {
|
||||
String errmsg = "No setter for attribute '" + name + "'.";
|
||||
throw new ObjectAccessException(errmsg);
|
||||
}
|
||||
|
||||
// and cache it
|
||||
_setterCache.put(name, setter);
|
||||
return setter;
|
||||
}
|
||||
|
||||
protected static String setterName (String name)
|
||||
{
|
||||
StringBuffer sname = new StringBuffer();
|
||||
sname.append("get");
|
||||
sname.append(Character.toUpperCase(name.charAt(0)));
|
||||
sname.append(name.substring(1));
|
||||
return sname.toString();
|
||||
}
|
||||
|
||||
protected static HashMap _setterCache = new HashMap();
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: DObject.java,v 1.6 2001/06/01 05:17:16 mdb Exp $
|
||||
// $Id: DObject.java,v 1.7 2001/06/01 19:56:13 mdb Exp $
|
||||
|
||||
package com.threerings.cocktail.cher.dobj;
|
||||
|
||||
@@ -73,17 +73,17 @@ import java.util.ArrayList;
|
||||
public class DObject
|
||||
{
|
||||
/**
|
||||
* Constructs a new distributed object with the supplied object id.
|
||||
* This should not be called directly, rather objects should be
|
||||
* created via the distributed object manager.
|
||||
* Initializes this distributed object with the supplied object id and
|
||||
* distributed object manager. This is called by the distributed
|
||||
* object manager when an object is created and registered with the
|
||||
* system. Don't call this function yourself.
|
||||
*
|
||||
* @see DObjectManager.createObject
|
||||
*/
|
||||
public DObject (int oid, DObjectManager manager)
|
||||
public void init (int oid, DObjectManager mgr)
|
||||
{
|
||||
_oid = oid;
|
||||
_mgr = manager;
|
||||
_subscribers = new ArrayList();
|
||||
_mgr = mgr;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,10 +106,10 @@ public class DObject
|
||||
* <p> If the specified subscriber is already subscribed to this
|
||||
* object, they will not be added to the list a second time.
|
||||
*/
|
||||
public void addSubscriber (Subscriber subscriber)
|
||||
public void addSubscriber (Subscriber sub)
|
||||
{
|
||||
if (!_subscribers.contains(subscriber)) {
|
||||
_subscribers.add(subscriber);
|
||||
if (!_subscribers.contains(sub)) {
|
||||
_subscribers.add(sub);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,12 +121,66 @@ public class DObject
|
||||
* subscriber is not currently on the list of subscribers for this
|
||||
* object, nothing happens.
|
||||
*/
|
||||
public void removeSubscriber (Subscriber subscriber)
|
||||
public void removeSubscriber (Subscriber sub)
|
||||
{
|
||||
_subscribers.remove(subscriber);
|
||||
_subscribers.remove(sub);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to ensure that the specified subscriber has access to this
|
||||
* object. This will be called before satisfying any fetch or
|
||||
* subscription request. By default objects are accessible to all
|
||||
* subscriber, but certain objects may wish to implement more fine
|
||||
* grained access control.
|
||||
*
|
||||
* @param sub the subscriber that will fetch or subscribe to this
|
||||
* object.
|
||||
*
|
||||
* @return true if the subscriber has access to the object, false if
|
||||
* they do not.
|
||||
*/
|
||||
public boolean checkPermissions (Subscriber sub)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to ensure that this event which is about to be processed,
|
||||
* has the appropriate permissions. By default objects accept all
|
||||
* manner of events, but certain objects may wish to implement more
|
||||
* fine grained access control.
|
||||
*
|
||||
* @param event the event that will be dispatched, object permitting.
|
||||
*
|
||||
* @return true if the event is valid and should be dispatched, false
|
||||
* if the event fails the permissions check and should be aborted.
|
||||
*/
|
||||
public boolean checkPermissions (DEvent event)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the distributed object manager after it has applied an
|
||||
* event to this object. This dispatches an event notification to all
|
||||
* of the subscribers of this object.
|
||||
*
|
||||
* @param event the event that was just applied.
|
||||
*/
|
||||
public void notifySubscribers (DEvent event)
|
||||
{
|
||||
for (int i = 0; i < _subscribers.size(); i++) {
|
||||
Subscriber sub = (Subscriber)_subscribers.get(i);
|
||||
// notify the subscriber
|
||||
if (!sub.handleEvent(event, this)) {
|
||||
// if they return false, we need to remove them from the
|
||||
// subscriber list
|
||||
_subscribers.remove(i--);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected int _oid;
|
||||
protected DObjectManager _mgr;
|
||||
protected ArrayList _subscribers;
|
||||
protected ArrayList _subscribers = new ArrayList();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user