Julian Steenbakker

fix: hot-restart by adding force parameter

... ... @@ -440,12 +440,14 @@ class MobileScanner(
/**
* Pause barcode scanning.
*/
fun pause() {
fun pause(force: Boolean = false) {
if (!force) {
if (isPaused) {
throw AlreadyPaused()
} else if (isStopped()) {
throw AlreadyStopped()
}
}
pauseCamera()
}
... ... @@ -453,10 +455,12 @@ class MobileScanner(
/**
* Stop barcode scanning.
*/
fun stop() {
fun stop(force: Boolean = false) {
if (!force) {
if (!isPaused && isStopped()) {
throw AlreadyStopped()
}
}
releaseCamera()
}
... ...
... ... @@ -118,8 +118,8 @@ class MobileScannerHandler(
}
})
"start" -> start(call, result)
"pause" -> pause(result)
"stop" -> stop(result)
"pause" -> pause(call, result)
"stop" -> stop(call, result)
"toggleTorch" -> toggleTorch(result)
"analyzeImage" -> analyzeImage(call, result)
"setScale" -> setScale(call, result)
... ... @@ -214,9 +214,10 @@ class MobileScannerHandler(
)
}
private fun pause(result: MethodChannel.Result) {
private fun pause(call: MethodCall, result: MethodChannel.Result) {
val force: Boolean = call.argument<Boolean>("force") ?: false
try {
mobileScanner!!.pause()
mobileScanner!!.pause(force)
result.success(null)
} catch (e: Exception) {
when (e) {
... ... @@ -226,9 +227,10 @@ class MobileScannerHandler(
}
}
private fun stop(result: MethodChannel.Result) {
private fun stop(call: MethodCall, result: MethodChannel.Result) {
val force: Boolean = call.argument<Boolean>("force") ?: false
try {
mobileScanner!!.stop()
mobileScanner!!.stop(force)
result.success(null)
} catch (e: AlreadyStopped) {
result.success(null)
... ...
... ... @@ -303,18 +303,20 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega
}
/// Pause scanning for barcodes
func pause() throws {
func pause(force: Bool = false) throws {
if (!force) {
if (paused) {
throw MobileScannerError.alreadyPaused
} else if (stopped) {
throw MobileScannerError.alreadyStopped
}
}
releaseCamera()
}
/// Stop scanning for barcodes
func stop() throws {
if (!paused && stopped) {
func stop(force: Bool = false) throws {
if (!paused && stopped && !force) {
throw MobileScannerError.alreadyStopped
}
releaseCamera()
... ... @@ -343,7 +345,9 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega
}
private func releaseTexture() {
if (textureId != nil) {
registry?.unregisterTexture(textureId)
}
textureId = nil
scanner = nil
}
... ...
... ... @@ -106,9 +106,9 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin {
case "start":
start(call, result)
case "pause":
pause(result)
pause(call, result)
case "stop":
stop(result)
stop(call, result)
case "toggleTorch":
toggleTorch(result)
case "analyzeImage":
... ... @@ -170,17 +170,19 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin {
}
/// Stops the mobileScanner without closing the texture.
private func pause(_ result: @escaping FlutterResult) {
private func pause(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) {
let force = (call.arguments as? Bool) ?? false
do {
try mobileScanner.pause()
try mobileScanner.pause(force: force)
} catch {}
result(nil)
}
/// Stops the mobileScanner and closes the texture.
private func stop(_ result: @escaping FlutterResult) {
private func stop(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) {
let force = (call.arguments as? Bool) ?? false
do {
try mobileScanner.stop()
try mobileScanner.stop(force: force)
} catch {}
result(nil)
}
... ...
... ... @@ -292,26 +292,26 @@ class MethodChannelMobileScanner extends MobileScannerPlatform {
}
@override
Future<void> stop() async {
if (_textureId == null) {
Future<void> stop({bool force = false}) async {
if (_textureId == null && !force) {
return;
}
_textureId = null;
_pausing = false;
await methodChannel.invokeMethod<void>('stop');
await methodChannel.invokeMethod<void>('stop', {'force' : force});
}
@override
Future<void> pause() async {
Future<void> pause({bool force = false}) async {
if (_pausing) {
return;
}
_pausing = true;
await methodChannel.invokeMethod<void>('pause');
await methodChannel.invokeMethod<void>('pause', {'force' : force});
}
@override
... ...
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:mobile_scanner/src/method_channel/mobile_scanner_method_channel.dart';
import 'package:mobile_scanner/src/mobile_scanner_controller.dart';
import 'package:mobile_scanner/src/mobile_scanner_exception.dart';
import 'package:mobile_scanner/src/mobile_scanner_platform_interface.dart';
... ... @@ -259,19 +261,21 @@ class _MobileScannerState extends State<MobileScanner>
StreamSubscription? _subscription;
Future<void> initController() async {
// TODO: This will be fixed in another PR
// If debug mode is enabled, stop the controller first before starting it.
// If a hot-restart is initiated, the controller won't be stopped, and because
// there is no way of knowing if a hot-restart has happened, we must assume
// every start is a hot-restart.
// if (kDebugMode) {
// try {
// await controller.stop();
// } catch (e) {
// // Don't do anything if the controller is already stopped.
// debugPrint('$e');
// }
// }
if (kDebugMode) {
final platformInterface = MobileScannerPlatform.instance;
if (platformInterface is MethodChannelMobileScanner) {
try {
await platformInterface.stop(force: true);
} catch (e) {
// Don't do anything if the controller is already stopped.
debugPrint('$e');
}
}
}
if (widget.onDetect != null) {
WidgetsBinding.instance.addObserver(this);
... ...
... ... @@ -76,9 +76,9 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler,
case "resetScale":
resetScale(call, result)
case "pause":
pause(result)
pause(call, result)
case "stop":
stop(result)
stop(call, result)
case "updateScanWindow":
updateScanWindow(call, result)
case "analyzeImage":
... ... @@ -448,19 +448,24 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler,
result(nil)
}
func pause(_ result: FlutterResult) {
func pause(_ call: FlutterMethodCall, _ result: FlutterResult) {
let force = (call.arguments as? Bool) ?? false
if (!force) {
if (paused || stopped) {
result(nil)
return
}
}
releaseCamera()
result(nil)
}
func stop(_ result: FlutterResult) {
if (!paused && stopped) {
func stop(_ call: FlutterMethodCall, _ result: FlutterResult) {
let force = (call.arguments as? Bool) ?? false
if (!paused && stopped && !force) {
result(nil)
return
... ...