MaaFw 4.5.5__py3-none-win_arm64.whl → 5.0.0a1__py3-none-win_arm64.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/MaaAdbControlUnit.dll +0 -0
- maa/bin/MaaAgentClient.dll +0 -0
- maa/bin/MaaAgentServer.dll +0 -0
- maa/bin/MaaCustomControlUnit.dll +0 -0
- maa/bin/MaaDbgControlUnit.dll +0 -0
- maa/bin/MaaFramework.dll +0 -0
- maa/bin/MaaToolkit.dll +0 -0
- maa/bin/MaaUtils.dll +0 -0
- maa/bin/MaaWin32ControlUnit.dll +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 -91
- {maafw-4.5.5.dist-info → maafw-5.0.0a1.dist-info}/METADATA +8 -3
- maafw-5.0.0a1.dist-info/RECORD +34 -0
- maa/notification_handler.py +0 -199
- maafw-4.5.5.dist-info/RECORD +0 -33
- {maafw-4.5.5.dist-info → maafw-5.0.0a1.dist-info}/WHEEL +0 -0
- {maafw-4.5.5.dist-info → maafw-5.0.0a1.dist-info}/licenses/LICENSE.md +0 -0
maa/bin/MaaAdbControlUnit.dll
CHANGED
|
Binary file
|
maa/bin/MaaAgentClient.dll
CHANGED
|
Binary file
|
maa/bin/MaaAgentServer.dll
CHANGED
|
Binary file
|
maa/bin/MaaCustomControlUnit.dll
CHANGED
|
Binary file
|
maa/bin/MaaDbgControlUnit.dll
CHANGED
|
Binary file
|
maa/bin/MaaFramework.dll
CHANGED
|
Binary file
|
maa/bin/MaaToolkit.dll
CHANGED
|
Binary file
|
maa/bin/MaaUtils.dll
CHANGED
|
Binary file
|
maa/bin/MaaWin32ControlUnit.dll
CHANGED
|
Binary file
|
maa/context.py
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import ctypes
|
|
2
2
|
import json
|
|
3
|
-
from typing import Dict, Optional, Tuple
|
|
3
|
+
from typing import Any, Dict, Optional, Tuple, Union
|
|
4
4
|
|
|
5
5
|
import numpy
|
|
6
6
|
|
|
7
|
+
from .event_sink import EventSink, NotificationType
|
|
7
8
|
from .buffer import ImageBuffer, RectBuffer, StringBuffer, StringListBuffer
|
|
8
9
|
from .define import *
|
|
9
10
|
from .library import Library
|
|
10
11
|
from .tasker import Tasker
|
|
12
|
+
from .pipeline import JPipelineData, JPipelineParser
|
|
11
13
|
from .job import JobWithResult
|
|
12
14
|
|
|
13
15
|
|
|
@@ -43,7 +45,10 @@ class Context:
|
|
|
43
45
|
return self.tasker.get_task_detail(task_id)
|
|
44
46
|
|
|
45
47
|
def run_recognition(
|
|
46
|
-
self,
|
|
48
|
+
self,
|
|
49
|
+
entry: str,
|
|
50
|
+
image: numpy.ndarray,
|
|
51
|
+
pipeline_override: Dict = {},
|
|
47
52
|
) -> Optional[RecognitionDetail]:
|
|
48
53
|
image_buffer = ImageBuffer()
|
|
49
54
|
image_buffer.set(image)
|
|
@@ -84,10 +89,12 @@ class Context:
|
|
|
84
89
|
return self.tasker.get_node_detail(node_id)
|
|
85
90
|
|
|
86
91
|
def override_pipeline(self, pipeline_override: Dict) -> bool:
|
|
92
|
+
pipeline_json = json.dumps(pipeline_override, ensure_ascii=False)
|
|
93
|
+
|
|
87
94
|
return bool(
|
|
88
95
|
Library.framework().MaaContextOverridePipeline(
|
|
89
96
|
self._handle,
|
|
90
|
-
|
|
97
|
+
pipeline_json.encode(),
|
|
91
98
|
)
|
|
92
99
|
)
|
|
93
100
|
|
|
@@ -101,7 +108,7 @@ class Context:
|
|
|
101
108
|
)
|
|
102
109
|
)
|
|
103
110
|
|
|
104
|
-
def get_node_data(self, name: str) -> Optional[
|
|
111
|
+
def get_node_data(self, name: str) -> Optional[Dict]:
|
|
105
112
|
string_buffer = StringBuffer()
|
|
106
113
|
if not Library.framework().MaaContextGetNodeData(
|
|
107
114
|
self._handle, name.encode(), string_buffer._handle
|
|
@@ -117,6 +124,14 @@ class Context:
|
|
|
117
124
|
except json.JSONDecodeError:
|
|
118
125
|
return None
|
|
119
126
|
|
|
127
|
+
def get_node_object(self, name: str) -> Optional[JPipelineData]:
|
|
128
|
+
node_data = self.get_node_data(name)
|
|
129
|
+
|
|
130
|
+
if not node_data:
|
|
131
|
+
return None
|
|
132
|
+
|
|
133
|
+
return JPipelineParser.parse_pipeline_data(node_data)
|
|
134
|
+
|
|
120
135
|
@property
|
|
121
136
|
def tasker(self) -> Tasker:
|
|
122
137
|
return self._tasker
|
|
@@ -145,9 +160,11 @@ class Context:
|
|
|
145
160
|
|
|
146
161
|
@staticmethod
|
|
147
162
|
def _gen_post_param(entry: str, pipeline_override: Dict) -> Tuple[bytes, bytes]:
|
|
163
|
+
pipeline_json = json.dumps(pipeline_override, ensure_ascii=False)
|
|
164
|
+
|
|
148
165
|
return (
|
|
149
166
|
entry.encode(),
|
|
150
|
-
|
|
167
|
+
pipeline_json.encode(),
|
|
151
168
|
)
|
|
152
169
|
|
|
153
170
|
_api_properties_initialized: bool = False
|
|
@@ -217,3 +234,82 @@ class Context:
|
|
|
217
234
|
Library.framework().MaaContextClone.argtypes = [
|
|
218
235
|
MaaContextHandle,
|
|
219
236
|
]
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
class ContextEventSink(EventSink):
|
|
240
|
+
|
|
241
|
+
@dataclass
|
|
242
|
+
class NodeNextListDetail:
|
|
243
|
+
task_id: int
|
|
244
|
+
name: str
|
|
245
|
+
next_list: list[str]
|
|
246
|
+
focus: Any
|
|
247
|
+
|
|
248
|
+
def on_node_next_list(
|
|
249
|
+
self,
|
|
250
|
+
context: "Context",
|
|
251
|
+
noti_type: NotificationType,
|
|
252
|
+
detail: NodeNextListDetail,
|
|
253
|
+
):
|
|
254
|
+
pass
|
|
255
|
+
|
|
256
|
+
@dataclass
|
|
257
|
+
class NodeRecognitionDetail:
|
|
258
|
+
task_id: int
|
|
259
|
+
reco_id: int
|
|
260
|
+
name: str
|
|
261
|
+
focus: Any
|
|
262
|
+
|
|
263
|
+
def on_node_recognition(
|
|
264
|
+
self,
|
|
265
|
+
context: "Context",
|
|
266
|
+
noti_type: NotificationType,
|
|
267
|
+
detail: NodeRecognitionDetail,
|
|
268
|
+
):
|
|
269
|
+
pass
|
|
270
|
+
|
|
271
|
+
@dataclass
|
|
272
|
+
class NodeActionDetail:
|
|
273
|
+
task_id: int
|
|
274
|
+
node_id: int
|
|
275
|
+
name: str
|
|
276
|
+
focus: Any
|
|
277
|
+
|
|
278
|
+
def on_node_action(
|
|
279
|
+
self, context: "Context", noti_type: NotificationType, detail: NodeActionDetail
|
|
280
|
+
):
|
|
281
|
+
pass
|
|
282
|
+
|
|
283
|
+
def on_raw_notification(self, handle: ctypes.c_void_p, msg: str, details: dict):
|
|
284
|
+
context = Context(handle=handle)
|
|
285
|
+
noti_type = EventSink._notification_type(msg)
|
|
286
|
+
|
|
287
|
+
if msg.startswith("Node.NextList"):
|
|
288
|
+
detail = self.NodeNextListDetail(
|
|
289
|
+
task_id=details["task_id"],
|
|
290
|
+
name=details["name"],
|
|
291
|
+
next_list=details["list"],
|
|
292
|
+
focus=details["focus"],
|
|
293
|
+
)
|
|
294
|
+
self.on_node_next_list(context, noti_type, detail)
|
|
295
|
+
|
|
296
|
+
elif msg.startswith("Node.Recognition"):
|
|
297
|
+
detail = self.NodeRecognitionDetail(
|
|
298
|
+
task_id=details["task_id"],
|
|
299
|
+
reco_id=details["reco_id"],
|
|
300
|
+
name=details["name"],
|
|
301
|
+
focus=details["focus"],
|
|
302
|
+
)
|
|
303
|
+
self.on_node_recognition(context, noti_type, detail)
|
|
304
|
+
|
|
305
|
+
elif msg.startswith("Node.Action"):
|
|
306
|
+
detail = self.NodeActionDetail(
|
|
307
|
+
task_id=details["task_id"],
|
|
308
|
+
node_id=details["node_id"],
|
|
309
|
+
name=details["name"],
|
|
310
|
+
focus=details["focus"],
|
|
311
|
+
)
|
|
312
|
+
self.on_node_action(context, noti_type, detail)
|
|
313
|
+
|
|
314
|
+
else:
|
|
315
|
+
self.on_unknown_notification(context, msg, details)
|
maa/controller.py
CHANGED
|
@@ -6,7 +6,7 @@ from pathlib import Path
|
|
|
6
6
|
from typing import Any, Dict, Optional, Union
|
|
7
7
|
|
|
8
8
|
from .buffer import ImageBuffer, StringBuffer
|
|
9
|
-
from .
|
|
9
|
+
from .event_sink import EventSink, NotificationType
|
|
10
10
|
from .define import *
|
|
11
11
|
from .job import Job, JobWithResult
|
|
12
12
|
from .library import Library
|
|
@@ -20,7 +20,6 @@ __all__ = [
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
class Controller:
|
|
23
|
-
_notification_handler: Optional[NotificationHandler]
|
|
24
23
|
_handle: MaaControllerHandle
|
|
25
24
|
_own: bool
|
|
26
25
|
|
|
@@ -173,6 +172,27 @@ class Controller:
|
|
|
173
172
|
)
|
|
174
173
|
)
|
|
175
174
|
|
|
175
|
+
_sink_holder: Dict[int, "ControllerEventSink"] = {}
|
|
176
|
+
|
|
177
|
+
def add_sink(self, sink: "ControllerEventSink") -> Optional[int]:
|
|
178
|
+
sink_id = int(
|
|
179
|
+
Library.framework().MaaControllerAddSink(
|
|
180
|
+
self._handle, *EventSink._gen_c_param(sink)
|
|
181
|
+
)
|
|
182
|
+
)
|
|
183
|
+
if sink_id == MaaInvalidId:
|
|
184
|
+
return None
|
|
185
|
+
|
|
186
|
+
self._sink_holder[sink_id] = sink
|
|
187
|
+
return sink_id
|
|
188
|
+
|
|
189
|
+
def remove_sink(self, sink_id: int) -> None:
|
|
190
|
+
Library.framework().MaaControllerRemoveSink(self._handle, sink_id)
|
|
191
|
+
self._sink_holder.pop(sink_id)
|
|
192
|
+
|
|
193
|
+
def clear_sinks(self) -> None:
|
|
194
|
+
Library.framework().MaaControllerClearSinks(self._handle)
|
|
195
|
+
|
|
176
196
|
### private ###
|
|
177
197
|
|
|
178
198
|
def _status(self, maaid: int) -> MaaStatus:
|
|
@@ -319,6 +339,22 @@ class Controller:
|
|
|
319
339
|
MaaStringBufferHandle,
|
|
320
340
|
]
|
|
321
341
|
|
|
342
|
+
Library.framework().MaaControllerAddSink.restype = MaaSinkId
|
|
343
|
+
Library.framework().MaaControllerAddSink.argtypes = [
|
|
344
|
+
MaaControllerHandle,
|
|
345
|
+
MaaEventCallback,
|
|
346
|
+
ctypes.c_void_p,
|
|
347
|
+
]
|
|
348
|
+
|
|
349
|
+
Library.framework().MaaControllerRemoveSink.restype = None
|
|
350
|
+
Library.framework().MaaControllerRemoveSink.argtypes = [
|
|
351
|
+
MaaControllerHandle,
|
|
352
|
+
MaaSinkId,
|
|
353
|
+
]
|
|
354
|
+
|
|
355
|
+
Library.framework().MaaControllerClearSinks.restype = None
|
|
356
|
+
Library.framework().MaaControllerClearSinks.argtypes = [MaaControllerHandle]
|
|
357
|
+
|
|
322
358
|
|
|
323
359
|
class AdbController(Controller):
|
|
324
360
|
AGENT_BINARY_PATH = os.path.join(
|
|
@@ -334,13 +370,16 @@ class AdbController(Controller):
|
|
|
334
370
|
input_methods: int = MaaAdbInputMethodEnum.Default,
|
|
335
371
|
config: Dict[str, Any] = {},
|
|
336
372
|
agent_path: Union[str, Path] = AGENT_BINARY_PATH,
|
|
337
|
-
notification_handler:
|
|
373
|
+
notification_handler: None = None,
|
|
338
374
|
):
|
|
375
|
+
if notification_handler:
|
|
376
|
+
raise NotImplementedError(
|
|
377
|
+
"NotificationHandler is deprecated, use add_sink instead."
|
|
378
|
+
)
|
|
379
|
+
|
|
339
380
|
super().__init__()
|
|
340
381
|
self._set_adb_api_properties()
|
|
341
382
|
|
|
342
|
-
self._notification_handler = notification_handler
|
|
343
|
-
|
|
344
383
|
self._handle = Library.framework().MaaAdbControllerCreate(
|
|
345
384
|
str(adb_path).encode(),
|
|
346
385
|
address.encode(),
|
|
@@ -348,7 +387,6 @@ class AdbController(Controller):
|
|
|
348
387
|
MaaAdbInputMethod(input_methods),
|
|
349
388
|
json.dumps(config, ensure_ascii=False).encode(),
|
|
350
389
|
str(agent_path).encode(),
|
|
351
|
-
*NotificationHandler._gen_c_param(self._notification_handler)
|
|
352
390
|
)
|
|
353
391
|
|
|
354
392
|
if not self._handle:
|
|
@@ -364,8 +402,6 @@ class AdbController(Controller):
|
|
|
364
402
|
MaaAdbInputMethod,
|
|
365
403
|
ctypes.c_char_p,
|
|
366
404
|
ctypes.c_char_p,
|
|
367
|
-
MaaNotificationCallback,
|
|
368
|
-
ctypes.c_void_p,
|
|
369
405
|
]
|
|
370
406
|
|
|
371
407
|
|
|
@@ -376,17 +412,20 @@ class Win32Controller(Controller):
|
|
|
376
412
|
hWnd: Union[ctypes.c_void_p, int, None],
|
|
377
413
|
screencap_method: int = MaaWin32ScreencapMethodEnum.DXGI_DesktopDup,
|
|
378
414
|
input_method: int = MaaWin32InputMethodEnum.Seize,
|
|
379
|
-
notification_handler:
|
|
415
|
+
notification_handler: None = None,
|
|
380
416
|
):
|
|
417
|
+
if notification_handler:
|
|
418
|
+
raise NotImplementedError(
|
|
419
|
+
"NotificationHandler is deprecated, use add_sink instead."
|
|
420
|
+
)
|
|
421
|
+
|
|
381
422
|
super().__init__()
|
|
382
423
|
self._set_win32_api_properties()
|
|
383
424
|
|
|
384
|
-
self._notification_handler = notification_handler
|
|
385
425
|
self._handle = Library.framework().MaaWin32ControllerCreate(
|
|
386
426
|
hWnd,
|
|
387
427
|
MaaWin32ScreencapMethod(screencap_method),
|
|
388
428
|
MaaWin32InputMethod(input_method),
|
|
389
|
-
*NotificationHandler._gen_c_param(self._notification_handler)
|
|
390
429
|
)
|
|
391
430
|
|
|
392
431
|
if not self._handle:
|
|
@@ -398,8 +437,6 @@ class Win32Controller(Controller):
|
|
|
398
437
|
ctypes.c_void_p,
|
|
399
438
|
MaaWin32ScreencapMethod,
|
|
400
439
|
MaaWin32InputMethod,
|
|
401
|
-
MaaNotificationCallback,
|
|
402
|
-
ctypes.c_void_p,
|
|
403
440
|
]
|
|
404
441
|
|
|
405
442
|
|
|
@@ -411,18 +448,21 @@ class DbgController(Controller):
|
|
|
411
448
|
write_path: Union[str, Path],
|
|
412
449
|
dbg_type: int,
|
|
413
450
|
config: Dict[str, Any] = {},
|
|
414
|
-
notification_handler:
|
|
451
|
+
notification_handler: None = None,
|
|
415
452
|
):
|
|
453
|
+
if notification_handler:
|
|
454
|
+
raise NotImplementedError(
|
|
455
|
+
"NotificationHandler is deprecated, use add_sink instead."
|
|
456
|
+
)
|
|
457
|
+
|
|
416
458
|
super().__init__()
|
|
417
459
|
self._set_dbg_api_properties()
|
|
418
460
|
|
|
419
|
-
self._notification_handler = notification_handler
|
|
420
461
|
self._handle = Library.framework().MaaDbgControllerCreate(
|
|
421
462
|
str(read_path).encode(),
|
|
422
463
|
str(write_path).encode(),
|
|
423
464
|
MaaDbgControllerType(dbg_type),
|
|
424
465
|
json.dumps(config, ensure_ascii=False).encode(),
|
|
425
|
-
*NotificationHandler._gen_c_param(self._notification_handler)
|
|
426
466
|
)
|
|
427
467
|
|
|
428
468
|
if not self._handle:
|
|
@@ -435,8 +475,6 @@ class DbgController(Controller):
|
|
|
435
475
|
ctypes.c_char_p,
|
|
436
476
|
MaaDbgControllerType,
|
|
437
477
|
ctypes.c_char_p,
|
|
438
|
-
MaaNotificationCallback,
|
|
439
|
-
ctypes.c_void_p,
|
|
440
478
|
]
|
|
441
479
|
|
|
442
480
|
|
|
@@ -446,13 +484,16 @@ class CustomController(Controller):
|
|
|
446
484
|
|
|
447
485
|
def __init__(
|
|
448
486
|
self,
|
|
449
|
-
notification_handler:
|
|
487
|
+
notification_handler: None = None,
|
|
450
488
|
):
|
|
489
|
+
if notification_handler:
|
|
490
|
+
raise NotImplementedError(
|
|
491
|
+
"NotificationHandler is deprecated, use add_sink instead."
|
|
492
|
+
)
|
|
493
|
+
|
|
451
494
|
super().__init__()
|
|
452
495
|
self._set_custom_api_properties()
|
|
453
496
|
|
|
454
|
-
self._notification_handler = notification_handler
|
|
455
|
-
|
|
456
497
|
self._callbacks = MaaCustomControllerCallbacks(
|
|
457
498
|
CustomController._c_connect_agent,
|
|
458
499
|
CustomController._c_request_uuid_agent,
|
|
@@ -473,7 +514,6 @@ class CustomController(Controller):
|
|
|
473
514
|
self._handle = Library.framework().MaaCustomControllerCreate(
|
|
474
515
|
self.c_handle,
|
|
475
516
|
self.c_arg,
|
|
476
|
-
*NotificationHandler._gen_c_param(self._notification_handler)
|
|
477
517
|
)
|
|
478
518
|
|
|
479
519
|
if not self._handle:
|
|
@@ -805,6 +845,39 @@ class CustomController(Controller):
|
|
|
805
845
|
Library.framework().MaaCustomControllerCreate.argtypes = [
|
|
806
846
|
ctypes.POINTER(MaaCustomControllerCallbacks),
|
|
807
847
|
ctypes.c_void_p,
|
|
808
|
-
MaaNotificationCallback,
|
|
809
|
-
ctypes.c_void_p,
|
|
810
848
|
]
|
|
849
|
+
|
|
850
|
+
|
|
851
|
+
class ControllerEventSink(EventSink):
|
|
852
|
+
|
|
853
|
+
@dataclass
|
|
854
|
+
class ControllerActionDetail:
|
|
855
|
+
ctrl_id: int
|
|
856
|
+
uuid: str
|
|
857
|
+
action: str
|
|
858
|
+
param: dict
|
|
859
|
+
|
|
860
|
+
def on_controller_action(
|
|
861
|
+
self,
|
|
862
|
+
controller: Controller,
|
|
863
|
+
noti_type: NotificationType,
|
|
864
|
+
detail: ControllerActionDetail,
|
|
865
|
+
):
|
|
866
|
+
pass
|
|
867
|
+
|
|
868
|
+
def on_raw_notification(self, handle: ctypes.c_void_p, msg: str, details: dict):
|
|
869
|
+
|
|
870
|
+
controller = Controller(handle=handle)
|
|
871
|
+
noti_type = EventSink._notification_type(msg)
|
|
872
|
+
|
|
873
|
+
if msg.startswith("Controller.Action"):
|
|
874
|
+
detail = self.ControllerActionDetail(
|
|
875
|
+
ctrl_id=details["ctrl_id"],
|
|
876
|
+
uuid=details["uuid"],
|
|
877
|
+
action=details["action"],
|
|
878
|
+
param=details["param"],
|
|
879
|
+
)
|
|
880
|
+
self.on_controller_action(controller, noti_type, detail)
|
|
881
|
+
|
|
882
|
+
else:
|
|
883
|
+
self.on_unknown_notification(controller, msg, details)
|
maa/define.py
CHANGED
|
@@ -17,6 +17,7 @@ MaaResId = MaaId
|
|
|
17
17
|
MaaTaskId = MaaId
|
|
18
18
|
MaaRecoId = MaaId
|
|
19
19
|
MaaNodeId = MaaId
|
|
20
|
+
MaaSinkId = MaaId
|
|
20
21
|
MaaInvalidId = MaaId(0)
|
|
21
22
|
|
|
22
23
|
MaaStringBufferHandle = ctypes.c_void_p
|
|
@@ -240,8 +241,8 @@ class MaaDbgControllerTypeEnum(IntEnum):
|
|
|
240
241
|
|
|
241
242
|
FUNCTYPE = ctypes.WINFUNCTYPE if (platform.system() == "Windows") else ctypes.CFUNCTYPE
|
|
242
243
|
|
|
243
|
-
|
|
244
|
-
None, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_void_p
|
|
244
|
+
MaaEventCallback = FUNCTYPE(
|
|
245
|
+
None, ctypes.c_void_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_void_p
|
|
245
246
|
)
|
|
246
247
|
|
|
247
248
|
MaaCustomRecognitionCallback = FUNCTYPE(
|
maa/event_sink.py
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import ctypes
|
|
2
|
+
import json
|
|
3
|
+
from abc import ABC
|
|
4
|
+
from typing import Optional, Tuple, Any
|
|
5
|
+
from enum import IntEnum
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
|
|
8
|
+
from .define import MaaEventCallback
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# class NotificationEvent(IntEnum):
|
|
12
|
+
# ResourceLoading = 1
|
|
13
|
+
# ControllerAction = 2
|
|
14
|
+
# TaskerTask = 3
|
|
15
|
+
# TaskNextList = 4
|
|
16
|
+
# TaskRecognition = 5
|
|
17
|
+
# TaskAction = 6
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class NotificationType(IntEnum):
|
|
21
|
+
Unknown = 0
|
|
22
|
+
Starting = 1
|
|
23
|
+
Succeeded = 2
|
|
24
|
+
Failed = 3
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class EventSink(ABC):
|
|
28
|
+
def on_unknown_notification(self, instance, msg: str, details: dict):
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
def on_raw_notification(self, handle: ctypes.c_void_p, msg: str, details: dict):
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def c_callback(self) -> MaaEventCallback:
|
|
36
|
+
return self._c_sink_agent
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def c_callback_arg(self) -> ctypes.c_void_p:
|
|
40
|
+
return ctypes.c_void_p.from_buffer(ctypes.py_object(self))
|
|
41
|
+
|
|
42
|
+
@staticmethod
|
|
43
|
+
def _gen_c_param(
|
|
44
|
+
sink: "EventSink",
|
|
45
|
+
) -> Tuple[MaaEventCallback, ctypes.c_void_p]:
|
|
46
|
+
return sink.c_callback, sink.c_callback_arg
|
|
47
|
+
|
|
48
|
+
@staticmethod
|
|
49
|
+
def _notification_type(message: str) -> NotificationType:
|
|
50
|
+
if message.endswith(".Starting"):
|
|
51
|
+
return NotificationType.Starting
|
|
52
|
+
elif message.endswith(".Succeeded"):
|
|
53
|
+
return NotificationType.Succeeded
|
|
54
|
+
elif message.endswith(".Failed"):
|
|
55
|
+
return NotificationType.Failed
|
|
56
|
+
else:
|
|
57
|
+
return NotificationType.Unknown
|
|
58
|
+
|
|
59
|
+
@staticmethod
|
|
60
|
+
@MaaEventCallback
|
|
61
|
+
def _c_sink_agent(
|
|
62
|
+
handle: ctypes.c_void_p,
|
|
63
|
+
msg: ctypes.c_char_p,
|
|
64
|
+
details_json: ctypes.c_char_p,
|
|
65
|
+
callback_arg: ctypes.c_void_p,
|
|
66
|
+
):
|
|
67
|
+
if not callback_arg:
|
|
68
|
+
return
|
|
69
|
+
|
|
70
|
+
self: EventSink = ctypes.cast(callback_arg, ctypes.py_object).value
|
|
71
|
+
|
|
72
|
+
self.on_raw_notification(
|
|
73
|
+
handle, msg.decode(), json.loads(details_json.decode())
|
|
74
|
+
)
|