MaaFw 2.1.0__py3-none-manylinux2014_x86_64.whl → 5.4.0b1__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.
- maa/__init__.py +7 -5
- maa/agent/__init__.py +12 -0
- maa/agent/agent_server.py +350 -0
- maa/agent_client.py +291 -0
- 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/libMaaFramework.so +0 -0
- maa/bin/libMaaToolkit.so +0 -0
- maa/bin/libMaaUtils.so +0 -0
- maa/bin/libc++.so.1 +0 -0
- maa/bin/libc++abi.so.1 +0 -0
- maa/bin/libfastdeploy_ppocr.so +0 -0
- maa/bin/{libopencv_world4.so.408 → libonnxruntime.so.1} +0 -0
- maa/bin/{libonnxruntime.so.1.18.0 → libopencv_world4.so.411} +0 -0
- maa/bin/libunwind.so.1 +0 -0
- maa/bin/plugins/libMaaPluginDemo.so +0 -0
- maa/buffer.py +297 -153
- maa/context.py +449 -34
- maa/controller.py +760 -113
- maa/custom_action.py +46 -3
- maa/custom_recognition.py +69 -11
- maa/define.py +539 -42
- maa/event_sink.py +103 -0
- maa/job.py +95 -36
- maa/library.py +182 -53
- maa/pipeline.py +509 -0
- maa/resource.py +598 -71
- maa/tasker.py +696 -156
- maa/toolkit.py +125 -165
- maafw-5.4.0b1.dist-info/METADATA +297 -0
- maafw-5.4.0b1.dist-info/RECORD +35 -0
- maafw-5.4.0b1.dist-info/WHEEL +4 -0
- MaaFw-2.1.0.dist-info/METADATA +0 -166
- MaaFw-2.1.0.dist-info/RECORD +0 -26
- MaaFw-2.1.0.dist-info/WHEEL +0 -4
- MaaFw-2.1.0.dist-info/top_level.txt +0 -1
- maa/bin/libMaaDbgControlUnit.so +0 -0
- maa/notification_handler.py +0 -191
- {MaaFw-2.1.0.dist-info → maafw-5.4.0b1.dist-info/licenses}/LICENSE.md +0 -0
maa/context.py
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import ctypes
|
|
2
2
|
import json
|
|
3
|
-
from
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any, Dict, Optional, Tuple
|
|
4
5
|
|
|
5
6
|
import numpy
|
|
6
7
|
|
|
7
|
-
from .
|
|
8
|
+
from .event_sink import EventSink, NotificationType
|
|
9
|
+
from .buffer import ImageBuffer, RectBuffer, StringBuffer, StringListBuffer
|
|
8
10
|
from .define import *
|
|
9
11
|
from .library import Library
|
|
10
12
|
from .tasker import Tasker
|
|
13
|
+
from .pipeline import JPipelineData, JPipelineParser, JNodeAttr
|
|
11
14
|
from .job import JobWithResult
|
|
12
15
|
|
|
13
16
|
|
|
@@ -29,11 +32,20 @@ class Context:
|
|
|
29
32
|
def __del__(self):
|
|
30
33
|
pass
|
|
31
34
|
|
|
32
|
-
def
|
|
35
|
+
def run_task(
|
|
33
36
|
self, entry: str, pipeline_override: Dict = {}
|
|
34
37
|
) -> Optional[TaskDetail]:
|
|
38
|
+
"""同步执行任务 / Synchronously execute task
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
entry: 任务入口 / Task entry
|
|
42
|
+
pipeline_override: 用于覆盖的 json / JSON for overriding
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
Optional[TaskDetail]: 任务详情,执行失败则返回 None / Task detail, or None if execution failed
|
|
46
|
+
"""
|
|
35
47
|
task_id = int(
|
|
36
|
-
Library.framework.
|
|
48
|
+
Library.framework().MaaContextRunTask(
|
|
37
49
|
self._handle, *Context._gen_post_param(entry, pipeline_override)
|
|
38
50
|
)
|
|
39
51
|
)
|
|
@@ -43,12 +55,32 @@ class Context:
|
|
|
43
55
|
return self.tasker.get_task_detail(task_id)
|
|
44
56
|
|
|
45
57
|
def run_recognition(
|
|
46
|
-
self,
|
|
58
|
+
self,
|
|
59
|
+
entry: str,
|
|
60
|
+
image: numpy.ndarray,
|
|
61
|
+
pipeline_override: Dict = {},
|
|
47
62
|
) -> Optional[RecognitionDetail]:
|
|
63
|
+
"""同步执行识别逻辑 / Synchronously execute recognition logic
|
|
64
|
+
|
|
65
|
+
不会执行后续操作, 不会执行后续 next
|
|
66
|
+
Will not execute subsequent operations or next steps
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
entry: 任务名 / Task name
|
|
70
|
+
image: 前序截图 / Previous screenshot
|
|
71
|
+
pipeline_override: 用于覆盖的 json / JSON for overriding
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
Optional[RecognitionDetail]: 识别结果。无论是否命中,只要尝试进行了识别,就会返回;
|
|
75
|
+
请通过 RecognitionDetail.hit 判断是否命中。只在未能启动识别流程时(如 entry 不存在、node disabled、image 为空等),才可能返回 None。
|
|
76
|
+
Recognition detail. It always returns as long as recognition was attempted;
|
|
77
|
+
use RecognitionDetail.hit to determine hit. Only return None if the recognition process fails to start
|
|
78
|
+
(e.g., entry does not exist, node is disabled, image is empty).
|
|
79
|
+
"""
|
|
48
80
|
image_buffer = ImageBuffer()
|
|
49
81
|
image_buffer.set(image)
|
|
50
82
|
reco_id = int(
|
|
51
|
-
Library.framework.MaaContextRunRecognition(
|
|
83
|
+
Library.framework().MaaContextRunRecognition(
|
|
52
84
|
self._handle,
|
|
53
85
|
*Context._gen_post_param(entry, pipeline_override),
|
|
54
86
|
image_buffer._handle
|
|
@@ -65,12 +97,30 @@ class Context:
|
|
|
65
97
|
box: RectType = (0, 0, 0, 0),
|
|
66
98
|
reco_detail: str = "",
|
|
67
99
|
pipeline_override: Dict = {},
|
|
68
|
-
) -> Optional[
|
|
100
|
+
) -> Optional[ActionDetail]:
|
|
101
|
+
"""同步执行操作逻辑 / Synchronously execute action logic
|
|
102
|
+
|
|
103
|
+
不会执行后续 next
|
|
104
|
+
Will not execute subsequent next steps
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
entry: 任务名 / Task name
|
|
108
|
+
box: 前序识别位置 / Previous recognition position
|
|
109
|
+
reco_detail: 前序识别详情 / Previous recognition details
|
|
110
|
+
pipeline_override: 用于覆盖的 json / JSON for overriding
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
Optional[ActionDetail]: 操作结果。无论动作是否成功,只要尝试执行了动作,就会返回;
|
|
114
|
+
请通过 ActionDetail.success 判断是否执行成功。只在未能启动动作流程时(如 entry 不存在、node disabled 等),才可能返回 None。
|
|
115
|
+
Action detail. It always returns as long as the action was attempted;
|
|
116
|
+
use ActionDetail.success to determine success. Only return None if the action flow fails to start
|
|
117
|
+
(e.g., entry does not exist, node is disabled, etc.).
|
|
118
|
+
"""
|
|
69
119
|
rect = RectBuffer()
|
|
70
120
|
rect.set(box)
|
|
71
121
|
|
|
72
|
-
|
|
73
|
-
Library.framework.MaaContextRunAction(
|
|
122
|
+
act_id = int(
|
|
123
|
+
Library.framework().MaaContextRunAction(
|
|
74
124
|
self._handle,
|
|
75
125
|
*Context._gen_post_param(entry, pipeline_override),
|
|
76
126
|
rect._handle,
|
|
@@ -78,60 +128,228 @@ class Context:
|
|
|
78
128
|
)
|
|
79
129
|
)
|
|
80
130
|
|
|
81
|
-
if not
|
|
131
|
+
if not act_id:
|
|
82
132
|
return None
|
|
83
133
|
|
|
84
|
-
return self.tasker.
|
|
134
|
+
return self.tasker.get_action_detail(act_id)
|
|
85
135
|
|
|
86
136
|
def override_pipeline(self, pipeline_override: Dict) -> bool:
|
|
137
|
+
"""覆盖 pipeline / Override pipeline_override
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
pipeline_override: 用于覆盖的 json / JSON for overriding
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
bool: 是否成功 / Whether successful
|
|
144
|
+
"""
|
|
145
|
+
pipeline_json = json.dumps(pipeline_override, ensure_ascii=False)
|
|
146
|
+
|
|
87
147
|
return bool(
|
|
88
|
-
Library.framework.MaaContextOverridePipeline(
|
|
148
|
+
Library.framework().MaaContextOverridePipeline(
|
|
89
149
|
self._handle,
|
|
90
|
-
|
|
150
|
+
pipeline_json.encode(),
|
|
91
151
|
)
|
|
92
152
|
)
|
|
93
153
|
|
|
94
154
|
def override_next(self, name: str, next_list: List[str]) -> bool:
|
|
155
|
+
"""覆盖任务的 next 列表 / Override the next list of task
|
|
156
|
+
|
|
157
|
+
如果节点不存在,此方法会失败
|
|
158
|
+
This method will fail if the node does not exist
|
|
159
|
+
|
|
160
|
+
Args:
|
|
161
|
+
name: 任务名 / Task name
|
|
162
|
+
next_list: next 列表 / Next list
|
|
163
|
+
|
|
164
|
+
Returns:
|
|
165
|
+
bool: 成功返回 True,如果节点不存在则返回 False / Returns True on success, False if node does not exist
|
|
166
|
+
"""
|
|
95
167
|
list_buffer = StringListBuffer()
|
|
96
168
|
list_buffer.set(next_list)
|
|
97
169
|
|
|
98
170
|
return bool(
|
|
99
|
-
Library.framework.MaaContextOverrideNext(
|
|
171
|
+
Library.framework().MaaContextOverrideNext(
|
|
100
172
|
self._handle, name.encode(), list_buffer._handle
|
|
101
173
|
)
|
|
102
174
|
)
|
|
103
175
|
|
|
176
|
+
def override_image(self, image_name: str, image: numpy.ndarray) -> bool:
|
|
177
|
+
"""覆盖图片 / Override the image corresponding to image_name
|
|
178
|
+
|
|
179
|
+
Args:
|
|
180
|
+
image_name: 图片名 / Image name
|
|
181
|
+
image: 图片数据 / Image data
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
bool: 是否成功 / Whether successful
|
|
185
|
+
"""
|
|
186
|
+
image_buffer = ImageBuffer()
|
|
187
|
+
image_buffer.set(image)
|
|
188
|
+
|
|
189
|
+
return bool(
|
|
190
|
+
Library.framework().MaaContextOverrideImage(
|
|
191
|
+
self._handle, image_name.encode(), image_buffer._handle
|
|
192
|
+
)
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
def get_node_data(self, name: str) -> Optional[Dict]:
|
|
196
|
+
"""获取任务当前的定义 / Get the current definition of task
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
name: 任务名 / Task name
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
Optional[Dict]: 任务定义字典,如果不存在则返回 None / Task definition dict, or None if not exists
|
|
203
|
+
"""
|
|
204
|
+
string_buffer = StringBuffer()
|
|
205
|
+
if not Library.framework().MaaContextGetNodeData(
|
|
206
|
+
self._handle, name.encode(), string_buffer._handle
|
|
207
|
+
):
|
|
208
|
+
return None
|
|
209
|
+
|
|
210
|
+
data = string_buffer.get()
|
|
211
|
+
if not data:
|
|
212
|
+
return None
|
|
213
|
+
|
|
214
|
+
try:
|
|
215
|
+
return json.loads(data)
|
|
216
|
+
except json.JSONDecodeError:
|
|
217
|
+
return None
|
|
218
|
+
|
|
219
|
+
def get_node_object(self, name: str) -> Optional[JPipelineData]:
|
|
220
|
+
"""获取任务当前的定义(解析为对象) / Get the current definition of task (parsed as object)
|
|
221
|
+
|
|
222
|
+
Args:
|
|
223
|
+
name: 任务名 / Task name
|
|
224
|
+
|
|
225
|
+
Returns:
|
|
226
|
+
Optional[JPipelineData]: 任务定义对象,如果不存在则返回 None / Task definition object, or None if not exists
|
|
227
|
+
"""
|
|
228
|
+
node_data = self.get_node_data(name)
|
|
229
|
+
|
|
230
|
+
if not node_data:
|
|
231
|
+
return None
|
|
232
|
+
|
|
233
|
+
return JPipelineParser.parse_pipeline_data(node_data)
|
|
234
|
+
|
|
104
235
|
@property
|
|
105
236
|
def tasker(self) -> Tasker:
|
|
237
|
+
"""获取实例 / Get instance
|
|
238
|
+
|
|
239
|
+
Returns:
|
|
240
|
+
Tasker: 实例对象 / Instance object
|
|
241
|
+
"""
|
|
106
242
|
return self._tasker
|
|
107
243
|
|
|
108
244
|
def get_task_job(self) -> JobWithResult:
|
|
109
|
-
|
|
245
|
+
"""获取对应任务号的任务作业 / Get task job for corresponding task id
|
|
246
|
+
|
|
247
|
+
Returns:
|
|
248
|
+
JobWithResult: 任务作业对象 / Task job object
|
|
249
|
+
|
|
250
|
+
Raises:
|
|
251
|
+
ValueError: 如果任务 id 为 None
|
|
252
|
+
"""
|
|
253
|
+
task_id = Library.framework().MaaContextGetTaskId(self._handle)
|
|
110
254
|
if not task_id:
|
|
111
255
|
raise ValueError("task_id is None")
|
|
112
256
|
|
|
113
257
|
return self.tasker._gen_task_job(task_id)
|
|
114
258
|
|
|
115
259
|
def clone(self) -> "Context":
|
|
116
|
-
|
|
260
|
+
"""复制上下文 / Clone context
|
|
261
|
+
|
|
262
|
+
Returns:
|
|
263
|
+
Context: 复制的上下文对象 / Cloned context object
|
|
264
|
+
|
|
265
|
+
Raises:
|
|
266
|
+
ValueError: 如果克隆失败
|
|
267
|
+
"""
|
|
268
|
+
cloned_handle = Library.framework().MaaContextClone(self._handle)
|
|
117
269
|
if not cloned_handle:
|
|
118
270
|
raise ValueError("cloned_handle is None")
|
|
119
271
|
|
|
120
272
|
return Context(cloned_handle)
|
|
121
273
|
|
|
274
|
+
def set_anchor(self, anchor_name: str, node_name: str) -> bool:
|
|
275
|
+
"""设置锚点 / Set anchor
|
|
276
|
+
|
|
277
|
+
Args:
|
|
278
|
+
anchor_name: 锚点名称 / Anchor name
|
|
279
|
+
node_name: 节点名称 / Node name
|
|
280
|
+
|
|
281
|
+
Returns:
|
|
282
|
+
bool: 是否成功 / Whether successful
|
|
283
|
+
"""
|
|
284
|
+
return bool(
|
|
285
|
+
Library.framework().MaaContextSetAnchor(
|
|
286
|
+
self._handle, anchor_name.encode(), node_name.encode()
|
|
287
|
+
)
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
def get_anchor(self, anchor_name: str) -> Optional[str]:
|
|
291
|
+
"""获取锚点对应的节点名 / Get node name for anchor
|
|
292
|
+
|
|
293
|
+
Args:
|
|
294
|
+
anchor_name: 锚点名称 / Anchor name
|
|
295
|
+
|
|
296
|
+
Returns:
|
|
297
|
+
Optional[str]: 节点名称,如果不存在则返回 None / Node name, or None if not exists
|
|
298
|
+
"""
|
|
299
|
+
string_buffer = StringBuffer()
|
|
300
|
+
if not Library.framework().MaaContextGetAnchor(
|
|
301
|
+
self._handle, anchor_name.encode(), string_buffer._handle
|
|
302
|
+
):
|
|
303
|
+
return None
|
|
304
|
+
|
|
305
|
+
return string_buffer.get()
|
|
306
|
+
|
|
307
|
+
def get_hit_count(self, node_name: str) -> int:
|
|
308
|
+
"""获取节点命中计数 / Get hit count for node
|
|
309
|
+
|
|
310
|
+
Args:
|
|
311
|
+
node_name: 节点名称 / Node name
|
|
312
|
+
|
|
313
|
+
Returns:
|
|
314
|
+
int: 命中计数 / Hit count
|
|
315
|
+
"""
|
|
316
|
+
count = ctypes.c_uint64()
|
|
317
|
+
if not Library.framework().MaaContextGetHitCount(
|
|
318
|
+
self._handle, node_name.encode(), ctypes.byref(count)
|
|
319
|
+
):
|
|
320
|
+
return 0
|
|
321
|
+
return count.value
|
|
322
|
+
|
|
323
|
+
def clear_hit_count(self, node_name: str) -> bool:
|
|
324
|
+
"""清除节点命中计数 / Clear hit count for node
|
|
325
|
+
|
|
326
|
+
Args:
|
|
327
|
+
node_name: 节点名称 / Node name
|
|
328
|
+
|
|
329
|
+
Returns:
|
|
330
|
+
bool: 是否成功 / Whether successful
|
|
331
|
+
"""
|
|
332
|
+
return bool(
|
|
333
|
+
Library.framework().MaaContextClearHitCount(
|
|
334
|
+
self._handle, node_name.encode()
|
|
335
|
+
)
|
|
336
|
+
)
|
|
337
|
+
|
|
122
338
|
### private ###
|
|
123
339
|
|
|
124
340
|
def _init_tasker(self):
|
|
125
|
-
tasker_handle = Library.framework.MaaContextGetTasker(self._handle)
|
|
341
|
+
tasker_handle = Library.framework().MaaContextGetTasker(self._handle)
|
|
126
342
|
if not tasker_handle:
|
|
127
343
|
raise ValueError("tasker_handle is None")
|
|
128
344
|
self._tasker = Tasker(handle=tasker_handle)
|
|
129
345
|
|
|
130
346
|
@staticmethod
|
|
131
347
|
def _gen_post_param(entry: str, pipeline_override: Dict) -> Tuple[bytes, bytes]:
|
|
348
|
+
pipeline_json = json.dumps(pipeline_override, ensure_ascii=False)
|
|
349
|
+
|
|
132
350
|
return (
|
|
133
351
|
entry.encode(),
|
|
134
|
-
|
|
352
|
+
pipeline_json.encode(),
|
|
135
353
|
)
|
|
136
354
|
|
|
137
355
|
_api_properties_initialized: bool = False
|
|
@@ -143,23 +361,23 @@ class Context:
|
|
|
143
361
|
|
|
144
362
|
Context._api_properties_initialized = True
|
|
145
363
|
|
|
146
|
-
Library.framework.
|
|
147
|
-
Library.framework.
|
|
364
|
+
Library.framework().MaaContextRunTask.restype = MaaTaskId
|
|
365
|
+
Library.framework().MaaContextRunTask.argtypes = [
|
|
148
366
|
MaaContextHandle,
|
|
149
367
|
ctypes.c_char_p,
|
|
150
368
|
ctypes.c_char_p,
|
|
151
369
|
]
|
|
152
370
|
|
|
153
|
-
Library.framework.MaaContextRunRecognition.restype = MaaRecoId
|
|
154
|
-
Library.framework.MaaContextRunRecognition.argtypes = [
|
|
371
|
+
Library.framework().MaaContextRunRecognition.restype = MaaRecoId
|
|
372
|
+
Library.framework().MaaContextRunRecognition.argtypes = [
|
|
155
373
|
MaaContextHandle,
|
|
156
374
|
ctypes.c_char_p,
|
|
157
375
|
ctypes.c_char_p,
|
|
158
376
|
MaaImageBufferHandle,
|
|
159
377
|
]
|
|
160
378
|
|
|
161
|
-
Library.framework.MaaContextRunAction.restype =
|
|
162
|
-
Library.framework.MaaContextRunAction.argtypes = [
|
|
379
|
+
Library.framework().MaaContextRunAction.restype = MaaActId
|
|
380
|
+
Library.framework().MaaContextRunAction.argtypes = [
|
|
163
381
|
MaaContextHandle,
|
|
164
382
|
ctypes.c_char_p,
|
|
165
383
|
ctypes.c_char_p,
|
|
@@ -167,30 +385,227 @@ class Context:
|
|
|
167
385
|
MaaStringBufferHandle,
|
|
168
386
|
]
|
|
169
387
|
|
|
170
|
-
Library.framework.MaaContextOverridePipeline.restype = MaaBool
|
|
171
|
-
Library.framework.MaaContextOverridePipeline.argtypes = [
|
|
388
|
+
Library.framework().MaaContextOverridePipeline.restype = MaaBool
|
|
389
|
+
Library.framework().MaaContextOverridePipeline.argtypes = [
|
|
172
390
|
MaaContextHandle,
|
|
173
391
|
ctypes.c_char_p,
|
|
174
392
|
]
|
|
175
393
|
|
|
176
|
-
Library.framework.MaaContextOverrideNext.restype = MaaBool
|
|
177
|
-
Library.framework.MaaContextOverrideNext.argtypes = [
|
|
394
|
+
Library.framework().MaaContextOverrideNext.restype = MaaBool
|
|
395
|
+
Library.framework().MaaContextOverrideNext.argtypes = [
|
|
396
|
+
MaaContextHandle,
|
|
397
|
+
ctypes.c_char_p,
|
|
398
|
+
MaaStringListBufferHandle,
|
|
399
|
+
]
|
|
400
|
+
|
|
401
|
+
Library.framework().MaaContextOverrideImage.restype = MaaBool
|
|
402
|
+
Library.framework().MaaContextOverrideImage.argtypes = [
|
|
403
|
+
MaaContextHandle,
|
|
404
|
+
ctypes.c_char_p,
|
|
405
|
+
MaaImageBufferHandle,
|
|
406
|
+
]
|
|
407
|
+
|
|
408
|
+
Library.framework().MaaContextGetNodeData.restype = MaaBool
|
|
409
|
+
Library.framework().MaaContextGetNodeData.argtypes = [
|
|
178
410
|
MaaContextHandle,
|
|
179
411
|
ctypes.c_char_p,
|
|
180
412
|
MaaStringBufferHandle,
|
|
181
413
|
]
|
|
182
414
|
|
|
183
|
-
Library.framework.MaaContextGetTaskId.restype = MaaTaskId
|
|
184
|
-
Library.framework.MaaContextGetTaskId.argtypes = [
|
|
415
|
+
Library.framework().MaaContextGetTaskId.restype = MaaTaskId
|
|
416
|
+
Library.framework().MaaContextGetTaskId.argtypes = [
|
|
417
|
+
MaaContextHandle,
|
|
418
|
+
]
|
|
419
|
+
|
|
420
|
+
Library.framework().MaaContextGetTasker.restype = MaaTaskerHandle
|
|
421
|
+
Library.framework().MaaContextGetTasker.argtypes = [
|
|
185
422
|
MaaContextHandle,
|
|
186
423
|
]
|
|
187
424
|
|
|
188
|
-
Library.framework.
|
|
189
|
-
Library.framework.
|
|
425
|
+
Library.framework().MaaContextClone.restype = MaaContextHandle
|
|
426
|
+
Library.framework().MaaContextClone.argtypes = [
|
|
190
427
|
MaaContextHandle,
|
|
191
428
|
]
|
|
192
429
|
|
|
193
|
-
Library.framework.
|
|
194
|
-
Library.framework.
|
|
430
|
+
Library.framework().MaaContextSetAnchor.restype = MaaBool
|
|
431
|
+
Library.framework().MaaContextSetAnchor.argtypes = [
|
|
195
432
|
MaaContextHandle,
|
|
433
|
+
ctypes.c_char_p,
|
|
434
|
+
ctypes.c_char_p,
|
|
196
435
|
]
|
|
436
|
+
|
|
437
|
+
Library.framework().MaaContextGetAnchor.restype = MaaBool
|
|
438
|
+
Library.framework().MaaContextGetAnchor.argtypes = [
|
|
439
|
+
MaaContextHandle,
|
|
440
|
+
ctypes.c_char_p,
|
|
441
|
+
MaaStringBufferHandle,
|
|
442
|
+
]
|
|
443
|
+
|
|
444
|
+
Library.framework().MaaContextGetHitCount.restype = MaaBool
|
|
445
|
+
Library.framework().MaaContextGetHitCount.argtypes = [
|
|
446
|
+
MaaContextHandle,
|
|
447
|
+
ctypes.c_char_p,
|
|
448
|
+
ctypes.POINTER(ctypes.c_uint64),
|
|
449
|
+
]
|
|
450
|
+
|
|
451
|
+
Library.framework().MaaContextClearHitCount.restype = MaaBool
|
|
452
|
+
Library.framework().MaaContextClearHitCount.argtypes = [
|
|
453
|
+
MaaContextHandle,
|
|
454
|
+
ctypes.c_char_p,
|
|
455
|
+
]
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
class ContextEventSink(EventSink):
|
|
459
|
+
@dataclass
|
|
460
|
+
class NodeNextListDetail:
|
|
461
|
+
task_id: int
|
|
462
|
+
name: str
|
|
463
|
+
next_list: list[JNodeAttr]
|
|
464
|
+
focus: Any
|
|
465
|
+
|
|
466
|
+
def on_node_next_list(
|
|
467
|
+
self,
|
|
468
|
+
context: Context,
|
|
469
|
+
noti_type: NotificationType,
|
|
470
|
+
detail: NodeNextListDetail,
|
|
471
|
+
):
|
|
472
|
+
pass
|
|
473
|
+
|
|
474
|
+
@dataclass
|
|
475
|
+
class NodeRecognitionDetail:
|
|
476
|
+
task_id: int
|
|
477
|
+
reco_id: int
|
|
478
|
+
name: str
|
|
479
|
+
focus: Any
|
|
480
|
+
|
|
481
|
+
def on_node_recognition(
|
|
482
|
+
self,
|
|
483
|
+
context: Context,
|
|
484
|
+
noti_type: NotificationType,
|
|
485
|
+
detail: NodeRecognitionDetail,
|
|
486
|
+
):
|
|
487
|
+
pass
|
|
488
|
+
|
|
489
|
+
@dataclass
|
|
490
|
+
class NodeActionDetail:
|
|
491
|
+
task_id: int
|
|
492
|
+
action_id: int
|
|
493
|
+
name: str
|
|
494
|
+
focus: Any
|
|
495
|
+
|
|
496
|
+
def on_node_action(
|
|
497
|
+
self, context: Context, noti_type: NotificationType, detail: NodeActionDetail
|
|
498
|
+
):
|
|
499
|
+
pass
|
|
500
|
+
|
|
501
|
+
@dataclass
|
|
502
|
+
class NodePipelineNodeDetail:
|
|
503
|
+
task_id: int
|
|
504
|
+
node_id: int
|
|
505
|
+
name: str
|
|
506
|
+
focus: Any
|
|
507
|
+
|
|
508
|
+
def on_node_pipeline_node(
|
|
509
|
+
self,
|
|
510
|
+
context: Context,
|
|
511
|
+
noti_type: NotificationType,
|
|
512
|
+
detail: NodePipelineNodeDetail,
|
|
513
|
+
):
|
|
514
|
+
pass
|
|
515
|
+
|
|
516
|
+
@dataclass
|
|
517
|
+
class NodeRecognitionNodeDetail:
|
|
518
|
+
task_id: int
|
|
519
|
+
node_id: int
|
|
520
|
+
name: str
|
|
521
|
+
focus: Any
|
|
522
|
+
|
|
523
|
+
def on_node_recognition_node(
|
|
524
|
+
self,
|
|
525
|
+
context: Context,
|
|
526
|
+
noti_type: NotificationType,
|
|
527
|
+
detail: NodeRecognitionNodeDetail,
|
|
528
|
+
):
|
|
529
|
+
pass
|
|
530
|
+
|
|
531
|
+
@dataclass
|
|
532
|
+
class NodeActionNodeDetail:
|
|
533
|
+
task_id: int
|
|
534
|
+
node_id: int
|
|
535
|
+
name: str
|
|
536
|
+
focus: Any
|
|
537
|
+
|
|
538
|
+
def on_node_action_node(
|
|
539
|
+
self,
|
|
540
|
+
context: Context,
|
|
541
|
+
noti_type: NotificationType,
|
|
542
|
+
detail: NodeActionNodeDetail,
|
|
543
|
+
):
|
|
544
|
+
pass
|
|
545
|
+
|
|
546
|
+
def on_raw_notification(self, context: Context, msg: str, details: dict):
|
|
547
|
+
pass
|
|
548
|
+
|
|
549
|
+
def _on_raw_notification(self, handle: ctypes.c_void_p, msg: str, details: dict):
|
|
550
|
+
|
|
551
|
+
context = Context(handle=handle)
|
|
552
|
+
self.on_raw_notification(context, msg, details)
|
|
553
|
+
|
|
554
|
+
noti_type = EventSink._notification_type(msg)
|
|
555
|
+
if msg.startswith("Node.NextList"):
|
|
556
|
+
next_list = JPipelineParser._parse_node_attr_list(details["list"])
|
|
557
|
+
detail = self.NodeNextListDetail(
|
|
558
|
+
task_id=details["task_id"],
|
|
559
|
+
name=details["name"],
|
|
560
|
+
next_list=next_list,
|
|
561
|
+
focus=details["focus"],
|
|
562
|
+
)
|
|
563
|
+
self.on_node_next_list(context, noti_type, detail)
|
|
564
|
+
|
|
565
|
+
elif msg.startswith("Node.PipelineNode"):
|
|
566
|
+
detail = self.NodePipelineNodeDetail(
|
|
567
|
+
task_id=details["task_id"],
|
|
568
|
+
node_id=details["node_id"],
|
|
569
|
+
name=details["name"],
|
|
570
|
+
focus=details["focus"],
|
|
571
|
+
)
|
|
572
|
+
self.on_node_pipeline_node(context, noti_type, detail)
|
|
573
|
+
|
|
574
|
+
elif msg.startswith("Node.RecognitionNode"):
|
|
575
|
+
detail = self.NodeRecognitionNodeDetail(
|
|
576
|
+
task_id=details["task_id"],
|
|
577
|
+
node_id=details["node_id"],
|
|
578
|
+
name=details["name"],
|
|
579
|
+
focus=details["focus"],
|
|
580
|
+
)
|
|
581
|
+
self.on_node_recognition_node(context, noti_type, detail)
|
|
582
|
+
|
|
583
|
+
elif msg.startswith("Node.ActionNode"):
|
|
584
|
+
detail = self.NodeActionNodeDetail(
|
|
585
|
+
task_id=details["task_id"],
|
|
586
|
+
node_id=details["node_id"],
|
|
587
|
+
name=details["name"],
|
|
588
|
+
focus=details["focus"],
|
|
589
|
+
)
|
|
590
|
+
self.on_node_action_node(context, noti_type, detail)
|
|
591
|
+
|
|
592
|
+
elif msg.startswith("Node.Recognition"):
|
|
593
|
+
detail = self.NodeRecognitionDetail(
|
|
594
|
+
task_id=details["task_id"],
|
|
595
|
+
reco_id=details["reco_id"],
|
|
596
|
+
name=details["name"],
|
|
597
|
+
focus=details["focus"],
|
|
598
|
+
)
|
|
599
|
+
self.on_node_recognition(context, noti_type, detail)
|
|
600
|
+
|
|
601
|
+
elif msg.startswith("Node.Action"):
|
|
602
|
+
detail = self.NodeActionDetail(
|
|
603
|
+
task_id=details["task_id"],
|
|
604
|
+
action_id=details["action_id"],
|
|
605
|
+
name=details["name"],
|
|
606
|
+
focus=details["focus"],
|
|
607
|
+
)
|
|
608
|
+
self.on_node_action(context, noti_type, detail)
|
|
609
|
+
|
|
610
|
+
else:
|
|
611
|
+
self.on_unknown_notification(context, msg, details)
|