diff --git a/src/backend/concrete_history.cc b/src/backend/concrete_history.cc index 32cd497..fb2a379 100644 --- a/src/backend/concrete_history.cc +++ b/src/backend/concrete_history.cc @@ -174,7 +174,7 @@ ConcreteHistory::remove(resource_key_t resource_key) for (Threads::iterator it2 = threads.begin(); it2 != threads.end(); it2++) { Requests& reqs = (*it2)->get_dynamic_requests(); - for (Requests::iterator it3 = reqs.begin(); it3 != reqs.end();) + for (Requests::iterator it3 = reqs.begin(); it3 != reqs.end(); it3++) { SubRequests& subr = (*it3)->get_dynamic_subrequests(); SubRequests::iterator it4 = subr.begin(); @@ -186,12 +186,6 @@ ConcreteHistory::remove(resource_key_t resource_key) } else it4++; - - // erase empty requests - if(subr.size() == 0) - it3 = reqs.erase(it3); - else - ++it3; } } } //~ end monstrous construct, "The Thing That Should Not Be" diff --git a/src/resources_widget.cc b/src/resources_widget.cc index af1d5b7..8a7d80a 100644 --- a/src/resources_widget.cc +++ b/src/resources_widget.cc @@ -23,9 +23,13 @@ #include "backend/history.hh" #include "backend/simulation.hh" #include "backend/resource.hh" +#include "backend/process.hh" +#include "backend/thread.hh" +#include "backend/request.hh" #include #include +#include #include "gettext.h" @@ -133,8 +137,6 @@ ResourcesWidget::update(const History& history) _model->clear(); - // TODO use the new sequence iterator, it's been made for - // something!!! for(Iseq it = const_iseq(resources); it; ++it) { Resource& r = *(it->second); @@ -177,4 +179,36 @@ ResourcesWidget::_on_remove_resource() unsigned int selection; if(get_selected_key(selection)) Simulation::get_instance().get_history().remove(selection); + + /** Delete empty requests, they are useless with the current GUI **/ + + typedef Environment::Processes::const_iterator ProcessIt; + using std::vector; + + const Environment& env = Simulation::get_instance().get_history().get_last_environment(); + const Environment::Processes& processes = env.get_processes(); + + std::stack to_delete; + + for(ProcessIt pit = processes.begin(); pit != processes.end(); ++pit) + { + vector threads = (*pit)->get_threads(); + + for(vector::iterator tit = threads.begin(); tit != threads.end(); ++tit) + { + vector requests = (*tit)->get_requests(); + + for(vector::iterator rit = requests.begin(); rit != requests.end(); ++rit) + { + if((*rit)->get_subrequests().empty()) + to_delete.push(*rit); + } + } + } + + while(!to_delete.empty()) + { + Simulation::get_instance().get_history().remove(*to_delete.top()); + to_delete.pop(); + } } diff --git a/src/schedulables_tree_widget.cc b/src/schedulables_tree_widget.cc index acb162f..411fbd8 100644 --- a/src/schedulables_tree_widget.cc +++ b/src/schedulables_tree_widget.cc @@ -75,8 +75,47 @@ SchedulablesTreeWidget::~SchedulablesTreeWidget() Simulation::get_instance().get_history().detach(*this); } -sgpem::Process* -SchedulablesTreeWidget::get_selected_process() +template +bool +SchedulablesTreeWidget::check_type(SchedulablesTreeWidget::HandleType type) +{ + return false; +} + +namespace sgpem +{ + template <> + bool + SchedulablesTreeWidget::check_type(HandleType type) + { + return type == htype_process; + } + + template <> + bool + SchedulablesTreeWidget::check_type(HandleType type) + { + return type == htype_thread; + } + + template <> + bool + SchedulablesTreeWidget::check_type(HandleType type) + { + return type == htype_request; + } + + template <> + bool + SchedulablesTreeWidget::check_type(HandleType type) + { + return type == htype_subrequest; + } +} + +template +T* +SchedulablesTreeWidget::get_selected() { TreeModel::iterator sel = get_selection()->get_selected(); @@ -86,27 +125,21 @@ SchedulablesTreeWidget::get_selected_process() const void* p_handle = (*sel)[_handles_column]; HandleType type = (*sel)[_types_column]; - if(type != htype_process) + if(!check_type(type)) return NULL; - return reinterpret_cast(const_cast(p_handle)); + return reinterpret_cast(const_cast(p_handle)); } -sgpem::Thread* -SchedulablesTreeWidget::get_selected_thread() +SchedulablesTreeWidget::HandleType +SchedulablesTreeWidget::get_selection_type() { TreeModel::iterator sel = get_selection()->get_selected(); if(!sel) - return NULL; - - const void* p_handle = (*sel)[_handles_column]; - HandleType type = (*sel)[_types_column]; - - if(type != htype_thread) - return NULL; - - return reinterpret_cast(const_cast(p_handle)); + return htype_undefined; + else + return (*sel)[_types_column]; } bool @@ -127,19 +160,60 @@ SchedulablesTreeWidget::on_button_press_event(GdkEventButton* event) action_group->add( Gtk::Action::create("AddRequest", "Add Request"), sigc::mem_fun(*this, &SchedulablesTreeWidget::_on_add_request) ); + action_group->add( Gtk::Action::create("RemoveProcess", "Remove Process"), + sigc::mem_fun(*this, &SchedulablesTreeWidget::_on_remove_process) ); + + action_group->add( Gtk::Action::create("RemoveThread", "Remove Thread"), + sigc::mem_fun(*this, &SchedulablesTreeWidget::_on_remove_thread) ); + + action_group->add( Gtk::Action::create("RemoveRequest", "Remove Request"), + sigc::mem_fun(*this, &SchedulablesTreeWidget::_on_remove_request) ); + + action_group->add( Gtk::Action::create("RemoveSubrequest", "Remove Subrequest"), + sigc::mem_fun(*this, &SchedulablesTreeWidget::_on_remove_subrequest) ); + RefPtr UIManager = Gtk::UIManager::create(); UIManager->insert_action_group(action_group); + const HandleType selection_type = get_selection_type(); + Glib::ustring ui_info = "" - " " - " "; - if(get_selected_process() != NULL) - ui_info += + " "; + + if(selection_type == htype_process) + ui_info += " "; - if(get_selected_thread() != NULL) + else if(selection_type == htype_thread) ui_info += " "; + + ui_info += + " "; + + if(selection_type != htype_undefined) + ui_info += + " "; + + switch(selection_type) + { + case htype_process: + ui_info += + " "; + break; + case htype_thread: + ui_info += + " "; + break; + case htype_request: + ui_info += + " "; + break; + case htype_subrequest: + ui_info += + " "; + } + ui_info += " " ""; @@ -244,7 +318,7 @@ SchedulablesTreeWidget::_on_add_process() void SchedulablesTreeWidget::_on_add_thread() { - Process* p = get_selected_process(); + Process* p = get_selected(); if(p == NULL) return; @@ -274,7 +348,7 @@ SchedulablesTreeWidget::_on_add_thread() void SchedulablesTreeWidget::_on_add_request() { - Thread* t = get_selected_thread(); + Thread* t = get_selected(); if(t == NULL) return; @@ -284,3 +358,46 @@ SchedulablesTreeWidget::_on_add_request() _add_request_dialog->hide(); } + +void +SchedulablesTreeWidget::_on_remove_process() +{ + Process* p = get_selected(); + assert(p != NULL); + + Simulation::get_instance().get_history().remove(*p); +} + +void +SchedulablesTreeWidget::_on_remove_thread() +{ + Thread* t = get_selected(); + assert(t != NULL); + + Simulation::get_instance().get_history().remove(*t); +} + +void +SchedulablesTreeWidget::_on_remove_request() +{ + Request* r = get_selected(); + assert(r != NULL); + + Simulation::get_instance().get_history().remove(*r); +} + +void +SchedulablesTreeWidget::_on_remove_subrequest() +{ + SubRequest* sr = get_selected(); + assert(sr != NULL); + + Request& owner = sr->get_request(); + + Simulation::get_instance().get_history().remove(*sr); + + // empty requests are COMPLETELY useless with the current GUI + if(owner.get_subrequests().empty()) + Simulation::get_instance().get_history().remove(owner); +} + diff --git a/src/schedulables_tree_widget.hh b/src/schedulables_tree_widget.hh index b0d9a3d..51eadae 100644 --- a/src/schedulables_tree_widget.hh +++ b/src/schedulables_tree_widget.hh @@ -67,12 +67,21 @@ namespace sgpem htype_undefined }; - Process* get_selected_process(); - Thread* get_selected_thread(); + template + bool check_type(HandleType type); + + template + T* get_selected(); + HandleType get_selection_type(); void _on_add_process(); void _on_add_thread(); void _on_add_request(); + + void _on_remove_process(); + void _on_remove_thread(); + void _on_remove_request(); + void _on_remove_subrequest(); Glib::RefPtr _model; Gtk::TreeModelColumnRecord _columns;