diff --git a/src/MeoAssistant/Task/Sub/ProcessTask.cpp b/src/MeoAssistant/Task/Sub/ProcessTask.cpp index 650d9cd67d..dab9e4d9b8 100644 --- a/src/MeoAssistant/Task/Sub/ProcessTask.cpp +++ b/src/MeoAssistant/Task/Sub/ProcessTask.cpp @@ -78,11 +78,65 @@ ProcessTask& asst::ProcessTask::set_rear_delay(std::string name, int delay) return *this; } +bool ProcessTask::generate_tasks(const std::vector& raw_tasks) +{ + for (const std::string& task : raw_tasks) { + size_t pos = task.find('#'); + if (pos == std::string_view::npos) { + m_cur_tasks_name.emplace_back(task); + continue; + } + std::string other_task_name = task.substr(0, pos); + std::string type = task.substr(pos + 1); + auto other_tasklist_ref = Task.get(other_task_name); + if (other_tasklist_ref == nullptr) { + Log.error(task, "not found"); + continue; + } + +#define ASST_PROCESSTASK_GENERATE_TASKS(t) \ + else if (type == #t) \ + { \ + if (!generate_tasks(other_tasklist_ref->t)) { \ + return false; \ + } \ + } + if constexpr (false) {} + ASST_PROCESSTASK_GENERATE_TASKS(next) + ASST_PROCESSTASK_GENERATE_TASKS(sub) + ASST_PROCESSTASK_GENERATE_TASKS(on_error_next) + ASST_PROCESSTASK_GENERATE_TASKS(exceeded_next) + ASST_PROCESSTASK_GENERATE_TASKS(reduce_other_times) + else { + Log.error("Unknown type", type); + return false; + } + } +#undef ASST_PROCESSTASK_GENERATE_TASKS + + return true; +} + +bool ProcessTask::generate_tasks() +{ + // std::move 后 m_cur_tasks_name 已经为空 + std::vector cur_tasks_name = std::move(m_cur_tasks_name); + if (!generate_tasks(cur_tasks_name)) [[unlikely]] { + Log.error("Generate task failed."); + m_cur_tasks_name.clear(); + return false; + } + return true; +} + bool ProcessTask::_run() { LogTraceFunction; while (!m_cur_tasks_name.empty()) { + if (!generate_tasks()) { + return false; + } if (need_exit()) { return false; } diff --git a/src/MeoAssistant/Task/Sub/ProcessTask.h b/src/MeoAssistant/Task/Sub/ProcessTask.h index 763e06ba9f..e9ef01c472 100644 --- a/src/MeoAssistant/Task/Sub/ProcessTask.h +++ b/src/MeoAssistant/Task/Sub/ProcessTask.h @@ -41,6 +41,8 @@ namespace asst virtual json::value basic_info() const override; std::pair calc_time_limit() const; + bool generate_tasks(const std::vector& raw_tasks); + bool generate_tasks(); void exec_click_task(const Rect& matched_rect); void exec_swipe_task(ProcessTaskAction action); void exec_slowly_swipe_task(ProcessTaskAction action); diff --git a/src/MeoAssistant/TaskData.cpp b/src/MeoAssistant/TaskData.cpp index 1bfc492a08..1a53c91127 100644 --- a/src/MeoAssistant/TaskData.cpp +++ b/src/MeoAssistant/TaskData.cpp @@ -62,9 +62,26 @@ bool asst::TaskData::parse(const json::value& json) // TODO: 这块感觉可以合并到 syntax_check 里 for (const auto& [name, task] : m_all_tasks_info) { for (const auto& next : task->next) { - if (get(next, false) == nullptr) { - Log.error(name, "'s next", next, "is null"); - validity = false; + size_t pos = next.find('#'); + if (pos == std::string_view::npos) { + if (get(next, false) == nullptr) { + Log.error(name, "'s next", next, "is null"); + validity = false; + } + } + else { + if (get(next.substr(0, pos), false) == nullptr) { + Log.error(name, "'s next", next, "is null"); + validity = false; + } + static const std::unordered_set accepted_type = { + "next", "sub", "on_error_next", "exceeded_next", "reduce_other_times", + }; + std::string type = next.substr(pos + 1); + if (!accepted_type.contains(type)) { + Log.error(name, "'s next", next, "has unknown type:", type); + validity = false; + } } } }