-
Notifications
You must be signed in to change notification settings - Fork 4
/
plugin_scaffold.dart
118 lines (102 loc) · 3.26 KB
/
plugin_scaffold.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import 'dart:async';
import 'package:flutter/services.dart';
typedef void MethodCallHandler(dynamic args);
class PluginScaffold {
static const onListen = "OnListen";
static const onCancel = "OnCancel";
static const onSuccess = "onSuccess";
static const onError = "onError";
static const endOfStream = "endOfStream";
static final callHandlers = <String, Set<MethodCallHandler>>{};
static String getCallHandlerKey(MethodChannel channel, String methodName) {
return "${channel.name}/$methodName";
}
static void _setChannelCallHandler(MethodChannel channel) {
channel.setMethodCallHandler((call) async {
final key = getCallHandlerKey(channel, call.method);
final handlers = callHandlers[key];
for (var handler in handlers) {
handler(call.arguments);
}
});
}
static void addCallHandler(
MethodChannel channel,
String methodName,
MethodCallHandler handler,
) {
final key = getCallHandlerKey(channel, methodName);
callHandlers.putIfAbsent(key, () => {});
callHandlers[key].add(handler);
_setChannelCallHandler(channel);
}
static void setCallHandler(
MethodChannel channel,
String methodName,
MethodCallHandler handler,
) {
final key = getCallHandlerKey(channel, methodName);
callHandlers[key] = {handler};
_setChannelCallHandler(channel);
}
static void removeCallHandler(MethodCallHandler handler) {
for (final it in callHandlers.values) {
it.remove(handler);
}
}
static void removeCallHandlersWithName(
MethodChannel channel,
String methodName,
) {
callHandlers.remove(getCallHandlerKey(channel, methodName));
}
static Stream<T> createStream<T>(
MethodChannel channel,
String streamName, [
dynamic args,
]) {
return createStreamController(channel, streamName, args).stream;
}
static StreamController<T> createStreamController<T>(
MethodChannel channel,
String streamName, [
dynamic args,
]) {
StreamController<T> controller;
controller = StreamController<T>.broadcast(
onListen: () async {
final hashCode = controller.hashCode;
final prefix = '$streamName/$hashCode';
setCallHandler(channel, "$prefix/$onSuccess", (event) {
controller.add(event);
});
setCallHandler(channel, "$prefix/$onError", (err) {
controller.addError(
PlatformException(code: err[0], message: err[1], details: err[2]),
);
});
setCallHandler(channel, "$prefix/$endOfStream", (_) {
controller.close();
});
try {
await channel.invokeMethod(streamName + onListen, [hashCode, args]);
} catch (e, trace) {
controller.addError(e, trace);
}
},
onCancel: () async {
final hashCode = controller.hashCode;
final prefix = '$streamName/$hashCode';
removeCallHandlersWithName(channel, "$prefix/$onSuccess");
removeCallHandlersWithName(channel, "$prefix/$onError");
removeCallHandlersWithName(channel, "$prefix/$endOfStream");
try {
await channel.invokeMethod(streamName + onCancel, [hashCode, args]);
} catch (e, trace) {
controller.addError(e, trace);
}
},
);
return controller;
}
}