Skip to content

Commit 6de5ee9

Browse files
committed
♻️ refactor(tasks): 优化自动瞄准与移动任务调度与睡眠检查
1 parent 8a72734 commit 6de5ee9

5 files changed

Lines changed: 78 additions & 25 deletions

File tree

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,4 @@ mod/*
7878

7979
# 忽略vscode插件文件
8080
.history/
81-
oooook
81+
ook

src/globals.py

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from qfluentwidgets import DoubleSpinBox
55
from PySide6.QtWidgets import QApplication
66
from ok import Logger, og
7+
from threading import Event
78

89
logger = Logger.get_logger(__name__)
910

@@ -33,6 +34,7 @@ def __init__(self, exit_event):
3334
self.pynput_keyboard = None
3435
self._thread_pool_executor_max_workers = 0
3536
self.thread_pool_executor = None
37+
self.thread_pool_exit_event = Event()
3638
self.shared_frame = None
3739
exit_event.bind_stop(self)
3840
self.init_pynput()
@@ -65,30 +67,66 @@ def on_click(self, x, y, button, pressed):
6567
def on_press(self, key):
6668
self.pressed.emit(key)
6769

68-
def get_thread_pool_executor(self, max_workers=4):
70+
def get_thread_pool_executor(self, max_workers=6):
6971
"""
7072
获取全局执行器。
71-
7273
如果请求的 max_workers 大于当前值,将安全地重建线程池。
7374
"""
7475
if self.thread_pool_executor is not None and max_workers > self._thread_pool_executor_max_workers:
7576
logger.info(
7677
f"thread pool max_workers not enough, reset max_workers {self._thread_pool_executor_max_workers} -> {max_workers}")
77-
self.shutdown_task_executor()
78+
self.shutdown_thread_pool_executor()
7879

7980
if self.thread_pool_executor is None:
8081
logger.info(f"create thread pool executor, max_workers: {max_workers}")
82+
self.thread_pool_exit_event.clear()
8183
self.thread_pool_executor = concurrent.futures.ThreadPoolExecutor(max_workers=max_workers)
8284
self._thread_pool_executor_max_workers = max_workers
8385

8486
return self.thread_pool_executor
8587

8688
def shutdown_thread_pool_executor(self):
8789
if self.thread_pool_executor is not None:
90+
logger.info("Shutting down thread pool executor...")
91+
self.thread_pool_exit_event.set()
8892
self.thread_pool_executor.shutdown(wait=False, cancel_futures=True)
8993
self.thread_pool_executor = None
9094
self._thread_pool_executor_max_workers = 0
9195

96+
def submit_periodic_task(self, delay, task, *args, **kwargs):
97+
"""
98+
提交一个循环任务到线程池。
99+
如果要停止循环,任务函数应返回 False。
100+
101+
:param task: 要执行的函数
102+
:param delay: 每次执行后的间隔时间(秒)
103+
:param args: 位置参数
104+
:param kwargs: 关键字参数
105+
"""
106+
executor = self.get_thread_pool_executor()
107+
108+
def loop_wrapper():
109+
logger.debug(f"Periodic task {task.__name__} started.")
110+
111+
while not self.thread_pool_exit_event.is_set():
112+
should_stop = False
113+
try:
114+
if task(*args, **kwargs) is False:
115+
should_stop = True
116+
except Exception as e:
117+
logger.error(f"Error in periodic task {task.__name__}: {e}")
118+
119+
if should_stop:
120+
logger.debug(f"Periodic task {task.__name__} decided to stop.")
121+
break
122+
123+
if self.thread_pool_exit_event.wait(timeout=delay):
124+
logger.debug(f"Periodic task {task.__name__} received stop signal.")
125+
break
126+
127+
logger.debug(f"Periodic task {task.__name__} stopped.")
128+
129+
executor.submit(loop_wrapper)
92130

93131
if __name__ == "__main__":
94132
glbs = Globals(exit_event=None)

src/tasks/BaseDNATask.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,14 @@ def f_search_box(self) -> Box:
9595

9696
@property
9797
def thread_pool_executor(self) -> ThreadPoolExecutor:
98+
if og.my_app is None:
99+
return None
98100
return og.my_app.get_thread_pool_executor()
101+
102+
def submit_periodic_task(self, delay, task, *args, **kwargs):
103+
if og.my_app is None:
104+
return None
105+
return og.my_app.submit_periodic_task(delay, task, *args, **kwargs)
99106

100107
@property
101108
def shared_frame(self) -> np.ndarray:

src/tasks/trigger/AutoAimTask.py

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from contextlib import contextmanager
2+
import time
23

34
from ok import TriggerTask, Logger, og
45
from src.scene.DNAScene import DNAScene
@@ -69,7 +70,7 @@ def run(self):
6970

7071
if self.manual_activate and not self.running:
7172
self.running = True
72-
self.handler.post(self.do_aim)
73+
self.submit_periodic_task(0.01, self.do_aim)
7374

7475
return
7576

@@ -89,24 +90,27 @@ def do_aim(self):
8990
except CharDeadException:
9091
self.log_error("Characters dead", notify=True)
9192
self.running = False
92-
return
93+
return False
9394
except TriggerDeactivateException as e:
9495
logger.info(f"auto_aim_task_deactivate {e}")
9596
self.running = False
96-
return
97-
self.handler.post(self.do_aim)
97+
return False
9898

9999
def sleep_check(self, sec, check_signal_flag=True):
100-
remaining = sec
101-
step = 0.2
102-
while remaining > 0:
100+
if sec <= 0:
101+
return
102+
end_time = time.perf_counter() + sec
103+
step = 0.01
104+
while True:
105+
remaining = end_time - time.perf_counter()
106+
if remaining <= 0:
107+
break
103108
s = step if remaining > step else remaining
104-
self.sleep(s)
105-
remaining -= s
109+
time.sleep(s)
110+
if not self.manual_activate or not self._enabled or self.paused:
111+
raise TriggerDeactivateException
106112
if self._should_interrupt(check_signal_flag):
107113
self.switch_state()
108-
if not self.manual_activate:
109-
raise TriggerDeactivateException
110114

111115
def _should_interrupt(self, check_signal_flag: bool) -> bool:
112116
"""检查是否应该中断当前操作"""

src/tasks/trigger/AutoMoveTask.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from contextlib import contextmanager
2+
import time
23

34
from ok import TriggerTask, Logger, og
45
from src.scene.DNAScene import DNAScene
@@ -64,7 +65,7 @@ def run(self):
6465

6566
if self.manual_activate and not self.running:
6667
self.running = True
67-
self.handler.post(self.do_move)
68+
self.submit_periodic_task(0.005, self.do_move)
6869

6970
@contextmanager
7071
def left_click_scope(self):
@@ -82,20 +83,23 @@ def do_move(self):
8283
except TriggerDeactivateException as e:
8384
logger.info(f"auto_aim_task_deactivate {e}")
8485
self.running = False
85-
return
86-
self.handler.post(self.do_move)
86+
return False
8787

8888
def sleep_check(self, sec, check_signal_flag=True):
89-
remaining = sec
90-
step = 0.1
91-
while remaining > 0:
89+
if sec <= 0:
90+
return
91+
end_time = time.perf_counter() + sec
92+
step = 0.01
93+
while True:
94+
remaining = end_time - time.perf_counter()
95+
if remaining <= 0:
96+
break
9297
s = step if remaining > step else remaining
93-
self.sleep(s)
94-
remaining -= s
98+
time.sleep(s)
99+
if not self.manual_activate or not self._enabled or self.paused:
100+
raise TriggerDeactivateException
95101
if self._should_interrupt(check_signal_flag):
96102
self.switch_state()
97-
if not self.manual_activate:
98-
raise TriggerDeactivateException
99103

100104
def _should_interrupt(self, check_signal_flag: bool) -> bool:
101105
"""检查是否应该中断当前操作"""

0 commit comments

Comments
 (0)