Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reworked writeBytes method #117

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
1 change: 1 addition & 0 deletions lib/src/enums.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class PosPrintResult {
static const ticketEmpty = PosPrintResult._internal(4);
static const printInProgress = PosPrintResult._internal(5);
static const scanInProgress = PosPrintResult._internal(6);
static const error = PosPrintResult._internal(7);

String get msg {
if (value == PosPrintResult.success.value) {
Expand Down
122 changes: 61 additions & 61 deletions lib/src/printer_bluetooth_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,83 +63,83 @@ class PrinterBluetoothManager {
});
}

void stopScan() async {
await _bluetoothManager.stopScan();
Future<void> stopScan() async {
return _bluetoothManager.stopScan();
}

void selectPrinter(PrinterBluetooth printer) {
_selectedPrinter = printer;
}

Future<PosPrintResult> writeBytes(
List<int> bytes, {
int chunkSizeBytes = 20,
int queueSleepTimeMs = 20,
}) async {
final Completer<PosPrintResult> completer = Completer();

const int timeout = 5;
Future<PosPrintResult> writeBytes(List<int> bytes,
{int chunkSizeBytes = 20,
int queueSleepTimeMs = 20,
Duration timeout = const Duration(seconds: 5)}) async {
if (_selectedPrinter == null) {
return Future<PosPrintResult>.value(PosPrintResult.printerNotSelected);
return PosPrintResult.printerNotSelected;
} else if (_isScanning.value!) {
return Future<PosPrintResult>.value(PosPrintResult.scanInProgress);
return PosPrintResult.scanInProgress;
} else if (_isPrinting) {
return Future<PosPrintResult>.value(PosPrintResult.printInProgress);
return PosPrintResult.printInProgress;
}

if (!_isConnected) {
// We have to rescan before connecting, otherwise we can connect only once
await _bluetoothManager.startScan(timeout: Duration(seconds: 1));
await _bluetoothManager.stopScan();

// Connect
await _bluetoothManager.connect(_selectedPrinter!._device);

if (await _bluetoothManager.state
.firstWhere((element) => element == BluetoothManager.CONNECTED)
.timeout(timeout, onTimeout: () {
return BluetoothManager.DISCONNECTED;
}) !=
BluetoothManager.CONNECTED) {
_isConnected = false;
return PosPrintResult.timeout;
}
_isConnected = true;
}

final len = bytes.length;
List<List<int>> chunks = [];
for (var i = 0; i < len; i += chunkSizeBytes) {
var end = (i + chunkSizeBytes < len) ? i + chunkSizeBytes : len;
chunks.add(bytes.sublist(i, end));
}

List<Future> futures = <Future>[];

_isPrinting = true;

// We have to rescan before connecting, otherwise we can connect only once
await _bluetoothManager.startScan(timeout: Duration(seconds: 1));
await _bluetoothManager.stopScan();

// Connect
await _bluetoothManager.connect(_selectedPrinter!._device);

// Subscribe to the events
_bluetoothManager.state.listen((state) async {
switch (state) {
case BluetoothManager.CONNECTED:
// To avoid double call
if (!_isConnected) {
final len = bytes.length;
List<List<int>> chunks = [];
for (var i = 0; i < len; i += chunkSizeBytes) {
var end = (i + chunkSizeBytes < len) ? i + chunkSizeBytes : len;
chunks.add(bytes.sublist(i, end));
}

for (var i = 0; i < chunks.length; i += 1) {
await _bluetoothManager.writeData(chunks[i]);
sleep(Duration(milliseconds: queueSleepTimeMs));
}

completer.complete(PosPrintResult.success);
}
// TODO sending disconnect signal should be event-based
_runDelayed(3).then((dynamic v) async {
await _bluetoothManager.disconnect();
_isPrinting = false;
});
_isConnected = true;
break;
case BluetoothManager.DISCONNECTED:
_isConnected = false;
break;
default:
break;
}
});
for (var i = 0; i < chunks.length; i += 1) {
futures.add(_bluetoothManager.writeData(chunks[i]));
sleep(Duration(milliseconds: queueSleepTimeMs));
}

// Printing timeout
_runDelayed(timeout).then((dynamic v) async {
if (_isPrinting) {
_isPrinting = false;
completer.complete(PosPrintResult.timeout);
}
await Future.delayed(timeout);

return Future.wait(futures).then((_) async {
_isPrinting = false;
return PosPrintResult.success;
}).catchError((e) async {
_isPrinting = false;
_isConnected = false;
await _bluetoothManager.disconnect();
return PosPrintResult.error;
}).timeout(timeout, onTimeout: () async {
_isPrinting = false;
_isConnected = false;
await _bluetoothManager.disconnect();
return PosPrintResult.timeout;
});
}

return completer.future;
Future<void> disconnect() async {
await _bluetoothManager.disconnect();
_isConnected = false;
}

Future<PosPrintResult> printTicket(
Expand Down
7 changes: 5 additions & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@ name: esc_pos_bluetooth
description: The library allows to print receipts using an ESC/POS thermal Bluetooth printer.
version: 0.4.1
homepage: https://github.com/andrey-ushakov/esc_pos_bluetooth
publish_to: none

environment:
sdk: ">=2.12.0 <3.0.0"

dependencies:
flutter:
sdk: flutter
rxdart: ^0.26.0
rxdart: ^0.27.7
esc_pos_utils: ^1.1.0
# esc_pos_utils:
# path: ../esc_pos_utils
flutter_bluetooth_basic: ^0.1.7
flutter_bluetooth_basic:
git:
url: https://github.com/benlrichards/flutter_bluetooth_basic.git

dev_dependencies:
flutter_test:
Expand Down