多线程

This commit is contained in:
daiqingshuang
2025-05-27 16:03:26 +08:00
parent 5bbd8454db
commit fc9c8dbb44
7 changed files with 339 additions and 219 deletions

View File

@@ -19,25 +19,28 @@ BranchSelector::BranchSelector(wxWindow* parent, std::shared_ptr<git::Repository
// 创建下拉列表
branch_combo_ = new wxComboBox(this, wxID_ANY);
// 填充分支列表
const auto& branches = repo->GetAllBranches();
for (const auto& branch : branches.value()) {
branch_combo_->Append(branch);
}
auto result = repo->GetCurrentBranchName();
// 选择当前分支
if (!result.has_value()) {
ProcessResult(result);
return;
}
branch_combo_->SetStringSelection(result.value());
// 布局
hbox->Add(label_ctrl, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
hbox->Add(branch_combo_, 1);
SetSizerAndFit(hbox);
// 填充分支列表
repo->GetAllBranches([this](const std::expected<std::vector<std::string>, std::string>& branches) {
for (const auto& branch : branches.value()) {
branch_combo_->Append(branch);
}
});
repo->GetCurrentBranchName([this](const std::expected<std::string, std::string>& result) {
// 选择当前分支
if (!result.has_value()) {
ProcessResult(result);
}
else {
branch_combo_->SetStringSelection(result.value());
}
});
}
bool BranchSelector::SelectBranch(const wxString& branch_name) {
@@ -81,22 +84,55 @@ std::string BranchSelector::GetSelectedBranchName() const {
return branch_combo_->GetStringSelection().ToStdString();
}
std::expected<std::string, std::string> BranchSelector::ApplyBranchChange() {
void BranchSelector::ApplyBranchChange() {
const std::string selected_branch = GetSelectedBranchName();
if (selected_branch.empty()) {
return std::unexpected("No branch selected");
return;
}
// 先切换分支
if (auto switch_result = repo_->SwitchBranch(selected_branch); !switch_result.has_value()) { return switch_result; }
repo_->SwitchBranch(selected_branch, [this](const git::result_t& result) {
ProcessResult(result);
if (!result.has_value()) {
wxLogError("%s SwitchBranch: %s", repo_->GetName(), result.error());
return;
}
wxLogInfo("%s SwitchBranch: %s", repo_->GetName(), result.value());
// 分支切换成功后,更新当前分支名称
branch_combo_->SetStringSelection(result.value());
// 如果需要硬重置
if (ConfigManager::Instance().GetHardReset()) {
if (auto reset_result = repo_->HardReset(); !reset_result) { return reset_result; }
}
// 如果需要硬重置
if (ConfigManager::Instance().GetHardReset()) {
repo_->HardReset([this](const git::result_t& reset_result) {
ProcessResult(reset_result);
if (!reset_result.has_value()) {
wxLogError("%s HardReset: %s", repo_->GetName(), reset_result.error());
return;
}
// 拉取更新
return repo_->Pull();
wxLogInfo("%s HardReset: %s", repo_->GetName(), reset_result.value());
// 拉取更新
repo_->Pull([this](const git::result_t& pull_result) {
ProcessResult(pull_result);
if (!pull_result.has_value()) {
wxLogError("%s Pull: %s", repo_->GetName(), pull_result.error());
} else {
wxLogInfo("%s Pull: %s", repo_->GetName(), pull_result.value());
}
});
});
}
else {
// 拉取更新
repo_->Pull([this](const git::result_t& pull_result) {
ProcessResult(pull_result);
if (!pull_result.has_value()) {
wxLogError("%s Pull: %s", repo_->GetName(), pull_result.error());
} else {
wxLogInfo("%s Pull: %s", repo_->GetName(), pull_result.value());
}
});
}
});
}
void BranchSelector::OnBranchSelected(wxCommandEvent& event) {

View File

@@ -12,8 +12,7 @@ public:
bool SelectGroupBranch(const wxString& group_name);
std::string GetSelectedBranchName() const;
std::expected<std::string, std::string> ApplyBranchChange();
bool HardReset() const { return repo_->HardReset().has_value(); }
void ApplyBranchChange();
std::shared_ptr<git::Repository> GetRepo() const { return repo_; }
@@ -21,10 +20,10 @@ public:
void ProcessResult(const std::expected<Value, ErrMsg>& in_expected) {
if (in_expected.has_value()) {
label_ctrl->SetForegroundColour(*wxGREEN);
label_ctrl->SetToolTip(in_expected.value());
label_ctrl->SetToolTip(wxString::FromUTF8(in_expected.value()));
} else {
label_ctrl->SetForegroundColour(*wxRED);
label_ctrl->SetToolTip(in_expected.error());
label_ctrl->SetToolTip(wxString::FromUTF8(in_expected.error()));
}
label_ctrl->Refresh(true);
}

View File

@@ -2,24 +2,32 @@
#include <algorithm>
#include <direct.h>
#include <bits/this_thread_sleep.h>
#include <wx/process.h>
#include <wx/txtstrm.h>
#include "git_command.h"
#include "task_manager.h"
std::expected<std::string, std::string> ExecGitCommand(
const std::string& cmd,
const std::filesystem::path& path) {
wxProcess* CreateGitProcess(const std::string& cmd, const std::filesystem::path& path) {
// 使用完整路径执行命令,避免改变工作目录
std::string fullCmd = "git -C \"" + path.string() + "\" " + cmd;
std::string full_cmd = "git -C \"" + path.string() + "\" " + cmd;
wxProcess process;
process.Redirect();
long exit_code = wxExecute(fullCmd, wxEXEC_SYNC | wxEXEC_HIDE_CONSOLE, &process);
// ReSharper disable once CppDFAMemoryLeak
wxProcess* process = new wxProcess();
process->Redirect();
wxExecute(full_cmd, wxEXEC_ASYNC | wxEXEC_HIDE_CONSOLE | wxUSE_STREAMS, process);
return process;
}
git::result_t ExecGitCommand(wxProcess* process) {
while (wxProcess::Exists(process->GetPid())) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
// 读取输出
wxString process_result;
if (wxInputStream* stream = process.GetInputStream()) {
if (wxInputStream* stream = process->GetInputStream(); process->IsInputAvailable()) {
wxTextInputStream tis(*stream);
while (!stream->Eof()) {
process_result += tis.ReadLine() + "\n";
@@ -28,100 +36,179 @@ std::expected<std::string, std::string> ExecGitCommand(
// 读取错误输出
wxString error_result;
if (wxInputStream* errorStream = process.GetErrorStream()) {
if (wxInputStream* errorStream = process->GetErrorStream(); process->IsErrorAvailable()) {
wxTextInputStream tis(*errorStream, wxT("\n"), wxConvUTF8);
while (!errorStream->Eof()) {
error_result += tis.ReadLine() + "\n";
const auto& line = tis.ReadLine();
if (!line.empty())
error_result += line + "\n";
}
}
// 检查命令是否成功
if (!error_result.empty() && exit_code != 0) {
return std::unexpected("Git command failed: " + error_result.ToStdString());
while (!error_result.empty()) {
if (error_result.Contains("Switched to branch"))
break;
if (error_result.Contains("Already on"))
break;
if (error_result.Contains("Updating files"))
break;
return std::unexpected("git命令失败: " + error_result.ToStdString());
}
return process_result.ToStdString();
}
void GitCommandTask(const std::string& cmd, const std::filesystem::path& path, std::function<void(git::result_t)> callback) {
wxASSERT_MSG(wxIsMainThread(), "GitCommandTask must be called from the main thread");
const auto process = CreateGitProcess(cmd, path);
if (!process) {
callback(std::unexpected("无法启动git进程: " + cmd));
return;
}
TaskManager::Get().PushTask([process] {
return ExecGitCommand(process);
}, callback);
// ReSharper disable once CppDFAMemoryLeak
}
git::Repository::Repository(const std::filesystem::path& in_path) {
path_ = in_path;
name_ = path_.filename().string();
}
std::expected<std::string, std::string> git::Repository::SwitchBranch(const std::string& in_branch) {
void git::Repository::SwitchBranch(const std::string& in_branch, const std::function<void(result_t)>& in_callback) {
const std::string cmd = "checkout " + in_branch;
auto result = ExecGitCommand(cmd, path_);
if (result)
branch_ = in_branch;
return result;
GitCommandTask(cmd, path_, [this, in_branch, in_callback](result_t result) {
if (result.has_value()) {
const std::unique_lock u_lock(branch_name_mutex_);
branch_ = in_branch;
}
in_callback(result);
});
}
std::expected<std::string, std::string> git::Repository::HardReset() {
return ExecGitCommand("reset --hard", path_);
void git::Repository::HardReset(const std::function<void(result_t)>& in_callback) {
GitCommandTask("reset --hard", path_, [in_callback](result_t result) {
in_callback(result);
});
}
std::expected<std::string, std::string> git::Repository::Pull() {
return ExecGitCommand("pull", path_);
void git::Repository::Pull(const std::function<void(result_t)>& in_callback) {
GitCommandTask("pull", path_, [in_callback](result_t result) {
in_callback(result);
});
}
void git::Repository::GetSubmodules(const std::function<void(submodules_t)>& in_callback) const {
{
std::shared_lock s_lock(submodules_mutex_);
if (!submodules_.empty()) {
in_callback(submodules_);
return;
}
}
GitCommandTask("submodule", path_, [this, in_callback](result_t result) {
if (!result.has_value()) {
in_callback(std::unexpected(result.error()));
return;
}
std::vector<std::shared_ptr<git::Repository>> submodules;
std::istringstream iss(result.value());
std::string line;
while (std::getline(iss, line)) {
// 截取第一个空格到第二个空格之间的内容
const size_t first_space = line.find(' ', 1);
const size_t second_space = line.find(' ', first_space + 1);
if (first_space != std::string::npos && second_space != std::string::npos) {
std::string submodule_path = line.substr(first_space + 1, second_space - first_space - 1);
std::filesystem::path submodule_full_path = path_ / submodule_path;
auto submodule_repo = std::make_shared<Repository>(submodule_full_path);
submodules.push_back(submodule_repo);
}
}
const std::unique_lock u_lock(submodules_mutex_);
submodules_ = submodules;
in_callback(submodules);
});
}
void git::Repository::GetCurrentBranchName(const std::function<void(result_t)>& in_callback) const {
std::shared_lock s_lock(branch_name_mutex_);
if (branch_) {
in_callback(branch_.value());
return;
}
GitCommandTask("rev-parse --abbrev-ref HEAD", path_, [this, in_callback](result_t result) {
if (!result.has_value()) {
in_callback(std::unexpected(result.error()));
return;
}
std::string branch_name = result.value();
std::erase(branch_name, '\n'); // Remove trailing newline
const std::unique_lock u_lock(branch_name_mutex_);
branch_ = branch_name;
in_callback(branch_name);
});
}
void git::Repository::GetAllBranches(
const std::function<void(branches_t)>& in_callback) const {
{
std::shared_lock s_lock(all_branches_mutex_);
if (!all_branches_.empty()) {
in_callback(all_branches_);
return;
}
}
GitCommandTask("branch", path_, [this, in_callback](result_t result) {
if (!result.has_value()) {
in_callback(std::unexpected(result.error()));
return;
}
std::vector<std::string> branches;
std::istringstream iss(result.value());
std::string line;
while (std::getline(iss, line)) {
if (!line.empty()) {
branches.push_back(line.substr(2)); // Remove the leading "* " or " "
}
}
const std::unique_lock u_lock(all_branches_mutex_);
all_branches_ = branches;
in_callback(branches);
});
}
std::expected<std::vector<std::shared_ptr<git::Repository>>, std::string> git::Repository::GetSubmodules() const {
if (!submodules_.empty())
std::shared_lock s_lock(submodules_mutex_);
if (!submodules_.empty()) {
return submodules_;
std::vector<std::shared_ptr<git::Repository>> submodules;
std::string cmd = "submodule";
auto result = ExecGitCommand(cmd, path_);
if (!result.has_value())
return std::unexpected(result.error());
std::istringstream iss(result.value());
std::string line;
while (std::getline(iss, line)) {
// 截取第一个空格到第二个空格之间的内容
const size_t first_space = line.find(' ', 1);
const size_t second_space = line.find(' ', first_space + 1);
if (first_space != std::string::npos && second_space != std::string::npos) {
std::string submodule_path = line.substr(first_space + 1, second_space - first_space - 1);
std::filesystem::path submodule_full_path = path_ / submodule_path;
auto submodule_repo = std::make_shared<Repository>(submodule_full_path);
submodules.push_back(submodule_repo);
}
}
submodules_ = submodules;
return submodules;
return std::unexpected("No submodules available");
}
std::expected<std::string, std::string> git::Repository::GetCurrentBranchName() const {
if (branch_)
return branch_.value();
const std::string cmd = "rev-parse --abbrev-ref HEAD";
auto result = ExecGitCommand(cmd, path_);
if (!result.has_value())
return result;
auto& str = result.value();
str.replace(str.find('\n'), 2, ""); // Remove trailing newline
branch_ = str;
return result;
std::shared_lock s_lock(branch_name_mutex_);
if (branch_) {
return *branch_;
}
return std::unexpected("No current branch set");
}
std::expected<std::vector<std::string>, std::string> git::Repository::GetAllBranches() const {
std::shared_lock s_lock(all_branches_mutex_);
if (!all_branches_.empty())
return all_branches_;
std::vector<std::string> branches;
const std::string cmd = "branch";
auto result = ExecGitCommand(cmd, path_);
if (!result.has_value())
return std::unexpected(result.error());
std::istringstream iss(result.value());
std::string line;
while (std::getline(iss, line)) {
if (!line.empty()) {
branches.push_back(line.substr(2)); // Remove the leading "* " or " "
}
}
all_branches_ = branches;
return branches;
return std::unexpected("No branches available");
}
bool git::Repository::IsValid() const {

View File

@@ -4,21 +4,37 @@
#include <string>
#include <vector>
#include <expected>
#include <functional>
#include <shared_mutex>
namespace git {
class Repository;
using result_t = std::expected<std::string, std::string>;
using submodules_t = std::expected<std::vector<std::shared_ptr<Repository>>, std::string>;
using branches_t = std::expected<std::vector<std::string>, std::string>;
class Repository {
public:
explicit Repository(const std::filesystem::path& in_path);
std::expected<std::string, std::string> SwitchBranch(const std::string& in_branch);
std::expected<std::string, std::string> HardReset();
std::expected<std::string, std::string> Pull();
void SwitchBranch(const std::string& in_branch, const std::function<void(result_t)>& in_callback);
void HardReset(const std::function<void(result_t)>& in_callback);
void Pull(const std::function<void(result_t)>& in_callback);
void GetSubmodules(const std::function<void(submodules_t)>& in_callback) const;
void GetCurrentBranchName(const std::function<void(result_t)>& in_callback) const;
void GetAllBranches(const std::function<void(branches_t)>& in_callback) const;
[[nodiscard]] std::expected<std::vector<std::shared_ptr<Repository>>, std::string> GetSubmodules() const;
[[nodiscard]] std::expected<std::string, std::string> GetCurrentBranchName() const;
[[nodiscard]] std::expected<std::vector<std::string>, std::string> GetAllBranches() const;
[[nodiscard]] auto GetName() const { return name_; }
[[nodiscard]] std::expected<std::string, std::string> GetCurrentBranchName() const;
[[nodiscard]] std::expected<std::vector<std::string>, std::string> GetAllBranches() const;
[[nodiscard]] auto GetName() const { return name_; }
[[nodiscard]] bool IsValid() const;
private:
std::string name_;
@@ -26,6 +42,10 @@ namespace git {
mutable std::vector<std::shared_ptr<Repository>> submodules_;
mutable std::optional<std::string> branch_;
mutable std::vector<std::string> all_branches_;
// mutable std::shared_mutex mutex_;
mutable std::shared_mutex branch_name_mutex_;
mutable std::shared_mutex all_branches_mutex_;
mutable std::shared_mutex submodules_mutex_;
};
std::shared_ptr<Repository> OpenRepository(const std::filesystem::path& in_path);

View File

@@ -17,14 +17,6 @@ public:
}
}
// 打开主仓库
std::string repo_path = config.GetRepositoryPath();
auto repo = git::OpenRepository(repo_path);
if (!repo) {
wxMessageBox("Failed to open repository: " + repo_path, "Error", wxICON_ERROR);
return false;
}
// 创建并显示主窗口
auto* frame = new MainFrame("Git Branch Manager");
frame->Show(true);

View File

@@ -37,69 +37,69 @@ MainFrame::MainFrame(const wxString& title)
// 初始化UI
InitializeUI();
// 设置分支组
PopulateBranchGroups();
}
void MainFrame::InitializeUI() {
// 创建主布局
main_sizer_ = new wxBoxSizer(wxVERTICAL);
// 创建日志控件
log_ctrl_ = new ColoredLogCtrl(this);
// 创建分支组选择器
group_combo_ = new wxComboBox(this, wxID_ANY);
main_repo_->GetSubmodules([this](const git::submodules_t& submodules){
if (!submodules) {
// 弹出窗口报错
wxMessageBox(wxString::Format(wxString::FromUTF8("获取子模块失败: %s"), submodules.error()), "Error", wxICON_ERROR);
return;
}
// 创建主布局
main_sizer_ = new wxBoxSizer(wxVERTICAL);
// 创建日志控件
log_ctrl_ = new ColoredLogCtrl(this);
// 创建分支组选择器
group_combo_ = new wxComboBox(this, wxID_ANY);
// 创建主仓库分支选择器
branch_selectors_.push_back(new BranchSelector(this, main_repo_, wxString::FromUTF8("主仓库")));
// 创建子模块分支选择器
auto submodules = main_repo_->GetSubmodules();
for (const auto& submodule: submodules.value()) {
branch_selectors_.push_back(new BranchSelector(this, submodule));
}
// 创建主仓库分支选择器
branch_selectors_.push_back(new BranchSelector(this, main_repo_, wxString::FromUTF8("主仓库")));
// 创建子模块分支选择器
for (const auto& submodule: submodules.value()) {
branch_selectors_.push_back(new BranchSelector(this, submodule));
}
// 创建硬重置选项
hard_reset_checkbox_ = new wxCheckBox(this, wxID_ANY, "Hard reset");
hard_reset_checkbox_->SetValue(is_hard_reset_);
// 创建硬重置选项
hard_reset_checkbox_ = new wxCheckBox(this, wxID_ANY, "Hard reset");
hard_reset_checkbox_->SetValue(is_hard_reset_);
// 创建应用按钮
apply_button_ = new wxButton(this, wxID_APPLY, "Apply");
// 创建应用按钮
apply_button_ = new wxButton(this, wxID_APPLY, "Apply");
// 添加分支组选择器
main_sizer_->Add(group_combo_, 0, wxEXPAND | wxALL, 5);
// 添加分支选择器
main_sizer_->Add(group_combo_, 0, wxEXPAND | wxALL, 5);
// 添加所有分支选择器到布局
for (auto selector: branch_selectors_) { main_sizer_->Add(selector, 0, wxEXPAND | wxALL, 5); }
// 添加所有分支选择器到布局
for (auto selector: branch_selectors_) {
main_sizer_->Add(selector, 0, wxEXPAND | wxALL, 5);
}
main_sizer_->Add(hard_reset_checkbox_, 0, wxALL, 5);
main_sizer_->Add(apply_button_, 0, wxALL, 5);
main_sizer_->Add(hard_reset_checkbox_, 0, wxALL, 5);
main_sizer_->Add(apply_button_, 0, wxALL, 5);
// 添加日志控件
main_sizer_->Add(log_ctrl_, 1, wxEXPAND | wxALL, 5);
// 添加日志控件
main_sizer_->Add(log_ctrl_, 1, wxEXPAND | wxALL, 5);
SetSizerAndFit(main_sizer_);
SetSize(wxSize(600, 400));
SetMinSize(wxSize(600, 400));
SetSizerAndFit(main_sizer_);
SetSize(wxSize(600, 400));
SetMinSize(wxSize(600, 400));
// 设置分支组
CallAfter([this] { PopulateBranchGroups(); });
});
}
void MainFrame::PopulateBranchGroups() {
apply_button_->Enable(false); // 初始时禁用应用按钮
auto task = [this] -> std::vector<std::string> {
main_repo_->GetAllBranches([this](const std::expected<std::vector<std::string>, std::string>& branches) {
// 获取所有分支组
std::vector<std::string> branch_groups;
auto result = main_repo_->GetAllBranches();
if (!result.has_value()) {
log_ctrl_->LogError(wxString::Format(wxString::FromUTF8("获取主仓库分支失败: %s"),
result.error()));
return {};
if (!branches.has_value()) {
log_ctrl_->LogError(wxString::Format(wxString::FromUTF8("获取主仓库分支失败: %s"), branches.error()));
return;
}
// 获取主仓库的所有分支
for (const auto& branch: result.value()) { branch_groups.push_back(branch); }
for (const auto& branch: branches.value()) { branch_groups.push_back(branch); }
// 获取子模块的所有分支
auto submodules = main_repo_->GetSubmodules();
@@ -107,8 +107,8 @@ void MainFrame::PopulateBranchGroups() {
auto r = submodule->GetAllBranches();
if (!r.has_value()) {
log_ctrl_->LogError(wxString::Format(wxString::FromUTF8("获取子模块 %s 的分支失败: %s"),
submodule->GetName(),
r.error()));
submodule->GetName(),
r.error()));
continue;
}
for (const auto& branch: r.value()) { branch_groups.push_back(branch); }
@@ -116,23 +116,20 @@ void MainFrame::PopulateBranchGroups() {
// 去重
std::ranges::sort(branch_groups);
branch_groups.erase(std::ranges::unique(branch_groups).begin(),
branch_groups.end());
return branch_groups;
};
auto callback = [this](std::vector<std::string> branch_groups) {
branch_groups.erase(std::ranges::unique(branch_groups).begin(), branch_groups.end());
// 填充分支组
for (const auto& group: branch_groups) { group_combo_->Append(group); }
apply_button_->Enable(true);
if (group_combo_->GetCount() > 0) {
if (auto result = main_repo_->GetCurrentBranchName()) {
log_ctrl_->LogInfo(wxString::Format(wxString::FromUTF8("当前分支: %s"), result.value()));
group_combo_->SetStringSelection(result.value());
if (auto branch_name = main_repo_->GetCurrentBranchName()) {
log_ctrl_->LogInfo(wxString::Format(wxString::FromUTF8("当前分支: %s"), branch_name.value()));
group_combo_->SetStringSelection(branch_name.value());
}
else {
log_ctrl_->LogError(wxString::Format(wxString::FromUTF8("获取当前分支失败: %s, 将使用默认分支 Develop"),
result.error()));
branch_name.error()));
group_combo_->SetStringSelection("Develop");
}
wxCommandEvent event(wxEVT_COMBOBOX);
@@ -141,68 +138,57 @@ void MainFrame::PopulateBranchGroups() {
else { log_ctrl_->LogError(wxString::FromUTF8("没有可用的分支")); }
// 置顶窗口
Raise();
};
TaskManager::Get().PushTask(task, callback);
});
}
void MainFrame::OnApply(wxCommandEvent& event) {
// 禁用按钮防止重复点击
wxButton* apply_button = wxDynamicCast(event.GetEventObject(), wxButton);
if (apply_button) { apply_button->Enable(false); }
// 创建进度对话框
auto* progress = new wxProgressDialog(wxString::FromUTF8("应用修改"),
wxString::FromUTF8("处理中..."),
branch_selectors_.size(),
this,
wxPD_AUTO_HIDE | wxPD_APP_MODAL);
log_ctrl_->LogInfo(wxString::FromUTF8("...开始应用修改..."));
for (auto branch_selector : branch_selectors_) {
auto selector = branch_selector;
selector->ApplyBranchChange();
TaskManager::Get().PushTask(
[selector, this]() -> std::expected<std::string, std::string> {
return selector->ApplyBranchChange();
},
[this, progress, selector, apply_button]
(const std::expected<std::string, std::string>& result) {
const auto& log_str = wxString::Format(wxString::FromUTF8("%s => %s"), selector->GetRepo()->GetName(), result ? result.value() : result.error());
if (result) {
log_ctrl_->LogSuccess(TrimTrailingNewline(log_str));
} else {
log_ctrl_->LogError(TrimTrailingNewline(log_str));
}
selector->ProcessResult(result);
if (!result.has_value()) {
has_errors = true;
log_ctrl_->LogError(selector->GetRepo()->GetName() + wxString::FromUTF8(" 操作失败: ") + result.error());
}
++completed;
progress->Update(completed);
// 所有任务完成
if (completed == branch_selectors_.size()) {
if (apply_button) {
apply_button->Enable(true);
}
if (has_errors) {
wxMessageBox(wxString::FromUTF8("某些操作失败,请检查日志。"),
"Warning", wxICON_WARNING);
} else {
log_ctrl_->LogInfo(wxString::FromUTF8("所有操作已成功完成。"));
}
completed = 0; // 重置计数器
has_errors = false; // 重置错误状态
delete progress;
}
}
);
// TaskManager::Get().PushTask(
// [selector, this] {
// return selector->ApplyBranchChange();
// },
// [this, progress, selector, apply_button]
// (const git::result_t& result) {
// const auto& log_str = wxString::Format(wxString::FromUTF8("%s => %s"), selector->GetRepo()->GetName(), result ? result.value() : result.error());
// if (result) {
// log_ctrl_->LogSuccess(TrimTrailingNewline(log_str));
// } else {
// log_ctrl_->LogError(TrimTrailingNewline(log_str));
// }
//
// selector->ProcessResult(result);
// if (!result.has_value()) {
// has_errors = true;
// log_ctrl_->LogError(selector->GetRepo()->GetName() + wxString::FromUTF8(" 操作失败: ") + result.error());
// }
//
// ++completed;
// progress->Update(completed);
//
// // 所有任务完成
// if (completed == branch_selectors_.size()) {
// if (apply_button) {
// apply_button->Enable(true);
// }
//
// if (has_errors) {
// wxMessageBox(wxString::FromUTF8("某些操作失败,请检查日志。"),
// "Warning", wxICON_WARNING);
// } else {
// log_ctrl_->LogInfo(wxString::FromUTF8("所有操作已成功完成。"));
// }
//
// completed = 0; // 重置计数器
// has_errors = false; // 重置错误状态
// delete progress;
// }
// }
// );
}
}

View File

@@ -65,7 +65,7 @@ public:
private:
TaskManager() : shutdown_(false) {
// 创建工作线程池
const size_t num_threads = std::thread::hardware_concurrency();
const size_t num_threads = 4;
for (size_t i = 0; i < num_threads; ++i) {
workers_.emplace_back(&TaskManager::WorkerThread, this);
}
@@ -75,7 +75,7 @@ private:
while (true) {
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(queue_mutex_);
std::unique_lock lock(queue_mutex_);
cv_.wait(lock, [this] { return shutdown_ || !tasks_.empty(); });
if (shutdown_ && tasks_.empty()) {