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/resource.py CHANGED
@@ -1,31 +1,37 @@
1
1
  import ctypes
2
2
  import pathlib
3
- from typing import Any, Optional, Union
3
+ import json
4
+ from typing import Optional, Union, List, Dict
5
+ from dataclasses import dataclass, field
4
6
 
5
- from .notification_handler import NotificationHandler
7
+ import numpy
8
+
9
+ from .event_sink import EventSink, NotificationType
6
10
  from .define import *
7
11
  from .job import Job
8
12
  from .library import Library
9
- from .buffer import StringBuffer
13
+ from .buffer import StringBuffer, StringListBuffer, ImageBuffer
14
+ from .pipeline import JPipelineData, JPipelineParser
10
15
 
11
16
 
12
17
  class Resource:
13
- _notification_handler: Optional[NotificationHandler]
14
18
  _handle: MaaResourceHandle
15
- _own: bool = False
19
+ _own: bool
16
20
 
17
21
  ### public ###
18
22
 
19
23
  def __init__(
20
24
  self,
21
- notification_handler: Optional[NotificationHandler] = None,
22
25
  handle: Optional[MaaResourceHandle] = None,
23
26
  ):
27
+ """创建资源 / Create resource
24
28
 
25
- if not Library.initialized:
26
- raise RuntimeError(
27
- "Library not initialized, please call `library.open()` first."
28
- )
29
+ Args:
30
+ handle: 可选的外部句柄 / Optional external handle
31
+
32
+ Raises:
33
+ RuntimeError: 如果创建失败
34
+ """
29
35
 
30
36
  self._set_api_properties()
31
37
 
@@ -33,10 +39,7 @@ class Resource:
33
39
  self._handle = handle
34
40
  self._own = False
35
41
  else:
36
- self._notification_handler = notification_handler
37
- self._handle = Library.framework.MaaResourceCreate(
38
- *NotificationHandler._gen_c_param(self._notification_handler)
39
- )
42
+ self._handle = Library.framework().MaaResourceCreate()
40
43
  self._own = True
41
44
 
42
45
  if not self._handle:
@@ -47,41 +50,299 @@ class Resource:
47
50
 
48
51
  def __del__(self):
49
52
  if self._handle and self._own:
