1 package com.github.davidmoten.rx;
2
3 import com.github.davidmoten.rx.util.BackpressureStrategy;
4
5 import rx.Observable.Transformer;
6 import rx.Subscriber;
7 import rx.functions.Func0;
8 import rx.functions.Func2;
9 import rx.functions.Func3;
10
11 public final class StateMachine {
12
13 private StateMachine() {
14
15 }
16
17 public static interface Transition<State, In, Out>
18 extends Func3<State, In, Subscriber<Out>, State> {
19
20
21 @Override
22 public State call(State state, In value, Subscriber<Out> subscriber);
23
24 }
25
26 public static interface Completion<State, Out> extends Func2<State, Subscriber<Out>, Boolean> {
27
28
29 @Override
30 public Boolean call(State state, Subscriber<Out> subscriber);
31
32 }
33
34 public static Builder builder() {
35 return new Builder();
36 }
37
38 public static final class Builder {
39
40 private Builder() {
41
42 }
43
44 public <State> Builder2<State> initialStateFactory(Func0<State> initialState) {
45 return new Builder2<State>(initialState);
46 }
47
48 public <State> Builder2<State> initialState(final State initialState) {
49 return new Builder2<State>(Functions.constant0(initialState));
50 }
51
52 }
53
54 public static final class Builder2<State> {
55
56 private final Func0<State> initialState;
57
58 private Builder2(Func0<State> initialState) {
59 this.initialState = initialState;
60 }
61
62 public <In, Out> Builder3<State, In, Out> transition(
63 Transition<State, In, Out> transition) {
64 return new Builder3<State, In, Out>(initialState, transition);
65 }
66
67 }
68
69 public static final class Builder3<State, In, Out> {
70
71 private final Func0<State> initialState;
72 private final Transition<State, In, Out> transition;
73 private Completion<State, Out> completion = CompletionAlwaysTrueHolder.instance();
74 private BackpressureStrategy backpressureStrategy = BackpressureStrategy.BUFFER;
75 private int initialRequest = Transformers.DEFAULT_INITIAL_BATCH;
76
77 private Builder3(Func0<State> initialState, Transition<State, In, Out> transition) {
78 this.initialState = initialState;
79 this.transition = transition;
80 }
81
82 public Builder3<State, In, Out> completion(Completion<State, Out> completion) {
83 this.completion = completion;
84 return this;
85 }
86
87 public Builder3<State, In, Out> backpressureStrategy(
88 BackpressureStrategy backpressureStrategy) {
89 this.backpressureStrategy = backpressureStrategy;
90 return this;
91 }
92
93 public Builder3<State, In, Out> initialRequest(int value) {
94 this.initialRequest = value;
95 return this;
96 }
97
98 public Transformer<In, Out> build() {
99 return Transformers.stateMachine(initialState, transition, completion,
100 backpressureStrategy, initialRequest);
101 }
102
103 }
104
105 private static final class CompletionAlwaysTrueHolder {
106
107 private static final Completion<Object, Object> INSTANCE = new Completion<Object, Object>() {
108 @Override
109 public Boolean call(Object t1, Subscriber<Object> t2) {
110 return true;
111 }
112 };
113
114 @SuppressWarnings("unchecked")
115 static <State, Out> Completion<State, Out> instance() {
116 return (Completion<State, Out>) INSTANCE;
117 }
118 }
119 }