001    // Copyright 2007 Waterken Inc. under the terms of the MIT X license
002    // found at http://www.opensource.org/licenses/mit-license.html
003    package org.waterken.serial;
004    
005    import static org.ref_send.promise.Eventual.cast;
006    
007    import java.io.Serializable;
008    import java.util.Iterator;
009    
010    import org.ref_send.promise.Deferred;
011    import org.ref_send.promise.Eventual;
012    import org.ref_send.promise.Promise;
013    import org.ref_send.promise.Resolver;
014    
015    /**
016     * A {@link Series} maker.
017     * @see "Section 19.9 'Queues' of 'Systems Programming in Concurrent Prolog';
018     *       Concurrent Prolog Collected Papers Volume 2; Ehud Shapiro; 1987."
019     */
020    public final class
021    Serial {
022        private Serial() {}
023    
024        /**
025         * Makes a {@link Series}.
026         * @param _ eventual operator
027         */
028        static public <T> Series<T>
029        make(final Eventual _) {
030            /*
031             * The implementation starts with a promise for the initial element,
032             * from which all other promises are derived.
033             */ 
034            final Deferred<Element<T>> initial = _.defer();
035            class SeriesX implements Series<T>, Serializable {
036                static private final long serialVersionUID = 1L;
037    
038                protected Element<T> front_ = cast(Element.class, initial.promise);
039                private   Resolver<Element<T>> back = initial.resolver;
040    
041                public Iterator<Promise<T>>
042                iterator() {
043                    class IteratorX implements Iterator<Promise<T>>, Serializable {
044                        static private final long serialVersionUID = 1L;
045    
046                        private Element<T> current_ = front_;
047    
048                        public boolean
049                        hasNext() { return true; }  // The future is unlimited.
050    
051                        public Promise<T>
052                        next() {
053                            /*
054                             * Produce a promise for what will be the value of the
055                             * current element and hold onto an eventual reference
056                             * for what will be the next element in the list, which
057                             * is now the current element in the iteration order.
058                             */
059                            final Promise<T> r = current_.getValue();
060                            current_ = current_.getNext();
061                            return r;
062                        }
063    
064                        public void
065                        remove() { throw new UnsupportedOperationException(); }
066                    }
067                    return new IteratorX();
068                }
069                
070                public Element<T>
071                getFront() { return front_; }
072    
073                public void
074                produce(final Promise<T> value) {
075                    /*
076                     * Resolve the promise for the last element in the list with an
077                     * actual element containing the provided value, and an eventual
078                     * reference for what will be the next element in the list,
079                     * which is now the new last element.
080                     */
081                    final Deferred<Element<T>> x = _.defer();
082                    back.apply(Link.link(value, cast(Element.class, x.promise)));
083                    back = x.resolver;
084                }
085    
086                public Promise<T>
087                consume() {
088                    /*
089                     * Produce a promise for what will be the value of the first
090                     * element and hold onto an eventual reference for what will be
091                     * the next element in the list, which is now the first element.
092                     */
093                    final Promise<T> r = front_.getValue();
094                    front_ = front_.getNext();
095                    return r;
096                }
097            }
098            return new SeriesX();
099        }
100    }