50
- Library.framework.MaaResourceDestroy(self._handle)
53
+ Library.framework().MaaResourceDestroy(self._handle)
54
+
55
+ def post_bundle(self, path: Union[pathlib.Path, str]) -> Job:
56
+ """异步加载资源 / Asynchronously load resources from path
57
+
58
+ 这是一个异步操作,会立即返回一个 Job 对象
59
+ This is an asynchronous operation that immediately returns a Job object
60
+
61
+ Args:
62
+ path: 资源路径 / Resource path
63
+
64
+ Returns:
65
+ Job: 作业对象,可通过 status/wait 查询状态 / Job object, can query status via status/wait
66
+ """
67
+ res_id = Library.framework().MaaResourcePostBundle(
68
+ self._handle, str(path).encode()
69
+ )
70
+ return Job(res_id, self._status, self._wait)
71
+
72
+ def post_ocr_model(self, path: Union[pathlib.Path, str]) -> Job:
73
+ """异步加载 OCR 模型 / Asynchronously load OCR model from path
74
+
75
+ 这是一个异步操作,会立即返回一个 Job 对象
76
+ This is an asynchronous operation that immediately returns a Job object
77
+
78
+ Args:
79
+ path: OCR 模型目录路径 / OCR model directory path
80
+
81
+ Returns:
82
+ Job: 作业对象,可通过 status/wait 查询状态 / Job object, can query status via status/wait
83
+ """
84
+ res_id = Library.framework().MaaResourcePostOcrModel(
85
+ self._handle, str(path).encode()
86
+ )
87
+ return Job(res_id, self._status, self._wait)
88
+
89
+ def post_pipeline(self, path: Union[pathlib.Path, str]) -> Job:
90
+ """异步加载 Pipeline / Asynchronously load pipeline from path
91
+
92
+ 这是一个异步操作,会立即返回一个 Job 对象
93
+ This is an asynchronous operation that immediately returns a Job object
94
+
95
+ 支持加载目录或单个 json/jsonc 文件
96
+ Supports loading a directory or a single json/jsonc file
97
+
98
+ Args:
99
+ path: Pipeline 目录或文件路径 / Pipeline directory or file path
100
+
101
+ Returns:
102
+ Job: 作业对象,可通过 status/wait 查询状态 / Job object, can query status via status/wait
103
+ """
104
+ res_id = Library.framework().MaaResourcePostPipeline(
105
+ self._handle, str(path).encode()
106
+ )
107
+ return Job(res_id, self._status, self._wait)
108
+
109
+ def post_image(self, path: Union[pathlib.Path, str]) -> Job:
110
+ """异步加载图片资源 / Asynchronously load image resources from path
111
+
112
+ 这是一个异步操作,会立即返回一个 Job 对象
113
+ This is an asynchronous operation that immediately returns a Job object
114
+
115
+ 支持加载目录或单个图片文件
116
+ Supports loading a directory or a single image file
117
+
118
+ Args:
119
+ path: 图片目录或文件路径 / Image directory or file path
120
+
121
+ Returns:
122
+ Job: 作业对象,可通过 status/wait 查询状态 / Job object, can query status via status/wait
123
+ """
124
+ res_id = Library.framework().MaaResourcePostImage(
125
+ self._handle, str(path).encode()
126
+ )
127
+ return Job(res_id, self._status, self._wait)
128
+
129
+ def override_pipeline(self, pipeline_override: Dict) -> bool:
130
+ """覆盖 pipeline / Override pipeline_override
131
+
132
+ Args:
133
+ pipeline_override: 用于覆盖的 json / JSON for overriding
134
+
135
+ Returns:
136
+ bool: 是否成功 / Whether successful
137
+ """
138
+ pipeline_json = json.dumps(pipeline_override, ensure_ascii=False)
139
+
140
+ return bool(
141
+ Library.framework().MaaResourceOverridePipeline(
142
+ self._handle,
143
+ pipeline_json.encode(),
144
+ )
145
+ )
146
+
147
+ def override_next(self, name: str, next_list: List[str]) -> bool:
148
+ """覆盖任务的 next 列表 / Override the next list of task
149
+
150
+ 注意:此方法会直接设置 next 列表,即使节点不存在也会创建
151
+ Note: This method directly sets the next list, creating the node if it doesn't exist
152
+
153
+ Args:
154
+ name: 任务名 / Task name
155
+ next_list: next 列表 / Next list
156
+
157
+ Returns:
158
+ bool: 总是返回 True / Always returns True
159
+ """
160
+ list_buffer = StringListBuffer()
161
+ list_buffer.set(next_list)
162
+
163
+ return bool(
164
+ Library.framework().MaaResourceOverrideNext(
165
+ self._handle, name.encode(), list_buffer._handle
166
+ )
167
+ )
168
+
169
+ def override_image(self, image_name: str, image: numpy.ndarray) -> bool:
170
+ """覆盖图片 / Override the image corresponding to image_name
171
+
172
+ Args:
173
+ image_name: 图片名 / Image name
174
+ image: 图片数据 / Image data
51
175
 
52
- def post_path(self, path: Union[pathlib.Path, str]) -> Job:
53
- resid = Library.framework.MaaResourcePostPath(self._handle, str(path).encode())
54
- return Job(resid, self._status, self._wait)
176
+ Returns:
177
+ bool: 总是返回 True / Always returns True
178
+ """
179
+ image_buffer = ImageBuffer()
180
+ image_buffer.set(image)
181
+
182
+ return bool(
183
+ Library.framework().MaaResourceOverrideImage(
184
+ self._handle, image_name.encode(), image_buffer._handle
185
+ )
186
+ )
187
+
188
+ def get_node_data(self, name: str) -> Optional[Dict]:
189
+ """获取任务当前的定义 / Get the current definition of task
190
+
191
+ Args:
192
+ name: 任务名 / Task name
193
+
194
+ Returns:
195
+ Optional[Dict]: 任务定义字典,如果不存在则返回 None / Task definition dict, or None if not exists
196
+ """
197
+ string_buffer = StringBuffer()
198
+ if not Library.framework().MaaResourceGetNodeData(
199
+ self._handle, name.encode(), string_buffer._handle
200
+ ):
201
+ return None
202
+ data = string_buffer.get()
203
+ if not data:
204
+ return None
205
+
206
+ try:
207
+ return json.loads(data)
208
+ except json.JSONDecodeError:
209
+ return None
210
+
211
+ def get_node_object(self, name: str) -> Optional[JPipelineData]:
212
+ """获取任务当前的定义(解析为对象) / Get the current definition of task (parsed as object)
213
+
214
+ Args:
215
+ name: 任务名 / Task name
216
+
217
+ Returns:
218
+ Optional[JPipelineData]: 任务定义对象,如果不存在则返回 None / Task definition object, or None if not exists
219
+ """
220
+ node_data = self.get_node_data(name)
221
+
222
+ if not node_data:
223
+ return None
224
+
225
+ return JPipelineParser.parse_pipeline_data(node_data)
55
226
 
56
227
  @property
57
228
  def loaded(self) -> bool:
58
- return bool(Library.framework.MaaResourceLoaded(self._handle))
229
+ """判断是否加载正常 / Check if resources loaded normally
230
+
231
+ Returns:
232
+ bool: 是否已加载 / Whether loaded
233
+ """
234
+ return bool(Library.framework().MaaResourceLoaded(self._handle))
59
235
 
60
236
  def clear(self) -> bool:
61
- return bool(Library.framework.MaaResourceClear(self._handle))
237
+ """清除已加载内容 / Clear loaded content
238
+
239
+ 如果资源正在加载中,此方法会失败
240
+ This method will fail if resources are currently loading
241
+
242
+ Returns:
243
+ bool: 成功返回 True,如果正在加载中则返回 False / Returns True on success, False if currently loading
244
+ """
245
+ return bool(Library.framework().MaaResourceClear(self._handle))
246
+
247
+ def use_cpu(self) -> bool:
248
+ """使用 CPU 进行推理 / Use CPU for inference
249
+
250
+ Returns:
251
+ bool: 是否成功 / Whether successful
252
+ """
253
+ return self.set_inference(
254
+ MaaInferenceExecutionProviderEnum.CPU, MaaInferenceDeviceEnum.CPU
255
+ )
256
+
257
+ def use_directml(self, device_id: int = MaaInferenceDeviceEnum.Auto) -> bool:
258
+ """使用 DirectML 进行推理 / Use DirectML for inference
259
+
260
+ Args:
261
+ device_id: 设备 id,默认为自动选择 / Device id, default is Auto
262
+
263
+ Returns:
264
+ bool: 是否成功 / Whether successful
265
+ """
266
+ return self.set_inference(MaaInferenceExecutionProviderEnum.DirectML, device_id)
267
+
268
+ def use_coreml(self, coreml_flag: int = MaaInferenceDeviceEnum.Auto) -> bool:
269
+ """使用 CoreML 进行推理 / Use CoreML for inference
270
+
271
+ Args:
272
+ coreml_flag: CoreML 标志,默认为自动选择 / CoreML flag, default is Auto
273
+
274
+ Returns:
275
+ bool: 是否成功 / Whether successful
276
+ """
277
+ return self.set_inference(MaaInferenceExecutionProviderEnum.CoreML, coreml_flag)
278
+
279
+ def use_auto_ep(self) -> bool:
280
+ """自动选择推理执行提供者 / Auto select inference execution provider
281
+
282
+ Returns:
283
+ bool: 是否成功 / Whether successful
284
+ """
285
+ return self.set_inference(
286
+ MaaInferenceExecutionProviderEnum.Auto, MaaInferenceDeviceEnum.Auto
287
+ )
288
+
289
+ # not implemented
290
+ # def use_cuda(self, nvidia_gpu_id: int) -> bool:
291
+ # return self.set_inference(MaaInferenceExecutionProviderEnum.CUDA, nvidia_gpu_id)
62
292
 
63
293
  def set_gpu(self, gpu_id: int) -> bool:
294
+ """
295
+ Deprecated, please use `use_directml`, `use_coreml` or `use_cuda` instead.
296
+ """
64
297
  if gpu_id < 0:
65
298
  return False
66
- return self.set_inference_device(gpu_id)
299
+ return self.use_directml(gpu_id)
67
300
 
68
301
  def set_cpu(self) -> bool:
69
- MaaInferenceDevice_CPU = -2
70
- return self.set_inference_device(MaaInferenceDevice_CPU)
71
-
302
+ """
303
+ Deprecated, please use `use_cpu` instead.
304
+ """
305
+ return self.use_cpu()
306
+
72
307
  def set_auto_device(self) -> bool:
73
- MaaInferenceDevice_Auto = -1
74
- return self.set_inference_device(MaaInferenceDevice_Auto)
308
+ """
309
+ Deprecated, please use `use_auto_ep` instead.
310
+ """
311
+ return self.use_auto_ep()
312
+
313
+ def custom_recognition(self, name: str):
314
+ """自定义识别器装饰器 / Custom recognition decorator
315
+
316
+ Args:
317
+ name: 识别器名称,需与 Pipeline 中的 custom_recognition 字段匹配 / Recognition name, should match the custom_recognition field in Pipeline
318
+
319
+ Returns:
320
+ 装饰器函数 / Decorator function
321
+ """
322
+
323
+ def wrapper_recognition(recognition):
324
+ self.register_custom_recognition(name=name, recognition=recognition())
325
+ return recognition
326
+
327
+ return wrapper_recognition
75
328
 
76
329
  def register_custom_recognition(
77
330
  self, name: str, recognition: "CustomRecognition" # type: ignore
78
331
  ) -> bool:
332
+ """注册自定义识别器 / Register a custom recognizer
333
+
334
+ Args:
335
+ name: 名称 / Name
336
+ recognition: 自定义识别器 / Custom recognizer
79
337
 
338
+ Returns:
339
+ bool: 是否成功 / Whether successful
340
+ """
80
341
  # avoid gc
81
342
  self._custom_recognition_holder[name] = recognition
82
343
 
