diff --git a/glade/main-window.glade b/glade/main-window.glade index c12e008..8d5c57e 100644 --- a/glade/main-window.glade +++ b/glade/main-window.glade @@ -42,6 +42,14 @@ + + + True + gtk-new + True + + + True diff --git a/src/backend/concrete_history.cc b/src/backend/concrete_history.cc index 39461c2..8d2e85b 100644 --- a/src/backend/concrete_history.cc +++ b/src/backend/concrete_history.cc @@ -298,6 +298,7 @@ ConcreteHistory::clear() _snapshots.clear(); _snapshots.push_back(new ConcreteEnvironment()); assert(_snapshots.size() == 1); + notify_change(); } diff --git a/src/backend/scheduler.cc b/src/backend/scheduler.cc index 3eccb4d..2db8123 100644 --- a/src/backend/scheduler.cc +++ b/src/backend/scheduler.cc @@ -344,7 +344,11 @@ determine_subr_allocable_status(const Resource& res, const SubRequestQueue& queu if (sr.get_state() == Request::state_allocated) continue; if(position_in_queue + 1 > total_places) - sr.set_state(Request::state_unallocable); + { + sr.set_state(Request::state_unallocable); + // Kludge: + sr.get_request().get_thread().set_state(Schedulable::state_blocked); + } else sr.set_state(Request::state_allocable); } //~ for(over subrequest queue) diff --git a/src/gui_builder.cc b/src/gui_builder.cc index b0604a8..e9a9ca1 100644 --- a/src/gui_builder.cc +++ b/src/gui_builder.cc @@ -113,6 +113,29 @@ GuiBuilder::on_view_show_holt_graph_activate() } +void +GuiBuilder::on_file_new_activate() +{ + Simulation& sim = Simulation::get_instance(); + History& history = sim.get_history(); + const Environment& env = history.get_environment_at(0); + + if(!(_filename.empty() && env.get_processes().empty() && env.get_resources().empty())) + { + Gtk::MessageDialog want_to_save(get_initial_window(), + _("Want to save?\nYou'll lose your changes if you don't."), + true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true); + if(want_to_save.run() == Gtk::RESPONSE_YES) + on_file_save_activate(); + } + + sim.stop(); + history.clear(); + _filename = ""; +} + + + void GuiBuilder::on_file_open_activate() { @@ -489,6 +512,15 @@ GuiBuilder::GuiBuilder(const std::string& gladefile) { using namespace Gtk; + // ---------------- Menu items ------------------ + + // Note: the Play, Pause and Stop menu items are already managed by sgpem::SimulationController. + + // file new dialog + MenuItem* file_new = NULL; + _refXml->get_widget("MenuItem.File.New", file_new); + file_new->signal_activate().connect(sigc::mem_fun(*this, &GuiBuilder::on_file_new_activate)); + // file open dialog MenuItem* file_open = NULL; _refXml->get_widget("MenuItem.File.Open", file_open); @@ -504,11 +536,6 @@ GuiBuilder::GuiBuilder(const std::string& gladefile) _refXml->get_widget("MenuItem.File.SaveAs", file_saveas); file_saveas->signal_activate().connect(sigc::mem_fun(*this, &GuiBuilder::on_file_saveas_activate)); - - // ---------------- Menu items ------------------ - - // Note: the Play, Pause and Stop menu items are already managed by sgpem::SimulationController. - MenuItem* file_quit = NULL; _refXml->get_widget("MenuItem.File.Quit", file_quit); file_quit->signal_activate().connect(sigc::ptr_fun(&Main::quit)); diff --git a/src/gui_builder.hh b/src/gui_builder.hh index 7ccfa42..5005602 100644 --- a/src/gui_builder.hh +++ b/src/gui_builder.hh @@ -51,6 +51,7 @@ namespace sgpem Gtk::Window& get_initial_window() const; + void on_file_new_activate(); void on_file_open_activate(); void on_file_save_activate(); void on_file_saveas_activate(); diff --git a/src/holt_widget.cc b/src/holt_widget.cc index 84f3423..89ef5de 100644 --- a/src/holt_widget.cc +++ b/src/holt_widget.cc @@ -183,7 +183,7 @@ HoltSchedulable::~HoltSchedulable() void HoltSchedulable::draw(cairo_t *cr) { static const Color red(1, 0, 0); - static const Color yellow(1, 0.9, 0); + static const Color yellow(1, 0.8, 0); static const Color green(0, 1, 0); @@ -284,7 +284,7 @@ void HoltRequest::draw(cairo_t *cr) break; case Request::state_allocable: // yellow - cairo_set_source_rgb(cr, 1, 1, 0); + cairo_set_source_rgb(cr, 1, 0.7, 0); arrow(cr, schedulable, resource); break; } diff --git a/src/simulation_widget.cc b/src/simulation_widget.cc index 034a99c..1f11fd0 100644 --- a/src/simulation_widget.cc +++ b/src/simulation_widget.cc @@ -262,6 +262,7 @@ SimulationWidget::draw_grid(cairo_t* ctx) // draw last HOR line cairo_move_to(ctx, left_graph_margin, ypos); cairo_rel_line_to(ctx, graph_width, 0); + // - draw left VER line cairo_move_to(ctx, left_graph_margin, top_margin); cairo_rel_line_to(ctx, 0, graph_height); @@ -271,9 +272,25 @@ SimulationWidget::draw_grid(cairo_t* ctx) // - draw right VER line cairo_move_to(ctx, left_graph_margin + graph_width, top_margin); cairo_rel_line_to(ctx, 0, graph_height); + } + cairo_stroke(ctx); + // Draw a vertical line every fifth step + cairo_save(ctx); + cairo_set_line_width(ctx, 0.125 * cairo_get_line_width(ctx)); + cairo_set_source_rgb(ctx, 0.3, 0.3, 0.3); + for(double step = 2.0 + _x_unit; step < graph_width - _x_unit; step += 5 * _x_unit) + { + cairo_new_path(ctx); + cairo_move_to(ctx, left_graph_margin + step, top_margin); + cairo_rel_line_to(ctx, 0, graph_height); + cairo_stroke(ctx); + } + cairo_restore(ctx); + + // draw and write time line cairo_save(ctx); cairo_set_source_rgb(ctx, 0, 0, 0); @@ -332,19 +349,19 @@ SimulationWidget::draw_bars(cairo_t* ctx) from_time = 1; } - // We draw the interval [0, front) - // so if front <= 1, we've nothing to draw - if(hist_front <= 1) - return; - else - hist_front--; #ifndef NDEBUG std::cout << " SimulationWidget::draw_bars from:" << from_time << " to:" << hist_front << std::endl; #endif for(unsigned int t=from_time; t<=hist_front; t++) - { + { + // We draw the interval [0, front), entirely, and + // the instant "front" as a briefer `pulse' + float width_percent = 1.0f; + if(t == hist_front) + width_percent = 0.1f; + // draw schedulables bars double xpos = left_graph_margin + t * _x_unit; // left start of first process double ypos = top_margin; // vertical start of first process @@ -358,7 +375,8 @@ SimulationWidget::draw_bars(cairo_t* ctx) ypos += process_bar_spacing; // white row before bar draw_instant_rect(ctx, xpos, ypos, - _x_unit, process_bar_height, p->get_state()); + _x_unit * width_percent, process_bar_height, + p->get_state()); ypos += process_bar_height; // height of process bar if(_show_threads) { @@ -369,13 +387,14 @@ SimulationWidget::draw_bars(cairo_t* ctx) Thread* t = (*thr_iter); thr_iter++; draw_instant_rect(ctx, xpos, ypos + thread_bar_spacing, - _x_unit, thread_bar_height, t->get_state()); + _x_unit * width_percent, thread_bar_height, t->get_state()); ypos += thread_height; // height of thread bar } // ~ while(thr_iter!=tvect.end()) } // ~ if(_show_threads) ypos += process_bar_spacing; // white row after bar } // ~ while(proc_iter!=processes.end()) } // ~ for(int t=0; t<=hist_front; t++) + _last_drawn = hist_front; _partial_redraw = false; } @@ -493,9 +512,9 @@ SimulationWidget::make_gradients() _ready_process_gradient = cairo_pattern_create_linear(0, 0, 0, _yu_process_bar_height * _y_unit); // yellow - cairo_pattern_add_color_stop_rgb(_ready_process_gradient, 0.0, 1.00, 0.9, 0.0); - cairo_pattern_add_color_stop_rgb(_ready_process_gradient, 0.3, 1.00, 1.0, 0.9); - cairo_pattern_add_color_stop_rgb(_ready_process_gradient, 1.0, 1.00, 0.8, 0.0); + cairo_pattern_add_color_stop_rgb(_ready_process_gradient, 0.0, 1.00, 0.7, 0.0); + cairo_pattern_add_color_stop_rgb(_ready_process_gradient, 0.3, 1.00, 0.9, 0.0); + cairo_pattern_add_color_stop_rgb(_ready_process_gradient, 1.0, 1.00, 0.7, 0.0); _running_process_gradient = cairo_pattern_create_linear(0, 0, 0, _yu_process_bar_height * _y_unit); // green