diff --git a/src/backend/concrete_simulation.cc b/src/backend/concrete_simulation.cc index f9a22c5..4285682 100644 --- a/src/backend/concrete_simulation.cc +++ b/src/backend/concrete_simulation.cc @@ -19,6 +19,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "concrete_simulation.hh" + #include #include #include @@ -61,7 +62,7 @@ ConcreteSimulation::jump_to(History::position p) throw(UserInterruptException, N switch (_state) { case state_running: - // pauses the simulation (see below) + // pauses the simulation (done below) break; case state_stopped: _history.set_front(0); @@ -72,7 +73,6 @@ ConcreteSimulation::jump_to(History::position p) throw(UserInterruptException, N // Disable momentarily updates for registered observers on // sgpem::Simulation too. - // See History for an example of how to implement this. set_notify_enabled(false); pause(); @@ -83,8 +83,16 @@ ConcreteSimulation::jump_to(History::position p) throw(UserInterruptException, N History::position increment = 0; while (yet_to_finish && p > _history.get_front() + increment) { - yet_to_finish = step(); - increment++; + try + { + yet_to_finish = step(); + increment++; + } + catch(...) + { + // FIXME: manage exceptions! Lookout that notifications + // have to be re-enabled. + } } get_history().set_front(std::min(p, _history.get_size())); if (!yet_to_finish) diff --git a/src/jump_to_dialog.cc b/src/jump_to_dialog.cc index 15d855d..dcd5802 100644 --- a/src/jump_to_dialog.cc +++ b/src/jump_to_dialog.cc @@ -18,17 +18,21 @@ // 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 "jump_to_dialog.hh" + #include #include #include #include #include -#include -#include +#include -#include "gettext.h" +#ifndef NDEBUG +#include +#endif #include @@ -56,6 +60,11 @@ JumpToDialog::JumpToDialog(BaseObjectType* cobject, const RefPtr& glade) : _stop_button->signal_clicked().connect( sigc::mem_fun(*this, &JumpToDialog::_on_stop)); + _ok_button->signal_clicked().connect(sigc::bind( + sigc::mem_fun(*this, &JumpToDialog::response), RESPONSE_OK)); + _ok_button->signal_clicked().connect( + sigc::mem_fun(*this, &JumpToDialog::hide)); + // FIXME: not implemented _stop_button->set_sensitive(false); } @@ -64,24 +73,47 @@ void JumpToDialog::_on_jump() { _ok_button->set_sensitive(false); -// _stop_button->set_sensitive(true); + _stop_button->set_sensitive(true); _jump_button->set_sensitive(false); _progress->set_fraction(0.0); + assert(_instant_spin->get_value_as_int() > 0); _target_instant = _instant_spin->get_value_as_int(); - Simulation::get_instance().attach(*this); - Simulation::get_instance().jump_to(_target_instant); - Simulation::get_instance().detach(*this); + Simulation& sim = Simulation::get_instance(); + History& h = sim.get_history(); + + sim.attach(*this); + h.set_notify_enabled(false); + try + { + if(_target_instant < h.get_size() - 1) + sim.jump_to(_target_instant); + else + sim.jump_to(h.get_size() - 1); + while(h.get_front() < _target_instant) + { + sim.run(); + if(sim.get_state() == Simulation::state_stopped) + break; // Simulation ended before reaching _target_instant + } + } + catch(...) + { + // FIXME: correctly manage exceptions! + } + h.set_notify_enabled(true); + sim.detach(*this); _ok_button->set_sensitive(true); -// _stop_button->set_sensitive(false); + _stop_button->set_sensitive(false); _jump_button->set_sensitive(true); } void JumpToDialog::_on_stop() { + Simulation::get_instance().stop(); } void @@ -92,4 +124,10 @@ JumpToDialog::update(const Simulation& changed_simulation) double percent = static_cast(front) / _target_instant; _progress->set_fraction(percent); + + // Needed to force display (else under + // intensive computation it doesn't have + // the time to flush all UI events): + while(Gtk::Main::events_pending()) + Gtk::Main::iteration(); }