All Downloads are FREE. Search and download functionalities are using the official Maven repository.

rx.lang.scala.observables.BlockingObservable.scala Maven / Gradle / Ivy

/**
 * Copyright 2013 Netflix, Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package rx.lang.scala.observables

import scala.collection.JavaConverters._
import rx.lang.scala.ImplicitFunctionConversions._


/**
 * An Observable that provides blocking operators.
 * 
 * You can obtain a BlockingObservable from an Observable using [[rx.lang.scala.Observable.toBlockingObservable]]
 */
// constructor is private because users should use Observable.toBlockingObservable
class BlockingObservable[+T] private[scala] (val asJava: rx.observables.BlockingObservable[_ <: T]) 
  extends AnyVal 
{

  /**
   * Invoke a method on each item emitted by the {@link Observable}; block until the Observable
   * completes.
   * 
   * NOTE: This will block even if the Observable is asynchronous.
   * 
   * This is similar to {@link Observable#subscribe(Observer)}, but it blocks. Because it blocks it does
   * not need the {@link Observer#onCompleted()} or {@link Observer#onError(Throwable)} methods.
   * 
   * 
   *
   * @param f
   *            the {@link Action1} to invoke for every item emitted by the {@link Observable}
   * @throws RuntimeException
   *             if an error occurs
   */
  def foreach(f: T => Unit): Unit = {
    asJava.forEach(f)
  }
  
  def withFilter(p: T => Boolean): WithFilter[T] = {
    new WithFilter[T](p, asJava)
  }

  // last                 -> use toIterable.last
  // lastOrDefault        -> use toIterable.lastOption
  // first                -> use toIterable.head
  // firstOrDefault       -> use toIterable.headOption
  // single(predicate)    -> use filter and single
  // singleOrDefault      -> use singleOption

  /**
   * Returns an {@link Iterable} that always returns the item most recently emitted by an {@link Observable}.
   * 

* * * @param initialValue * the initial value that will be yielded by the {@link Iterable} sequence if the {@link Observable} has not yet emitted an item * @return an {@link Iterable} that on each iteration returns the item that the {@link Observable} has most recently emitted */ def mostRecent[U >: T](initialValue: U): Iterable[U] = { val asJavaU = asJava.asInstanceOf[rx.observables.BlockingObservable[U]] asJavaU.mostRecent(initialValue).asScala: Iterable[U] // useless ascription because of compiler bug } /** * Returns an {@link Iterable} that blocks until the {@link Observable} emits another item, * then returns that item. *

* * * @return an {@link Iterable} that blocks upon each iteration until the {@link Observable} emits a new item, whereupon the Iterable returns that item */ def next: Iterable[T] = { asJava.next().asScala: Iterable[T] // useless ascription because of compiler bug } /** * If this {@link Observable} completes after emitting a single item, return that item, * otherwise throw an exception. *

* * * @return the single item emitted by the {@link Observable} */ def single: T = { asJava.single(): T // useless ascription because of compiler bug } /** * If this {@link Observable} completes after emitting a single item, return an Option containing * this item, otherwise return {@code None}. */ def singleOption: Option[T] = { var size: Int = 0 var last: Option[T] = None for (t <- toIterable) { size += 1 last = Some(t) } if (size == 1) last else None } // TODO toFuture() /** * Returns an {@link Iterator} that iterates over all items emitted by this {@link Observable}. */ def toIterable: Iterable[T] = { asJava.toIterable.asScala: Iterable[T] // useless ascription because of compiler bug } /** * Returns a {@link List} that contains all items emitted by this {@link Observable}. */ def toList: List[T] = { asJava.toIterable.asScala.toList: List[T] // useless ascription because of compiler bug } } // Cannot yet have inner class because of this error message: // "implementation restriction: nested class is not allowed in value class. // This restriction is planned to be removed in subsequent releases." private[observables] class WithFilter[+T] (p: T => Boolean, asJava: rx.observables.BlockingObservable[_ <: T]) { import rx.lang.scala.ImplicitFunctionConversions._ // there's no map and flatMap here, they're only available on Observable def withFilter(q: T => Boolean) = new WithFilter[T]((x: T) => p(x) && q(x), asJava) def foreach(f: T => Unit): Unit = { asJava.forEach((e: T) => { if (p(e)) f(e) }) } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy