MaaFw 4.5.5__py3-none-manylinux2014_x86_64.whl → 5.4.0__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/agent/agent_server.py +221 -3
- maa/agent_client.py +170 -2
- 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/libonnxruntime.so.1 +0 -0
- maa/bin/libopencv_world4.so.411 +0 -0
- maa/bin/libunwind.so.1 +0 -0
- maa/bin/plugins/libMaaPluginDemo.so +0 -0
- maa/buffer.py +168 -0
- maa/context.py +402 -10
- maa/controller.py +611 -36
- maa/custom_action.py +40 -0
- maa/custom_recognition.py +57 -5
- maa/define.py +432 -16
- maa/event_sink.py +103 -0
- maa/job.py +77 -1
- maa/library.py +118 -50
- maa/pipeline.py +509 -0
- maa/resource.py +430 -21
- maa/tasker.py +630 -75
- maa/toolkit.py +52 -91
- {maafw-4.5.5.dist-info → maafw-5.4.0.dist-info}/METADATA +89 -44
- maafw-5.4.0.dist-info/RECORD +35 -0
- {maafw-4.5.5.dist-info → maafw-5.4.0.dist-info}/WHEEL +1 -1
- maa/bin/libMaaDbgControlUnit.so +0 -0
- maa/notification_handler.py +0 -199
- maafw-4.5.5.dist-info/RECORD +0 -34
- {maafw-4.5.5.dist-info → maafw-5.4.0.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
|
|
|
8
|
+
from .event_sink import EventSink, NotificationType
|
|
7
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
|
|
|
@@ -32,6 +35,15 @@ class Context:
|
|
|
32
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
48
|
Library.framework().MaaContextRunTask(
|
|
37
49
|
self._handle, *Context._gen_post_param(entry, pipeline_override)
|
|
@@ -43,8 +55,28 @@ 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(
|
|
@@ -65,11 +97,29 @@ 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
|
-
|
|
122
|
+
act_id = int(
|
|
73
123
|
Library.framework().MaaContextRunAction(
|
|
74
124
|
self._handle,
|
|
75
125
|
*Context._gen_post_param(entry, pipeline_override),
|
|
@@ -78,20 +128,42 @@ 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
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
|
|
|
@@ -101,7 +173,34 @@ class Context:
|
|
|
101
173
|
)
|
|
102
174
|
)
|
|
103
175
|
|
|
104
|
-
def
|
|
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
|
+
"""
|
|
105
204
|
string_buffer = StringBuffer()
|
|
106
205
|
if not Library.framework().MaaContextGetNodeData(
|
|
107
206
|
self._handle, name.encode(), string_buffer._handle
|
|
@@ -117,11 +216,40 @@ class Context:
|
|
|
117
216
|
except json.JSONDecodeError:
|
|
118
217
|
return None
|
|
119
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
|
+
|
|
120
235
|
@property
|
|
121
236
|
def tasker(self) -> Tasker:
|
|
237
|
+
"""获取实例 / Get instance
|
|
238
|
+
|
|
239
|
+
Returns:
|
|
240
|
+
Tasker: 实例对象 / Instance object
|
|
241
|
+
"""
|
|
122
242
|
return self._tasker
|
|
123
243
|
|
|
124
244
|
def get_task_job(self) -> JobWithResult:
|
|
245
|
+
"""获取对应任务号的任务作业 / Get task job for corresponding task id
|
|
246
|
+
|
|
247
|
+
Returns:
|
|
248
|
+
JobWithResult: 任务作业对象 / Task job object
|
|
249
|
+
|
|
250
|
+
Raises:
|
|
251
|
+
ValueError: 如果任务 id 为 None
|
|
252
|
+
"""
|
|
125
253
|
task_id = Library.framework().MaaContextGetTaskId(self._handle)
|
|
126
254
|
if not task_id:
|
|
127
255
|
raise ValueError("task_id is None")
|
|
@@ -129,12 +257,84 @@ class Context:
|
|
|
129
257
|
return self.tasker._gen_task_job(task_id)
|
|
130
258
|
|
|
131
259
|
def clone(self) -> "Context":
|
|
260
|
+
"""复制上下文 / Clone context
|
|
261
|
+
|
|
262
|
+
Returns:
|
|
263
|
+
Context: 复制的上下文对象 / Cloned context object
|
|
264
|
+
|
|
265
|
+
Raises:
|
|
266
|
+
ValueError: 如果克隆失败
|
|
267
|
+
"""
|
|
132
268
|
cloned_handle = Library.framework().MaaContextClone(self._handle)
|
|
133
269
|
if not cloned_handle:
|
|
134
270
|
raise ValueError("cloned_handle is None")
|
|
135
271
|
|
|
136
272
|
return Context(cloned_handle)
|
|
137
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
|
+
|
|
138
338
|
### private ###
|
|
139
339
|
|
|
140
340
|
def _init_tasker(self):
|
|
@@ -145,9 +345,11 @@ class Context:
|
|
|
145
345
|
|
|
146
346
|
@staticmethod
|
|
147
347
|
def _gen_post_param(entry: str, pipeline_override: Dict) -> Tuple[bytes, bytes]:
|
|
348
|
+
pipeline_json = json.dumps(pipeline_override, ensure_ascii=False)
|
|
349
|
+
|
|
148
350
|
return (
|
|
149
351
|
entry.encode(),
|
|
150
|
-
|
|
352
|
+
pipeline_json.encode(),
|
|
151
353
|
)
|
|
152
354
|
|
|
153
355
|
_api_properties_initialized: bool = False
|
|
@@ -174,7 +376,7 @@ class Context:
|
|
|
174
376
|
MaaImageBufferHandle,
|
|
175
377
|
]
|
|
176
378
|
|
|
177
|
-
Library.framework().MaaContextRunAction.restype =
|
|
379
|
+
Library.framework().MaaContextRunAction.restype = MaaActId
|
|
178
380
|
Library.framework().MaaContextRunAction.argtypes = [
|
|
179
381
|
MaaContextHandle,
|
|
180
382
|
ctypes.c_char_p,
|
|
@@ -196,6 +398,13 @@ class Context:
|
|
|
196
398
|
MaaStringListBufferHandle,
|
|
197
399
|
]
|
|
198
400
|
|
|
401
|
+
Library.framework().MaaContextOverrideImage.restype = MaaBool
|
|
402
|
+
Library.framework().MaaContextOverrideImage.argtypes = [
|
|
403
|
+
MaaContextHandle,
|
|
404
|
+
ctypes.c_char_p,
|
|
405
|
+
MaaImageBufferHandle,
|
|
406
|
+
]
|
|
407
|
+
|
|
199
408
|
Library.framework().MaaContextGetNodeData.restype = MaaBool
|
|
200
409
|
Library.framework().MaaContextGetNodeData.argtypes = [
|
|
201
410
|
MaaContextHandle,
|
|
@@ -217,3 +426,186 @@ class Context:
|
|
|
217
426
|
Library.framework().MaaContextClone.argtypes = [
|
|
218
427
|
MaaContextHandle,
|
|
219
428
|
]
|
|
429
|
+
|
|
430
|
+
Library.framework().MaaContextSetAnchor.restype = MaaBool
|
|
431
|
+
Library.framework().MaaContextSetAnchor.argtypes = [
|
|
432
|
+
MaaContextHandle,
|
|
433
|
+
ctypes.c_char_p,
|
|
434
|
+
ctypes.c_char_p,
|
|
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)
|