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)
|
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
|
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
|
![cuttle mobile app receiving data](./mobile_receiving.png)
|
||||||
data](./mobile_finished.png)
|
|
||||||
|
|
||||||
I might take a crack at making it less hideous before I start on the mobile transmitting/desktop
|
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
|
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
|
flutter_rust_bridge_codegen
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
cd native && cargo fmt
|
|
||||||
dart format .
|
dart format .
|
||||||
|
|
||||||
|
native: native-debug native-release
|
||||||
|
|
||||||
|
native-release:
|
||||||
|
cd android && ./gradlew :app:cargoBuildRelease
|
||||||
|
|
||||||
|
native-debug:
|
||||||
|
cd android && ./gradlew :app:cargoBuildDebug
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
flutter clean
|
flutter clean
|
||||||
cd native && cargo clean
|
cd native && cargo clean
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:collection';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:camerawesome/camerawesome_plugin.dart';
|
import 'package:camerawesome/camerawesome_plugin.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:google_mlkit_barcode_scanning/google_mlkit_barcode_scanning.dart';
|
import 'package:google_mlkit_barcode_scanning/google_mlkit_barcode_scanning.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
import 'package:rxdart/rxdart.dart';
|
import 'package:rxdart/rxdart.dart';
|
||||||
import 'ffi.dart';
|
import 'ffi.dart';
|
||||||
import 'utils/mlkit_utils.dart';
|
import 'utils/mlkit_utils.dart';
|
||||||
|
@ -45,12 +47,14 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||||
final _barcodeScanner = BarcodeScanner(formats: [BarcodeFormat.qrCode]);
|
final _barcodeScanner = BarcodeScanner(formats: [BarcodeFormat.qrCode]);
|
||||||
final _rxTextController = BehaviorSubject<String>();
|
final _rxTextController = BehaviorSubject<String>();
|
||||||
late final Stream<String> _rxTextStream = _rxTextController.stream;
|
late final Stream<String> _rxTextStream = _rxTextController.stream;
|
||||||
final _scrollController = ScrollController();
|
|
||||||
|
|
||||||
TxConfig? _txConfig;
|
TxConfig? _txConfig;
|
||||||
var _cuttleState = CuttleState.unitialized;
|
var _cuttleState = CuttleState.unitialized;
|
||||||
final List<RaptorPacket> _rxData = [];
|
final HashSet<RaptorPacket> _rxData = HashSet();
|
||||||
String _rxText = '';
|
String _rxText = '';
|
||||||
|
int _rxCount = 1;
|
||||||
|
|
||||||
|
final _formatter = NumberFormat('###,###,###');
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
@ -65,15 +69,14 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||||
onImageForAnalysis: (img) => _processImageBarcode(img),
|
onImageForAnalysis: (img) => _processImageBarcode(img),
|
||||||
imageAnalysisConfig: AnalysisConfig(
|
imageAnalysisConfig: AnalysisConfig(
|
||||||
androidOptions: const AndroidAnalysisOptions.nv21(
|
androidOptions: const AndroidAnalysisOptions.nv21(
|
||||||
width: 1024,
|
width: 600,
|
||||||
),
|
),
|
||||||
maxFramesPerSecond: 30,
|
maxFramesPerSecond: 20,
|
||||||
autoStart: false,
|
autoStart: false,
|
||||||
),
|
),
|
||||||
builder: (cameraModeState, previewSize, previewRect) {
|
builder: (cameraModeState, previewSize, previewRect) {
|
||||||
return _RxTextDisplayWidget(
|
return _RxTextDisplayWidget(
|
||||||
rxTextStream: _rxTextStream,
|
rxTextStream: _rxTextStream,
|
||||||
scrollController: _scrollController,
|
|
||||||
analysisController: cameraModeState.analysisController!,
|
analysisController: cameraModeState.analysisController!,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -103,7 +106,8 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||||
_txConfig!.filename ?? "large text on the command line";
|
_txConfig!.filename ?? "large text on the command line";
|
||||||
|
|
||||||
final desc = _txConfig!.description;
|
final desc = _txConfig!.description;
|
||||||
final text = 'Receiving $fname, ${_txConfig!.len} bytes: $desc';
|
final text =
|
||||||
|
'Receiving $fname, ${_formatter.format(_txConfig!.len)} bytes ($desc)';
|
||||||
_rxText = text;
|
_rxText = text;
|
||||||
_rxTextController.add(text);
|
_rxTextController.add(text);
|
||||||
continue;
|
continue;
|
||||||
|
@ -121,25 +125,32 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||||
case CuttleState.receiving:
|
case CuttleState.receiving:
|
||||||
{
|
{
|
||||||
var txconf = await api.getTxConfig(bytes: dbytes);
|
var txconf = await api.getTxConfig(bytes: dbytes);
|
||||||
if (txconf != null || barcode.rawValue != null) {
|
if (txconf != null) {
|
||||||
await api.dropTxConfig(txc: txconf!);
|
await api.dropTxConfig(txc: txconf);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final packet = RaptorPacket(field0: dbytes);
|
final packet = RaptorPacket(field0: dbytes);
|
||||||
_rxData.add(packet);
|
_rxData.add(packet);
|
||||||
final content =
|
_rxCount += 1;
|
||||||
await api.decodePackets(packets: _rxData, txconf: _txConfig!);
|
if (_rxCount % 40 == 0) {
|
||||||
if (content != null) {
|
_rxCount = 1;
|
||||||
_rxData.clear();
|
final content = await api.decodePackets(
|
||||||
_barcodeScanner.close();
|
packets: _rxData.toList(), txconf: _txConfig!);
|
||||||
_cuttleState = CuttleState.received;
|
if (content != null) {
|
||||||
_rxTextController.add("DONE RECEIVING $_rxText");
|
_rxData.clear();
|
||||||
final f = await _saveReceivedFile(_txConfig!.filename, content);
|
_barcodeScanner.close();
|
||||||
_rxTextController.add("Saved content to $f");
|
_cuttleState = CuttleState.received;
|
||||||
continue;
|
_rxTextController.add("DONE RECEIVING $_rxText");
|
||||||
|
final f =
|
||||||
|
await _saveReceivedFile(_txConfig!.filename, content);
|
||||||
|
_rxTextController.add("Saved content to $f");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_rxTextController
|
final bytesTotal = _rxData.length * dbytes.length;
|
||||||
.add("$_rxText -- ${_rxData.length} bytes so far");
|
final pct = (100.0 * bytesTotal / _txConfig!.len).floor();
|
||||||
|
_rxTextController.add(
|
||||||
|
"$_rxText -- $pct% received (${_formatter.format(bytesTotal)} bytes)");
|
||||||
}
|
}
|
||||||
|
|
||||||
case CuttleState.received:
|
case CuttleState.received:
|
||||||
|
@ -164,7 +175,6 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||||
|
|
||||||
class _RxTextDisplayWidget extends StatefulWidget {
|
class _RxTextDisplayWidget extends StatefulWidget {
|
||||||
final Stream<String> rxTextStream;
|
final Stream<String> rxTextStream;
|
||||||
final ScrollController scrollController;
|
|
||||||
|
|
||||||
final AnalysisController analysisController;
|
final AnalysisController analysisController;
|
||||||
|
|
||||||
|
@ -172,7 +182,6 @@ class _RxTextDisplayWidget extends StatefulWidget {
|
||||||
// ignore: unused_element
|
// ignore: unused_element
|
||||||
super.key,
|
super.key,
|
||||||
required this.rxTextStream,
|
required this.rxTextStream,
|
||||||
required this.scrollController,
|
|
||||||
required this.analysisController,
|
required this.analysisController,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -186,8 +195,8 @@ class _RxTextDisplayWidgetState extends State<_RxTextDisplayWidget> {
|
||||||
return Align(
|
return Align(
|
||||||
alignment: Alignment.bottomCenter,
|
alignment: Alignment.bottomCenter,
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
color: Colors.tealAccent.withOpacity(0.7),
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
child: Column(mainAxisSize: MainAxisSize.min, children: [
|
child: Column(mainAxisSize: MainAxisSize.min, children: [
|
||||||
Material(
|
Material(
|
||||||
|
|
|
@ -45,6 +45,7 @@ dependencies:
|
||||||
path_provider: ^2.1.0
|
path_provider: ^2.1.0
|
||||||
rxdart: ^0.27.7
|
rxdart: ^0.27.7
|
||||||
uuid: ^3.0.7
|
uuid: ^3.0.7
|
||||||
|
intl: ^0.18.1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 698 KiB After Width: | Height: | Size: 708 KiB |
Loading…
Reference in a new issue