// src/simulation_widget.cc - Copyright 2005, 2006, University // of Padova, dept. of Pure and Applied // Mathematics // // This file is part of SGPEMv2. // // This is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // SGPEMv2 is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with SGPEMv2; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "simulation_widget.hh" #include "cairo_elements.hh" #include "backend/history.hh" #include "backend/simulation.hh" #include "backend/string_utils.hh" #include #ifndef NDEBUG #include #endif using namespace sgpem; SimulationWidget::SimulationWidget() : Glib::ObjectBase("sgpem_SimulationWidget"), CairoWidget(), SimulationObserver(), _simulation(0), _x_unit(10), _y_unit(10) { // Register this observer: Simulation::get_instance().attach(*this); } SimulationWidget::~SimulationWidget() { Simulation::get_instance().detach(*this); } void SimulationWidget::update(const Simulation& changed_simulation) { _simulation = &changed_simulation; // Force redraw //redraw(); resize_redraw(); } void SimulationWidget::draw_widget(cairo_t* ctx) { /* std::cout << " draw_widget start " << std::endl; if(!_simulation) return; std::cout << " draw_widget continue " << std::endl; */ const Simulation& simu = Simulation::get_instance(); double top_margin = _y_unit; double left_margin = _x_unit; double top_graph_margin = 1.0 * _y_unit; //3.0 * _y_unit; double left_graph_margin = 11.0 * _x_unit; double process_label_delta = 1.0 * _y_unit; double process_bar_delta = 1.0 * _y_unit; double process_bar_height = 1.0 * _y_unit; double process_height = process_bar_height + 2*process_bar_delta; Simulation::state sim_state = simu.get_state(); const History& hist = simu.get_history(); const Environment::Processes& processes = hist.get_last_environment().get_processes(); int nproc = processes.size(); double text_maxw = 0; bool* terminated = 0; cairo_text_extents_t extents; // evaluate minimum x and y extensions /* // show simulation title Glib::ustring title; switch(sim_state) { case Simulation::state_running: title = "Simulation Running"; break; case Simulation::state_paused: title = "Simulation Paused"; break; case Simulation::state_stopped: title = "Simulation Stopped"; break; } cairo_text_extents(ctx, title.c_str(), &extents); cairo_move_to(ctx, left_margin, extents.height + top_margin); cairo_show_text(ctx,title.c_str()); */ if(nproc>0) terminated = new bool[nproc]; // show processes names... // set clip region to cut long names cairo_rectangle(ctx, 0, top_graph_margin, left_graph_margin - _x_unit, nproc*process_height); cairo_clip(ctx); // set the rectangular clip region for(int i=0; iget_name().c_str(), &extents); if(text_maxwget_name().c_str()); terminated[i] = false; } cairo_reset_clip(ctx); // remove clip region if(_simulation && hist.get_size()>0 /* && _simulation->get_state()!=Simulation::state_stopped */ ) { // std::cout << " draw_widget not_stop " << std::endl; unsigned int pos = _simulation->get_front(); // show grid cairo_save(ctx); cairo_set_line_width(ctx, 0.5*cairo_get_line_width(ctx)); // nproc+1 horizontal lines for(int i=0; i<=nproc; i++) { cairo_move_to(ctx, left_graph_margin, top_graph_margin + process_height*i); cairo_line_to(ctx, left_graph_margin + (pos+2)*_x_unit, top_graph_margin + process_height*i); } // opening vertical line cairo_move_to(ctx, left_graph_margin, top_graph_margin); cairo_line_to(ctx, left_graph_margin, top_graph_margin + process_height*nproc); cairo_stroke(ctx); // closing vertical line if(sim_state!=Simulation::state_stopped) { double dashes = 1.5; cairo_set_dash(ctx, &dashes, 1, 0.0); } cairo_move_to(ctx, left_graph_margin + (pos+2)*_x_unit, top_graph_margin); cairo_line_to(ctx, left_graph_margin + (pos+2)*_x_unit, top_graph_margin + process_height*nproc); cairo_stroke(ctx); cairo_restore(ctx); for(int t=1; t<=pos; t++) { const Environment::Processes& processes = hist.get_environment_at(t).get_processes(); double xpos = left_graph_margin + t*_x_unit; for(int i=0; iget_state(); switch(st) { case Schedulable::state_running: cairo_set_source_rgb(ctx, 0, 1, 0); cairo_rectangle(ctx, xpos, ypos, _x_unit, _y_unit); cairo_fill(ctx); break; case Schedulable::state_ready: cairo_set_source_rgb(ctx, 1, 1, 0); cairo_rectangle(ctx, xpos, ypos, _x_unit, _y_unit); cairo_fill(ctx); break; case Schedulable::state_blocked: cairo_set_source_rgb(ctx, 1, 0, 0); cairo_rectangle(ctx, xpos, ypos, _x_unit, _y_unit); cairo_fill(ctx); break; case Schedulable::state_future: break; case Schedulable::state_terminated: if(!terminated[i]) { cairo_set_source_rgb(ctx, 0, 0, 0); cairo_rectangle(ctx, xpos, ypos, _x_unit, _y_unit); cairo_fill(ctx); } terminated[i] = true; break; } } } cairo_save(ctx); cairo_set_source_rgb(ctx, 0, 0, 0); cairo_set_line_width(ctx, 0.25*cairo_get_line_width(ctx)); for(int t=0; t<=pos; t++) { cairo_move_to(ctx, left_graph_margin + (t+1)*_x_unit, top_graph_margin + process_height*nproc); cairo_rel_line_to(ctx, 0, 0.5 * _y_unit); Glib::ustring val; int_to_string(t, val); cairo_move_to(ctx, left_graph_margin + (t+1)*_x_unit, top_graph_margin + process_height*nproc + _y_unit + extents.height); cairo_show_text(ctx,val.c_str()); } cairo_stroke(ctx); cairo_restore(ctx); /* int w = left_graph_margin + (pos+4)*_x_unit; int h = top_graph_margin + process_height*nproc + 4*_y_unit; if(get_height()get_history(); const Environment::Processes& processes = hist.get_last_environment().get_processes(); int pos = _simulation->get_front(); cairo_text_extents_t extents; // std::cout << " x_unit: " << std::endl; Glib::ustring val("999"); cairo_text_extents(ctx, val.c_str(), &extents); if(_x_unit