More progress on the basic distributed object facilities.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@16 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
//
|
||||
// $Id: DEvent.java,v 1.1 2001/06/01 05:01:52 mdb Exp $
|
||||
|
||||
package com.threerings.cocktail.cher.dobj;
|
||||
|
||||
/**
|
||||
* 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 class DEvent
|
||||
{
|
||||
}
|
||||
@@ -1,23 +1,130 @@
|
||||
//
|
||||
// $Id: DObject.java,v 1.4 2001/05/30 23:58:31 mdb Exp $
|
||||
// $Id: DObject.java,v 1.5 2001/06/01 05:01:52 mdb Exp $
|
||||
|
||||
package com.threerings.cocktail.cher.dobj;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* The distributed object forms the foundation of the cocktail system. All
|
||||
* information shared among users of the system is done via distributed
|
||||
* objects. A distributed object has a set of subscribers. These
|
||||
* subscribers have access to the object or a proxy of the object and
|
||||
* therefore have access to the data stored in the object's members at all
|
||||
* times.
|
||||
*
|
||||
* <p> When there is any change to that data, initiated by one of the
|
||||
* subscribers, an event is generated which is dispatched to all
|
||||
* subscribers of the object, notifying them of that change and affecting
|
||||
* that change to the copy of the object maintained at each client. In
|
||||
* this way, both a respository of shared information and a mechanism for
|
||||
* asynchronous notification are made available as a fundamental
|
||||
* application building blocks.
|
||||
*
|
||||
* <p> To define what information is shared, an application creates a
|
||||
* distributed object declaration which is much like a class declaration
|
||||
* except that it is transformed into a proper derived class of
|
||||
* <code>DObject</code> by a script. A declaration looks something like
|
||||
* this:
|
||||
*
|
||||
* <pre>
|
||||
* public dclass RoomObject
|
||||
* {
|
||||
* public String description;
|
||||
* public int[] occupants;
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* which is converted into an actual Java class that looks like this:
|
||||
*
|
||||
* <pre>
|
||||
* public class RoomObject extends DObject
|
||||
* {
|
||||
* public String getDescription ()
|
||||
* {
|
||||
* // ...
|
||||
* }
|
||||
*
|
||||
* public void setDescription (String description)
|
||||
* {
|
||||
* // ...
|
||||
* }
|
||||
*
|
||||
* public int[] getOccupants ()
|
||||
* {
|
||||
* // ...
|
||||
* }
|
||||
*
|
||||
* public void setOccupants (int[] occupants)
|
||||
* {
|
||||
* // ...
|
||||
* }
|
||||
*
|
||||
* public void setOccupantsAt (int index, int value)
|
||||
* {
|
||||
* // ...
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* These method calls on the actual distributed object will result in the
|
||||
* proper attribute change events being generated and dispatched.
|
||||
*/
|
||||
public class DObject
|
||||
{
|
||||
public void writeTo (DataOutputStream out)
|
||||
throws IOException
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @see DObjectManager.createObject
|
||||
*/
|
||||
public DObject (int oid)
|
||||
{
|
||||
// nothing doing!
|
||||
_oid = oid;
|
||||
_subscribers = new ArrayList();
|
||||
}
|
||||
|
||||
public void readFrom (DataInputStream in)
|
||||
throws IOException
|
||||
/**
|
||||
* Returns the object id of this object. All objects in the system
|
||||
* have a unique object id.
|
||||
*/
|
||||
public int getOid ()
|
||||
{
|
||||
// nothing doing!
|
||||
return _oid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the supplied subscriber to the subscriber list for this
|
||||
* object. This is done automatically when an object is requested for
|
||||
* subscription by the distributed object manager, thus this function
|
||||
* should not be called directly except in circumstances where one
|
||||
* subscriber has already obtained a subscription to an object and
|
||||
* wishes to include a subordinate subscriber in on the fun.
|
||||
*
|
||||
* <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)
|
||||
{
|
||||
if (!_subscribers.contains(subscriber)) {
|
||||
_subscribers.add(subscriber);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified subscriber from the subscriber list for this
|
||||
* object. This is done automatically when a subscriber returns false
|
||||
* from <code>handleEvent</code>, but can also be done directly
|
||||
* through a call to <code>removeSubscriber</code>. If the specified
|
||||
* subscriber is not currently on the list of subscribers for this
|
||||
* object, nothing happens.
|
||||
*/
|
||||
public void removeSubscriber (Subscriber subscriber)
|
||||
{
|
||||
_subscribers.remove(subscriber);
|
||||
}
|
||||
|
||||
protected int _oid;
|
||||
protected ArrayList _subscribers;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// $Id: DObjectManager.java,v 1.1 2001/06/01 05:01:52 mdb Exp $
|
||||
|
||||
package com.threerings.cocktail.cher.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
|
||||
{
|
||||
public void createObject (Class dclass, Subscriber sub);
|
||||
|
||||
public void subscribeToObject (int oid, Subscriber sub);
|
||||
|
||||
public void fetchObject (int oid, Subscriber sub);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// $Id: NoSuchObjectException.java,v 1.1 2001/06/01 05:01:52 mdb Exp $
|
||||
|
||||
package com.threerings.cocktail.cher.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,19 @@
|
||||
//
|
||||
// $Id: ObjectAccessException.java,v 1.1 2001/06/01 05:01:52 mdb Exp $
|
||||
|
||||
package com.threerings.cocktail.cher.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
|
||||
{
|
||||
public ObjectAccessException (String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// $Id: Subscriber.java,v 1.1 2001/06/01 05:01:52 mdb Exp $
|
||||
|
||||
package com.threerings.cocktail.cher.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.
|
||||
*/
|
||||
public interface Subscriber
|
||||
{
|
||||
/**
|
||||
* Called when a subscription request has succeeded and the object is
|
||||
* available. If the object was requested for subscription, the
|
||||
* subscriber will subsequently receive notifications via
|
||||
* <code>handleEvent</code>. If the object was requested as a one-time
|
||||
* read-only copy, these updates will not occur and the subscriber
|
||||
* should not attempt to modify the object.
|
||||
*
|
||||
* @see DObjectManager.subscribeToObject
|
||||
* @see DObjectManager.fetchObject
|
||||
*/
|
||||
public void objectAvailable (DObject 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
|
||||
* @see DObjectManager.fetchObject
|
||||
*/
|
||||
public void subscriptionFailed (ObjectAccessException cause);
|
||||
|
||||
/**
|
||||
* Called when an 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. <code>handleEvent</code> 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 dispatched on the object.
|
||||
* @param target The object on which the event was dispatched.
|
||||
*/
|
||||
public void handleEvent (DEvent event, DObject target);
|
||||
}
|
||||
Reference in New Issue
Block a user