From 7722e7eee5fae41f0faa5ed46b402c12a81ee1dc Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 14 Feb 2016 23:09:10 +0100 Subject: [PATCH] Dispatcher cleanup --- src/directories.cc | 26 +++--- src/directories.h | 3 +- src/source_clang.cc | 202 ++++++++++++++++++++------------------------ src/source_clang.h | 19 +---- 4 files changed, 110 insertions(+), 140 deletions(-) diff --git a/src/directories.cc b/src/directories.cc index 7301030..977e3f7 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -77,17 +77,7 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { child->set_value(column_record.color, rgba); } }); - - update_dispatcher.connect([this](){ - update_mutex.lock(); - for(auto &path: update_paths) { - if(last_write_times.count(path)>0) - add_path(path, last_write_times.at(path).first); - } - update_paths.clear(); - update_mutex.unlock(); - }); - + update_thread=std::thread([this](){ while(!stop_update_thread) { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); @@ -105,8 +95,17 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { else it=last_write_times.erase(it); } - if(update_paths.size()>0) - update_dispatcher(); + if(update_paths.size()>0) { + dispatcher.add([this] { + update_mutex.lock(); + for(auto &path: update_paths) { + if(last_write_times.count(path)>0) + add_path(path, last_write_times.at(path).first); + } + update_paths.clear(); + update_mutex.unlock(); + }); + } } update_mutex.unlock(); } @@ -116,6 +115,7 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { Directories::~Directories() { stop_update_thread=true; update_thread.join(); + dispatcher.disconnect(); } void Directories::open(const boost::filesystem::path& dir_path) { diff --git a/src/directories.h b/src/directories.h index 9314605..5e5e374 100644 --- a/src/directories.h +++ b/src/directories.h @@ -9,6 +9,7 @@ #include #include #include +#include "dispatcher.h" class Directories : public Gtk::TreeView { public: @@ -51,7 +52,7 @@ private: std::mutex update_mutex; std::thread update_thread; std::atomic stop_update_thread; - Glib::Dispatcher update_dispatcher; + Dispatcher dispatcher; std::vector update_paths; }; diff --git a/src/source_clang.cc b/src/source_clang.cc index 7c6e12d..27345ca 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -35,36 +35,6 @@ Source::View(file_path, project_path, language) { configure(); parsing_in_progress=Terminal::get().print_in_progress("Parsing "+file_path.string()); - //GTK-calls must happen in main thread, so the parse_thread - //sends signals to the main thread that it is to call the following functions: - parse_preprocess_connection=parse_preprocess.connect([this]{ - auto expected=ParseProcessState::PREPROCESSING; - if(parse_mutex.try_lock()) { - if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::PROCESSING)) - parse_thread_buffer=get_buffer()->get_text(); - parse_mutex.unlock(); - } - else - parse_process_state.compare_exchange_strong(expected, ParseProcessState::STARTING); - }); - parse_postprocess_connection=parse_postprocess.connect([this](){ - if(parse_mutex.try_lock()) { - auto expected=ParseProcessState::POSTPROCESSING; - if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::IDLE)) { - update_syntax(); - update_diagnostics(); - parsed=true; - set_status(""); - } - parse_mutex.unlock(); - } - }); - parse_error_connection=parse_error.connect([this](){ - Terminal::get().print("Error: failed to reparse "+this->file_path.string()+".\n", true); - set_status(""); - set_info(""); - parsing_in_progress->cancel("failed"); - }); parse_initialize(); get_buffer()->signal_changed().connect([this]() { @@ -140,8 +110,18 @@ void Source::ClangViewParse::parse_initialize() { if(parse_state!=ParseState::PROCESSING) break; auto expected=ParseProcessState::STARTING; - if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::PREPROCESSING)) - parse_preprocess(); + if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::PREPROCESSING)) { + dispatcher.add([this] { + auto expected=ParseProcessState::PREPROCESSING; + if(parse_mutex.try_lock()) { + if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::PROCESSING)) + parse_thread_buffer=get_buffer()->get_text(); + parse_mutex.unlock(); + } + else + parse_process_state.compare_exchange_strong(expected, ParseProcessState::STARTING); + }); + } else if (parse_process_state==ParseProcessState::PROCESSING && parse_mutex.try_lock()) { auto status=clang_tu->ReparseTranslationUnit(parse_thread_buffer.raw()); parsing_in_progress->done("done"); @@ -150,7 +130,18 @@ void Source::ClangViewParse::parse_initialize() { if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::POSTPROCESSING)) { clang_tokens=clang_tu->get_tokens(0, parse_thread_buffer.bytes()-1); parse_mutex.unlock(); - parse_postprocess(); + dispatcher.add([this] { + if(parse_mutex.try_lock()) { + auto expected=ParseProcessState::POSTPROCESSING; + if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::IDLE)) { + update_syntax(); + update_diagnostics(); + parsed=true; + set_status(""); + } + parse_mutex.unlock(); + } + }); } else parse_mutex.unlock(); @@ -158,7 +149,12 @@ void Source::ClangViewParse::parse_initialize() { else { parse_state=ParseState::STOP; parse_mutex.unlock(); - parse_error(); + dispatcher.add([this] { + Terminal::get().print("Error: failed to reparse "+this->file_path.string()+".\n", true); + set_status(""); + set_info(""); + parsing_in_progress->cancel("failed"); + }); } } } @@ -713,70 +709,11 @@ Source::ClangViewParse(file_path, project_path, language), autocomplete_state(Au return false; }); - autocomplete_done_connection=autocomplete_done.connect([this](){ - if(autocomplete_state==AutocompleteState::CANCELED) { - set_status(""); - soft_reparse(); - autocomplete_state=AutocompleteState::IDLE; - } - else if(autocomplete_state==AutocompleteState::RESTARTING) { - set_status(""); - soft_reparse(); - autocomplete_state=AutocompleteState::IDLE; - autocomplete_restart(); - } - else { - autocomplete_dialog_setup(); - - for (auto &data : autocomplete_data) { - std::string row; - std::string return_value; - for (auto &chunk : data.chunks) { - if(chunk.kind==clang::CompletionChunk_ResultType) - return_value=chunk.chunk; - else if(chunk.kind!=clang::CompletionChunk_Informative) - row+=chunk.chunk; - } - data.chunks.clear(); - if (!row.empty()) { - auto row_insert_on_selection=row; - if(!return_value.empty()) - row+=" --> " + return_value; - autocomplete_dialog_rows[row] = std::pair(std::move(row_insert_on_selection), std::move(data.brief_comments)); - autocomplete_dialog->add_row(row); - } - } - autocomplete_data.clear(); - set_status(""); - autocomplete_state=AutocompleteState::IDLE; - if (!autocomplete_dialog_rows.empty()) { - get_source_buffer()->begin_user_action(); - autocomplete_dialog->show(); - } - else - soft_reparse(); - } - }); - - autocomplete_restart_connection=autocomplete_restart.connect([this]() { - autocomplete_check(); - }); - autocomplete_error_connection=autocomplete_error.connect([this]() { - Terminal::get().print("Error: autocomplete failed, reparsing "+this->file_path.string()+"\n", true); - autocomplete_state=AutocompleteState::CANCELED; - full_reparse(); - }); - - do_delete_object_connection=do_delete_object.connect([this](){ + do_delete_object.connect([this](){ if(delete_thread.joinable()) delete_thread.join(); - do_delete_object_connection.disconnect(); delete this; }); - do_full_reparse.connect([this](){ - parse_initialize(); - full_reparse_running=false; - }); } bool Source::ClangViewAutocomplete::on_key_press_event(GdkEventKey *key) { @@ -847,7 +784,7 @@ void Source::ClangViewAutocomplete::autocomplete_dialog_setup() { //new autocomplete after for instance when selecting "std::" auto iter=get_buffer()->get_insert()->get_iter(); if(iter.backward_char() && *iter==':') - autocomplete_restart(); + autocomplete_check(); } } }; @@ -918,8 +855,6 @@ void Source::ClangViewAutocomplete::autocomplete() { autocomplete_state=AutocompleteState::STARTING; - autocomplete_data.clear(); - set_status("autocomplete..."); if(autocomplete_thread.joinable()) autocomplete_thread.join(); @@ -938,12 +873,62 @@ void Source::ClangViewAutocomplete::autocomplete() { parse_mutex.lock(); if(parse_state==ParseState::PROCESSING) { parse_process_state=ParseProcessState::IDLE; - autocomplete_data=autocomplete_get_suggestions(buffer->raw(), line_nr, column_nr); + auto autocomplete_data=std::make_shared >(autocomplete_get_suggestions(buffer->raw(), line_nr, column_nr)); + + if(parse_state==ParseState::PROCESSING) + dispatcher.add([this, autocomplete_data] { + if(autocomplete_state==AutocompleteState::CANCELED) { + set_status(""); + soft_reparse(); + autocomplete_state=AutocompleteState::IDLE; + } + else if(autocomplete_state==AutocompleteState::RESTARTING) { + set_status(""); + soft_reparse(); + autocomplete_state=AutocompleteState::IDLE; + dispatcher.add([this] { + autocomplete_check(); + }); + } + else { + autocomplete_dialog_setup(); + + for (auto &data : *autocomplete_data) { + std::string row; + std::string return_value; + for (auto &chunk : data.chunks) { + if(chunk.kind==clang::CompletionChunk_ResultType) + return_value=chunk.chunk; + else if(chunk.kind!=clang::CompletionChunk_Informative) + row+=chunk.chunk; + } + data.chunks.clear(); + if (!row.empty()) { + auto row_insert_on_selection=row; + if(!return_value.empty()) + row+=" --> " + return_value; + autocomplete_dialog_rows[row] = std::pair(std::move(row_insert_on_selection), std::move(data.brief_comments)); + autocomplete_dialog->add_row(row); + } + } + set_status(""); + autocomplete_state=AutocompleteState::IDLE; + if (!autocomplete_dialog_rows.empty()) { + get_source_buffer()->begin_user_action(); + autocomplete_dialog->show(); + } + else + soft_reparse(); + } + }); + else { + dispatcher.add([this] { + Terminal::get().print("Error: autocomplete failed, reparsing "+this->file_path.string()+"\n", true); + autocomplete_state=AutocompleteState::CANCELED; + full_reparse(); + }); + } } - if(parse_state==ParseState::PROCESSING) - autocomplete_done(); - else - autocomplete_error(); parse_mutex.unlock(); }); } @@ -1017,7 +1002,10 @@ bool Source::ClangViewAutocomplete::full_reparse() { parse_thread.join(); if(autocomplete_thread.joinable()) autocomplete_thread.join(); - do_full_reparse(); + dispatcher.add([this] { + parse_initialize(); + full_reparse_running=false; + }); }); return true; } @@ -1479,14 +1467,8 @@ Source::ClangView::ClangView(const boost::filesystem::path &file_path, const boo } void Source::ClangView::async_delete() { + dispatcher.disconnect(); delayed_reparse_connection.disconnect(); - parse_postprocess_connection.disconnect(); - parse_preprocess_connection.disconnect(); - parse_error_connection.disconnect(); - autocomplete_done_connection.disconnect(); - autocomplete_restart_connection.disconnect(); - autocomplete_error_connection.disconnect(); - do_restart_parse_connection.disconnect(); delayed_tag_similar_tokens_connection.disconnect(); ClangViewAutocomplete::async_delete(); } diff --git a/src/source_clang.h b/src/source_clang.h index 93b226d..cda1cbe 100644 --- a/src/source_clang.h +++ b/src/source_clang.h @@ -9,6 +9,7 @@ #include "clangmm.h" #include "source.h" #include "terminal.h" +#include "dispatcher.h" namespace Source { class ClangViewParse : public View { @@ -25,11 +26,13 @@ namespace Source { }; ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language); + ~ClangViewParse() { dispatcher.disconnect(); } void configure() override; void soft_reparse() override; protected: + Dispatcher dispatcher; void parse_initialize(); std::unique_ptr clang_tu; std::unique_ptr clang_tokens; @@ -53,13 +56,7 @@ namespace Source { std::mutex parse_mutex; std::atomic parse_state; std::atomic parse_process_state; - sigc::connection parse_preprocess_connection; - sigc::connection parse_postprocess_connection; - sigc::connection parse_error_connection; private: - Glib::Dispatcher parse_preprocess; - Glib::Dispatcher parse_postprocess; - Glib::Dispatcher parse_error; Glib::ustring parse_thread_buffer; void update_syntax(); @@ -90,29 +87,19 @@ namespace Source { bool on_key_press_event(GdkEventKey* key) override; std::thread autocomplete_thread; - sigc::connection autocomplete_done_connection; - sigc::connection autocomplete_restart_connection; - sigc::connection autocomplete_error_connection; - sigc::connection do_delete_object_connection; - sigc::connection do_restart_parse_connection; private: std::atomic autocomplete_state; void autocomplete_dialog_setup(); void autocomplete_check(); void autocomplete(); - std::vector autocomplete_data; std::unordered_map > autocomplete_dialog_rows; std::vector autocomplete_get_suggestions(const std::string &buffer, int line_number, int column); Tooltips autocomplete_tooltips; - Glib::Dispatcher autocomplete_done; - Glib::Dispatcher autocomplete_restart; - Glib::Dispatcher autocomplete_error; guint last_keyval=0; std::string prefix; std::mutex prefix_mutex; Glib::Dispatcher do_delete_object; - Glib::Dispatcher do_full_reparse; std::thread delete_thread; std::thread full_reparse_thread; bool full_reparse_running=false;