83
344
  return bool(
84
- Library.framework.MaaResourceRegisterCustomRecognition(
345
+ Library.framework().MaaResourceRegisterCustomRecognition(
85
346
  self._handle,
86
347
  name.encode(),
87
348
  recognition.c_handle,
@@ -90,30 +351,68 @@ class Resource:
90
351
  )
91
352
 
92
353
  def unregister_custom_recognition(self, name: str) -> bool:
354
+ """移除自定义识别器 / Remove the custom recognizer
355
+
356
+ Args:
357
+ name: 名称 / Name
358
+
359
+ Returns:
360
+ bool: 是否成功 / Whether successful
361
+ """
93
362
  self._custom_recognition_holder.pop(name, None)
94
363
 
95
364
  return bool(
96
- Library.framework.MaaResourceUnregisterCustomRecognition(
365
+ Library.framework().MaaResourceUnregisterCustomRecognition(
97
366
  self._handle,
98
367
  name.encode(),
99
368
  )
100
369
  )
101
370
 
102
371
  def clear_custom_recognition(self) -> bool:
372
+ """移除所有自定义识别器 / Remove all custom recognizers
373
+
374
+ Returns:
375
+ bool: 是否成功 / Whether successful
376
+ """
103
377
  self._custom_recognition_holder.clear()
104
378
 
105
379
  return bool(
106
- Library.framework.MaaResourceClearCustomRecognition(
380
+ Library.framework().MaaResourceClearCustomRecognition(
107
381
  self._handle,
108
382
  )
109
383
  )
110
384
 
385
+ def custom_action(self, name: str):
386
+ """自定义动作装饰器 / Custom action decorator
387
+
388
+ Args:
389
+ name: 动作名称,需与 Pipeline 中的 custom_action 字段匹配 / Action name, should match the custom_action field in Pipeline
390
+
391
+ Returns:
392
+ 装饰器函数 / Decorator function
393
+ """
394
+
395
+ def wrapper_action(action):
396
+ self.register_custom_action(name=name, action=action())
397
+ return action
398
+
399
+ return wrapper_action
400
+
111
401
  def register_custom_action(self, name: str, action: "CustomAction") -> bool: # type: ignore
402
+ """注册自定义操作 / Register a custom action
403
+
404
+ Args:
405
+ name: 名称 / Name
406
+ action: 自定义操作 / Custom action
407
+
408
+ Returns:
409
+ bool: 是否成功 / Whether successful
410
+ """
112
411
  # avoid gc
113
412
  self._custom_action_holder[name] = action
114
413
 
115
414
  return bool(
116
- Library.framework.MaaResourceRegisterCustomAction(
415
+ Library.framework().MaaResourceRegisterCustomAction(
117
416
  self._handle,
118
417
  name.encode(),
119
418
  action.c_handle,
@@ -122,49 +421,162 @@ class Resource:
122
421
  )
123
422
 
124
423
  def unregister_custom_action(self, name: str) -> bool:
424
+ """移除自定义操作 / Remove the custom action
425
+
426
+ Args:
427
+ name: 名称 / Name
428
+
429
+ Returns:
430
+ bool: 是否成功 / Whether successful
431
+ """
125
432
  self._custom_action_holder.pop(name, None)
126
433
 
127
434
  return bool(
128
- Library.framework.MaaResourceUnregisterCustomAction(
435
+ Library.framework().MaaResourceUnregisterCustomAction(
129
436
  self._handle,
130
437
  name.encode(),
131
438
  )
132
439
  )
133
440
 
134
441
  def clear_custom_action(self) -> bool:
442
+ """移除所有自定义操作 / Remove all custom actions
443
+
444
+ Returns:
445
+ bool: 是否成功 / Whether successful
446
+ """
135
447
  self._custom_action_holder.clear()
136
448
 
137
449
  return bool(
138
- Library.framework.MaaResourceClearCustomAction(
450
+ Library.framework().MaaResourceClearCustomAction(
139
451
  self._handle,
140
452
  )
141
453
  )
142
454
 
455
+ @property
456
+ def node_list(self) -> list[str]:
457
+ """获取任务列表 / Get task list
458
+
459
+ Returns:
460
+ list[str]: 任务名列表 / List of task names
461
+
462
+ Raises:
463
+ RuntimeError: 如果获取失败
464
+ """
465
+ buffer = StringListBuffer()
466
+ if not Library.framework().MaaResourceGetNodeList(self._handle, buffer._handle):
467
+ raise RuntimeError("Failed to get node list.")
468
+ return buffer.get()
469
+
470
+ @property
471
+ def custom_recognition_list(self) -> list[str]:
472
+ """获取已注册的自定义识别器列表 / Get registered custom recognizer list
473
+
474
+ Returns:
475
+ list[str]: 自定义识别器名列表 / List of custom recognizer names
476
+
477
+ Raises:
478
+ RuntimeError: 如果获取失败
479
+ """
480
+ buffer = StringListBuffer()
481
+ if not Library.framework().MaaResourceGetCustomRecognitionList(
482
+ self._handle, buffer._handle
483
+ ):
484
+ raise RuntimeError("Failed to get custom recognition list.")
485
+ return buffer.get()
486
+
487
+ @property
488
+ def custom_action_list(self) -> list[str]:
489
+ """获取已注册的自定义操作列表 / Get registered custom action list
490
+
491
+ Returns:
492
+ list[str]: 自定义操作名列表 / List of custom action names
493
+
494
+ Raises:
495
+ RuntimeError: 如果获取失败
496
+ """
497
+ buffer = StringListBuffer()
498
+ if not Library.framework().MaaResourceGetCustomActionList(
499
+ self._handle, buffer._handle
500
+ ):
501
+ raise RuntimeError("Failed to get custom action list.")
502
+ return buffer.get()
503
+
143
504
  @property
144
505
  def hash(self) -> str:
506
+ """获取资源 hash / Get resource hash
507
+
508
+ Returns:
509
+ str: 资源 hash / Resource hash
510
+
511
+ Raises:
512
+ RuntimeError: 如果获取失败
513
+ """
145
514
  buffer = StringBuffer()
146
- if not Library.framework.MaaResourceGetHash(self._handle, buffer._handle):
515
+ if not Library.framework().MaaResourceGetHash(self._handle, buffer._handle):
147
516
  raise RuntimeError("Failed to get hash.")
148
517
  return buffer.get()
149
518
 
519
+ _sink_holder: Dict[int, "ResourceEventSink"] = {}
520
+
521
+ def add_sink(self, sink: "ResourceEventSink") -> Optional[int]:
522
+ """添加资源事件监听器 / Add resource event listener
523
+
524
+ Args:
525
+ sink: 事件监听器 / Event sink
526
+
527
+ Returns:
528
+ Optional[int]: 监听器 id,失败返回 None / Listener id, or None if failed
529
+ """
530
+ sink_id = int(
531
+ Library.framework().MaaResourceAddSink(
532
+ self._handle, *EventSink._gen_c_param(sink)
533
+ )
534
+ )
535
+ if sink_id == MaaInvalidId:
536
+ return None
537
+
538
+ self._sink_holder[sink_id] = sink
539
+ return sink_id
540
+
541
+ def remove_sink(self, sink_id: int) -> None:
542
+ """移除资源事件监听器 / Remove resource event listener
543
+
544
+ Args:
545
+ sink_id: 监听器 id / Listener id
546
+ """
547
+ Library.framework().MaaResourceRemoveSink(self._handle, sink_id)
548
+ self._sink_holder.pop(sink_id)
549
+
550
+ def clear_sinks(self) -> None:
551
+ """清除所有资源事件监听器 / Clear all resource event listeners"""
552
+ Library.framework().MaaResourceClearSinks(self._handle)
553
+
150
554
  ### private ###
151
555
 
152
- def set_inference_device(self, device_id: int) -> bool:
153
- cint = ctypes.c_int32(device_id)
556
+ def set_inference(self, execution_provider: int, device_id: int) -> bool:
557
+ cep = ctypes.c_int32(execution_provider)
558
+ cdevice = ctypes.c_int32(device_id)
154
559
  return bool(
155
- Library.framework.MaaResourceSetOption(
560
+ Library.framework().MaaResourceSetOption(
561
+ self._handle,
562
+ MaaResOptionEnum.InferenceExecutionProvider,
563
+ ctypes.pointer(cep),
564
+ ctypes.sizeof(ctypes.c_int32),
565
+ )
566
+ ) and bool(
567
+ Library.framework().MaaResourceSetOption(
156
568
  self._handle,
157
569
  MaaResOptionEnum.InferenceDevice,
158
- ctypes.pointer(cint),
570
+ ctypes.pointer(cdevice),
159
571
  ctypes.sizeof(ctypes.c_int32),
160
572
  )
161
573
  )
162
574
 
163
575
  def _status(self, id: int) -> ctypes.c_int32:
164
- return Library.framework.MaaResourceStatus(self._handle, id)
576
+ return Library.framework().MaaResourceStatus(self._handle, id)
165
577
 
166
578
  def _wait(self, id: int) -> ctypes.c_int32:
167
- return Library.framework.MaaResourceWait(self._handle, id)
579
+ return Library.framework().MaaResourceWait(self._handle, id)
168
580
 
169
581
  _api_properties_initialized: bool = False
170
582
 
@@ -174,87 +586,202 @@ class Resource:
174
586
  return
175
587
  Resource._api_properties_initialized = True
176
588
 
177
- Library.framework.MaaResourceCreate.restype = MaaResourceHandle
178
- Library.framework.MaaResourceCreate.argtypes = [
179
- MaaNotificationCallback,
180
- ctypes.c_void_p,
589
+ Library.framework().MaaResourceCreate.restype = MaaResourceHandle
590
+ Library.framework().MaaResourceCreate.argtypes = []
591
+
592
+ Library.framework().MaaResourceDestroy.restype = None
593
+ Library.framework().MaaResourceDestroy.argtypes = [MaaResourceHandle]
594
+
595
+ Library.framework().MaaResourcePostBundle.restype = MaaResId
596
+ Library.framework().MaaResourcePostBundle.argtypes = [
597
+ MaaResourceHandle,
598
+ ctypes.c_char_p,
181
599
  ]
182
600
 
183
- Library.framework.MaaResourceDestroy.restype = None
184
- Library.framework.MaaResourceDestroy.argtypes = [MaaResourceHandle]
601
+ Library.framework().MaaResourcePostOcrModel.restype = MaaResId
602
+ Library.framework().MaaResourcePostOcrModel.argtypes = [
603
+ MaaResourceHandle,
604
+ ctypes.c_char_p,
605
+ ]
185
606
 
186
- Library.framework.MaaResourcePostPath.restype = MaaResId
187
- Library.framework.MaaResourcePostPath.argtypes = [
607
+ Library.framework().MaaResourcePostPipeline.restype = MaaResId
608
+ Library.framework().MaaResourcePostPipeline.argtypes = [
188
609
  MaaResourceHandle,
189
610
  ctypes.c_char_p,
190
611
  ]
191
612
 
192
- Library.framework.MaaResourceStatus.restype = MaaStatus
193
- Library.framework.MaaResourceStatus.argtypes = [
613
+ Library.framework().MaaResourcePostImage.restype = MaaResId
614
+ Library.framework().MaaResourcePostImage.argtypes = [
615
+ MaaResourceHandle,
616
+ ctypes.c_char_p,
617
+ ]
618
+
619
+ Library.framework().MaaResourceStatus.restype = MaaStatus
620
+ Library.framework().MaaResourceStatus.argtypes = [
194
621
  MaaResourceHandle,
195
622
  MaaResId,
196
623
  ]
197
624
 
198
- Library.framework.MaaResourceWait.restype = MaaStatus
199
- Library.framework.MaaResourceWait.argtypes = [
625
+ Library.framework().MaaResourceWait.restype = MaaStatus
626
+ Library.framework().MaaResourceWait.argtypes = [
200
627
  MaaResourceHandle,
201
628
  MaaResId,
202
629
  ]
203
630
 
204
- Library.framework.MaaResourceLoaded.restype = MaaBool
205
- Library.framework.MaaResourceLoaded.argtypes = [MaaResourceHandle]
631
+ Library.framework().MaaResourceLoaded.restype = MaaBool
632
+ Library.framework().MaaResourceLoaded.argtypes = [MaaResourceHandle]
206
633
 
207
- Library.framework.MaaResourceClear.restype = MaaBool
208
- Library.framework.MaaResourceClear.argtypes = [MaaResourceHandle]
634
+ Library.framework().MaaResourceClear.restype = MaaBool
635
+ Library.framework().MaaResourceClear.argtypes = [MaaResourceHandle]
209
636
 
210
- Library.framework.MaaResourceGetHash.restype = MaaBool
211
- Library.framework.MaaResourceGetHash.argtypes = [
637
+ Library.framework().MaaResourceOverridePipeline.restype = MaaBool
638
+ Library.framework().MaaResourceOverridePipeline.argtypes = [
639
+ MaaResourceHandle,
640
+ ctypes.c_char_p,
641
+ ]
642
+
643
+ Library.framework().MaaResourceOverrideNext.restype = MaaBool
644
+ Library.framework().MaaResourceOverrideNext.argtypes = [
645
+ MaaResourceHandle,
646
+ ctypes.c_char_p,
647
+ MaaStringListBufferHandle,
648
+ ]
649
+
650
+ Library.framework().MaaResourceOverrideImage.restype = MaaBool
651
+ Library.framework().MaaResourceOverrideImage.argtypes = [
652
+ MaaResourceHandle,
653
+ ctypes.c_char_p,
654
+ MaaImageBufferHandle,
655
+ ]
656
+
657
+ Library.framework().MaaResourceGetNodeData.restype = MaaBool
658
+ Library.framework().MaaResourceGetNodeData.argtypes = [
659
+ MaaContextHandle,
660
+ ctypes.c_char_p,
661
+ MaaStringBufferHandle,
662
+ ]
663
+
664
+ Library.framework().MaaResourceGetHash.restype = MaaBool
665
+ Library.framework().MaaResourceGetHash.argtypes = [
212
666
  MaaResourceHandle,
213
667
  MaaStringBufferHandle,
214
668
  ]
215
669
 
216
- Library.framework.MaaResourceSetOption.restype = MaaBool
217
- Library.framework.MaaResourceSetOption.argtypes = [
670
+ Library.framework().MaaResourceSetOption.restype = MaaBool
671
+ Library.framework().MaaResourceSetOption.argtypes = [
218
672
  MaaResourceHandle,
219
673
  MaaResOption,
220
674
  MaaOptionValue,
221
675
  MaaOptionValueSize,
222
676
  ]
223
677
 
224
- Library.framework.MaaResourceRegisterCustomRecognition.restype = MaaBool
225
- Library.framework.MaaResourceRegisterCustomRecognition.argtypes = [
678
+ Library.framework().MaaResourceRegisterCustomRecognition.restype = MaaBool
679
+ Library.framework().MaaResourceRegisterCustomRecognition.argtypes = [
226
680
  MaaResourceHandle,
227
681
  ctypes.c_char_p,
228
682
  MaaCustomRecognitionCallback,
229
683
  ctypes.c_void_p,
230
684
  ]
231
685
 
232
- Library.framework.MaaResourceUnregisterCustomRecognition.restype = MaaBool
233
- Library.framework.MaaResourceUnregisterCustomRecognition.argtypes = [
686
+ Library.framework().MaaResourceUnregisterCustomRecognition.restype = MaaBool
687
+ Library.framework().MaaResourceUnregisterCustomRecognition.argtypes = [
234
688
  MaaResourceHandle,
235
689
  ctypes.c_char_p,
236
690
  ]
237
691
 
238
- Library.framework.MaaResourceClearCustomRecognition.restype = MaaBool
239
- Library.framework.MaaResourceClearCustomRecognition.argtypes = [
692
+ Library.framework().MaaResourceClearCustomRecognition.restype = MaaBool
693
+ Library.framework().MaaResourceClearCustomRecognition.argtypes = [
240
694
  MaaResourceHandle,
241
695
  ]
242
696
 
243
- Library.framework.MaaResourceRegisterCustomAction.restype = MaaBool
244
- Library.framework.MaaResourceRegisterCustomAction.argtypes = [
697
+ Library.framework().MaaResourceRegisterCustomAction.restype = MaaBool
698
+ Library.framework().MaaResourceRegisterCustomAction.argtypes = [
245
699
  MaaResourceHandle,
246
700
  ctypes.c_char_p,
247
701
  MaaCustomActionCallback,
248
702
  ctypes.c_void_p,
249
703
  ]
250
704
 
251
- Library.framework.MaaResourceUnregisterCustomAction.restype = MaaBool
252
- Library.framework.MaaResourceUnregisterCustomAction.argtypes = [
705
+ Library.framework().MaaResourceUnregisterCustomAction.restype = MaaBool
706
+ Library.framework().MaaResourceUnregisterCustomAction.argtypes = [
253
707
  MaaResourceHandle,
254
708
  ctypes.c_char_p,
255
709
  ]
256
710
 
257
- Library.framework.MaaResourceClearCustomAction.restype = MaaBool
258
- Library.framework.MaaResourceClearCustomAction.argtypes = [
711
+ Library.framework().MaaResourceClearCustomAction.restype = MaaBool
712
+ Library.framework().MaaResourceClearCustomAction.argtypes = [
713
+ MaaResourceHandle,
714
+ ]
715
+
716
+ Library.framework().MaaResourceGetNodeList.restype = MaaBool
717
+ Library.framework().MaaResourceGetNodeList.argtypes = [
718
+ MaaResourceHandle,
719
+ MaaStringListBufferHandle,
720
+ ]
721
+
722
+ Library.framework().MaaResourceGetCustomRecognitionList.restype = MaaBool
723
+ Library.framework().MaaResourceGetCustomRecognitionList.argtypes = [
724
+ MaaResourceHandle,
725
+ MaaStringListBufferHandle,
726
+ ]
727
+
728
+ Library.framework().MaaResourceGetCustomActionList.restype = MaaBool
729
+ Library.framework().MaaResourceGetCustomActionList.argtypes = [
259
730
  MaaResourceHandle,
731
+ MaaStringListBufferHandle,
260
732
  ]
733
+
734
+ Library.framework().MaaResourceAddSink.restype = MaaSinkId
735
+ Library.framework().MaaResourceAddSink.argtypes = [
736
+ MaaResourceHandle,
737
+ MaaEventCallback,
738
+ ctypes.c_void_p,
739
+ ]
740
+
741
+ Library.framework().MaaResourceRemoveSink.restype = None
742
+ Library.framework().MaaResourceRemoveSink.argtypes = [
743
+ MaaResourceHandle,
744
+ MaaSinkId,
745
+ ]
746
+
747
+ Library.framework().MaaResourceClearSinks.restype = None
748
+ Library.framework().MaaResourceClearSinks.argtypes = [MaaResourceHandle]
749
+
750
+
751
+ class ResourceEventSink(EventSink):
752
+
753
+ @dataclass
754
+ class ResourceLoadingDetail:
755
+ res_id: int
756
+ path: str
757
+ type: str
758
+ hash: str
759
+
760
+ def on_resource_loading(
761
+ self,
762
+ resource: Resource,
763
+ noti_type: NotificationType,
764
+ detail: ResourceLoadingDetail,
765
+ ):
766
+ pass
767
+
768
+ def on_raw_notification(self, resource: Resource, msg: str, details: dict):
769
+ pass
770
+
771
+ def _on_raw_notification(self, handle: ctypes.c_void_p, msg: str, details: dict):
772
+
773
+ resource = Resource(handle=handle)
774
+ self.on_raw_notification(resource, msg, details)
775
+
776
+ noti_type = EventSink._notification_type(msg)
777
+ if msg.startswith("Resource.Loading"):
778
+ detail = self.ResourceLoadingDetail(
779
+ res_id=details["res_id"],
780
+ path=details["path"],
781
+ type=details.get("type", "Bundle"),
782
+ hash=details["hash"],
783
+ )
784
+ self.on_resource_loading(resource, noti_type, detail)
785
+
786
+ else:
787
+ self.on_unknown_notification(resource, msg, details)