From 4f3e8f61dfbb31867873c14563d1feafddb187c0 Mon Sep 17 00:00:00 2001 From: tchernobog Date: Wed, 30 Aug 2006 23:37:11 +0000 Subject: [PATCH] - Enable CPUPolicy configuration in the GUI through clicking on the toolbar button about the "Scheduling policy". The same is true also for a ResourcePolicy. These two features will also need a related entry under the "Edit" menu. Closes task #15. git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@970 3ecf2c5c-341e-0410-92b4-d18e462d057c --- Makefile.am | 2 + src/configure_policy_dialog.cc | 253 +++++++++++++++++++++++++++++++++ src/configure_policy_dialog.hh | 62 ++++++++ src/gui_builder.cc | 75 ++++++++-- src/gui_builder.hh | 2 + 5 files changed, 386 insertions(+), 8 deletions(-) create mode 100644 src/configure_policy_dialog.cc create mode 100644 src/configure_policy_dialog.hh diff --git a/Makefile.am b/Makefile.am index 58e6fdc..c2bb375 100644 --- a/Makefile.am +++ b/Makefile.am @@ -299,6 +299,7 @@ sgpemv2_SOURCES = \ src/add_request_dialog.cc \ src/cairo_elements.cc \ src/cairo_widget.cc \ + src/configure_policy_dialog.cc \ src/graphical_preferences_editor.cc \ src/gui_builder.cc \ src/main.cc \ @@ -313,6 +314,7 @@ noinst_HEADERS += \ src/add_request_dialog.hh \ src/cairo_elements.hh \ src/cairo_widget.hh \ + src/configure_policy_dialog.hh \ src/graphical_preferences_editor.hh \ src/gui_builder.hh \ src/main.hh \ diff --git a/src/configure_policy_dialog.cc b/src/configure_policy_dialog.cc new file mode 100644 index 0000000..2ecc27b --- /dev/null +++ b/src/configure_policy_dialog.cc @@ -0,0 +1,253 @@ +// src/configure_policy_dialog.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 "gettext.h" + +#include "sequences.tcc" + +#include "configure_policy_dialog.hh" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace sgpem; +using namespace Gtk; + + +// WARNING: Note that we make strong assumptions on the number of columns +// of the table. If you change it, you've to edit all the other methods +// to reflect it, expecially "on_okay()" + +ConfigurePolicyDialog::ConfigurePolicyDialog(const Glib::ustring title, + PolicyParameters& parameters) + : Gtk::Dialog(title, true, true), _parameters(parameters), + _table_int(NULL), _table_float(NULL), _table_string(NULL) +{ + typedef std::map > IntParams; + typedef std::map > FloatParams; + typedef std::map > StringParams; + + VBox& main_vbox = *get_vbox(); + guint row_n; + + // Integer parameters + const IntParams intpars = _parameters.get_registered_int_parameters(); + + if(!intpars.empty()) + { + Frame& intframe = *manage(create_category(_("Integer values"))); + main_vbox.pack_end(intframe); + _table_int = manage(new Table(intpars.size(), 2)); + _table_int->set_row_spacings(2); + _table_int->set_col_spacings(2); + _table_int->set_border_width(3); + intframe.add(*_table_int); + + row_n = 0; + for(Iseq it = const_iseq(intpars); it; ++it, ++row_n) + parameter_int(it->second, row_n); + } + + + // Float parameters + const FloatParams floatpars = _parameters.get_registered_float_parameters(); + if(!floatpars.empty()) + { + Frame& floatframe = *manage(create_category(_("Floating point values"))); + main_vbox.pack_end(floatframe); + _table_float = manage(new Table(floatpars.size(), 2)); + _table_float->set_row_spacings(2); + _table_float->set_col_spacings(2); + _table_float->set_border_width(3); + floatframe.add(*_table_float); + + row_n = 0; + for(Iseq it = const_iseq(floatpars); it; ++it, ++row_n) + parameter_float(it->second, row_n); + } + + // String parameters + const StringParams stringpars = _parameters.get_registered_string_parameters(); + if(!stringpars.empty()) + { + Frame& stringframe = *manage(create_category(_("Alphanumerical values"))); + main_vbox.pack_end(stringframe); + _table_string = manage(new Table(stringpars.size(), 2)); + _table_string->set_row_spacings(2); + _table_string->set_col_spacings(2); + _table_string->set_border_width(3); + stringframe.add(*_table_string); + + row_n = 0; + for(Iseq it = const_iseq(stringpars); it; ++it, ++row_n) + parameter_string(it->second, row_n); + } + + if(_table_int == NULL && _table_float == NULL && _table_string == NULL) + { + Label& message = *manage(new Label(_("No options to configure for this policy"))); + main_vbox.pack_end(message); + } + + // Add final buttons, and we're done. + add_button(Stock::CANCEL, RESPONSE_CANCEL); + HButtonBox& bbox = *get_action_area(); + Button& okay_bt = *manage(new Button(Stock::OK)); + okay_bt.set_flags(CAN_DEFAULT); + set_default(okay_bt); + bbox.pack_end(okay_bt); + + okay_bt.signal_clicked().connect(sigc::mem_fun(*this, &ConfigurePolicyDialog::on_okay)); + + main_vbox.show_all(); +} + + + +Gtk::Frame* +ConfigurePolicyDialog::create_category(const Glib::ustring& type_name) const +{ + Frame& frame = *new Frame("" + type_name + ""); + + frame.set_border_width(3); + static_cast(frame.get_label_widget())->set_use_markup(true); + + return &frame; +} + + +void +ConfigurePolicyDialog::parameter_int(const PolicyParameters::Parameter& param, guint row) +{ + Label& desc = *manage(new Label(param.get_name(), ALIGN_LEFT)); + _table_int->attach(desc, 0, 1, row, row + 1); + + Adjustment& adj = *manage(new Adjustment(param.get_value(), param.get_lower_bound(), param.get_upper_bound())); + SpinButton& spin = *manage(new SpinButton(adj)); + _table_int->attach(spin, 1, 2, row, row + 1); +} + + +void +ConfigurePolicyDialog::parameter_float(const PolicyParameters::Parameter& param, guint row) +{ + Label& desc = *manage(new Label(param.get_name(), ALIGN_LEFT)); + _table_float->attach(desc, 0, 1, row, row + 1); + + Adjustment& adj = *manage(new Adjustment(param.get_value(), param.get_lower_bound(), param.get_upper_bound())); + SpinButton& spin = *manage(new SpinButton(adj, 0, 3)); + _table_float->attach(spin, 1, 2, row, row + 1); +} + + +void +ConfigurePolicyDialog::parameter_string(const PolicyParameters::Parameter& param, guint row) +{ + Label& desc = *manage(new Label(param.get_name(), ALIGN_LEFT)); + _table_string->attach(desc, 0, 1, row, row + 1); + + Entry& entry = *manage(new Entry()); + entry.set_text(param.get_value()); + _table_string->attach(entry, 1, 2, row, row + 1); +} + + +void +ConfigurePolicyDialog::on_okay() +{ + // Save all values + if(_table_int != NULL) + { + const Table::TableList list = _table_int->children(); + + // (cannot) fixme: Using a reverse iterator makes me feel REALLY uneasy... + // what if the implementation changes between different gtk+ versions? + for(Iseq it = const_riseq(list); it; ++it) + { + Widget* w; + + w = it->get_widget(); // First column + assert(dynamic_cast(w) != NULL); + Glib::ustring name = static_cast(w)->get_text(); + + w = (++it)->get_widget(); // Pass to the second column + assert(dynamic_cast(w) != NULL); + int value = static_cast(w)->get_value_as_int(); + + _parameters.set_int(name, value); + } + } //~ if _table_int + + if(_table_float != NULL) + { + const Table::TableList list = _table_float->children(); + + // (cannot) fixme: Using a reverse iterator makes me feel REALLY uneasy... + // what if the implementation changes between different gtk+ versions? + for(Iseq it = const_riseq(list); it; ++it) + { + Widget* w; + + w = it->get_widget(); // First column + assert(dynamic_cast(w) != NULL); + Glib::ustring name = static_cast(w)->get_text(); + + w = (++it)->get_widget(); // Pass to the second column + assert(dynamic_cast(w) != NULL); + double value = static_cast(w)->get_value(); + + _parameters.set_float(name, static_cast(value)); + } + } //~ if _table_float + + if(_table_string != NULL) + { + const Table::TableList list = _table_string->children(); + + // (cannot) fixme: Using a reverse iterator makes me feel REALLY uneasy... + // what if the implementation changes between different gtk+ versions? + for(Iseq it = const_riseq(list); it; ++it) + { + Widget* w; + + w = it->get_widget(); // First column + assert(dynamic_cast(w) != NULL); + Glib::ustring name = static_cast(w)->get_text(); + + w = (++it)->get_widget(); // Pass to the second column + assert(dynamic_cast(w) != NULL); + Glib::ustring value = static_cast(w)->get_text(); + + _parameters.set_string(name, value); + } + } //~ if _table_string + + + // We're done. + response(RESPONSE_OK); +} diff --git a/src/configure_policy_dialog.hh b/src/configure_policy_dialog.hh new file mode 100644 index 0000000..fe7bda5 --- /dev/null +++ b/src/configure_policy_dialog.hh @@ -0,0 +1,62 @@ +// src/configure_policy_dialog.hh - 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 + +#ifndef CONFIGURE_POLICY_DIALOG_HH +#define CONFIGURE_POLICY_DIALOG_HH 1 + +#include "backend/policy_parameters.hh" + +#include +#include +#include +#include +#include +#include + +namespace sgpem +{ + + class ConfigurePolicyDialog : public Gtk::Dialog + { + public: + ConfigurePolicyDialog(const Glib::ustring title, PolicyParameters& parameters); + + protected: + Gtk::Frame* create_category(const Glib::ustring& type_name) const; + + void parameter_int(const PolicyParameters::Parameter& param, guint row); + void parameter_float(const PolicyParameters::Parameter& param, guint row); + void parameter_string(const PolicyParameters::Parameter& param, guint row); + + private: + void on_okay(); + + PolicyParameters& _parameters; + + Gtk::Table* _table_int; + Gtk::Table* _table_float; + Gtk::Table* _table_string; + + }; //~ class ConfigurePolicyDialog + +} //~ namespace sgpem + + +#endif //~ CONFIGURE_POLICY_DIALOG_HH diff --git a/src/gui_builder.cc b/src/gui_builder.cc index ce4bfd9..c276bbb 100644 --- a/src/gui_builder.cc +++ b/src/gui_builder.cc @@ -21,26 +21,25 @@ #include "config.h" #include "gettext.h" +#include "configure_policy_dialog.hh" +#include "gui_builder.hh" +#include "graphical_preferences_editor.hh" #include "schedulables_tree_widget.hh" #include "simulation_widget.hh" #include "resources_widget.hh" -#include "gui_builder.hh" -#include "graphical_preferences_editor.hh" - #include "backend/cpu_policy_exception.hh" #include "backend/malformed_policy_exception.hh" #include "backend/null_policy_exception.hh" #include "backend/user_interrupt_exception.hh" - #include "backend/cpu_policies_gatekeeper.hh" #include "backend/cpu_policy.hh" #include "backend/cpu_policy_manager.hh" #include "backend/resource_policies_gatekeeper.hh" #include "backend/resource_policy_manager.hh" - - +#include "backend/resource_policy.hh" #include "backend/history.hh" +#include "backend/policy_parameters.hh" #include "backend/simulation.hh" #include "backend/serializers_gatekeeper.hh" #include "backend/serializer.hh" @@ -51,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -197,10 +197,52 @@ GuiBuilder::on_file_saveas_activate() Gtk::Statusbar* sbar = _refXml->get_widget("MainStatusBar", sbar); sbar->push(msg); } - - } + +void +GuiBuilder::on_configure_cpu_policy() +{ + using namespace Gtk; + + CPUPolicy* policy = Simulation::get_instance().get_policy(); + + if(policy == NULL) + { + MessageDialog warn(_("No CPU policy is currently selected.\nPlease choose one before trying to configure it."), + true, MESSAGE_WARNING, BUTTONS_OK, true); + warn.run(); + return; + } + + PolicyParameters& params = policy->get_parameters(); + ConfigurePolicyDialog config_dialog(_("Configuring CPU Policy ") + policy->get_name(), params); + config_dialog.run(); +} + + +void +GuiBuilder::on_configure_resource_policy() +{ + using namespace Gtk; + + ResourcePolicy* policy = Simulation::get_instance().get_resource_policy(); + + if(policy == NULL) + { + MessageDialog warn(_("No CPU policy is currently selected.\nPlease choose one before trying to configure it."), + true, MESSAGE_WARNING, BUTTONS_OK, true); + warn.run(); + return; + } + + PolicyParameters& params = policy->get_parameters(); + ConfigurePolicyDialog config_dialog(_("Configuring CPU Policy ") + policy->get_name(), params); + config_dialog.run(); +} + + + GuiBuilder::GuiBuilder(const std::string& gladefile) : _refXml(Xml::create(gladefile)), _controller(Simulation::get_instance(), _refXml) { @@ -237,6 +279,22 @@ GuiBuilder::GuiBuilder(const std::string& gladefile) edit_preferences->signal_activate().connect(sigc::mem_fun(*this, &GuiBuilder::on_edit_preferences_activate)); + // ---------------- Toolbar buttons ------------------ + + // Note: the Play, Pause and Stop buttons are already managed by sgpem::SimulationController. + + // Configure CPU Policy + MenuToolButton* cpu_policies_tb_menu; + _refXml->get_widget("ToolBar.PolicySelector", cpu_policies_tb_menu); + cpu_policies_tb_menu->signal_clicked().connect(sigc::mem_fun(*this, &GuiBuilder::on_configure_cpu_policy)); + + // Configure Resource Policy + MenuToolButton* res_policies_tb_menu; + _refXml->get_widget("ToolBar.ResourceScheduling", res_policies_tb_menu); + res_policies_tb_menu->signal_clicked().connect(sigc::mem_fun(*this, &GuiBuilder::on_configure_resource_policy)); + + // --------------------------------------------------- + // About dialog MenuItem* help_about; _refXml->get_widget("MenuItem.Help.About", help_about); @@ -256,6 +314,7 @@ GuiBuilder::GuiBuilder(const std::string& gladefile) scheds_tree->show(); + // Resources ListView widget ResourcesWidget* resources_widget = NULL; _refXml->get_widget_derived("Resources.Tree", resources_widget); resources_widget->show(); diff --git a/src/gui_builder.hh b/src/gui_builder.hh index 1f3478e..ea75051 100644 --- a/src/gui_builder.hh +++ b/src/gui_builder.hh @@ -81,6 +81,8 @@ namespace sgpem void on_file_open_activate(); void on_file_save_activate(); void on_file_saveas_activate(); + void on_configure_cpu_policy(); + void on_configure_resource_policy(); private: Glib::RefPtr _refXml;