Browse Source

Fixed crash from last commit. Moved the progress messages to a seperate class, and added cancel message.

merge-requests/365/head
eidheim 11 years ago
parent
commit
c1714c5b35
  1. 2
      juci/notebook.h
  2. 12
      juci/source.cc
  3. 3
      juci/source.h
  4. 88
      juci/terminal.cc
  5. 28
      juci/terminal.h
  6. 10
      juci/window.cc

2
juci/notebook.h

@ -49,6 +49,7 @@ namespace Notebook {
std::string project_path; std::string project_path;
Directories::Controller directories; //Todo: make private after creating open_directory() Directories::Controller directories; //Todo: make private after creating open_directory()
Entry entry; Entry entry;
std::vector<std::unique_ptr<Source::Controller> > text_vec_;
private: private:
void CreateKeybindings(Keybindings::Controller& keybindings); void CreateKeybindings(Keybindings::Controller& keybindings);
void AskToSaveDialog(); void AskToSaveDialog();
@ -57,7 +58,6 @@ namespace Notebook {
Terminal::Controller& terminal; Terminal::Controller& terminal;
Source::Config& source_config; Source::Config& source_config;
std::vector<std::unique_ptr<Source::Controller> > text_vec_;
std::vector<Gtk::ScrolledWindow*> scrolledtext_vec_; std::vector<Gtk::ScrolledWindow*> scrolledtext_vec_;
std::vector<Gtk::HBox*> editor_vec_; std::vector<Gtk::HBox*> editor_vec_;
std::list<Gtk::TargetEntry> listTargets_; std::list<Gtk::TargetEntry> listTargets_;

12
juci/source.cc

@ -163,16 +163,12 @@ parse_thread_go(true), parse_thread_mapped(false), parse_thread_stop(false) {
parse_thread_go=true; 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](){ parse_done.connect([this](){
if(parse_thread_mapped) { if(parse_thread_mapped) {
INFO("Updating syntax"); INFO("Updating syntax");
update_syntax(extract_tokens(0, get_source_buffer()->get_text().size())); update_syntax(extract_tokens(0, get_source_buffer()->get_text().size()));
if(first_time_parse) { parsing_in_progress->done("done");
first_time_parse_done();
first_time_parse_done=[](){};
first_time_parse=false;
}
INFO("Syntax updated"); INFO("Syntax updated");
} }
else { else {
@ -210,13 +206,13 @@ parse_thread_go(true), parse_thread_mapped(false), parse_thread_stop(false) {
} }
Source::ClangView::~ClangView() { Source::ClangView::~ClangView() {
//TODO: Is it possible to stop the clang-process in progress?
parsing_in_progress->cancel("canceled");
parse_thread_stop=true; parse_thread_stop=true;
if(parse_thread.joinable()) if(parse_thread.joinable())
parse_thread.join(); parse_thread.join();
parsing_mutex.lock(); //Be sure not to destroy while still parsing with libclang parsing_mutex.lock(); //Be sure not to destroy while still parsing with libclang
parsing_mutex.unlock(); 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:: void Source::ClangView::

3
juci/source.h

@ -109,8 +109,7 @@ namespace Source {
bool on_key_press(GdkEventKey* key); bool on_key_press(GdkEventKey* key);
bool on_key_release(GdkEventKey* key); bool on_key_release(GdkEventKey* key);
Terminal::Controller& terminal; Terminal::Controller& terminal;
bool first_time_parse=true; std::shared_ptr<Terminal::InProgress> parsing_in_progress;
std::function<void()> first_time_parse_done;
Glib::Dispatcher parse_done; Glib::Dispatcher parse_done;
Glib::Dispatcher parse_start; Glib::Dispatcher parse_start;

88
juci/terminal.cc

@ -1,16 +1,54 @@
#include "terminal.h" #include "terminal.h"
#include <iostream> #include <iostream>
#include <thread>
#include <atomic>
#include "logging.h" #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(){ Terminal::View::View(){
text_view.set_editable(false); text_view.set_editable(false);
scrolled_window.add(text_view); scrolled_window.add(text_view);
add(scrolled_window); add(scrolled_window);
} }
Terminal::Controller::Controller(Terminal::Config& cfg) : Terminal::Controller::Controller(Terminal::Config& cfg) :
config(cfg) { config(cfg) {
folder_command_ = ""; folder_command_ = "";
@ -33,20 +71,20 @@ void Terminal::Controller::Compile(){
ExecuteCommand(commands.at(it), "r"); ExecuteCommand(commands.at(it), "r");
} }
PrintMessage("\n"); print("\n");
DEBUG("Terminal: Compile: compile done"); DEBUG("Terminal: Compile: compile done");
} }
void Terminal::Controller::Run(std::string executable) { void Terminal::Controller::Run(std::string executable) {
INFO("Terminal: Run"); INFO("Terminal: Run");
PrintMessage("juCi++ execute: " + executable + "\n"); print("juCi++ execute: " + executable + "\n");
DEBUG("Terminal: Compile: running run command: "); DEBUG("Terminal: Compile: running run command: ");
DEBUG_VAR(executable); DEBUG_VAR(executable);
ExecuteCommand("cd "+config.run_command + "; ./"+executable, "r"); 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"); INFO("Terminal: PrintMessage");
view.text_view.get_buffer()->insert(view.text_view.get_buffer()->end(), "> "+message); 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()); 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(); 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); INFO("Terminal: PrintMessage at line " << line_nr);
auto iter=view.text_view.get_buffer()->get_iter_at_line(line_nr); auto iter=view.text_view.get_buffer()->get_iter_at_line(line_nr);
while(!iter.ends_line()) 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); view.text_view.get_buffer()->insert(iter, message);
} }
//TODO: this was way too dirty, return a class instead. std::shared_ptr<Terminal::InProgress> Terminal::Controller::print_in_progress(std::string start_msg) {
std::function<void()> Terminal::Controller::PrintMessage(std::string start_msg, std::string done_msg) { std::shared_ptr<Terminal::InProgress> in_progress=std::shared_ptr<Terminal::InProgress>(new Terminal::InProgress(*this, start_msg));
int line_nr=PrintMessage(start_msg+"...\n"); return in_progress;
std::shared_ptr<std::atomic<bool> > stop(new std::atomic<bool>(false));
std::shared_ptr<Glib::Dispatcher> waiting_print(new Glib::Dispatcher());
waiting_print->connect([this, line_nr](){
PrintMessage(line_nr-1, ".");
});
std::shared_ptr<std::thread> 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<void()> 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;
} }
bool Terminal::Controller::ExistInConsole(std::string string) { 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; std::cout << command << std::endl;
p = popen(command.c_str(), mode.c_str()); p = popen(command.c_str(), mode.c_str());
if (p == NULL) { if (p == NULL) {
PrintMessage("juCi++ ERROR: Failed to run command" + command + "\n"); print("juCi++ ERROR: Failed to run command" + command + "\n");
}else { }else {
char buffer[1028]; char buffer[1028];
while (fgets(buffer, 1028, p) != NULL) { while (fgets(buffer, 1028, p) != NULL) {
PrintMessage(buffer); print(buffer);
} }
pclose(p); pclose(p);
} }

28
juci/terminal.h

@ -5,9 +5,10 @@
#include <functional> #include <functional>
#include "gtkmm.h" #include "gtkmm.h"
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <thread>
#include <atomic>
namespace Terminal { namespace Terminal {
class Config { class Config {
public: public:
std::vector<std::string> compile_commands; std::vector<std::string> compile_commands;
@ -21,15 +22,34 @@ namespace Terminal {
Gtk::ScrolledWindow scrolled_window; Gtk::ScrolledWindow scrolled_window;
}; // class view }; // 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<bool> stop;
Glib::Dispatcher waiting_print;
std::thread wait_thread;
};
class Controller { class Controller {
public: public:
Controller(Terminal::Config& cfg); Controller(Terminal::Config& cfg);
void SetFolderCommand(boost::filesystem::path CMake_path); void SetFolderCommand(boost::filesystem::path CMake_path);
void Run(std::string executable); void Run(std::string executable);
void Compile(); void Compile();
int PrintMessage(std::string message); int print(std::string message);
void PrintMessage(int line_nr, std::string message); void print(int line_nr, std::string message);
std::function<void()> PrintMessage(std::string start_msg, std::string stop_msg); std::shared_ptr<InProgress> print_in_progress(std::string start_msg);
Terminal::View view; Terminal::View view;
private: private:
Terminal::Config& config; Terminal::Config& config;

10
juci/window.cc

@ -121,6 +121,8 @@ Window::Window() :
} // Window constructor } // Window constructor
void Window::OnWindowHide() { void Window::OnWindowHide() {
for(size_t c=0;c<notebook.text_vec_.size();c++)
notebook.OnCloseCurrentPage(); //TODO: This only works on one page at the momemt. Change to notebook.close_page(page_nr);
hide(); hide();
} }
void Window::OnFileOpenFolder() { void Window::OnFileOpenFolder() {
@ -202,19 +204,19 @@ void Window::OnOpenFile() {
bool Window::SaveFile() { bool Window::SaveFile() {
if(notebook.OnSaveFile()) { if(notebook.OnSaveFile()) {
terminal.PrintMessage("File saved to: " + terminal.print("File saved to: " +
notebook.CurrentTextView().file_path+"\n"); notebook.CurrentTextView().file_path+"\n");
return true; return true;
} }
terminal.PrintMessage("File not saved"); terminal.print("File not saved");
return false; return false;
} }
bool Window::SaveFileAs() { bool Window::SaveFileAs() {
if(notebook.OnSaveFile(notebook.OnSaveFileAs())){ if(notebook.OnSaveFile(notebook.OnSaveFileAs())){
terminal.PrintMessage("File saved to: " + terminal.print("File saved to: " +
notebook.CurrentTextView().file_path+"\n"); notebook.CurrentTextView().file_path+"\n");
return true; return true;
} }
terminal.PrintMessage("File not saved"); terminal.print("File not saved");
return false; return false;
} }

Loading…
Cancel
Save