diff --git a/src/MeoAssistant/Assistant.cpp b/src/MeoAssistant/Assistant.cpp index b955d40dc2..ae815cc80a 100644 --- a/src/MeoAssistant/Assistant.cpp +++ b/src/MeoAssistant/Assistant.cpp @@ -62,12 +62,19 @@ bool asst::Assistant::connect(const std::string& adb_path, const std::string& ad std::unique_lock lock(m_mutex); - stop(false); + // 仍有任务进行,connect 前需要 stop + if (!m_thread_idle) { + return false; + } + + m_thread_idle = false; bool ret = m_ctrler->connect(adb_path, address, config.empty() ? "General" : config); if (ret) { m_uuid = m_ctrler->get_uuid(); } + + m_thread_idle = true; return ret; } diff --git a/src/MeoAssistant/Controller.cpp b/src/MeoAssistant/Controller.cpp index af838d8a58..6386d98cdb 100644 --- a/src/MeoAssistant/Controller.cpp +++ b/src/MeoAssistant/Controller.cpp @@ -263,6 +263,9 @@ std::optional asst::Controller::call_command(const std::string& cmd } while (true) { + if (need_exit()) { + break; + } wait_handles.clear(); if (process_running) wait_handles.push_back(process_info.hProcess); if (!pipe_eof) wait_handles.push_back(pipeov.hEvent); @@ -272,7 +275,7 @@ std::optional asst::Controller::call_command(const std::string& cmd if (wait_handles.empty()) break; auto elapsed = steady_clock::now() - start_time; auto wait_time = - (std::min)(timeout - duration_cast(elapsed).count(), process_running ? 0xFFFFFFFELL : 0LL); + (std::min)(timeout - duration_cast(elapsed).count(), process_running ? 5LL * 1000 : 0LL); if (wait_time < 0) break; auto wait_result = WaitForMultipleObjectsEx((DWORD)wait_handles.size(), &wait_handles[0], FALSE, (DWORD)wait_time, TRUE); @@ -440,7 +443,11 @@ std::optional asst::Controller::call_command(const std::string& cmd reconnect_info["details"]["times"] = i; callback(AsstMsg::ConnectionInfo, reconnect_info); + // TODO: 应该有外部中断 sleep 的写法吧?现在只能在开始或者结束 sleep 的时候判断( std::this_thread::sleep_for(10s); + if (need_exit()) { + break; + } auto reconnect_ret = call_command(m_adb.connect, 60LL * 1000, false, false /* 禁止重连避免无限递归 */); bool is_reconnect_success = false; if (reconnect_ret) { @@ -1025,6 +1032,10 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a }); }; + if (need_exit()) { + return false; + } + /* connect */ { m_adb.connect = cmd_replace(adb_cfg.connect); @@ -1049,6 +1060,10 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a } } + if (need_exit()) { + return false; + } + /* get uuid (imei) */ { auto uuid_ret = call_command(cmd_replace(adb_cfg.uuid), 20000, false, false /* adb 连接时不允许重试 */); @@ -1073,6 +1088,10 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a callback(AsstMsg::ConnectionInfo, info); } + if (need_exit()) { + return false; + } + // 按需获取display ID 信息 if (!adb_cfg.display_id.empty()) { auto display_id_ret = call_command(cmd_replace(adb_cfg.display_id)); @@ -1092,6 +1111,10 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a display_id.pop_back(); } + if (need_exit()) { + return false; + } + /* display */ { auto display_ret = call_command(cmd_replace(adb_cfg.display)); @@ -1150,6 +1173,10 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a } } + if (need_exit()) { + return false; + } + /* calc ratio */ { constexpr double DefaultRatio = @@ -1205,6 +1232,10 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a } } + if (need_exit()) { + return false; + } + auto socket_opt = try_to_init_socket(bind_address); if (socket_opt) { nc_port = socket_opt.value(); diff --git a/src/MeoAsstGui/Helper/AsstProxy.cs b/src/MeoAsstGui/Helper/AsstProxy.cs index 0992a3f14f..5083b78195 100644 --- a/src/MeoAsstGui/Helper/AsstProxy.cs +++ b/src/MeoAsstGui/Helper/AsstProxy.cs @@ -371,6 +371,11 @@ namespace MeoAsstGui case "Disconnect": connected = false; mainModel.AddLog(Localization.GetString("ReconnectFailed"), LogColor.Error); + if (mainModel.Idle) + { + break; + } + AsstStop(); var settingsModel = _container.Get(); @@ -1002,6 +1007,11 @@ namespace MeoAsstGui { foreach (var address in settings.DefaultAddress[settings.ConnectConfig]) { + if (settings.Idle) + { + break; + } + ret = AsstConnect(_handle, settings.AdbPath, address, settings.ConnectConfig); if (ret) { diff --git a/src/MeoAsstGui/Resources/Localizations/en-us.xaml b/src/MeoAsstGui/Resources/Localizations/en-us.xaml index 9584f61ea4..d6310825df 100644 --- a/src/MeoAsstGui/Resources/Localizations/en-us.xaml +++ b/src/MeoAsstGui/Resources/Localizations/en-us.xaml @@ -235,6 +235,7 @@ Connecting to emulator... Unselected task Running... + Stopping... Has stopped Unknown error occurred Set successfully diff --git a/src/MeoAsstGui/Resources/Localizations/ja-jp.xaml b/src/MeoAsstGui/Resources/Localizations/ja-jp.xaml index e9a070783a..49c367854a 100644 --- a/src/MeoAsstGui/Resources/Localizations/ja-jp.xaml +++ b/src/MeoAsstGui/Resources/Localizations/ja-jp.xaml @@ -235,6 +235,7 @@ エミュレータ接続中…… タスクが選択されていません 動作中…… + 動作停止中…… 動作停止 不明なエラーが発生しました 設定に成功しました diff --git a/src/MeoAsstGui/Resources/Localizations/ko-kr.xaml b/src/MeoAsstGui/Resources/Localizations/ko-kr.xaml index e3b0fe7604..6e981f1f4b 100644 --- a/src/MeoAsstGui/Resources/Localizations/ko-kr.xaml +++ b/src/MeoAsstGui/Resources/Localizations/ko-kr.xaml @@ -234,7 +234,8 @@ 에뮬레이터에 연결중... 선택된 작업이 없다 실행중... - 정지됐다 + 멎는... + 멈췄다 예상치 못한 오류가 발생했습니다 설정 성공 설정 실패 diff --git a/src/MeoAsstGui/Resources/Localizations/pallas.xaml b/src/MeoAsstGui/Resources/Localizations/pallas.xaml index 3e9bfae033..6c6ec740b9 100644 --- a/src/MeoAsstGui/Resources/Localizations/pallas.xaml +++ b/src/MeoAsstGui/Resources/Localizations/pallas.xaml @@ -234,6 +234,7 @@ 🍸🕺🍻💃🕺 🍺🍸🍻 🍷🍻🍷🍺 + 🍷💃🍸 💃🍺 🕺🍸🍻🍷 🍸🍸🍺 diff --git a/src/MeoAsstGui/Resources/Localizations/zh-cn.xaml b/src/MeoAsstGui/Resources/Localizations/zh-cn.xaml index fa94880da8..8a5dcf2f30 100644 --- a/src/MeoAsstGui/Resources/Localizations/zh-cn.xaml +++ b/src/MeoAsstGui/Resources/Localizations/zh-cn.xaml @@ -235,6 +235,7 @@ 正在连接模拟器…… 未选择任务 正在运行中…… + 正在停止…… 已停止 出现未知错误 设置成功 diff --git a/src/MeoAsstGui/Resources/Localizations/zh-tw.xaml b/src/MeoAsstGui/Resources/Localizations/zh-tw.xaml index c117d6b0b6..5f12971ca1 100644 --- a/src/MeoAsstGui/Resources/Localizations/zh-tw.xaml +++ b/src/MeoAsstGui/Resources/Localizations/zh-tw.xaml @@ -235,6 +235,7 @@ 正在連接模擬器…… 未選擇任務 正在運行中…… + 正在停止…… 已停止 出現未知錯誤 設定成功 diff --git a/src/MeoAsstGui/ViewModels/TaskQueueViewModel.cs b/src/MeoAsstGui/ViewModels/TaskQueueViewModel.cs index 02076f282c..38b2cb4256 100644 --- a/src/MeoAsstGui/ViewModels/TaskQueueViewModel.cs +++ b/src/MeoAsstGui/ViewModels/TaskQueueViewModel.cs @@ -624,6 +624,13 @@ namespace MeoAsstGui return asstProxy.AsstConnect(ref errMsg, true); }); bool caught = await task; + + // 一般是点了“停止”按钮了 + if (Idle) + { + return; + } + if (!caught) { AddLog(errMsg, LogColor.Error); @@ -732,12 +739,18 @@ namespace MeoAsstGui /// /// Stops. /// - public void Stop() + public async void Stop() { - var asstProxy = _container.Get(); - asstProxy.AsstStop(); + Idle = true; // 提前将 Idle 置为 true + Stopping = true; + AddLog(Localization.GetString("Stopping")); + var task = Task.Run(() => + { + return _container.Get().AsstStop(); + }); + await task; AddLog(Localization.GetString("Stopped")); - Idle = true; + Stopping = false; } private bool appendStart() @@ -1254,6 +1267,17 @@ namespace MeoAsstGui } } + private bool _stopping = false; + + /// + /// Gets or sets a value indicating whether `stop` is awaiting. + /// + public bool Stopping + { + get => _stopping; + set => SetAndNotify(ref _stopping, value); + } + private bool _fightTaskRunning = false; /// diff --git a/src/MeoAsstGui/Views/TaskQueueView.xaml b/src/MeoAsstGui/Views/TaskQueueView.xaml index 7a82531ac8..6ff2b590ff 100644 --- a/src/MeoAsstGui/Views/TaskQueueView.xaml +++ b/src/MeoAsstGui/Views/TaskQueueView.xaml @@ -140,14 +140,15 @@ Command="{s:Action LinkStart}" Content="{DynamicResource LinkStart}" IsEnabled="{Binding Inited}" - Visibility="{c:Binding Path='Idle or !Inited'}" /> + Visibility="{c:Binding Path='(Idle and !Stopping) or !Inited'}" />