aboutsummaryrefslogtreecommitdiff
path: root/bt/src/main/java/io/trygvis/android/bt/BtSequence.java
diff options
context:
space:
mode:
Diffstat (limited to 'bt/src/main/java/io/trygvis/android/bt/BtSequence.java')
-rw-r--r--bt/src/main/java/io/trygvis/android/bt/BtSequence.java243
1 files changed, 243 insertions, 0 deletions
diff --git a/bt/src/main/java/io/trygvis/android/bt/BtSequence.java b/bt/src/main/java/io/trygvis/android/bt/BtSequence.java
new file mode 100644
index 0000000..be1be4c
--- /dev/null
+++ b/bt/src/main/java/io/trygvis/android/bt/BtSequence.java
@@ -0,0 +1,243 @@
+package io.trygvis.android.bt;
+
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+
+import io.trygvis.android.Consumer;
+import io.trygvis.android.F2;
+import io.trygvis.android.F3;
+import io.trygvis.android.Function;
+import io.trygvis.android.Optional;
+
+import static io.trygvis.android.bt.BtSequencer.EventType.onCharacteristicChanged;
+import static io.trygvis.android.bt.BtSequencer.EventType.onCharacteristicRead;
+import static io.trygvis.android.bt.BtSequencer.EventType.onCharacteristicWrite;
+import static io.trygvis.android.bt.BtSequencer.EventType.onConnectionStateChange;
+import static io.trygvis.android.bt.BtSequencer.EventType.onDescriptorRead;
+import static io.trygvis.android.bt.BtSequencer.EventType.onDescriptorWrite;
+import static io.trygvis.android.bt.BtSequencer.EventType.onDirect;
+import static io.trygvis.android.bt.BtSequencer.EventType.onFinally;
+import static io.trygvis.android.bt.BtSequencer.EventType.onReadRemoteRssi;
+import static io.trygvis.android.bt.BtSequencer.EventType.onReliableWriteCompleted;
+import static io.trygvis.android.bt.BtSequencer.EventType.onServicesDiscovered;
+import static java.util.Collections.unmodifiableList;
+
+public class BtSequence {
+ private static final SequenceResult waitForNextEvent = new WaitForNextEvent();
+ private static final SequenceResult stop = new Stop();
+ private static final SequenceResult fail = new Fail();
+ private static final SequenceResult continueDirectly = new ContinueDirectly();
+
+ public static class SequenceResult {
+ private SequenceResult() {
+ }
+
+ public static SequenceResult waitForNextEvent() {
+ return waitForNextEvent;
+ }
+
+ public static SequenceResult continueDirectly() {
+ return continueDirectly;
+ }
+
+ public static SequenceResult stop() {
+ return stop;
+ }
+
+ public static SequenceResult fail() {
+ return fail;
+ }
+
+ public static SequenceResult detour(BtSequence sequence) {
+ return new Detour(sequence);
+ }
+ }
+
+ public static class WaitForNextEvent extends SequenceResult {
+ }
+
+ public static class ContinueDirectly extends SequenceResult {
+ }
+
+ public static class Stop extends SequenceResult {
+ }
+
+ public static class Fail extends SequenceResult {
+ }
+
+ public static class Detour extends SequenceResult {
+ final BtSequence sequence;
+
+ private Detour(BtSequence sequence) {
+ this.sequence = sequence;
+ }
+ }
+
+ private final List<BtCallback> actionQ;
+ private final List<BtCallback> finallyQ;
+ private final Optional<BtSequence> next;
+
+ private Boolean stopOnFailure = true;
+
+ public BtSequence() {
+ actionQ = new ArrayList<>();
+ finallyQ = new ArrayList<>();
+ next = Optional.empty();
+ }
+
+ private BtSequence(List<BtCallback> actionQ, List<BtCallback> finallyQ, Optional<BtSequence> next) {
+ this.actionQ = actionQ;
+ this.finallyQ = finallyQ;
+ this.next = next;
+ }
+
+ public BtSequence andThen(BtSequence btSequence) {
+ return new BtSequence(actionQ, finallyQ, Optional.of(btSequence));
+ }
+
+ public ListIterator<BtCallback> actionQ() {
+ return actionQ.listIterator();
+ }
+
+ public List<BtCallback> finallyQ() {
+ return unmodifiableList(finallyQ);
+ }
+
+ public boolean firstIsOnDirect() {
+ return actionQ.size() > 0 && actionQ.get(0).type == onDirect;
+ }
+
+ public Optional<BtSequence> getNext() {
+ return next;
+ }
+
+ public String toString() {
+ return "actionQ=" + actionQ.size() + ", finallyQ=" + finallyQ.size() + ", has next=" + next.isPresent();
+ }
+
+ private BtSequence add(BtCallback callback) {
+ List<BtCallback> actions = new ArrayList<>(this.actionQ);
+ actions.add(callback);
+ return new BtSequence(actions, finallyQ, next);
+ }
+
+ private boolean stopOnFailure() {
+ if (stopOnFailure != null) {
+ boolean b = stopOnFailure;
+ stopOnFailure = null;
+ return b;
+ }
+ return false;
+ }
+
+ public BtSequence ignoreFailureForNext() {
+ stopOnFailure = true;
+ return this;
+ }
+
+ public BtSequence onConnectionStateChange(F3<BluetoothGatt, Integer, Integer, SequenceResult> callback) {
+ return add(new BtCallback(stopOnFailure(), onConnectionStateChange) {
+ @Override
+ public SequenceResult onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
+ return callback.apply(gatt, status, newState);
+ }
+ });
+ }
+
+ public BtSequence onServicesDiscovered(Function<BluetoothGatt, SequenceResult> callback) {
+ return add(new BtCallback(stopOnFailure(), onServicesDiscovered) {
+ @Override
+ public SequenceResult onServicesDiscovered(BluetoothGatt gatt) {
+ return callback.apply(gatt);
+ }
+ });
+ }
+
+ public BtSequence onCharacteristicRead(F2<BluetoothGatt, BluetoothGattCharacteristic, SequenceResult> callback) {
+ return add(new BtCallback(stopOnFailure(), onCharacteristicRead) {
+ @Override
+ public SequenceResult onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
+ return callback.apply(gatt, characteristic);
+ }
+ });
+ }
+
+ public BtSequence onCharacteristicWrite(F2<BluetoothGatt, BluetoothGattCharacteristic, SequenceResult> callback) {
+ return add(new BtCallback(stopOnFailure(), onCharacteristicWrite) {
+ @Override
+ public SequenceResult onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
+ return callback.apply(gatt, characteristic);
+ }
+ });
+ }
+
+ public BtSequence onCharacteristicChanged(F2<BluetoothGatt, BluetoothGattCharacteristic, SequenceResult> callback) {
+ return add(new BtCallback(stopOnFailure(), onCharacteristicChanged) {
+ @Override
+ public SequenceResult onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
+ return callback.apply(gatt, characteristic);
+ }
+ });
+ }
+
+ public BtSequence onDescriptorRead(F2<BluetoothGatt, BluetoothGattDescriptor, SequenceResult> callback) {
+ return add(new BtCallback(stopOnFailure(), onDescriptorRead) {
+ @Override
+ public SequenceResult onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor) {
+ return callback.apply(gatt, descriptor);
+ }
+ });
+ }
+
+ public BtSequence onDescriptorWrite(F2<BluetoothGatt, BluetoothGattDescriptor, SequenceResult> callback) {
+ return add(new BtCallback(stopOnFailure(), onDescriptorWrite) {
+ @Override
+ public SequenceResult onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor) {
+ return callback.apply(gatt, descriptor);
+ }
+ });
+ }
+
+ public BtSequence onReliableWriteCompleted(Function<BluetoothGatt, SequenceResult> callback) {
+ return add(new BtCallback(stopOnFailure(), onReliableWriteCompleted) {
+ @Override
+ public SequenceResult onReliableWriteCompleted(BluetoothGatt gatt) {
+ return callback.apply(gatt);
+ }
+ });
+ }
+
+ public BtSequence onReadRemoteRssi(F2<BluetoothGatt, Integer, SequenceResult> callback) {
+ return add(new BtCallback(stopOnFailure(), onReadRemoteRssi) {
+ @Override
+ public SequenceResult onReadRemoteRssi(BluetoothGatt gatt, int rssi) {
+ return callback.apply(gatt, rssi);
+ }
+ });
+ }
+
+ public BtSequence onDirect(Function<BluetoothGatt, SequenceResult> callback) {
+ return add(new BtCallback(stopOnFailure(), onDirect) {
+ @Override
+ public SequenceResult onDirect(BluetoothGatt value) {
+ return callback.apply(value);
+ }
+ });
+ }
+
+ public BtSequence onFinally(Consumer<Boolean> callback) {
+ List<BtCallback> finallyQ = new ArrayList<>(this.finallyQ);
+ finallyQ.add(new BtCallback(stopOnFailure(), onFinally) {
+ @Override
+ public void onFinally(boolean success) {
+ callback.accept(success);
+ }
+ });
+ return new BtSequence(actionQ, finallyQ, next);
+ }
+}