diff --git a/juci/notebook.h b/juci/notebook.h index 4a7cc2e..6c96f5e 100644 --- a/juci/notebook.h +++ b/juci/notebook.h @@ -49,6 +49,7 @@ namespace Notebook { std::string project_path; Directories::Controller directories; //Todo: make private after creating open_directory() Entry entry; + std::vector > text_vec_; private: void CreateKeybindings(Keybindings::Controller& keybindings); void AskToSaveDialog(); @@ -57,7 +58,6 @@ namespace Notebook { Terminal::Controller& terminal; Source::Config& source_config; - std::vector > text_vec_; std::vector scrolledtext_vec_; std::vector editor_vec_; std::list listTargets_; diff --git a/juci/source.cc b/juci/source.cc index d053cac..cc6dbc6 100644 --- a/juci/source.cc +++ b/juci/source.cc @@ -163,16 +163,12 @@ parse_thread_go(true), parse_thread_mapped(false), parse_thread_stop(false) { parse_thread_go=true; }); - first_time_parse_done=this->terminal.PrintMessage("Parsing "+file_path, "finished"); + parsing_in_progress=this->terminal.print_in_progress("Parsing "+file_path); parse_done.connect([this](){ if(parse_thread_mapped) { INFO("Updating syntax"); update_syntax(extract_tokens(0, get_source_buffer()->get_text().size())); - if(first_time_parse) { - first_time_parse_done(); - first_time_parse_done=[](){}; - first_time_parse=false; - } + parsing_in_progress->done("done"); INFO("Syntax updated"); } else { @@ -210,13 +206,13 @@ parse_thread_go(true), parse_thread_mapped(false), parse_thread_stop(false) { } Source::ClangView::~ClangView() { + //TODO: Is it possible to stop the clang-process in progress? + parsing_in_progress->cancel("canceled"); parse_thread_stop=true; if(parse_thread.joinable()) parse_thread.join(); parsing_mutex.lock(); //Be sure not to destroy while still parsing with libclang parsing_mutex.unlock(); - if(first_time_parse) - first_time_parse_done(); //This function must be run if it is not run already } void Source::ClangView:: diff --git a/juci/source.h b/juci/source.h index 3c0a71d..7653ba1 100644 --- a/juci/source.h +++ b/juci/source.h @@ -109,8 +109,7 @@ namespace Source { bool on_key_press(GdkEventKey* key); bool on_key_release(GdkEventKey* key); Terminal::Controller& terminal; - bool first_time_parse=true; - std::function first_time_parse_done; + std::shared_ptr parsing_in_progress; Glib::Dispatcher parse_done; Glib::Dispatcher parse_start; diff --git a/juci/terminal.cc b/juci/terminal.cc index c1ba7d3..02b9933 100644 --- a/juci/terminal.cc +++ b/juci/terminal.cc @@ -1,16 +1,54 @@ #include "terminal.h" #include -#include -#include #include "logging.h" +Terminal::InProgress::InProgress(Controller& terminal, const std::string& start_msg): + start_msg(start_msg), terminal(terminal), stop(false) { + waiting_print.connect([this](){ + this->terminal.print(line_nr-1, "."); + }); + start(); +} + +Terminal::InProgress::~InProgress() { + stop=true; + if(wait_thread.joinable()) + wait_thread.join(); +} + +void Terminal::InProgress::start() { + line_nr=this->terminal.print(start_msg+"...\n"); + wait_thread=std::thread([this](){ + size_t c=0; + while(!stop) { + if(c%100==0) + waiting_print(); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + c++; + } + }); +} + +void Terminal::InProgress::done(const std::string& msg) { + if(!stop) { + stop=true; + this->terminal.print(line_nr-1, msg); + } +} + +void Terminal::InProgress::cancel(const std::string& msg) { + if(!stop) { + stop=true; + this->terminal.print(line_nr-1, msg); + } +} + Terminal::View::View(){ text_view.set_editable(false); scrolled_window.add(text_view); add(scrolled_window); } - Terminal::Controller::Controller(Terminal::Config& cfg) : config(cfg) { folder_command_ = ""; @@ -33,20 +71,20 @@ void Terminal::Controller::Compile(){ ExecuteCommand(commands.at(it), "r"); } - PrintMessage("\n"); + print("\n"); DEBUG("Terminal: Compile: compile done"); } void Terminal::Controller::Run(std::string executable) { INFO("Terminal: Run"); - PrintMessage("juCi++ execute: " + executable + "\n"); + print("juCi++ execute: " + executable + "\n"); DEBUG("Terminal: Compile: running run command: "); DEBUG_VAR(executable); ExecuteCommand("cd "+config.run_command + "; ./"+executable, "r"); - PrintMessage("\n"); + print("\n"); } -int Terminal::Controller::PrintMessage(std::string message){ +int Terminal::Controller::print(std::string message){ INFO("Terminal: PrintMessage"); view.text_view.get_buffer()->insert(view.text_view.get_buffer()->end(), "> "+message); auto mark_end=view.text_view.get_buffer()->create_mark(view.text_view.get_buffer()->end()); @@ -54,7 +92,7 @@ int Terminal::Controller::PrintMessage(std::string message){ return mark_end->get_iter().get_line(); } -void Terminal::Controller::PrintMessage(int line_nr, std::string message){ +void Terminal::Controller::print(int line_nr, std::string message){ INFO("Terminal: PrintMessage at line " << line_nr); auto iter=view.text_view.get_buffer()->get_iter_at_line(line_nr); while(!iter.ends_line()) @@ -62,33 +100,9 @@ void Terminal::Controller::PrintMessage(int line_nr, std::string message){ view.text_view.get_buffer()->insert(iter, message); } -//TODO: this was way too dirty, return a class instead. -std::function Terminal::Controller::PrintMessage(std::string start_msg, std::string done_msg) { - int line_nr=PrintMessage(start_msg+"...\n"); - - std::shared_ptr > stop(new std::atomic(false)); - std::shared_ptr waiting_print(new Glib::Dispatcher()); - waiting_print->connect([this, line_nr](){ - PrintMessage(line_nr-1, "."); - }); - - std::shared_ptr wait_thread(new std::thread([this, stop, waiting_print](){ - size_t c=0; - while(!*stop) { - if(c%100==0) - (*waiting_print)(); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - c++; - } - })); - - std::function done=[this, line_nr, stop, done_msg, waiting_print, wait_thread](){ - *stop=true; - PrintMessage(line_nr-1, done_msg); - if(wait_thread->joinable()) - wait_thread->join(); //waiting_print has to be destroyed in main thread - }; - return done; +std::shared_ptr Terminal::Controller::print_in_progress(std::string start_msg) { + std::shared_ptr in_progress=std::shared_ptr(new Terminal::InProgress(*this, start_msg)); + return in_progress; } bool Terminal::Controller::ExistInConsole(std::string string) { @@ -108,11 +122,11 @@ void Terminal::Controller::ExecuteCommand(std::string command, std::string mode) std::cout << command << std::endl; p = popen(command.c_str(), mode.c_str()); if (p == NULL) { - PrintMessage("juCi++ ERROR: Failed to run command" + command + "\n"); + print("juCi++ ERROR: Failed to run command" + command + "\n"); }else { char buffer[1028]; while (fgets(buffer, 1028, p) != NULL) { - PrintMessage(buffer); + print(buffer); } pclose(p); } diff --git a/juci/terminal.h b/juci/terminal.h index 12fecc1..00e2fba 100644 --- a/juci/terminal.h +++ b/juci/terminal.h @@ -5,9 +5,10 @@ #include #include "gtkmm.h" #include +#include +#include namespace Terminal { - class Config { public: std::vector compile_commands; @@ -21,15 +22,34 @@ namespace Terminal { Gtk::ScrolledWindow scrolled_window; }; // class view + class Controller; + + //Temporary solution for displaying functions in progress, and when they are done. + class InProgress { + public: + InProgress(Controller& terminal, const std::string& start_msg); + ~InProgress(); + void done(const std::string& msg); + void cancel(const std::string& msg); + private: + void start(); + Controller& terminal; + std::string start_msg; + int line_nr; + std::atomic stop; + Glib::Dispatcher waiting_print; + std::thread wait_thread; + }; + class Controller { public: Controller(Terminal::Config& cfg); void SetFolderCommand(boost::filesystem::path CMake_path); void Run(std::string executable); void Compile(); - int PrintMessage(std::string message); - void PrintMessage(int line_nr, std::string message); - std::function PrintMessage(std::string start_msg, std::string stop_msg); + int print(std::string message); + void print(int line_nr, std::string message); + std::shared_ptr print_in_progress(std::string start_msg); Terminal::View view; private: Terminal::Config& config; diff --git a/juci/window.cc b/juci/window.cc index c7c1340..6c54878 100644 --- a/juci/window.cc +++ b/juci/window.cc @@ -121,6 +121,8 @@ Window::Window() : } // Window constructor void Window::OnWindowHide() { + for(size_t c=0;c