Skip to content
This repository has been archived by the owner on Aug 13, 2021. It is now read-only.

Commit

Permalink
Merge branch 'release-candidate' into stable
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark Wei committed Dec 7, 2016
2 parents a92110c + d0ce7e0 commit e2a0bed
Show file tree
Hide file tree
Showing 7 changed files with 341 additions and 32 deletions.
1 change: 1 addition & 0 deletions .arcconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
],
"arcanist_configuration": "HookConphig",
"phabricator.uri": "http://codereview.cc/",
"repository.callsign": "MDMOBSERVABLEANDROID",
"arc.land.onto.default": "develop",
"arc.feature.start.default": "origin/develop"
}
69 changes: 69 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# 1.0.0

## New features

* First release for IndefiniteObservable!
* Supports genericized Observers for optional multiple channels.

## Source changes

* [Genericize IndefiniteObservable.](https://github.com/material-motion/indefinite-observable-android/commit/d8107873075c8eb0b3e9b94a47c8c9a755b67ab2) (Mark Wei)
* [Implementation of IndefiniteObservable for android.](https://github.com/material-motion/indefinite-observable-android/commit/8accac96969c2d6b97cb66eb8e77e4d0e62a1c16) (Mark Wei)

## API changes

Auto-generated by running:

apidiff origin/stable release-candidate android library

## Observer<T>

*new* interface: `Observer<T>`

*new* method: `void next(T)`


## Subscriber<O

*new* interface: `Subscriber<O`

*new* method: `Unsubscriber subscribe(O)`


## Subscription

*new* final class: `Subscription`

*new* method: `void unsubscribe()`


## Unsubscriber

*new* interface: `Unsubscriber`

*new* method: `void unsubscribe()`


## IndefiniteObservable<O

*new* class: `IndefiniteObservable<O`

*new* constructor: `IndefiniteObservable(Subscriber<O>)`

*new* method: `Subscription subscribe(O)`


## Library

*removed* class: `Library`

*removed* constructor: `Library()`

*removed* static final field: `String LIBRARY_NAME`



## Non-source changes

* [Automatic changelog preparation for release.](https://github.com/material-motion/indefinite-observable-android/commit/17f21de7de0798698ccd978266e75c100154cff2) (Mark Wei)
* [callsign](https://github.com/material-motion/indefinite-observable-android/commit/7d4b10e3905992a93dbf8049d178777eb0257c2f) (Mark Wei)
1 change: 1 addition & 0 deletions library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ android {

dependencies {
// If you are developing any dependencies locally, also list them in local.dependencies.
compile 'com.android.support:support-compat:24.2.1'

testCompile 'com.google.truth:truth:0.28'
testCompile 'junit:junit:4.12'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
/*
* Copyright 2016-present The Material Motion Authors. All Rights Reserved.
*
* 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 com.google.android.material.motion.observable;

import android.support.annotation.Nullable;

import com.google.android.material.motion.observable.IndefiniteObservable.Observer;

/**
* An IndefiniteObservable represents a sequence of values that may be observed.
* <p>
* IndefiniteObservable is meant for use with streams of values that have no concept of completion.
* This is an implementation of a subset of the Observable interface defined at
* http://reactivex.io/
* <p>
* Simple stream that synchronously dispatches "10", "11", "12":
* <pre>
* {@code
* IndefiniteObservable<Observer<String>> observable = new IndefiniteObservable<>(
* new Subscriber<Observer<String>>() {
* public Unsubscriber subscribe(Observer<String> observer) {
* observer.next("10");
* observer.next("11");
* observer.next("12");
* return null;
* }
* });
*
* Subscription subscription = observable.subscribe(new Observer<String>() {
* public void next(String value) {
* Log.d(TAG, "Received value: " + value);
* }
* });
*
* subscription.unsubscribe();
* }
* </pre>
* Simple stream that asynchronously forwards values from some callback:
* <pre>
* {@code
* IndefiniteObservable<Observer<Integer>> observable = new IndefiniteObservable<>(
* new Subscriber<Observer<Integer>>() {
* public Unsubscriber subscribe(Observer<Integer> observer) {
* final SomeToken token = registerSomeCallback(new SomeCallback() {
* public void onCallbackValue(Integer value) {
* observer.next(value);
* }
* });
*
* return new Unsubscriber() {
* public void unsubscribe() {
* unregisterSomeCallback(token);
* }
* };
* }
* });
* }
* </pre>
*
* @param <O> The custom observer type that this IndefiniteObservable stream supports. See {@code
* Observer<T>} above for an example.
*/
public class IndefiniteObservable<O extends Observer<?>> {

private final Subscriber<O> subscriber;

/**
* Creates a new IndefiniteObservable with the given subscriber.
* <p>
* Accepts a subscriber that connects an observer to an external event source via {@link
* Subscriber#subscribe(Observer)}.
* <p>
* {@link Subscriber#subscribe(Observer)} is only invoked when {@link #subscribe(Observer)} is
* called.
*/
public IndefiniteObservable(Subscriber<O> subscriber) {
this.subscriber = subscriber;
}

/**
* Subscribes an observer to the IndefiniteObservable.
* <p>
* The observer will begin receiving values from the external event source.
* <p>
* To stop receiving values from the external event source, call {@link
* Subscription#unsubscribe()} on the returned subscription.
*
* @param observer The observer on which channel methods are called when new values are
* produced.
*/
public Subscription subscribe(O observer) {
return new Subscription(subscriber.subscribe(observer));
}

/**
* A subscriber provides the source of the stream.
* <p>
* When new values are produced, the subscriber should call {@link Observer#next(Object)} or
* another appropriate method to send them downstream.
* <p>
* See the class javadoc of {@link IndefiniteObservable} for an example implementation.
*/
public interface Subscriber<O extends Observer<?>> {

/**
* Connects an observer to an event source by calling {@link Observer#next(Object)} or
* another appropriate method when new values are received.
*/
@Nullable
Unsubscriber subscribe(O observer);
}

/**
* An unsubscriber tears down the source of the stream and releases any references made in
* {@link Subscriber#subscribe(Observer)}.
* <p>
* {@link Observer#next(Object)} and all other methods should no longer be called after {@link
* #unsubscribe()} is invoked.
* <p>
* See the class javadoc of {@link IndefiniteObservable} for an example implementation.
*/
public interface Unsubscriber {

/**
* Tears down the source of the stream.
*/
void unsubscribe();
}

/**
* An observer receives new values from upstream and forwards them to downstream.
* <p>
* Upstream forwards new values to downstream by invoking {@link #next(Object)} when they are
* produced. Implementations can have additional methods that can forward other values.
* <p>
* See the class javadoc of {@link IndefiniteObservable} for an example implementation.
*
* @param <T> The type of value passed through the default {@link #next(Object)} method.
*/
public interface Observer<T> {

/**
* The default method that handles new values from upstream.
*/
void next(T value);
}

/**
* A subscription is returned by {@link IndefiniteObservable#subscribe(Observer)} and allows you
* to {@link #unsubscribe()} from the stream.
*/
public static final class Subscription {

@Nullable
private Unsubscriber unsubscriber;

private Subscription(@Nullable Unsubscriber unsubscriber) {
this.unsubscriber = unsubscriber;
}

/**
* Unsubscribes from the stream.
*/
public void unsubscribe() {
if (unsubscriber != null) {
unsubscriber.unsubscribe();
unsubscriber = null;
}
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,94 @@
*/
package com.google.android.material.motion.observable.sample;

import com.google.android.material.motion.observable.Library;

import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;

import com.google.android.material.motion.observable.IndefiniteObservable;
import com.google.android.material.motion.observable.IndefiniteObservable.Observer;
import com.google.android.material.motion.observable.IndefiniteObservable.Subscriber;
import com.google.android.material.motion.observable.IndefiniteObservable.Subscription;
import com.google.android.material.motion.observable.IndefiniteObservable.Unsubscriber;

/**
* Observable implementation for Android sample Activity.
*/
public class MainActivity extends AppCompatActivity {

private TextView text1;
private TextView text2;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.main_activity);

TextView text = (TextView) findViewById(R.id.text);
text.setText(Library.LIBRARY_NAME);
text1 = (TextView) findViewById(R.id.text1);
text2 = (TextView) findViewById(R.id.text2);

runDemo1();
runDemo2();
}

private void runDemo1() {
IndefiniteObservable<Observer<String>> observable = new IndefiniteObservable<>(
new Subscriber<Observer<String>>() {
@Nullable
@Override
public Unsubscriber subscribe(Observer<String> observer) {
observer.next("foo");
return null;
}
});

Subscription subscription = observable.subscribe(new Observer<String>() {
@Override
public void next(String value) {
text1.setText(value);
}
});

subscription.unsubscribe();
}

private void runDemo2() {
IndefiniteObservable<MultiChannelObserver<String, Integer>> observable = new IndefiniteObservable<>(
new Subscriber<MultiChannelObserver<String, Integer>>() {
@Nullable
@Override
public Unsubscriber subscribe(MultiChannelObserver<String, Integer> observer) {
observer.next("bar");
observer.customChannel(Color.RED);
return null;
}
});

Subscription subscription = observable.subscribe(new MultiChannelObserver<String, Integer>() {
@Override
public void next(String value) {
text2.setText(value);
}

@Override
public void customChannel(Integer value) {
text2.setTextColor(value);
}
});

subscription.unsubscribe();
}

/**
* A multi-channel observer implementation.
*/
public interface MultiChannelObserver<T, U> extends Observer<T> {

void next(T value);

void customChannel(U value);
}
}
Loading

0 comments on commit e2a0bed

Please sign in to comment.