Skip to content

Commit 3b91d92

Browse files
committed
Implement singleton logic
1 parent 98643a9 commit 3b91d92

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

packages/sane/lib/src/sane.dart

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,14 @@ import 'package:sane/src/utils.dart';
1414
typedef AuthCallback = SaneCredentials Function(String resourceName);
1515

1616
class Sane {
17+
static Sane? _instance;
18+
bool _exited = false;
1719
final Map<SaneHandle, SANE_Handle> _nativeHandles = {};
20+
1821
SANE_Handle _getNativeHandle(SaneHandle handle) => _nativeHandles[handle]!;
1922

23+
Sane._();
24+
2025
Future<int> init({
2126
AuthCallback? authCallback,
2227
}) {
@@ -64,14 +69,20 @@ class Sane {
6469
return completer.future;
6570
}
6671

72+
factory Sane() => _instance ??= Sane._();
73+
6774
Future<void> exit() {
6875
final completer = Completer<void>();
6976

7077
Future(() {
78+
_exited = true;
79+
7180
dylib.sane_exit();
7281
print('sane_exit()');
7382

7483
completer.complete();
84+
85+
_instance = null;
7586
});
7687

7788
return completer.future;
@@ -80,6 +91,8 @@ class Sane {
8091
Future<List<SaneDevice>> getDevices({
8192
required bool localOnly,
8293
}) {
94+
if (_exited) throw StateError('SANE has been exited');
95+
8396
final completer = Completer<List<SaneDevice>>();
8497

8598
Future(() {
@@ -108,6 +121,8 @@ class Sane {
108121
}
109122

110123
Future<SaneHandle> open(String deviceName) {
124+
if (_exited) throw StateError('SANE has been exited');
125+
111126
final completer = Completer<SaneHandle>();
112127

113128
Future(() {
@@ -133,10 +148,14 @@ class Sane {
133148
}
134149

135150
Future<SaneHandle> openDevice(SaneDevice device) {
151+
if (_exited) throw StateError('SANE has been exited');
152+
136153
return open(device.name);
137154
}
138155

139156
Future<void> close(SaneHandle handle) {
157+
if (_exited) throw StateError('SANE has been exited');
158+
140159
final completer = Completer<void>();
141160

142161
Future(() {
@@ -154,6 +173,8 @@ class Sane {
154173
SaneHandle handle,
155174
int index,
156175
) {
176+
if (_exited) throw StateError('SANE has been exited');
177+
157178
final completer = Completer<SaneOptionDescriptor>();
158179

159180
Future(() {
@@ -175,6 +196,8 @@ class Sane {
175196
Future<List<SaneOptionDescriptor>> getAllOptionDescriptors(
176197
SaneHandle handle,
177198
) {
199+
if (_exited) throw StateError('SANE has been exited');
200+
178201
final completer = Completer<List<SaneOptionDescriptor>>();
179202

180203
Future(() {
@@ -201,6 +224,8 @@ class Sane {
201224
required SaneAction action,
202225
T? value,
203226
}) {
227+
if (_exited) throw StateError('SANE has been exited');
228+
204229
final completer = Completer<SaneOptionResult<T>>();
205230

206231
Future(() {
@@ -393,6 +418,8 @@ class Sane {
393418
}
394419

395420
Future<SaneParameters> getParameters(SaneHandle handle) {
421+
if (_exited) throw StateError('SANE has been exited');
422+
396423
final completer = Completer<SaneParameters>();
397424

398425
Future(() {
@@ -416,6 +443,8 @@ class Sane {
416443
}
417444

418445
Future<void> start(SaneHandle handle) {
446+
if (_exited) throw StateError('SANE has been exited');
447+
419448
final completer = Completer<void>();
420449

421450
Future(() {
@@ -431,6 +460,8 @@ class Sane {
431460
}
432461

433462
Future<Uint8List> read(SaneHandle handle, int bufferSize) {
463+
if (_exited) throw StateError('SANE has been exited');
464+
434465
final completer = Completer<Uint8List>();
435466

436467
Future(() {
@@ -464,6 +495,8 @@ class Sane {
464495
}
465496

466497
Future<void> cancel(SaneHandle handle) {
498+
if (_exited) throw StateError('SANE has been exited');
499+
467500
final completer = Completer<void>();
468501

469502
Future(() {
@@ -477,6 +510,8 @@ class Sane {
477510
}
478511

479512
Future<void> setIOMode(SaneHandle handle, SaneIOMode mode) {
513+
if (_exited) throw StateError('SANE has been exited');
514+
480515
final completer = Completer<void>();
481516

482517
Future(() {
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import 'package:sane/sane.dart';
2+
import 'package:test/test.dart';
3+
4+
void main() {
5+
late Sane sane;
6+
7+
test('can instantiate', () {
8+
sane = Sane();
9+
});
10+
11+
test('same instance on repeated instantiation', () {
12+
final newSane = Sane();
13+
expect(sane, equals(newSane));
14+
});
15+
16+
test('can exit', () {
17+
expect(sane.exit, returnsNormally);
18+
});
19+
20+
test('throws upon use', () {
21+
expect(() => sane.getDevices(localOnly: true), throwsStateError);
22+
});
23+
24+
test('can reinstiate with new instance', () {
25+
final newSane = Sane();
26+
expect(sane, isNot(newSane));
27+
sane = newSane;
28+
});
29+
30+
test('doesn\'t throw upon use', () {
31+
expect(() => sane.getDevices(localOnly: true), returnsNormally);
32+
});
33+
}

0 commit comments

Comments
 (0)