// Path: redux-rx/src/main/java/me/tatarka/redux/rx/ObservableAdapter.java
// public class ObservableAdapter {
// 
//     public static <S> Observable<S> observable(final SimpleStore<S> store) {
//         return Observable.fromEmitter(new Action1<Emitter<S>>() {
//             @Override
//             public void call(Emitter<S> emitter) {
//                 store.addListener(new EmitterListener<>(emitter, store));
//             }
//         }, Emitter.BackpressureMode.LATEST);
//     }
// 
//     private static class EmitterListener<S> implements SimpleStore.Listener<S>, Cancellable {
//         final SimpleStore<S> store;
//         final Observer<S> observer;
// 
//         EmitterListener(Emitter<S> emitter, SimpleStore<S> store) {
//             this.observer = new SerializedObserver<>(emitter);
//             this.store = store;
//             emitter.setCancellation(this);
//         }
// 
//         @Override
//         public void onNewState(S state) {
//             observer.onNext(state);
//         }
// 
//         @Override
//         public void cancel() throws Exception {
//             store.removeListener(this);
//         }
//     }
// }


import me.tatarka.redux.*;
import me.tatarka.redux.rx.ObservableAdapter;
    static class ChangeName implements Replace<String> {
        final String newName;

        ChangeName(String newName) {
            this.newName = newName;
        }

        @Override
        public String toString() {
            return "ChangeName(" + newName + ")";
        }

        @Override
        public String newValue() {
            return newName;
        }
    }

    static class IncrementAge implements Increment {
        @Override
        public String toString() {
            return "IncrementAge";
        }

    }

    public static void main(String[] args) {
        SimpleStore<Person> store = new SimpleStore<>(new Person("nobody", 0));
        Dispatcher<Action, Action> dispatcher = Dispatcher.forStore(store, updatePerson)
                .chain(new LogMiddleware<>(store));
// Path: redux-rx/src/main/java/me/tatarka/redux/rx/ObservableAdapter.java
// public class ObservableAdapter {
// 
//     public static <S> Observable<S> observable(final SimpleStore<S> store) {
//         return Observable.fromEmitter(new Action1<Emitter<S>>() {
//             @Override
//             public void call(Emitter<S> emitter) {
//                 store.addListener(new EmitterListener<>(emitter, store));
//             }
//         }, Emitter.BackpressureMode.LATEST);
//     }
// 
//     private static class EmitterListener<S> implements SimpleStore.Listener<S>, Cancellable {
//         final SimpleStore<S> store;
//         final Observer<S> observer;
// 
//         EmitterListener(Emitter<S> emitter, SimpleStore<S> store) {
//             this.observer = new SerializedObserver<>(emitter);
//             this.store = store;
//             emitter.setCancellation(this);
//         }
// 
//         @Override
//         public void onNewState(S state) {
//             observer.onNext(state);
//         }
// 
//         @Override
//         public void cancel() throws Exception {
//             store.removeListener(this);
//         }
//     }
// }


// Path: sample/src/main/java/me/tatarka/redux/sample/CompositeStateSample.java
import me.tatarka.redux.*;
import me.tatarka.redux.rx.ObservableAdapter;

    static class ChangeName implements Replace<String> {
        final String newName;

        ChangeName(String newName) {
            this.newName = newName;
        }

        @Override
        public String toString() {
            return "ChangeName(" + newName + ")";
        }

        @Override
        public String newValue() {
            return newName;
        }
    }

    static class IncrementAge implements Increment {
        @Override
        public String toString() {
            return "IncrementAge";
        }

    }

    public static void main(String[] args) {
        SimpleStore<Person> store = new SimpleStore<>(new Person("nobody", 0));
        Dispatcher<Action, Action> dispatcher = Dispatcher.forStore(store, updatePerson)
                .chain(new LogMiddleware<>(store));
        ObservableAdapter.observable(store).subscribe(person -> System.out.println("state: " + person));