Opt: Watch user config changes while waiting for new tasks (resolve #1176)

This commit is contained in:
LmeSzinc 2022-06-05 11:51:01 +08:00
parent e229954e4c
commit 3aafd4a5f2
3 changed files with 92 additions and 44 deletions

100
alas.py
View File

@ -2,7 +2,7 @@ import os
import re
import threading
import time
from datetime import datetime
from datetime import datetime, timedelta
import inflection
from cached_property import cached_property
@ -327,57 +327,71 @@ class AzurLaneAutoScript:
Args:
future (datetime):
"""
seconds = future.timestamp() - datetime.now().timestamp() + 1
if seconds <= 0:
logger.warning(f'Wait until {str(future)}, but sleep length < 0, skip waiting')
return
if self.stop_event is not None:
self.stop_event.wait(seconds)
if self.stop_event.is_set():
logger.info("Update event detected")
logger.info(f"[{self.config_name}] exited. Reason: Update")
exit(0)
else:
time.sleep(seconds)
Returns:
bool: True if wait finished, False if config changed.
"""
future = future + timedelta(seconds=1)
self.config.start_watching()
while 1:
if datetime.now() > future:
return True
if self.stop_event is not None:
if self.stop_event.is_set():
logger.info("Update event detected")
logger.info(f"[{self.config_name}] exited. Reason: Update")
exit(0)
time.sleep(5)
if self.config.should_reload():
return False
def get_next_task(self):
"""
Returns:
str: Name of the next task.
"""
while 1:
task = self.config.get_next()
self.config.task = task
self.config.bind(task)
task = self.config.get_next()
self.config.task = task
self.config.bind(task)
from module.base.resource import release_resources
if self.config.task.command != 'Alas':
release_resources(next_task=task.command)
from module.base.resource import release_resources
if self.config.task.command != 'Alas':
release_resources(next_task=task.command)
if task.next_run > datetime.now():
logger.info(f'Wait until {task.next_run} for task `{task.command}`')
method = self.config.Optimization_WhenTaskQueueEmpty
if method == 'close_game':
logger.info('Close game during wait')
self.device.app_stop()
release_resources()
self.wait_until(task.next_run)
self.run('start')
elif method == 'goto_main':
logger.info('Goto main page during wait')
self.run('goto_main')
release_resources()
self.wait_until(task.next_run)
elif method == 'stay_there':
logger.info('Stay there during wait')
release_resources()
self.wait_until(task.next_run)
else:
logger.warning(f'Invalid Optimization_WhenTaskQueueEmpty: {method}, fallback to stay_there')
release_resources()
self.wait_until(task.next_run)
if task.next_run > datetime.now():
logger.info(f'Wait until {task.next_run} for task `{task.command}`')
method = self.config.Optimization_WhenTaskQueueEmpty
if method == 'close_game':
logger.info('Close game during wait')
self.device.app_stop()
release_resources()
if not self.wait_until(task.next_run):
del self.__dict__['config']
continue
self.run('start')
elif method == 'goto_main':
logger.info('Goto main page during wait')
self.run('goto_main')
release_resources()
if not self.wait_until(task.next_run):
del self.__dict__['config']
continue
elif method == 'stay_there':
logger.info('Stay there during wait')
release_resources()
if not self.wait_until(task.next_run):
del self.__dict__['config']
continue
else:
logger.warning(f'Invalid Optimization_WhenTaskQueueEmpty: {method}, fallback to stay_there')
release_resources()
if not self.wait_until(task.next_run):
del self.__dict__['config']
continue
break
AzurLaneConfig.is_hoarding_task = False
return task.command

View File

@ -9,6 +9,7 @@ from module.base.filter import Filter
from module.config.config_generated import GeneratedConfig
from module.config.config_manual import ManualConfig, OutputConfig
from module.config.config_updater import ConfigUpdater
from module.config.watcher import ConfigWatcher
from module.config.utils import *
from module.exception import RequestHumanTakeover, ScriptError
from module.logger import logger
@ -55,7 +56,7 @@ def name_to_function(name):
return function
class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig):
class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig, ConfigWatcher):
stop_event: threading.Event = None
bound = {}

33
module/config/watcher.py Normal file
View File

@ -0,0 +1,33 @@
import os
from datetime import datetime
from module.config.utils import filepath_config, DEFAULT_TIME
from module.logger import logger
class ConfigWatcher:
config_name = 'alas'
start_mtime = DEFAULT_TIME
def start_watching(self) -> None:
self.start_mtime = self.get_mtime()
def get_mtime(self) -> datetime:
"""
Last modify time of the file
"""
timestamp = os.stat(filepath_config(self.config_name)).st_mtime
mtime = datetime.fromtimestamp(timestamp).replace(microsecond=0)
return mtime
def should_reload(self) -> bool:
"""
Returns:
bool: Whether the file has been modified and configs should reload
"""
mtime = self.get_mtime()
if mtime > self.start_mtime:
logger.info(f'Config "{self.config_name}" changed at {mtime}')
return True
else:
return False