public class DObject extends Object implements Streamable
Additionally, an object has a set of subscribers. Subscribers manage the lifespan of the object; while a subscriber is subscribed, the listeners registered with an object will be notified of events. When the subscriber unsubscribes, the object becomes non-live and the listeners are no longer notified. Note: on the server, object subscription is merely a formality as all objects remain live all the time, so do not depend on event notifications ceasing when a subscriber has relinquished its subscription. Always unregister all listeners when they no longer need to hear from an object.
When there is any change to the the object's properties (which must be effected via the setter methods), an event is generated which is dispatched to all listeners of the object, notifying them of that change and effecting that change to the copy of the object maintained at each client. In this way, both a repository of shared information and a mechanism for asynchronous notification are made available as a fundamental application building blocks.
Distributed object fields can be any of the following set of primitive types:
boolean, byte, short, int, long, float, double
Boolean, Byte, Short, Integer, Long, Float, Double, String
boolean[], byte[], short[], int[], long[], float[], double[], String[]
as well as custom types that implement Streamable.Streamable.Closure| Constructor and Description |
|---|
DObject() |
| Modifier and Type | Method and Description |
|---|---|
boolean |
acquireLock(String name)
At times, an entity on the server may need to ensure that events it has queued up have made
it through the event queue and are applied to their respective objects before a service may
safely be undertaken again.
|
void |
addListener(ChangeListener listener)
Adds an event listener to this object.
|
void |
addListener(ChangeListener listener,
boolean weak)
Adds an event listener to this object.
|
void |
addSubscriber(Subscriber<?> sub)
Don't call this function! Go through the distributed object manager instead to ensure that
everything is done on the proper thread.
|
<T extends DSet.Entry> |
addToSet(String setName,
T entry)
Request to have the specified item added to the specified DSet.
|
void |
cancelTransaction()
Cancels the transaction in which this distributed object is involved.
|
void |
changeAttribute(String name,
Object value)
Requests that the specified attribute be changed to the specified value.
|
boolean |
checkPermissions(DEvent event)
Checks to ensure that this event which is about to be processed, has the appropriate
permissions.
|
boolean |
checkPermissions(Subscriber<?> sub)
Checks to ensure that the specified subscriber has access to this object.
|
void |
commitTransaction()
Commits the transaction in which this distributed object is involved.
|
void |
destroy()
Requests that this distributed object be destroyed.
|
AccessController |
getAccessController()
Returns a reference to the access controller in use by this object or null if none has been
configured.
|
Object |
getAttribute(String name)
Looks up the named attribute and returns a reference to it.
|
<T> T |
getLocal(Class<T> key)
Retrieves a local attribute for the supplied key.
|
List<Object> |
getLocals()
Returns an array containing our local attributes.
|
DObjectManager |
getManager()
Returns the dobject manager under the auspices of which this object operates.
|
int |
getOid()
Returns the object id of this object.
|
<T extends DSet.Entry> |
getSet(String setName)
Get the DSet with the specified name.
|
boolean |
inTransaction()
Returns true if this object is in the middle of a transaction or false if it is not.
|
boolean |
isActive()
Returns true if this object is active and registered with the distributed object system.
|
void |
notifyListeners(DEvent event)
Called by the distributed object manager after it has applied an event to this object.
|
void |
notifyProxies(DEvent event)
Called by the distributed object manager after it has applied an event to this object.
|
void |
postEvent(DEvent event)
Posts the specified event either to our dobject manager or to the compound event for which
we are currently transacting.
|
void |
postMessage(String name,
Object... args)
Posts a message event on this distributed object.
|
void |
postMessage(Transport transport,
String name,
Object... args)
Posts a message event on this distributed object.
|
void |
releaseLock(String name)
Queues up an event that when processed will release the lock of the specified name.
|
void |
removeFromSet(String setName,
Comparable<?> key)
Request to have the specified key removed from the specified DSet.
|
void |
removeListener(ChangeListener listener)
Removes an event listener from this object.
|
void |
removeSubscriber(Subscriber<?> sub)
Don't call this function! Go through the distributed object manager instead to ensure that
everything is done on the proper thread.
|
void |
setAccessController(AccessController controller)
Provides this object with an entity that can be used to validate subscription requests and
events before they are processed.
|
void |
setAttribute(String name,
Object value)
Sets the named attribute to the specified value.
|
void |
setDestroyOnLastSubscriberRemoved(boolean deathWish)
Instructs this object to request to have a fork stuck in it when its last subscriber is
removed.
|
<T> void |
setLocal(Class<T> key,
T attr)
Configures a local attribute on this object.
|
void |
setManager(DObjectManager omgr)
Don't call this function! It initializes this distributed object with the supplied
distributed object manager.
|
void |
setOid(int oid)
Don't call this function.
|
void |
startTransaction()
Begins a transaction on this distributed object.
|
String |
toString() |
void |
updateSet(String setName,
DSet.Entry entry)
Request to have the specified item updated in the specified DSet.
|
String |
which()
Generates a concise string representation of this object.
|
public int getOid()
public DObjectManager getManager()
null if the object is not active.public void addSubscriber(Subscriber<?> sub)
objectAvailable or to a listener callback).public void removeSubscriber(Subscriber<?> sub)
objectAvailable or to a listener callback).public void setDestroyOnLastSubscriberRemoved(boolean deathWish)
public void addListener(ChangeListener listener)
Note that the entity adding itself as a listener should have obtained the object
reference by subscribing to it or should be acting on behalf of some other entity that
subscribed to the object, and that it must be sure to remove itself from the
listener list (via removeListener(com.threerings.presents.dobj.ChangeListener)) when it is done because unsubscribing from the
object (done by whatever entity subscribed in the first place) is not guaranteed to result
in the listeners added through that subscription being automatically removed (in most cases,
they definitely will not be removed).
listener - the listener to be added.EventListener,
AttributeChangeListener,
SetListener,
OidListListenerpublic void addListener(ChangeListener listener, boolean weak)
Note that the entity adding itself as a listener should have obtained the object
reference by subscribing to it or should be acting on behalf of some other entity that
subscribed to the object, and that it must be sure to remove itself from the
listener list (via removeListener(com.threerings.presents.dobj.ChangeListener)) when it is done because unsubscribing from the
object (done by whatever entity subscribed in the first place) is not guaranteed to result
in the listeners added through that subscription being automatically removed (in most cases,
they definitely will not be removed).
listener - the listener to be added.weak - if true, retain only a weak reference to the listener (do not prevent the
listener from being garbage-collected).EventListener,
AttributeChangeListener,
SetListener,
OidListListenerpublic void removeListener(ChangeListener listener)
listener - the listener to be removed.public void setAccessController(AccessController controller)
public AccessController getAccessController()
public final <T extends DSet.Entry> DSet<T> getSet(String setName)
public <T extends DSet.Entry> void addToSet(String setName, T entry)
public void updateSet(String setName, DSet.Entry entry)
public void removeFromSet(String setName, Comparable<?> key)
public boolean acquireLock(String name)
releaseLock) which will queue up a final event, the processing of which will
release the lock. Thus the lock will not be released until all of the previously generated
events have been processed. If the service is invoked again before that lock is released,
the associated call to acquireLock will fail and the code can respond
accordingly. An object may have any number of outstanding locks as long as they each have a
unique name.name - the name of the lock to acquire.releaseLock(java.lang.String)public void releaseLock(String name)
acquireLock(java.lang.String)public void destroy()
public boolean checkPermissions(Subscriber<?> sub)
AccessController has been
specified for this object, it will be used to determine whether or not to allow the
subscription request. If no controller is set, the subscription will be allowed.sub - the subscriber that will subscribe to this object.public boolean checkPermissions(DEvent event)
AccessController has been specified for this object, it will be
used to determine whether or not to allow the even dispatch. If no controller is set, all
events are allowed.event - the event that will be dispatched, object permitting.public void notifyListeners(DEvent event)
event - the event that was just applied.public void notifyProxies(DEvent event)
event - the event that was just applied.public void changeAttribute(String name, Object value)
public void setAttribute(String name, Object value)
public Object getAttribute(String name)
public void postMessage(String name, Object... args)
public void postMessage(Transport transport, String name, Object... args)
transport - a hint as to the type of transport desired for the message.public void postEvent(DEvent event)
public final boolean isActive()
DObjectManager.createObject it will be active until
such time as it is destroyed.public void setManager(DObjectManager omgr)
public void setOid(int oid)
public <T> void setLocal(Class<T> key, T attr)
Also note that it is illegal to replace the value of a local attribute. Attempting to set a local attribute that already contains a value will fail. This is intended to catch programmer error as early as possible. You may clear a local attribute by setting it to null and then it can be set to a new value.
Lastly, note that key polymorphism is implemented to allow a lower level framework to define a local attribute and users of that framework to extend the attribute class and have it returned whether the derived or base class is used to look up the attribute. For example:
class BaseLocalAttr {
public int foo;
}
class DerivedLocalAttr extends BaseLocalAttr {
public int bar;
}
// simple usage
DObject o1 = new DObject();
BaseLocalAttr base = new BaseLocalAttr();
o1.setLocal(BaseLocalAttr.class, base);
assertSame(o1.getLocal(BaseLocalAttr.class), base); // true
// polymorphic usage
DObject o2 = new DObject();
DerivedLocalAttr derived = new DerivedLocalAttr();
o2.setLocal(DerivedLocalAttr.class, derived);
BaseLocalAttr upcasted = derived;
assertSame(o2.getLocal(DerivedLocalAttr.class), derived); // true
assertSame(o2.getLocal(BaseLocalAttr.class), upcasted); // true
// cannot overwrite already set attribute
DObject o3 = new DObject();
o3.setLocal(DerivedLocalAttr.class, derived);
o3.setLocal(DerivedLocalAttr.class, new DerivedLocalAttr()); // will fail
o3.setLocal(BaseLocalAttr.class, new BaseLocalAttr()); // will fail
IllegalStateException - thrown if an attempt is made to set a local attribute that
already contains a non-null value with any non-null value.public <T> T getLocal(Class<T> key)
setLocal(java.lang.Class<T>, T) for
information on key polymorphism. Returns null if no attribute is found that matches the
supplied key.public String which()
public void startTransaction()
When the transaction is complete, the caller must call commitTransaction() or
CompoundEvent.commit() to commit the transaction and release the object back to its
normal non-transacting state. If the caller decides not to commit their transaction, they
must call cancelTransaction() or CompoundEvent.cancel() to cancel the
transaction. Failure to do so will cause the pooch to be totally screwed.
Note: like all other distributed object operations, transactions are not thread safe. It is expected that a single thread will handle all distributed object operations and that thread will begin and complete a transaction before giving up control to unknown code which might try to operate on the transacting distributed object.
Note also: if the object is already engaged in a transaction, a transaction participant
count will be incremented to note that an additional call to commitTransaction() is
required before the transaction should actually be committed. Thus every call to
startTransaction() must be accompanied by a call to either commitTransaction()
or cancelTransaction(). Additionally, if any transaction participant cancels the
transaction, the entire transaction is cancelled for all participants, regardless of whether
the other participants attempted to commit the transaction.
public void commitTransaction()
CompoundEvent.commit()public boolean inTransaction()
public void cancelTransaction()
CompoundEvent.cancel()Copyright © 2015. All rights reserved.