Browse Source

Added progress bar and possibility to cancel find usages and rename

pipelines/235045657
eidheim 6 years ago
parent
commit
5d6d664940
  1. 17
      src/dialogs.cpp
  2. 6
      src/dialogs.hpp
  3. 6
      src/source_clang.cpp
  4. 55
      src/usages_clang.cpp
  5. 1
      src/window.cpp
  6. 4
      tests/stubs/dialogs.cpp

17
src/dialogs.cpp

@ -1,7 +1,7 @@
#include "dialogs.hpp" #include "dialogs.hpp"
#include <cmath> #include <cmath>
Dialog::Message::Message(const std::string &text) : Gtk::Window(Gtk::WindowType::WINDOW_POPUP) { Dialog::Message::Message(const std::string &text, std::function<void()> &&on_cancel, bool show_progress_bar) : Gtk::Window(Gtk::WindowType::WINDOW_POPUP) {
auto g_application = g_application_get_default(); auto g_application = g_application_get_default();
auto gio_application = Glib::wrap(g_application, true); auto gio_application = Glib::wrap(g_application, true);
auto application = Glib::RefPtr<Gtk::Application>::cast_static(gio_application); auto application = Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
@ -17,6 +17,17 @@ Dialog::Message::Message(const std::string &text) : Gtk::Window(Gtk::WindowType:
auto label = Gtk::manage(new Gtk::Label(text)); auto label = Gtk::manage(new Gtk::Label(text));
label->set_padding(10, 10); label->set_padding(10, 10);
box->pack_start(*label); box->pack_start(*label);
if(on_cancel) {
auto cancel_button = Gtk::manage(new Gtk::Button("Cancel"));
cancel_button->signal_clicked().connect([label, on_cancel = std::move(on_cancel)] {
label->set_text("Canceling...");
if(on_cancel)
on_cancel();
});
box->pack_start(*cancel_button);
}
if(show_progress_bar)
box->pack_start(progress_bar);
add(*box); add(*box);
show_all_children(); show_all_children();
@ -26,6 +37,10 @@ Dialog::Message::Message(const std::string &text) : Gtk::Window(Gtk::WindowType:
Gtk::Main::iteration(); Gtk::Main::iteration();
} }
void Dialog::Message::set_fraction(double fraction) {
progress_bar.set_fraction(fraction);
}
bool Dialog::Message::on_delete_event(GdkEventAny *event) { bool Dialog::Message::on_delete_event(GdkEventAny *event) {
return true; return true;
} }

6
src/dialogs.hpp

@ -14,10 +14,14 @@ public:
class Message : public Gtk::Window { class Message : public Gtk::Window {
public: public:
Message(const std::string &text); Message(const std::string &text, std::function<void()> &&on_cancel = {}, bool show_progrss_bar = false);
void set_fraction(double fraction);
protected: protected:
bool on_delete_event(GdkEventAny *event) override; bool on_delete_event(GdkEventAny *event) override;
private:
Gtk::ProgressBar progress_bar;
}; };
private: private:

6
src/source_clang.cpp

@ -1849,9 +1849,7 @@ void Source::ClangViewRefactor::wait_parsing() {
} }
} }
if(message) { if(message) {
for(;;) { while(true) {
while(Gtk::Main::events_pending())
Gtk::Main::iteration();
bool all_parsed = true; bool all_parsed = true;
for(auto &clang_view : clang_views) { for(auto &clang_view : clang_views) {
if(!clang_view->parsed) { if(!clang_view->parsed) {
@ -1861,6 +1859,8 @@ void Source::ClangViewRefactor::wait_parsing() {
} }
if(all_parsed) if(all_parsed)
break; break;
while(Gtk::Main::events_pending())
Gtk::Main::iteration();
std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::this_thread::sleep_for(std::chrono::milliseconds(10));
} }
message->hide(); message->hide();

55
src/usages_clang.cpp

@ -6,6 +6,7 @@
#include "utility.hpp" #include "utility.hpp"
#include <chrono> #include <chrono>
#include <fstream> #include <fstream>
#include <iostream>
#include <regex> #include <regex>
#include <thread> #include <thread>
@ -161,13 +162,24 @@ std::vector<Usages::Clang::Usages> Usages::Clang::get_usages(const boost::filesy
// Wait for current caching to finish // Wait for current caching to finish
std::unique_ptr<Dialog::Message> message; std::unique_ptr<Dialog::Message> message;
const std::string message_string = "Please wait while finding usages"; const std::string message_string = "Please wait while finding usages";
if(cache_in_progress_count != 0) { std::atomic<bool> canceled(false);
message = std::make_unique<Dialog::Message>(message_string); auto on_cancel = [&canceled] {
canceled = true;
};
size_t tasks = cache_in_progress_count;
std::atomic<size_t> tasks_completed = {0};
if(tasks != 0) {
message = std::make_unique<Dialog::Message>(message_string, std::move(on_cancel), true);
while(cache_in_progress_count != 0) { while(cache_in_progress_count != 0) {
message->set_fraction((static_cast<double>(tasks - cache_in_progress_count) / tasks) / 10.0);
while(Gtk::Main::events_pending()) while(Gtk::Main::events_pending())
Gtk::Main::iteration(); Gtk::Main::iteration();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
} }
} }
tasks_completed = tasks;
if(canceled)
return {};
// Use cache // Use cache
for(auto it = potential_paths.begin(); it != potential_paths.end();) { for(auto it = potential_paths.begin(); it != potential_paths.end();) {
@ -205,8 +217,9 @@ std::vector<Usages::Clang::Usages> Usages::Clang::get_usages(const boost::filesy
// Parse potential paths // Parse potential paths
if(!potential_paths.empty()) { if(!potential_paths.empty()) {
tasks += potential_paths.size();
if(!message) if(!message)
message = std::make_unique<Dialog::Message>(message_string); message = std::make_unique<Dialog::Message>(message_string, std::move(on_cancel), true);
std::vector<std::thread> threads; std::vector<std::thread> threads;
auto it = potential_paths.begin(); auto it = potential_paths.begin();
@ -216,16 +229,19 @@ std::vector<Usages::Clang::Usages> Usages::Clang::get_usages(const boost::filesy
if(number_of_threads == 0) if(number_of_threads == 0)
number_of_threads = 1; number_of_threads = 1;
} }
std::vector<std::atomic<bool>> completed_threads(number_of_threads);
for(unsigned thread_id = 0; thread_id < number_of_threads; ++thread_id) { for(unsigned thread_id = 0; thread_id < number_of_threads; ++thread_id) {
completed_threads[thread_id] = false;
threads.emplace_back([&potential_paths, &it, &build_path, threads.emplace_back([&potential_paths, &it, &build_path,
&project_path, &usages, &visited, &spelling, &cursor] { &project_path, &usages, &visited, &spelling, &cursor,
while(true) { thread_id, &completed_threads, &tasks_completed, &canceled] {
while(!canceled) {
boost::filesystem::path path; boost::filesystem::path path;
{ {
static Mutex mutex; static Mutex mutex;
LockGuard lock(mutex); LockGuard lock(mutex);
if(it == potential_paths.end()) if(it == potential_paths.end())
return; break;
path = *it; path = *it;
++it; ++it;
} }
@ -256,11 +272,26 @@ std::vector<Usages::Clang::Usages> Usages::Clang::get_usages(const boost::filesy
add_usages_from_includes(project_path, build_path, usages, visited, spelling, cursor, &translation_unit, true); add_usages_from_includes(project_path, build_path, usages, visited, spelling, cursor, &translation_unit, true);
} }
// auto time = std::chrono::system_clock::now(); tasks_completed++;
// std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(time - before_time).count() << std::endl;
} }
completed_threads[thread_id] = true;
}); });
} }
while(true) {
bool all_completed = true;
for(auto &completed_thread : completed_threads) {
if(!completed_thread) {
all_completed = false;
break;
}
}
if(all_completed)
break;
message->set_fraction(static_cast<double>(tasks_completed) / tasks);
while(Gtk::Main::events_pending())
Gtk::Main::iteration();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
for(auto &thread : threads) for(auto &thread : threads)
thread.join(); thread.join();
} }
@ -268,6 +299,9 @@ std::vector<Usages::Clang::Usages> Usages::Clang::get_usages(const boost::filesy
if(message) if(message)
message->hide(); message->hide();
if(canceled)
return {};
return usages; return usages;
} }
@ -364,6 +398,7 @@ void Usages::Clang::erase_all_caches_for_project(const boost::filesystem::path &
while(cache_in_progress_count != 0) { while(cache_in_progress_count != 0) {
while(Gtk::Main::events_pending()) while(Gtk::Main::events_pending())
Gtk::Main::iteration(); Gtk::Main::iteration();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
} }
message.hide(); message.hide();
} }
@ -450,11 +485,9 @@ bool Usages::Clang::add_usages_from_cache(const boost::filesystem::path &path, s
for(auto &path_and_last_write_time : cache.paths_and_last_write_times) { for(auto &path_and_last_write_time : cache.paths_and_last_write_times) {
boost::system::error_code ec; boost::system::error_code ec;
auto last_write_time = boost::filesystem::last_write_time(path_and_last_write_time.first, ec); auto last_write_time = boost::filesystem::last_write_time(path_and_last_write_time.first, ec);
if(ec || last_write_time != path_and_last_write_time.second) { if(ec || last_write_time != path_and_last_write_time.second)
// std::cout << "updated file: " << path_and_last_write_time.first << ", included from " << path << std::endl;
return false; return false;
} }
}
auto offsets = cache.get_similar_token_offsets(cursor.get_kind(), spelling, cursor.get_all_usr_extended()); auto offsets = cache.get_similar_token_offsets(cursor.get_kind(), spelling, cursor.get_all_usr_extended());

1
src/window.cpp

@ -129,6 +129,7 @@ Window::Window() {
while(!Source::View::non_deleted_views.empty()) { while(!Source::View::non_deleted_views.empty()) {
while(Gtk::Main::events_pending()) while(Gtk::Main::events_pending())
Gtk::Main::iteration(); Gtk::Main::iteration();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
} }
message.hide(); message.hide();
} }

4
tests/stubs/dialogs.cpp

@ -1,6 +1,8 @@
#include "dialogs.hpp" #include "dialogs.hpp"
Dialog::Message::Message(const std::string &text) : Gtk::Window(Gtk::WindowType::WINDOW_POPUP) {} Dialog::Message::Message(const std::string &text, std::function<void()> &&on_cancel, bool show_progress_bar) : Gtk::Window(Gtk::WindowType::WINDOW_POPUP) {}
void Dialog::Message::set_fraction(double fraction) {}
bool Dialog::Message::on_delete_event(GdkEventAny *event) { bool Dialog::Message::on_delete_event(GdkEventAny *event) {
return true; return true;

Loading…
Cancel
Save