Jorge Canizales | e8304d5 | 2015-02-17 19:50:51 -0800 | [diff] [blame] | 1 | /* |
| 2 | * |
Yang Gao | 5fc9029 | 2015-02-20 09:46:22 -0800 | [diff] [blame] | 3 | * Copyright 2015, Google Inc. |
Jorge Canizales | e8304d5 | 2015-02-17 19:50:51 -0800 | [diff] [blame] | 4 | * All rights reserved. |
| 5 | * |
| 6 | * Redistribution and use in source and binary forms, with or without |
| 7 | * modification, are permitted provided that the following conditions are |
| 8 | * met: |
| 9 | * |
| 10 | * * Redistributions of source code must retain the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer. |
| 12 | * * Redistributions in binary form must reproduce the above |
| 13 | * copyright notice, this list of conditions and the following disclaimer |
| 14 | * in the documentation and/or other materials provided with the |
| 15 | * distribution. |
| 16 | * * Neither the name of Google Inc. nor the names of its |
| 17 | * contributors may be used to endorse or promote products derived from |
| 18 | * this software without specific prior written permission. |
| 19 | * |
| 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 31 | * |
| 32 | */ |
| 33 | |
Jorge Canizales | 30697c9 | 2015-02-17 17:09:14 -0800 | [diff] [blame] | 34 | #import <Foundation/Foundation.h> |
| 35 | |
| 36 | #import "GRXWriteable.h" |
| 37 | |
Jorge Canizales | b10776c | 2015-10-26 10:44:55 -0700 | [diff] [blame^] | 38 | /** States of a writer. */ |
Jorge Canizales | 30697c9 | 2015-02-17 17:09:14 -0800 | [diff] [blame] | 39 | typedef NS_ENUM(NSInteger, GRXWriterState) { |
| 40 | |
Jorge Canizales | b10776c | 2015-10-26 10:44:55 -0700 | [diff] [blame^] | 41 | /** |
| 42 | * The writer has not yet been given a writeable to which it can push its values. To have a writer |
| 43 | * transition to the Started state, send it a startWithWriteable: message. |
| 44 | * |
| 45 | * A writer's state cannot be manually set to this value. |
| 46 | */ |
Jorge Canizales | 30697c9 | 2015-02-17 17:09:14 -0800 | [diff] [blame] | 47 | GRXWriterStateNotStarted, |
| 48 | |
Jorge Canizales | b10776c | 2015-10-26 10:44:55 -0700 | [diff] [blame^] | 49 | /** The writer might push values to the writeable at any moment. */ |
Jorge Canizales | 30697c9 | 2015-02-17 17:09:14 -0800 | [diff] [blame] | 50 | GRXWriterStateStarted, |
| 51 | |
Jorge Canizales | b10776c | 2015-10-26 10:44:55 -0700 | [diff] [blame^] | 52 | /** |
| 53 | * The writer is temporarily paused, and won't send any more values to the writeable unless its |
| 54 | * state is set back to Started. The writer might still transition to the Finished state at any |
| 55 | * moment, and is allowed to send writesFinishedWithError: to its writeable. |
| 56 | */ |
Jorge Canizales | 30697c9 | 2015-02-17 17:09:14 -0800 | [diff] [blame] | 57 | GRXWriterStatePaused, |
| 58 | |
Jorge Canizales | b10776c | 2015-10-26 10:44:55 -0700 | [diff] [blame^] | 59 | /** |
| 60 | * The writer has released its writeable and won't interact with it anymore. |
| 61 | * |
| 62 | * One seldomly wants to set a writer's state to this value, as its writeable isn't notified with |
| 63 | * a writesFinishedWithError: message. Instead, sending finishWithError: to the writer will make |
| 64 | * it notify the writeable and then transition to this state. |
| 65 | */ |
Jorge Canizales | 30697c9 | 2015-02-17 17:09:14 -0800 | [diff] [blame] | 66 | GRXWriterStateFinished |
| 67 | }; |
| 68 | |
Jorge Canizales | b10776c | 2015-10-26 10:44:55 -0700 | [diff] [blame^] | 69 | /** |
| 70 | * An GRXWriter object can produce, on demand, a sequence of values. The sequence may be produced |
| 71 | * asynchronously, and it may consist of any number of elements, including none or an infinite |
| 72 | * number. |
| 73 | * |
| 74 | * GRXWriter is the active dual of NSEnumerator. The difference between them is thus whether the |
| 75 | * object plays an active or passive role during usage: A user of NSEnumerator pulls values off it, |
| 76 | * and passes the values to a writeable. A user of GRXWriter, though, just gives it a writeable, and |
| 77 | * the GRXWriter instance pushes values to the writeable. This makes this protocol suitable to |
| 78 | * represent a sequence of future values, as well as collections with internal iteration. |
| 79 | * |
| 80 | * An instance of GRXWriter can start producing values after a writeable is passed to it. It can |
| 81 | * also be commanded to finish the sequence immediately (with an optional error). Finally, it can be |
| 82 | * asked to pause, and resumed later. All GRXWriter objects support pausing and early termination. |
| 83 | * |
| 84 | * Thread-safety: |
| 85 | * |
| 86 | * State transitions take immediate effect if the object is used from a single thread. Subclasses |
| 87 | * might offer stronger guarantees. |
| 88 | * |
| 89 | * Unless otherwise indicated by a conforming subclass, no messages should be sent concurrently to a |
| 90 | * GRXWriter. I.e., conforming classes aren't required to be thread-safe. |
| 91 | */ |
Jorge Canizales | 7b52c98 | 2015-07-16 18:41:21 -0700 | [diff] [blame] | 92 | @interface GRXWriter : NSObject |
Jorge Canizales | 30697c9 | 2015-02-17 17:09:14 -0800 | [diff] [blame] | 93 | |
Jorge Canizales | b10776c | 2015-10-26 10:44:55 -0700 | [diff] [blame^] | 94 | /** |
| 95 | * This property can be used to query the current state of the writer, which determines how it might |
| 96 | * currently use its writeable. Some state transitions can be triggered by setting this property to |
| 97 | * the corresponding value, and that's useful for advanced use cases like pausing an writer. For |
| 98 | * more details, see the documentation of the enum further down. |
| 99 | */ |
Jorge Canizales | 30697c9 | 2015-02-17 17:09:14 -0800 | [diff] [blame] | 100 | @property(nonatomic) GRXWriterState state; |
| 101 | |
Jorge Canizales | b10776c | 2015-10-26 10:44:55 -0700 | [diff] [blame^] | 102 | /** |
| 103 | * Transition to the Started state, and start sending messages to the writeable (a reference to it |
| 104 | * is retained). Messages to the writeable may be sent before the method returns, or they may be |
| 105 | * sent later in the future. See GRXWriteable.h for the different messages a writeable can receive. |
| 106 | * |
| 107 | * If this writer draws its values from an external source (e.g. from the filesystem or from a |
| 108 | * server), calling this method will commonly trigger side effects (like network connections). |
| 109 | * |
| 110 | * This method might only be called on writers in the NotStarted state. |
| 111 | */ |
Jorge Canizales | 30697c9 | 2015-02-17 17:09:14 -0800 | [diff] [blame] | 112 | - (void)startWithWriteable:(id<GRXWriteable>)writeable; |
| 113 | |
Jorge Canizales | b10776c | 2015-10-26 10:44:55 -0700 | [diff] [blame^] | 114 | /** |
| 115 | * Send writesFinishedWithError:errorOrNil to the writeable. Then release the reference to it and |
| 116 | * transition to the Finished state. |
| 117 | * |
| 118 | * This method might only be called on writers in the Started or Paused state. |
| 119 | */ |
Jorge Canizales | 30697c9 | 2015-02-17 17:09:14 -0800 | [diff] [blame] | 120 | - (void)finishWithError:(NSError *)errorOrNil; |
| 121 | @end |