convert terminal sagas to typed-redux-saga/macro

This commit is contained in:
David Lechner
2021-01-23 18:58:26 -06:00
parent ca5bb8f2a5
commit 3ba52e560d
+27 -31
View File
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2020-2021 The Pybricks Authors
import { Channel } from 'redux-saga';
import {
actionChannel,
delay,
@@ -12,16 +11,11 @@ import {
select,
take,
takeEvery,
} from 'redux-saga/effects';
} from 'typed-redux-saga/macro';
import PushStream from 'zen-push';
import { Action } from '../actions';
import { AppActionType, AppDidStartAction } from '../actions/app';
import {
BleUartActionType,
BleUartNotifyAction,
BleUartWriteAction,
write,
} from '../actions/ble-uart';
import { BleUartActionType, BleUartNotifyAction, write } from '../actions/ble-uart';
import { HubRuntimeStatusType, checksum, updateStatus } from '../actions/hub';
import {
TerminalActionType,
@@ -32,13 +26,14 @@ import {
import { SafeTxCharLength } from '../protocols/nrf-uart';
import { RootState } from '../reducers';
import { HubRuntimeState } from '../reducers/hub';
import { defined } from '../utils';
const encoder = new TextEncoder();
const decoder = new TextDecoder();
const terminalDataSource = new PushStream<string>();
function* startup(_action: AppDidStartAction): Generator {
yield put(setDataSource(terminalDataSource.observable));
yield* put(setDataSource(terminalDataSource.observable));
}
function* handleMatch(
@@ -50,24 +45,24 @@ function* handleMatch(
}
if (match[1]) {
yield put(sendData(match[1]));
yield* put(sendData(match[1]));
}
yield put(updateStatus(status));
yield* put(updateStatus(status));
if (match[2]) {
yield put(sendData(match[2]));
yield* put(sendData(match[2]));
}
return true;
}
function* receiveUartData(action: BleUartNotifyAction): Generator {
const hubState = (yield select((s: RootState) => s.hub.runtime)) as HubRuntimeState;
const hubState = yield* select((s: RootState) => s.hub.runtime);
if (hubState === HubRuntimeState.Loading && action.value.buffer.byteLength === 1) {
const view = new DataView(action.value.buffer);
yield put(checksum(view.getUint8(0)));
yield* put(checksum(view.getUint8(0)));
return;
}
@@ -97,40 +92,41 @@ function* receiveUartData(action: BleUartNotifyAction): Generator {
return;
}
yield put(sendData(value));
yield* put(sendData(value));
}
function* receiveTerminalData(): Generator {
const channel = (yield actionChannel(
const channel = yield* actionChannel<TerminalDataReceiveDataAction>(
TerminalActionType.ReceivedData,
)) as Channel<TerminalDataReceiveDataAction>;
);
while (true) {
// wait for input from terminal
const action = (yield take(channel)) as TerminalDataReceiveDataAction;
const action = yield* take(channel);
let value = action.value;
// Try to collect more data so that we aren't sending just one byte at time
while (value.length < SafeTxCharLength) {
const [action, timeout] = (yield race([take(channel), delay(20)])) as [
TerminalDataReceiveDataAction,
boolean,
];
const { action, timeout } = yield* race({
action: take(channel),
timeout: delay(20),
});
if (timeout) {
break;
}
defined(action);
value += action.value;
}
const nextMessageId = (yield getContext('nextMessageId')) as () => number;
const nextMessageId = yield* getContext<() => number>('nextMessageId');
// stdin gets piped to BLE connection
const data = encoder.encode(value);
for (let i = 0; i < data.length; i += SafeTxCharLength) {
const { id } = (yield put(
const { id } = yield* put(
write(nextMessageId(), data.slice(i, i + SafeTxCharLength)),
)) as BleUartWriteAction;
);
yield take(
yield* take(
(a: Action) =>
(a.type === BleUartActionType.DidWrite ||
a.type === BleUartActionType.DidFailToWrite) &&
@@ -138,7 +134,7 @@ function* receiveTerminalData(): Generator {
);
// wait for echo so tht we don't overrun the hub with messages
yield race([take(BleUartActionType.Notify), delay(100)]);
yield* race([take(BleUartActionType.Notify), delay(100)]);
}
}
}
@@ -149,8 +145,8 @@ function sendTerminalData(action: TerminalDataReceiveDataAction): void {
}
export default function* (): Generator {
yield takeEvery(AppActionType.DidStart, startup);
yield takeEvery(BleUartActionType.Notify, receiveUartData);
yield fork(receiveTerminalData);
yield takeEvery(TerminalActionType.SendData, sendTerminalData);
yield* takeEvery(AppActionType.DidStart, startup);
yield* takeEvery(BleUartActionType.Notify, receiveUartData);
yield* fork(receiveTerminalData);
yield* takeEvery(TerminalActionType.SendData, sendTerminalData);
}