MaaFw 4.5.6__py3-none-manylinux2014_x86_64.whl → 5.0.0a2__py3-none-manylinux2014_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of MaaFw might be problematic. Click here for more details.
- maa/bin/libMaaAdbControlUnit.so +0 -0
- maa/bin/libMaaAgentClient.so +0 -0
- maa/bin/libMaaAgentServer.so +0 -0
- maa/bin/libMaaCustomControlUnit.so +0 -0
- maa/bin/libMaaDbgControlUnit.so +0 -0
- maa/bin/libMaaFramework.so +0 -0
- maa/bin/libMaaToolkit.so +0 -0
- maa/bin/libMaaUtils.so +0 -0
- maa/context.py +101 -5
- maa/controller.py +97 -24
- maa/define.py +3 -2
- maa/event_sink.py +74 -0
- maa/pipeline.py +374 -0
- maa/resource.py +97 -18
- maa/tasker.py +177 -60
- maa/toolkit.py +0 -85
- {maafw-4.5.6.dist-info → maafw-5.0.0a2.dist-info}/METADATA +8 -3
- maafw-5.0.0a2.dist-info/RECORD +35 -0
- maa/notification_handler.py +0 -199
- maafw-4.5.6.dist-info/RECORD +0 -34
- {maafw-4.5.6.dist-info → maafw-5.0.0a2.dist-info}/WHEEL +0 -0
- {maafw-4.5.6.dist-info → maafw-5.0.0a2.dist-info}/licenses/LICENSE.md +0 -0
maa/pipeline.py
ADDED
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from dataclasses import dataclass, field
|
|
3
|
+
from typing import Any, List, Tuple, Union, Dict
|
|
4
|
+
|
|
5
|
+
# Type aliases to match C++ std::variant types
|
|
6
|
+
JRect = Tuple[int, int, int, int] # std::array<int, 4>
|
|
7
|
+
JTarget = Union[bool, str, JRect] # std::variant<bool, std::string, JRect>
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# Recognition parameter dataclasses (matching C++ JRecognitionParam variants)
|
|
11
|
+
@dataclass
|
|
12
|
+
class JDirectHit:
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class JTemplateMatch:
|
|
18
|
+
roi: JTarget
|
|
19
|
+
roi_offset: JRect
|
|
20
|
+
template: List[str]
|
|
21
|
+
threshold: List[float]
|
|
22
|
+
order_by: str
|
|
23
|
+
index: int
|
|
24
|
+
method: int
|
|
25
|
+
green_mask: bool
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass
|
|
29
|
+
class JFeatureMatch:
|
|
30
|
+
roi: JTarget
|
|
31
|
+
roi_offset: JRect
|
|
32
|
+
template: List[str]
|
|
33
|
+
detector: str
|
|
34
|
+
order_by: str
|
|
35
|
+
count: int
|
|
36
|
+
index: int
|
|
37
|
+
green_mask: bool
|
|
38
|
+
ratio: float
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass
|
|
42
|
+
class JColorMatch:
|
|
43
|
+
roi: JTarget
|
|
44
|
+
roi_offset: JRect
|
|
45
|
+
lower: List[List[int]]
|
|
46
|
+
upper: List[List[int]]
|
|
47
|
+
order_by: str
|
|
48
|
+
method: int
|
|
49
|
+
count: int
|
|
50
|
+
index: int
|
|
51
|
+
connected: bool
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@dataclass
|
|
55
|
+
class JOCR:
|
|
56
|
+
roi: JTarget
|
|
57
|
+
roi_offset: JRect
|
|
58
|
+
expected: List[str]
|
|
59
|
+
threshold: float
|
|
60
|
+
replace: List[List[str]]
|
|
61
|
+
order_by: str
|
|
62
|
+
index: int
|
|
63
|
+
only_rec: bool
|
|
64
|
+
model: str
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@dataclass
|
|
68
|
+
class JNeuralNetworkClassify:
|
|
69
|
+
roi: JTarget
|
|
70
|
+
roi_offset: JRect
|
|
71
|
+
labels: List[str]
|
|
72
|
+
model: str
|
|
73
|
+
expected: List[int]
|
|
74
|
+
order_by: str
|
|
75
|
+
index: int
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@dataclass
|
|
79
|
+
class JNeuralNetworkDetect:
|
|
80
|
+
roi: JTarget
|
|
81
|
+
roi_offset: JRect
|
|
82
|
+
labels: List[str]
|
|
83
|
+
model: str
|
|
84
|
+
expected: List[int]
|
|
85
|
+
threshold: List[float]
|
|
86
|
+
order_by: str
|
|
87
|
+
index: int
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
@dataclass
|
|
91
|
+
class JCustomRecognition:
|
|
92
|
+
roi: JTarget
|
|
93
|
+
roi_offset: JRect
|
|
94
|
+
custom_recognition: str
|
|
95
|
+
custom_recognition_param: Any
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
# Recognition parameter union type
|
|
99
|
+
JRecognitionParam = Union[
|
|
100
|
+
JDirectHit,
|
|
101
|
+
JTemplateMatch,
|
|
102
|
+
JFeatureMatch,
|
|
103
|
+
JColorMatch,
|
|
104
|
+
JOCR,
|
|
105
|
+
JNeuralNetworkClassify,
|
|
106
|
+
JNeuralNetworkDetect,
|
|
107
|
+
JCustomRecognition,
|
|
108
|
+
]
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
# Action parameter dataclasses (matching C++ JActionParam variants)
|
|
112
|
+
@dataclass
|
|
113
|
+
class JDoNothing:
|
|
114
|
+
pass
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@dataclass
|
|
118
|
+
class JClick:
|
|
119
|
+
target: JTarget
|
|
120
|
+
target_offset: JRect
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@dataclass
|
|
124
|
+
class JLongPress:
|
|
125
|
+
target: JTarget
|
|
126
|
+
target_offset: JRect
|
|
127
|
+
duration: int
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
@dataclass
|
|
131
|
+
class JSwipe:
|
|
132
|
+
starting: int
|
|
133
|
+
begin: JTarget
|
|
134
|
+
begin_offset: JRect
|
|
135
|
+
end: List[JTarget]
|
|
136
|
+
end_offset: List[JRect]
|
|
137
|
+
end_hold: List[int]
|
|
138
|
+
duration: List[int]
|
|
139
|
+
only_hover: bool
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
@dataclass
|
|
143
|
+
class JMultiSwipe:
|
|
144
|
+
swipes: List[JSwipe]
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
@dataclass
|
|
148
|
+
class JClickKey:
|
|
149
|
+
key: List[int]
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
@dataclass
|
|
153
|
+
class JLongPressKey:
|
|
154
|
+
key: List[int]
|
|
155
|
+
duration: int
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
@dataclass
|
|
159
|
+
class JInputText:
|
|
160
|
+
input_text: str
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
@dataclass
|
|
164
|
+
class JStartApp:
|
|
165
|
+
package: str
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
@dataclass
|
|
169
|
+
class JStopApp:
|
|
170
|
+
package: str
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
@dataclass
|
|
174
|
+
class JStopTask:
|
|
175
|
+
pass
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
@dataclass
|
|
179
|
+
class JCommand:
|
|
180
|
+
exec: str
|
|
181
|
+
args: List[str]
|
|
182
|
+
detach: bool
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
@dataclass
|
|
186
|
+
class JCustomAction:
|
|
187
|
+
target: JTarget
|
|
188
|
+
custom_action: str
|
|
189
|
+
custom_action_param: Any
|
|
190
|
+
target_offset: JRect
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
# Action parameter union type
|
|
194
|
+
JActionParam = Union[
|
|
195
|
+
JDoNothing,
|
|
196
|
+
JClick,
|
|
197
|
+
JLongPress,
|
|
198
|
+
JSwipe,
|
|
199
|
+
JMultiSwipe,
|
|
200
|
+
JClickKey,
|
|
201
|
+
JLongPressKey,
|
|
202
|
+
JInputText,
|
|
203
|
+
JStartApp,
|
|
204
|
+
JStopApp,
|
|
205
|
+
JStopTask,
|
|
206
|
+
JCommand,
|
|
207
|
+
JCustomAction,
|
|
208
|
+
]
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
# Main pipeline dataclasses
|
|
212
|
+
@dataclass
|
|
213
|
+
class JRecognition:
|
|
214
|
+
type: str
|
|
215
|
+
param: JRecognitionParam
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
@dataclass
|
|
219
|
+
class JAction:
|
|
220
|
+
type: str
|
|
221
|
+
param: JActionParam
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
@dataclass
|
|
225
|
+
class JWaitFreezes:
|
|
226
|
+
time: int
|
|
227
|
+
target: JTarget
|
|
228
|
+
target_offset: JRect
|
|
229
|
+
threshold: float
|
|
230
|
+
method: int
|
|
231
|
+
rate_limit: int
|
|
232
|
+
timeout: int
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
@dataclass
|
|
236
|
+
class JPipelineData:
|
|
237
|
+
recognition: JRecognition
|
|
238
|
+
action: JAction
|
|
239
|
+
next: List[str]
|
|
240
|
+
interrupt: List[str]
|
|
241
|
+
is_sub: bool
|
|
242
|
+
rate_limit: int
|
|
243
|
+
timeout: int
|
|
244
|
+
on_error: List[str]
|
|
245
|
+
inverse: bool
|
|
246
|
+
enabled: bool
|
|
247
|
+
pre_delay: int
|
|
248
|
+
post_delay: int
|
|
249
|
+
pre_wait_freezes: JWaitFreezes
|
|
250
|
+
post_wait_freezes: JWaitFreezes
|
|
251
|
+
focus: Any
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
class JPipelineParser:
|
|
255
|
+
@staticmethod
|
|
256
|
+
def _parse_wait_freezes(data: dict) -> JWaitFreezes:
|
|
257
|
+
"""Convert wait freezes with proper defaults"""
|
|
258
|
+
return JWaitFreezes(
|
|
259
|
+
time=data.get("time"),
|
|
260
|
+
target=data.get("target"), # type: ignore
|
|
261
|
+
target_offset=data.get("target_offset"), # type: ignore
|
|
262
|
+
threshold=data.get("threshold"),
|
|
263
|
+
method=data.get("method"),
|
|
264
|
+
rate_limit=data.get("rate_limit"),
|
|
265
|
+
timeout=data.get("timeout"),
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
@classmethod
|
|
269
|
+
def _parse_param(
|
|
270
|
+
cls, param_type: str, param_data: dict, param_type_map: dict, default_class
|
|
271
|
+
):
|
|
272
|
+
"""Generic function to parse parameters based on type map."""
|
|
273
|
+
param_class = param_type_map.get(param_type)
|
|
274
|
+
if not param_class:
|
|
275
|
+
raise ValueError(f"Unknown type: {param_type}")
|
|
276
|
+
|
|
277
|
+
if param_class == default_class:
|
|
278
|
+
return param_class()
|
|
279
|
+
|
|
280
|
+
try:
|
|
281
|
+
return param_class(**param_data)
|
|
282
|
+
except TypeError as e:
|
|
283
|
+
print(
|
|
284
|
+
f"Warning: Failed to create {param_class.__name__} with data {param_data}: {e}"
|
|
285
|
+
)
|
|
286
|
+
return default_class()
|
|
287
|
+
|
|
288
|
+
@classmethod
|
|
289
|
+
def _parse_recognition_param(
|
|
290
|
+
cls, param_type: str, param_data: dict
|
|
291
|
+
) -> JRecognitionParam:
|
|
292
|
+
"""Convert dict to appropriate JRecognitionParam variant based on type."""
|
|
293
|
+
param_type_map = {
|
|
294
|
+
"DirectHit": JDirectHit,
|
|
295
|
+
"TemplateMatch": JTemplateMatch,
|
|
296
|
+
"FeatureMatch": JFeatureMatch,
|
|
297
|
+
"ColorMatch": JColorMatch,
|
|
298
|
+
"OCR": JOCR,
|
|
299
|
+
"NeuralNetworkClassify": JNeuralNetworkClassify,
|
|
300
|
+
"NeuralNetworkDetect": JNeuralNetworkDetect,
|
|
301
|
+
"Custom": JCustomRecognition,
|
|
302
|
+
}
|
|
303
|
+
return cls._parse_param(param_type, param_data, param_type_map, JDirectHit)
|
|
304
|
+
|
|
305
|
+
@classmethod
|
|
306
|
+
def _parse_action_param(cls, param_type: str, param_data: dict) -> JActionParam:
|
|
307
|
+
"""Convert dict to appropriate JActionParam variant based on type."""
|
|
308
|
+
param_type_map = {
|
|
309
|
+
"DoNothing": JDoNothing,
|
|
310
|
+
"Click": JClick,
|
|
311
|
+
"LongPress": JLongPress,
|
|
312
|
+
"Swipe": JSwipe,
|
|
313
|
+
"MultiSwipe": JMultiSwipe,
|
|
314
|
+
"ClickKey": JClickKey,
|
|
315
|
+
"LongPressKey": JLongPressKey,
|
|
316
|
+
"InputText": JInputText,
|
|
317
|
+
"StartApp": JStartApp,
|
|
318
|
+
"StopApp": JStopApp,
|
|
319
|
+
"StopTask": JStopTask,
|
|
320
|
+
"Command": JCommand,
|
|
321
|
+
"Custom": JCustomAction,
|
|
322
|
+
}
|
|
323
|
+
return cls._parse_param(param_type, param_data, param_type_map, JDoNothing)
|
|
324
|
+
|
|
325
|
+
@classmethod
|
|
326
|
+
def parse_pipeline_data(cls, pipeline_data: Union[str, Dict]) -> JPipelineData:
|
|
327
|
+
"""Parse JSON string to JPipelineData dataclass with proper variant types."""
|
|
328
|
+
if isinstance(pipeline_data, dict):
|
|
329
|
+
data = pipeline_data
|
|
330
|
+
elif isinstance(pipeline_data, str):
|
|
331
|
+
try:
|
|
332
|
+
data: dict = json.loads(pipeline_data)
|
|
333
|
+
except json.JSONDecodeError as e:
|
|
334
|
+
raise ValueError(f"Invalid JSON format: {e}")
|
|
335
|
+
else:
|
|
336
|
+
raise TypeError("Input must be a JSON string or a dict.")
|
|
337
|
+
|
|
338
|
+
# Convert recognition
|
|
339
|
+
recognition_data: dict = data.get("recognition")
|
|
340
|
+
recognition_type: str = recognition_data.get("type")
|
|
341
|
+
recognition_param_data: dict = recognition_data.get("param")
|
|
342
|
+
recognition_param = cls._parse_recognition_param(
|
|
343
|
+
recognition_type, recognition_param_data
|
|
344
|
+
)
|
|
345
|
+
recognition = JRecognition(type=recognition_type, param=recognition_param)
|
|
346
|
+
|
|
347
|
+
# Convert action
|
|
348
|
+
action_data: dict = data.get("action")
|
|
349
|
+
action_type: str = action_data.get("type")
|
|
350
|
+
action_param_data = action_data.get("param")
|
|
351
|
+
action_param = cls._parse_action_param(action_type, action_param_data)
|
|
352
|
+
action = JAction(type=action_type, param=action_param)
|
|
353
|
+
|
|
354
|
+
pre_wait_freezes = cls._parse_wait_freezes(data.get("pre_wait_freezes")) # type: ignore
|
|
355
|
+
post_wait_freezes = cls._parse_wait_freezes(data.get("post_wait_freezes")) # type: ignore
|
|
356
|
+
|
|
357
|
+
# Create JPipelineData with converted data
|
|
358
|
+
return JPipelineData(
|
|
359
|
+
recognition=recognition,
|
|
360
|
+
action=action,
|
|
361
|
+
next=data.get("next"),
|
|
362
|
+
interrupt=data.get("interrupt"),
|
|
363
|
+
is_sub=data.get("is_sub"),
|
|
364
|
+
rate_limit=data.get("rate_limit"),
|
|
365
|
+
timeout=data.get("timeout"),
|
|
366
|
+
on_error=data.get("on_error"),
|
|
367
|
+
inverse=data.get("inverse"),
|
|
368
|
+
enabled=data.get("enabled"),
|
|
369
|
+
pre_delay=data.get("pre_delay"),
|
|
370
|
+
post_delay=data.get("post_delay"),
|
|
371
|
+
pre_wait_freezes=pre_wait_freezes, # type: ignore
|
|
372
|
+
post_wait_freezes=post_wait_freezes, # type: ignore
|
|
373
|
+
focus=data.get("focus"),
|
|
374
|
+
)
|
maa/resource.py
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import ctypes
|
|
2
2
|
import pathlib
|
|
3
3
|
import json
|
|
4
|
-
from typing import Any, Optional, Union
|
|
4
|
+
from typing import Any, Optional, Union, List, Dict, Tuple
|
|
5
|
+
from dataclasses import dataclass, field
|
|
5
6
|
|
|
6
|
-
from .
|
|
7
|
+
from .event_sink import EventSink, NotificationType
|
|
7
8
|
from .define import *
|
|
8
9
|
from .job import Job
|
|
9
10
|
from .library import Library
|
|
10
11
|
from .buffer import StringBuffer, StringListBuffer
|
|
12
|
+
from .pipeline import JPipelineData, JPipelineParser
|
|
11
13
|
|
|
12
14
|
|
|
13
15
|
class Resource:
|
|
14
|
-
_notification_handler: Optional[NotificationHandler]
|
|
15
16
|
_handle: MaaResourceHandle
|
|
16
17
|
_own: bool
|
|
17
18
|
|
|
@@ -19,19 +20,21 @@ class Resource:
|
|
|
19
20
|
|
|
20
21
|
def __init__(
|
|
21
22
|
self,
|
|
22
|
-
notification_handler:
|
|
23
|
+
notification_handler: None = None,
|
|
23
24
|
handle: Optional[MaaResourceHandle] = None,
|
|
24
25
|
):
|
|
26
|
+
if notification_handler:
|
|
27
|
+
raise NotImplementedError(
|
|
28
|
+
"NotificationHandler is deprecated, use add_sink instead."
|
|
29
|
+
)
|
|
30
|
+
|
|
25
31
|
self._set_api_properties()
|
|
26
32
|
|
|
27
33
|
if handle:
|
|
28
34
|
self._handle = handle
|
|
29
35
|
self._own = False
|
|
30
36
|
else:
|
|
31
|
-
self.
|
|
32
|
-
self._handle = Library.framework().MaaResourceCreate(
|
|
33
|
-
*NotificationHandler._gen_c_param(self._notification_handler)
|
|
34
|
-
)
|
|
37
|
+
self._handle = Library.framework().MaaResourceCreate()
|
|
35
38
|
self._own = True
|
|
36
39
|
|
|
37
40
|
if not self._handle:
|
|
@@ -45,16 +48,18 @@ class Resource:
|
|
|
45
48
|
Library.framework().MaaResourceDestroy(self._handle)
|
|
46
49
|
|
|
47
50
|
def post_bundle(self, path: Union[pathlib.Path, str]) -> Job:
|
|
48
|
-
|
|
51
|
+
res_id = Library.framework().MaaResourcePostBundle(
|
|
49
52
|
self._handle, str(path).encode()
|
|
50
53
|
)
|
|
51
|
-
return Job(
|
|
54
|
+
return Job(res_id, self._status, self._wait)
|
|
52
55
|
|
|
53
56
|
def override_pipeline(self, pipeline_override: Dict) -> bool:
|
|
57
|
+
pipeline_json = json.dumps(pipeline_override, ensure_ascii=False)
|
|
58
|
+
|
|
54
59
|
return bool(
|
|
55
60
|
Library.framework().MaaResourceOverridePipeline(
|
|
56
61
|
self._handle,
|
|
57
|
-
|
|
62
|
+
pipeline_json.encode(),
|
|
58
63
|
)
|
|
59
64
|
)
|
|
60
65
|
|
|
@@ -67,14 +72,13 @@ class Resource:
|
|
|
67
72
|
self._handle, name.encode(), list_buffer._handle
|
|
68
73
|
)
|
|
69
74
|
)
|
|
70
|
-
|
|
71
|
-
def get_node_data(self, name: str) -> Optional[
|
|
75
|
+
|
|
76
|
+
def get_node_data(self, name: str) -> Optional[Dict]:
|
|
72
77
|
string_buffer = StringBuffer()
|
|
73
78
|
if not Library.framework().MaaResourceGetNodeData(
|
|
74
79
|
self._handle, name.encode(), string_buffer._handle
|
|
75
80
|
):
|
|
76
81
|
return None
|
|
77
|
-
|
|
78
82
|
data = string_buffer.get()
|
|
79
83
|
if not data:
|
|
80
84
|
return None
|
|
@@ -84,6 +88,14 @@ class Resource:
|
|
|
84
88
|
except json.JSONDecodeError:
|
|
85
89
|
return None
|
|
86
90
|
|
|
91
|
+
def get_node_object(self, name: str) -> Optional[JPipelineData]:
|
|
92
|
+
node_data = self.get_node_data(name)
|
|
93
|
+
|
|
94
|
+
if not node_data:
|
|
95
|
+
return None
|
|
96
|
+
|
|
97
|
+
return JPipelineParser.parse_pipeline_data(node_data)
|
|
98
|
+
|
|
87
99
|
@property
|
|
88
100
|
def loaded(self) -> bool:
|
|
89
101
|
return bool(Library.framework().MaaResourceLoaded(self._handle))
|
|
@@ -231,6 +243,27 @@ class Resource:
|
|
|
231
243
|
raise RuntimeError("Failed to get hash.")
|
|
232
244
|
return buffer.get()
|
|
233
245
|
|
|
246
|
+
_sink_holder: Dict[int, "ResourceEventSink"] = {}
|
|
247
|
+
|
|
248
|
+
def add_sink(self, sink: "ResourceEventSink") -> Optional[int]:
|
|
249
|
+
sink_id = int(
|
|
250
|
+
Library.framework().MaaResourceAddSink(
|
|
251
|
+
self._handle, *EventSink._gen_c_param(sink)
|
|
252
|
+
)
|
|
253
|
+
)
|
|
254
|
+
if sink_id == MaaInvalidId:
|
|
255
|
+
return None
|
|
256
|
+
|
|
257
|
+
self._sink_holder[sink_id] = sink
|
|
258
|
+
return sink_id
|
|
259
|
+
|
|
260
|
+
def remove_sink(self, sink_id: int) -> None:
|
|
261
|
+
Library.framework().MaaResourceRemoveSink(self._handle, sink_id)
|
|
262
|
+
self._sink_holder.pop(sink_id)
|
|
263
|
+
|
|
264
|
+
def clear_sinks(self) -> None:
|
|
265
|
+
Library.framework().MaaResourceClearSinks(self._handle)
|
|
266
|
+
|
|
234
267
|
### private ###
|
|
235
268
|
|
|
236
269
|
def set_inference(self, execution_provider: int, device_id: int) -> bool:
|
|
@@ -267,10 +300,7 @@ class Resource:
|
|
|
267
300
|
Resource._api_properties_initialized = True
|
|
268
301
|
|
|
269
302
|
Library.framework().MaaResourceCreate.restype = MaaResourceHandle
|
|
270
|
-
Library.framework().MaaResourceCreate.argtypes = [
|
|
271
|
-
MaaNotificationCallback,
|
|
272
|
-
ctypes.c_void_p,
|
|
273
|
-
]
|
|
303
|
+
Library.framework().MaaResourceCreate.argtypes = []
|
|
274
304
|
|
|
275
305
|
Library.framework().MaaResourceDestroy.restype = None
|
|
276
306
|
Library.framework().MaaResourceDestroy.argtypes = [MaaResourceHandle]
|
|
@@ -376,3 +406,52 @@ class Resource:
|
|
|
376
406
|
MaaResourceHandle,
|
|
377
407
|
MaaStringListBufferHandle,
|
|
378
408
|
]
|
|
409
|
+
|
|
410
|
+
Library.framework().MaaResourceAddSink.restype = MaaSinkId
|
|
411
|
+
Library.framework().MaaResourceAddSink.argtypes = [
|
|
412
|
+
MaaResourceHandle,
|
|
413
|
+
MaaEventCallback,
|
|
414
|
+
ctypes.c_void_p,
|
|
415
|
+
]
|
|
416
|
+
|
|
417
|
+
Library.framework().MaaResourceRemoveSink.restype = None
|
|
418
|
+
Library.framework().MaaResourceRemoveSink.argtypes = [
|
|
419
|
+
MaaResourceHandle,
|
|
420
|
+
MaaSinkId,
|
|
421
|
+
]
|
|
422
|
+
|
|
423
|
+
Library.framework().MaaResourceClearSinks.restype = None
|
|
424
|
+
Library.framework().MaaResourceClearSinks.argtypes = [MaaResourceHandle]
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
class ResourceEventSink(EventSink):
|
|
428
|
+
|
|
429
|
+
@dataclass
|
|
430
|
+
class ResourceLoadingDetail:
|
|
431
|
+
res_id: int
|
|
432
|
+
hash: str
|
|
433
|
+
path: str
|
|
434
|
+
|
|
435
|
+
def on_resource_loading(
|
|
436
|
+
self,
|
|
437
|
+
resource: Resource,
|
|
438
|
+
noti_type: NotificationType,
|
|
439
|
+
detail: ResourceLoadingDetail,
|
|
440
|
+
):
|
|
441
|
+
pass
|
|
442
|
+
|
|
443
|
+
def on_raw_notification(self, handle: ctypes.c_void_p, msg: str, details: dict):
|
|
444
|
+
|
|
445
|
+
resource = Resource(handle=handle)
|
|
446
|
+
noti_type = EventSink._notification_type(msg)
|
|
447
|
+
|
|
448
|
+
if msg.startswith("Resource.Loading"):
|
|
449
|
+
detail = self.ResourceLoadingDetail(
|
|
450
|
+
res_id=details["res_id"],
|
|
451
|
+
hash=details["hash"],
|
|
452
|
+
path=details["path"],
|
|
453
|
+
)
|
|
454
|
+
self.on_resource_loading(resource, noti_type, detail)
|
|
455
|
+
|
|
456
|
+
else:
|
|
457
|
+
self.on_unknown_notification(resource, msg, details)
|