batch calls to raptor check for better memory behavior.
It will still OOM because the barcode scanner will fill up memomry with unprocessed codes, so need to turn the cam off to let it drain.
This commit is contained in:
parent
85c60913d5
commit
d8ed7acddd
5 changed files with 44 additions and 28 deletions
|
@ -44,10 +44,9 @@ Currently, the following is done in terms of functionality:
|
|||
|
||||
The desktop app (unix-ish only; developed on linux, untested on anything else, but should run on macos)
|
||||
is closer to its final form in terms of UI/UX, though it currently can only transmit. The Android
|
||||
app is about halfway done in terms of functionality, but the UI is, shall we say, "hideous":
|
||||
app is about halfway done in terms of functionality, but the UI is, shall we say, "bad":
|
||||
|
||||
![cuttle mobile app receiving data](./mobile_receiving.png) ![cuttle mobile app done receiving
|
||||
data](./mobile_finished.png)
|
||||
![cuttle mobile app receiving data](./mobile_receiving.png)
|
||||
|
||||
I might take a crack at making it less hideous before I start on the mobile transmitting/desktop
|
||||
receiving side of the functionality, but maybe not! I often want to transfer a file or text from my
|
||||
|
|
|
@ -5,9 +5,16 @@ gen:
|
|||
flutter_rust_bridge_codegen
|
||||
|
||||
lint:
|
||||
cd native && cargo fmt
|
||||
dart format .
|
||||
|
||||
native: native-debug native-release
|
||||
|
||||
native-release:
|
||||
cd android && ./gradlew :app:cargoBuildRelease
|
||||
|
||||
native-debug:
|
||||
cd android && ./gradlew :app:cargoBuildDebug
|
||||
|
||||
clean:
|
||||
flutter clean
|
||||
cd native && cargo clean
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import 'dart:async';
|
||||
import 'dart:collection';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:camerawesome/camerawesome_plugin.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_mlkit_barcode_scanning/google_mlkit_barcode_scanning.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
import 'ffi.dart';
|
||||
import 'utils/mlkit_utils.dart';
|
||||
|
@ -45,12 +47,14 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||
final _barcodeScanner = BarcodeScanner(formats: [BarcodeFormat.qrCode]);
|
||||
final _rxTextController = BehaviorSubject<String>();
|
||||
late final Stream<String> _rxTextStream = _rxTextController.stream;
|
||||
final _scrollController = ScrollController();
|
||||
|
||||
TxConfig? _txConfig;
|
||||
var _cuttleState = CuttleState.unitialized;
|
||||
final List<RaptorPacket> _rxData = [];
|
||||
final HashSet<RaptorPacket> _rxData = HashSet();
|
||||
String _rxText = '';
|
||||
int _rxCount = 1;
|
||||
|
||||
final _formatter = NumberFormat('###,###,###');
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
|
@ -65,15 +69,14 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||
onImageForAnalysis: (img) => _processImageBarcode(img),
|
||||
imageAnalysisConfig: AnalysisConfig(
|
||||
androidOptions: const AndroidAnalysisOptions.nv21(
|
||||
width: 1024,
|
||||
width: 600,
|
||||
),
|
||||
maxFramesPerSecond: 30,
|
||||
maxFramesPerSecond: 20,
|
||||
autoStart: false,
|
||||
),
|
||||
builder: (cameraModeState, previewSize, previewRect) {
|
||||
return _RxTextDisplayWidget(
|
||||
rxTextStream: _rxTextStream,
|
||||
scrollController: _scrollController,
|
||||
analysisController: cameraModeState.analysisController!,
|
||||
);
|
||||
},
|
||||
|
@ -103,7 +106,8 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||
_txConfig!.filename ?? "large text on the command line";
|
||||
|
||||
final desc = _txConfig!.description;
|
||||
final text = 'Receiving $fname, ${_txConfig!.len} bytes: $desc';
|
||||
final text =
|
||||
'Receiving $fname, ${_formatter.format(_txConfig!.len)} bytes ($desc)';
|
||||
_rxText = text;
|
||||
_rxTextController.add(text);
|
||||
continue;
|
||||
|
@ -121,25 +125,32 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||
case CuttleState.receiving:
|
||||
{
|
||||
var txconf = await api.getTxConfig(bytes: dbytes);
|
||||
if (txconf != null || barcode.rawValue != null) {
|
||||
await api.dropTxConfig(txc: txconf!);
|
||||
if (txconf != null) {
|
||||
await api.dropTxConfig(txc: txconf);
|
||||
continue;
|
||||
}
|
||||
final packet = RaptorPacket(field0: dbytes);
|
||||
_rxData.add(packet);
|
||||
final content =
|
||||
await api.decodePackets(packets: _rxData, txconf: _txConfig!);
|
||||
_rxCount += 1;
|
||||
if (_rxCount % 40 == 0) {
|
||||
_rxCount = 1;
|
||||
final content = await api.decodePackets(
|
||||
packets: _rxData.toList(), txconf: _txConfig!);
|
||||
if (content != null) {
|
||||
_rxData.clear();
|
||||
_barcodeScanner.close();
|
||||
_cuttleState = CuttleState.received;
|
||||
_rxTextController.add("DONE RECEIVING $_rxText");
|
||||
final f = await _saveReceivedFile(_txConfig!.filename, content);
|
||||
final f =
|
||||
await _saveReceivedFile(_txConfig!.filename, content);
|
||||
_rxTextController.add("Saved content to $f");
|
||||
continue;
|
||||
}
|
||||
_rxTextController
|
||||
.add("$_rxText -- ${_rxData.length} bytes so far");
|
||||
}
|
||||
final bytesTotal = _rxData.length * dbytes.length;
|
||||
final pct = (100.0 * bytesTotal / _txConfig!.len).floor();
|
||||
_rxTextController.add(
|
||||
"$_rxText -- $pct% received (${_formatter.format(bytesTotal)} bytes)");
|
||||
}
|
||||
|
||||
case CuttleState.received:
|
||||
|
@ -164,7 +175,6 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||
|
||||
class _RxTextDisplayWidget extends StatefulWidget {
|
||||
final Stream<String> rxTextStream;
|
||||
final ScrollController scrollController;
|
||||
|
||||
final AnalysisController analysisController;
|
||||
|
||||
|
@ -172,7 +182,6 @@ class _RxTextDisplayWidget extends StatefulWidget {
|
|||
// ignore: unused_element
|
||||
super.key,
|
||||
required this.rxTextStream,
|
||||
required this.scrollController,
|
||||
required this.analysisController,
|
||||
});
|
||||
|
||||
|
@ -186,8 +195,8 @@ class _RxTextDisplayWidgetState extends State<_RxTextDisplayWidget> {
|
|||
return Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.tealAccent.withOpacity(0.7),
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
),
|
||||
child: Column(mainAxisSize: MainAxisSize.min, children: [
|
||||
Material(
|
||||
|
|
|
@ -45,6 +45,7 @@ dependencies:
|
|||
path_provider: ^2.1.0
|
||||
rxdart: ^0.27.7
|
||||
uuid: ^3.0.7
|
||||
intl: ^0.18.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 698 KiB After Width: | Height: | Size: 708 KiB |
Loading…
Reference in a new issue