<commit_before><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
  <head>
    <!-- $Id: package.html 617 2001-11-13 00:12:20Z mdb $ -->
  </head>

  <body bgcolor="white">

    Defines a framework for distributing information between multiple
    separate applications (over a network) and for coordinating control
    flow between those applications in the form of remote procedure call
    services. The normal configuration of the Presents system is
    client/server; generally with many clients connecting to a single
    server. All information transfer takes place through the server using
    the distributed object system documented below.

    <ul>
    <li><a href="#distributed_objects">Distributed Objects</a>
    <li><a href="#event_listeners">Event Listeners</a>
    <li><a href="#distributed_collections">Distributed Collections</a>
    <li><a href="#invocation_services">Invocation Services</a>
    <li><a href="#ant_tasks">Ant Tasks</a>
    </ul>

    <p> <em>A note to the reader:</em> the Presents system is a complex
    one and though a great deal of code is provided in explaining the
    services it provides, it is not the intent that one should start from
    only these examples and build a working system. A better approach is
    to read through this documentation to come to an understanding of the
    concepts and mechanisms that define the system and then take a look at
    some working sample code which is provided in the <code>tests</code>
    directory of this distribution.

    <h3><a name="distributed_objects">Distributed Objects</a></h3>

    The Presents services allow applications to access and update shared
    information through a mechanism known as distributed objects.
    Distributed objects are maintainedon the server and clients
    "subscribe" to the objects and are provided with proxy copies which
    are updated by a stream of events sent by the server when any state
    changes in the objects.

    <p> Clients cannot modify their proxy distributed objects directly,
    instead they make use of setter methods which package up the requested
    change into an event and send that event to the server for processing.
    After performing access control checks, the server will apply the
    event to the primary distributed object instance and then dispatch
    that event to all subscribed clients. Those clients (including the
    original change requesting client) then apply the event to their proxy
    copy of the object and in this way all clients maintain an up to date
    copy of the object's data.

    <p align="center"> <img src="images/dobject.png">

    <h4>Defining an object</h4>

    A distributed object is defined just like a regular Java object and is
    then run through a post-processor which inserts methods and constants
    into the object definition which are needed by the distributed object
    system. Here is a distributed object as originally defined:

    <pre class="example">
    public class CageObject extends DObject
    {
        /** The number of monkeys in the cage. */
        public int monkeys;

        /** The name of the owner of this cage. */
        public String owner;
    }</pre>

    Note that all distributed fields, or attributes (fields in a
    distributed object are frequently referred to as <i>attributes</i> in
    this documentation and elsewhere in the system), are public fields in
    our distributed object. Non-public fields will be ignored by the
    system and not transmitted when a proxy object is delivered over the
    network to a subscriber. Further, fields marked <code>transient</code>
    will also be ignored by the system.

    <p> We then run our class definition through a post-processor which
    turns it into the following:

    <pre class="example">
    public class CageObject extends DObject
    {
        <b>// AUTO-GENERATED: FIELDS START
        /** The field name of the <code>monkeys</code> field. */
        public static final String MONKEYS = "monkeys";

        /** The field name of the <code>owner</code> field. */
        public static final String OWNER = "owner";
        // AUTO-GENERATED: FIELDS END</b>

        /** The number of monkeys in the cage. */
        public int monkeys;

        /** The name of the owner of this cage. */
        public String owner;

        <b>// AUTO-GENERATED: METHODS START
        /**
         * Requests that the <code>monkeys</code> field be set to the
         * specified value. The local value will be updated immediately and an
         * event will be propagated through the system to notify all listeners
         * that the attribute did change. Proxied copies of this object (on
         * clients) will apply the value change when they received the
         * attribute changed notification.
         */
        public void setMonkeys (int value)
        {
            int ovalue = this.monkeys;
            requestAttributeChange(
                EVEN_BASE, new Integer(value), new Integer(ovalue));
            this.monkeys = value;
        }

        /**
         * Requests that the <code>owner</code> field be set to the
         * specified value. The local value will be updated immediately and an
         * event will be propagated through the system to notify all listeners
         * that the attribute did change. Proxied copies of this object (on
         * clients) will apply the value change when they received the
         * attribute changed notification.
         */
        public void setOwner (String value)
        {
            String ovalue = this.owner;
            requestAttributeChange(
                ODD_BASE, value, ovalue);
            this.owner = value;
        }
        // AUTO-GENERATED: METHODS END</b>
    }</pre>

    The contents of the methods are not too important, the main things to
    note are that setter methods for the two attributes were generated and
    constants were defined that will be used to identify which attribute
    changed if we choose to inspect an event notifying us of such a
    change.

    <p> One may also notice that attribute change requests result in the
    new value of the attribute being immediately written to the local copy
    of the object. This is a convention that was decided upon after
    repeatedly running into trouble when users of the system would set a
    value in an object and immediately assume it held the new value rather
    than realizing that an event would have to propagate back from the
    server before the value was in fact updated. By setting the value
    immediately, these problems are avoided and the opposite assumption is
    almost never made. This is further justified by the fact that, in
    general, attribute changes never originate on a client but instead
    originate on the server after processing a request from the client
    (via the below documented <a href="#invocation_services">invocation
    services</a>) to do something application-specific that results in one
    or more attribute changes taking place.

    <p> See the section on <a href="#ant_tasks">Ant Tasks</a> for
    information on how to configure and run this post-processor.

    <h4>Creating an object</h4>

    Generally, some entity on the server will choose to create a new
    instance of a distributed object. Rather than simply instantiate the
    object directly, one must create the object through the {@link
    com.threerings.presents.dobj.DObjectManager}:

    <pre class="example">
    public class ServerEntity implements Subscriber {
        public void init (DObjectManager omgr) {
            omgr.createObject(CageObject.class, this);
        }<commit_msg>Small documentation addition.<commit_after><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
  <head>
    <!-- $Id: package.html 617 2001-11-13 00:12:20Z mdb $ -->
  </head>

  <body bgcolor="white">

    Defines a framework for distributing information between multiple
    separate applications (over a network) and for coordinating control
    flow between those applications in the form of remote procedure call
    services. The normal configuration of the Presents system is
    client/server; generally with many clients connecting to a single
    server. All information transfer takes place through the server using
    the distributed object system documented below.

    <ul>
    <li><a href="#distributed_objects">Distributed Objects</a>
    <li><a href="#event_listeners">Event Listeners</a>
    <li><a href="#distributed_collections">Distributed Collections</a>
    <li><a href="#invocation_services">Invocation Services</a>
    <li><a href="#ant_tasks">Ant Tasks</a>
    </ul>

    <p> <em>A note to the reader:</em> the Presents system is a complex
    one and though a great deal of code is provided in explaining the
    services it provides, it is not the intent that one should start from
    only these examples and build a working system. A better approach is
    to read through this documentation to come to an understanding of the
    concepts and mechanisms that define the system and then take a look at
    some working sample code which is provided in the <code>tests</code>
    directory of this distribution.

    <h3><a name="distributed_objects">Distributed Objects</a></h3>

    The Presents services allow applications to access and update shared
    information through a mechanism known as distributed objects.
    Distributed objects are maintainedon the server and clients
    "subscribe" to the objects and are provided with proxy copies which
    are updated by a stream of events sent by the server when any state
    changes in the objects.

    <p> Clients cannot modify their proxy distributed objects directly,
    instead they make use of setter methods which package up the requested
    change into an event and send that event to the server for processing.
    After performing access control checks, the server will apply the
    event to the primary distributed object instance and then dispatch
    that event to all subscribed clients. Those clients (including the
    original change requesting client) then apply the event to their proxy
    copy of the object and in this way all clients maintain an up to date
    copy of the object's data.

    <p align="center"> <img src="images/dobject.png">

    <h4>Defining an object</h4>

    A distributed object is defined just like a regular Java object and is
    then run through a post-processor which inserts methods and constants
    into the object definition which are needed by the distributed object
    system. Here is a distributed object as originally defined:

    <pre class="example">
    public class CageObject extends DObject
    {
        /** The number of monkeys in the cage. */
        public int monkeys;

        /** The name of the owner of this cage. */
        public String owner;
    }</pre>

    Note that all distributed fields, or attributes (fields in a
    distributed object are frequently referred to as <i>attributes</i> in
    this documentation and elsewhere in the system), are public fields in
    our distributed object. Non-public fields will be ignored by the
    system and not transmitted when a proxy object is delivered over the
    network to a subscriber. Further, fields marked <code>transient</code>
    will also be ignored by the system.

    <p> We then run our class definition through a post-processor which
    turns it into the following:

    <pre class="example">
    public class CageObject extends DObject
    {
        <b>// AUTO-GENERATED: FIELDS START
        /** The field name of the <code>monkeys</code> field. */
        public static final String MONKEYS = "monkeys";

        /** The field name of the <code>owner</code> field. */
        public static final String OWNER = "owner";
        // AUTO-GENERATED: FIELDS END</b>

        /** The number of monkeys in the cage. */
        public int monkeys;

        /** The name of the owner of this cage. */
        public String owner;

        <b>// AUTO-GENERATED: METHODS START
        /**
         * Requests that the <code>monkeys</code> field be set to the
         * specified value. The local value will be updated immediately and an
         * event will be propagated through the system to notify all listeners
         * that the attribute did change. Proxied copies of this object (on
         * clients) will apply the value change when they received the
         * attribute changed notification.
         */
        public void setMonkeys (int value)
        {
            int ovalue = this.monkeys;
            requestAttributeChange(
                EVEN_BASE, new Integer(value), new Integer(ovalue));
            this.monkeys = value;
        }

        /**
         * Requests that the <code>owner</code> field be set to the
         * specified value. The local value will be updated immediately and an
         * event will be propagated through the system to notify all listeners
         * that the attribute did change. Proxied copies of this object (on
         * clients) will apply the value change when they received the
         * attribute changed notification.
         */
        public void setOwner (String value)
        {
            String ovalue = this.owner;
            requestAttributeChange(
                ODD_BASE, value, ovalue);
            this.owner = value;
        }
        // AUTO-GENERATED: METHODS END</b>
    }</pre>

    The contents of the methods are not too important, the main things to
    note are that setter methods for the two attributes were generated and
    constants were defined that will be used to identify which attribute
    changed if we choose to inspect an event notifying us of such a
    change. Note also that additional methods may be added to a
    distributed object class as long as nothing is modified in the
    <code>AUTO-GENERATED</code> section. As new fields are added and the
    post-processing tool re-run, everything outside the auto-generated
    section will be preserved.

    <p> One may also notice that attribute change requests result in the
    new value of the attribute being immediately written to the local copy
    of the object. This is a convention that was decided upon after
    repeatedly running into trouble when users of the system would set a
    value in an object and immediately assume it held the new value rather
    than realizing that an event would have to propagate back from the
    server before the value was in fact updated. By setting the value
    immediately, these problems are avoided and the opposite assumption is
    almost never made. This is further justified by the fact that, in
    general, attribute changes never originate on a client but instead
    originate on the server after processing a request from the client
    (via the below documented <a href="#invocation_services">invocation
    services</a>) to do something application-specific that results in one
    or more attribute changes taking place.

    <p> See the section on <a href="#ant_tasks">Ant Tasks</a> for
    information on how to configure and run this post-processor.

    <h4>Creating an object</h4>

    Generally, some entity on the server will choose to create a new
    instance of a distributed object. Rather than simply instantiate the
    object directly, one must create the object through the {@link
    com.threerings.presents.dobj.DObjectManager}:

    <pre class="example">
    public class ServerEntity implements Subscriber {
        public void init (DObjectManager omgr) {
            omgr.createObject(CageObject.class, this);
        }
{'fraction_non_alphanumeric': 0.057352005092297896, 'fraction_numerical': 0.003309993634627626, 'mean_word_length': 2.890787518573551, 'pattern_counts': {'":': 0, '<': 139, '<?xml version=': 0, '>': 139, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3945561', 'n_tokens_mistral': 3838, 'n_tokens_neox': 3687, 'n_words': 1999}