/* ** This file is part of the ViTE project. ** ** This software is governed by the CeCILL-A license under French law ** and abiding by the rules of distribution of free software. You can ** use, modify and/or redistribute the software under the terms of the ** CeCILL-A license as circulated by CEA, CNRS and INRIA at the following ** URL: "http://www.cecill.info". ** ** As a counterpart to the access to the source code and rights to copy, ** modify and redistribute granted by the license, users are provided ** only with a limited warranty and the software's author, the holder of ** the economic rights, and the successive licensors have only limited ** liability. ** ** In this respect, the user's attention is drawn to the risks associated ** with loading, using, modifying and/or developing or reproducing the ** software by the user in light of its specific status of free software, ** that may mean that it is complicated to manipulate, and that also ** therefore means that it is reserved for developers and experienced ** professionals having in-depth computer knowledge. Users are therefore ** encouraged to load and test the software's suitability as regards ** their requirements in conditions enabling the security of their ** systems and/or data to be ensured and, more generally, to use and ** operate it in the same conditions as regards security. ** ** The fact that you are presently reading this means that you have had ** knowledge of the CeCILL-A license and that you accept its terms. ** ** ** ViTE developers are (for version 0.* to 1.0): ** ** - COULOMB Kevin ** - FAVERGE Mathieu ** - JAZEIX Johnny ** - LAGRASSE Olivier ** - MARCOUEILLE Jule ** - NOISETTE Pascal ** - REDONDY Arthur ** - VUCHENER Clément ** */ /*! *\file DrawTrace.hpp */ #ifndef DRAW_TRACE_HPP #define DRAW_TRACE_HPP #include /* * Theses constants can not be put as static const float because it is a template and there binary representation is not normed by the C++ langage. */ /*! * \def _DRAWING_CONTAINER_HEIGHT_DEFAULT * \brief The default height for basic containers. */ #define _DRAWING_CONTAINER_HEIGHT_DEFAULT 1.2f /*! * \def _DRAWING_CONTAINER_WIDTH_DEFAULT * \brief The default width for containers. */ #define _DRAWING_CONTAINER_WIDTH_DEFAULT 2.5f /*! * \def _DRAWING_CONTAINER_H_SPACE_DEFAULT * \brief The default horizontal space between containers. */ #define _DRAWING_CONTAINER_H_SPACE_DEFAULT 0.1f /*! * \def _DRAWING_CONTAINER_V_SPACE_DEFAULT * \brief The default vertical space between containers. */ #define _DRAWING_CONTAINER_V_SPACE_DEFAULT 0.2f /*! * \def _DRAWING_STATE_HEIGHT_DEFAULT * \brief The default height for states. */ #define _DRAWING_STATE_HEIGHT_DEFAULT 1.2f /*! * \def _DRAWING_STATE_V_SPACE_DEFAULT * \brief The default vertical space between states. */ #define _DRAWING_STATE_V_SPACE_DEFAULT 0.2f /*! * \class DrawTrace * \brief Browse the trace and call back T drawing methods */ /*template*/ class DrawTrace { protected: // Interface_graphic* _window; /*! * \brief Containers with states or events */ std::list _entity_containers; /*! * \brief Containers with links */ std::list _link_containers; /*! * \brief Containers with variables */ std::list _variable_containers; std::map > _container_positions; std::map > _container_sizes; std::map _var_positions; // Geometrical informations about the trace shape. /*! * \brief _container_width width of the container */ Element_pos _container_width; /*! * \brief _container_height height of the container */ Element_pos _container_height; /*! * \brief _container_h_space Horizontal space beetween 2 containers */ Element_pos _container_h_space; /*! * \brief _container_v_space Vertical space between 2 containers */ Element_pos _container_v_space; /*! * \brief _state_height Height of the state */ Element_pos _state_height; /*! * \brief _state_v_space Vertical space between 2 states */ Element_pos _state_v_space; public: /*********************************** * * Constructor and destructor. * **********************************/ /*! * \brief The default constructor */ DrawTrace() { _container_width = _DRAWING_CONTAINER_WIDTH_DEFAULT; _container_height = _DRAWING_CONTAINER_HEIGHT_DEFAULT; _container_h_space = _DRAWING_CONTAINER_H_SPACE_DEFAULT; _container_v_space = _DRAWING_CONTAINER_V_SPACE_DEFAULT; _state_height = _DRAWING_STATE_HEIGHT_DEFAULT; _state_v_space = _DRAWING_STATE_V_SPACE_DEFAULT; } /*! * \brief The destructor */ virtual ~DrawTrace() { } /*********************************** * * Building functions. * **********************************/ /*! * \fn build(T* draw_object, Trace* trace) * \brief The trace building function that do not draw all the containers but only a part. * \param draw_object the kind of object which will be drawn (OpenGL, SVG...). * \param trace the trace data. */ template void build(T* draw_object, Trace* trace) { Info::Container::y_max=0;//reset the vertical zoom when rebuilding double zoom = trace->get_filter(); Interval * interval;// = trace->get_interval_constrained(); //clear entities _container_positions.clear(); _container_sizes.clear(); _entity_containers.clear(); _link_containers.clear(); _variable_containers.clear(); std::vector *container = trace->get_selected_container(); if(container == NULL || container->empty()){ container = new std::vector(); trace->set_filter(0); std::stack containers; const Container::Vector *root_containers = trace->get_view_root_containers(); if(root_containers->empty())root_containers= trace->get_root_containers(); for (Container::VectorIt i = root_containers->begin(); i != root_containers->end(); i++){ containers.push(*i); container->push_back(*i); } add(container, &containers); } //Adding the parent containers if not added yet else{ bool ended = false; std::vector store; store.clear(); while (!ended){ ended = true; for(std::vector::const_iterator it = container->begin() ; it != container->end(); it ++){ if( *it && (*it)->get_parent()) if(!is_in_set((*it)->get_parent(),container)){ store.push_back((*it)->get_parent()); ended = false; } }//end for //TODO Warning the same container should be added more than 1 time for(std::vector::const_iterator it = store.begin() ; it != store.end(); it ++){ if( !is_in_set(*it,container)) container->push_back(*it); } store.clear(); }//end while }//end else interval = trace->get_interval_constrained(); draw_object->start_draw(); draw_object->start_draw_containers(); browse_container_tree(draw_object, trace,container); draw_object->end_draw_containers(); browse_entities(draw_object,zoom,interval,container); draw_object->end_draw(); } /*********************************** * * Browsing functions. * **********************************/ /* * \fn browse_container_tree * \brief Function that browses the containers of the trace argument that * are in the set container and make them painted with a T object */ template inline void browse_container_tree(T* draw_object, Trace* trace, std::vector *container){ /*** Drawing containers ***/ Element_pos y = 0.; const Container::Vector *root_containers = trace->get_view_root_containers(); if (root_containers->empty()) root_containers = trace->get_root_containers(); if (root_containers->empty()) { *Message::get_instance() << QObject::tr("There is no container. The trace can not be drawn.").toStdString() << Message::endw; } else { for (Container::VectorIt i = root_containers->begin(); i != root_containers->end(); i++) // Use the fact that if a container is selected, then it implies that all his ancestors are if(is_in_set(*i,container)) y += browse_container(draw_object, *i, 0., y, _container_width, 0., container)+_container_v_space; } }/* end browse_container_tree */ /* * \fn browse_container * \brief Recursive function that browse a container to draw it if it is in * the set of container with a T painting object in position, knowing the * current depth in the tree */ template Element_pos browse_container(T* draw_object, const Container *container, Element_pos x, Element_pos y, Element_pos w, Element_pos h, std::vector *set_container) { //int size = 0; // Draw children: // we want to display only children meant to be displayed const Container::Vector *children = container->get_view_children(); if( children->empty() ) children = container->get_children(); /*if(!children.empty()) h = 0.;*/ for (Container::VectorIt i = children->begin(); i != children->end(); i++) { h += browse_container(draw_object, (*i), x + _container_width + _container_h_space, y + h, _container_width, 0., set_container) + _container_v_space; } // h -= _container_v_space; /*if(is_in_set(*i,set_container)) size += browse_container(draw_object, (*i), position+size, depth+1,set_container);*/ // Use one line for states and events #ifdef USE_ITC if ( (container->get_states() != NULL && !container->get_states()->empty()) || (container->get_events() != NULL && !container->get_events()->empty()) ) #else if ( !container->get_states()->empty() || !container->get_events()->empty() ) #endif { h += _container_height + _container_v_space; _entity_containers.push_back(container); } // Store the position to draw links _container_positions[container] = y; _container_sizes[container] = h; // Use one line for each variable if (container->get_variable_number() > 0) { _variable_containers.push_back(container); h += (_container_height + _container_v_space) * container->get_variable_number(); } if (h < _container_height) // Minimum size h = _container_height; // Push containers with links to draw if (!container->get_links()->empty()) _link_containers.push_back(container); h -= _container_v_space; // Draw this container draw_container(draw_object, x, y, w, h, container->get_name().to_string()); return h; } /*! * \brief Draw a container * \param draw_object Object that contains drawing methods to call * \param position Starting line of the container * \param size Height of the container in number of line * \param depth Depth of container in the tree * \param text Name of the container */ template inline void draw_container(T* draw_object, Element_pos x, Element_pos y, Element_pos w, Element_pos h, const std::string &text) { //Element_pos x = depth *(_container_width +_container_h_space) + _container_h_space/2; //Element_pos y = position*(_container_height+_container_v_space) + _container_v_space/2; //Element_pos height = size *(_container_height+_container_v_space) - _container_v_space; draw_object->draw_container(x, y+_container_v_space/2, w, h, text); //draw_object->draw_container_text(x, y+h/2, text); } /*! * \brief Browse the states list and draw them */ template inline void browse_entities(T* draw_object, double zoom, Interval* interval, std::vector *set_container) { ////////////////////////////////////////////////////////// const Container *container; StateChange::Tree *state_tree; Event::Tree *event_tree; const Link::Vector *link_list; Link *link; const std::map *variable_map; Variable *var; const std::list > *variable_values; Element_pos position; const Color *color; std::map::const_iterator field; Element_pos lvl_zoom; color = NULL; if(zoom>=0) lvl_zoom = zoom; else lvl_zoom = 0; draw_object->start_draw_states(); draw_object->start_draw_events(); for (std::list::const_iterator c = _entity_containers.begin(); c != _entity_containers.end(); c++) { if(is_in_set(*c,set_container)){ container = *c; position = _container_positions[container] + _container_sizes[container] - (_container_height + _container_v_space); state_tree = container->get_states(); event_tree = container->get_events(); #ifdef USE_ITC if(state_tree!=NULL){ #endif if ( !state_tree->empty() ) { //printf("drawing states for %s\n", container->get_name().to_string().c_str()); // Browse states DrawTree(draw_object, position, lvl_zoom, _container_height, _container_v_space, _state_height, _state_v_space) .draw_tree(state_tree, *interval); } #ifdef USE_ITC } if(event_tree!=NULL){ #endif if ( !event_tree->empty()){ //printf("drawing events for %s\n", container->get_name().to_string().c_str()); // Browse events DrawTree(draw_object, position, lvl_zoom, _container_height, _container_v_space, _state_height, _state_v_space) .draw_tree(event_tree, *interval); } #ifdef USE_ITC } #endif } }/* end for (!_stack_states.empty()) */ draw_object->end_draw_events(); draw_object->end_draw_states(); draw_object->start_draw_arrows(); for (std::list::const_iterator c = _link_containers.begin(); c != _link_containers.end(); c++) { if(is_in_set(*c,set_container)){ container = *c; // Browse links link_list = container->get_links(); for (Link::VectorIt it = link_list->begin(); it != link_list->end(); it++) { link = *it; bool display=false; color=NULL; if(!Session::get_use_palette("link_types")) display = true; else{ if (link->get_type()){ Palette *lt = Session::get_palette("link_types", Session::get_current_palette("link_types")); color = lt->get_color(link->get_type()->get_name().to_string()); if(color) display=true; /*for(std::list::const_iterator it2= link_types->get_->begin(); it2!= link_types->end(); it2++ ){ if(*it2 == link->get_type()->get_name().to_string()){ display=true; break; } } */ } } if(display && link_is_in_set(link,set_container,interval)){ // Search the color if (color==NULL && link->get_type()&& link->get_type()->get_extra_fields()!=NULL && !link->get_type()->get_extra_fields()->empty() && ((field = link->get_type()->get_extra_fields()->find(std::string("Color"))) != link->get_type()->get_extra_fields()->end())) /* Call the object link drawing function with the link color */ color = (const Color *)(*field).second; draw_link(draw_object, link, color ); } }/* end for */ }//end for }/* end while (!_stack_states.empty()) */ draw_object->end_draw_arrows(); draw_object->start_draw_counter(); for (std::list::const_iterator c = _variable_containers.begin(); c != _variable_containers.end(); c++) { if(is_in_set(*c,set_container)){ container = *c; position = _container_positions[container] + _container_sizes[container]; // Browse variables variable_map = container->get_variables(); for (std::map::const_iterator i = variable_map->begin(); i != variable_map->end(); i++) { var = (*i).second; double min = var->get_min().get_value(); double max = var->get_max().get_value(); variable_values = var->get_values(); double first_value = 0.; double second_value = 0.; //draw_object->draw_text_value((long int)var,0.0, (position+1)*(_container_height+_container_v_space) - _container_v_space/2 - 0.5*_container_height); draw_object->draw_text_value((long int)var, 0.0, position + 0.5 * _container_height + _container_v_space/2); _var_positions[var]=position; draw_variable_value(draw_object, 0.0, 0.0, position); for (std::list >::const_iterator value = variable_values->begin(); value != variable_values->end(); value++) { /* Call the object state drawing function. We pass the first value if correspond to the beginning */ first_value = (*value).first.get_value(); second_value =((*value).second.get_value()-min)/(max-min) ; if(!(first_value == 0. && second_value == 0.)) { draw_variable_value(draw_object, first_value, second_value, position); } } draw_variable_value(draw_object, 0.0, 0.0, position); position += _container_height + _container_v_space; // One line was used }/* end for */ } }//end for draw_object->end_draw_counter(); } /*! * \brief Draw a point of a variable curve * \param draw_object Object that contains the drawing methods * \param time Time of the point * \param value Value of of the variable (between 0.0 and 1.0) * \param position Line where the variable is drawn */ template inline void draw_variable_value(T *draw_object, double time, double value, Element_pos position) { Element_pos y = position + (_container_height+_container_v_space) -_container_v_space/2 - value*_container_height; draw_object->draw_counter(time, y); } /*! * \brief Draw a link * \param draw_object Object that contains the drawing methods * \param starttime Time of the start of the link * \param endtime Time of the end of the link * \param start Line of the start of the link * \param end Line of the end of the link * \param color The link color */ template inline void draw_link(T *draw_object, const Link *link, const Color* color) { double starttime = link->get_start_time().get_value(); double endtime = link->get_end_time().get_value(); double srcpos = _container_positions[link->get_source()]; double dstpos = _container_positions[link->get_destination()]; double srcsize = _container_sizes[link->get_source()]; double dstsize = _container_sizes[link->get_destination()]; Element_pos y1 = (srcpos + 0.5 * srcsize);//*(_container_height+_container_v_space); Element_pos y2 = (dstpos + 0.5 * dstsize);//*(_container_height+_container_v_space); if (color != NULL) draw_object->draw_arrow(starttime, endtime, y1, y2, color->get_red(), color->get_green(), color->get_blue()); else/* Draw white link */ draw_object->draw_arrow(starttime, endtime, y1, y2, 1.0, 1.0, 1.0); } /* * \brief Assuming someone has clicked in (x, y), display the description corresponding to the item clicked */ void display_information(const Trace *trace, double x, double y, double d) { const Container *container = NULL; const Container *ancestor = NULL; const Link *link; const Event *event; const State *state; const Variable *variable; // find container needs to know the position of each container double yr = y; const Container::Vector *root_containers = trace->get_view_root_containers(); if(root_containers->empty())root_containers= trace->get_root_containers(); if (!root_containers->empty()) for (Container::VectorIt i = root_containers->begin(); i != root_containers->end(); i++) if ((container = search_container_by_position(*i, yr))) break; // If the clic is out if (!container) return; // Calculate the container positions int position = 0; for (Container::VectorIt i = root_containers->begin(); i != root_containers->end(); i++) position += calc_container_positions(*i, position); // First we browse to find a communication ancestor = container; if (!Info::Render::_no_arrows) { while (ancestor) { if ((link = get_link(ancestor, x, y, d))) { *Message::get_instance() << "
Link
" << "Value: " << link->get_value()->get_name().to_string() << "
" << "Source: " << link->get_source()->get_name().to_string() << "
" << "Destination: " << link->get_destination()->get_name().to_string() << "
" << "Type: " << link->get_type()->get_name().to_string() << "
" << "Date: " << link->get_start_time().get_value() << " - " << link->get_end_time().get_value() << "
" << "Duration: " << link->get_duration() << "
"; print_extra_fields("Link", link->get_extra_fields()); print_extra_fields("Value", link->get_value()->get_extra_fields()); print_extra_fields("Type", link->get_type()->get_extra_fields()); *Message::get_instance() << Message::endsi; return; } else ancestor = ancestor->get_parent(); } //if not found, the link may hav been assigned to the first root container. if ((link = get_link(root_containers->front(), x, y, d))) { *Message::get_instance() << "
Link
" << "Value: " << link->get_value()->get_name().to_string() << "
" << "Source: " << link->get_source()->get_name().to_string() << "
" << "Destination: " << link->get_destination()->get_name().to_string() << "
" << "Type: " << link->get_type()->get_name().to_string() << "
" << "Date: " << link->get_start_time().get_value() << " - " << link->get_end_time().get_value() << "
" << "Duration: " << link->get_duration() << "
"; print_extra_fields("Link", link->get_extra_fields()); print_extra_fields("Value", link->get_value()->get_extra_fields()); print_extra_fields("Type", link->get_type()->get_extra_fields()); *Message::get_instance() << Message::endsi; return; } } // Now browsing for the events of the container root // Verification if it is a clic on an event #ifndef USE_ITC if ((!container->get_events()->empty() || !container->get_states()->empty()) && yr < _container_height+_container_v_space) { #else if (((container->get_states()!=NULL && !container->get_states()->empty()) ||(container->get_events()!=NULL && !container->get_events()->empty())) && yr < _container_height+_container_v_space) { #endif if (!Info::Render::_no_events) if ((event = find_event(container, x, d))) { *Message::get_instance() << "
Event
" << "Value: " << event->get_value()->get_name().to_string() << "
" << "Container: " << event->get_container()->get_name().to_string() << "
" << "Type: " << event->get_type()->get_name().to_string() << "
" << "Date: " << event->get_time().get_value() << "
"; print_extra_fields("Event", event->get_extra_fields()); print_extra_fields("Value", event->get_value()->get_extra_fields()); print_extra_fields("Type", event->get_type()->get_extra_fields()); *Message::get_instance() << Message::endsi; return; } if ((state = find_state(container, x))) { *Message::get_instance() << "
State
" << "Value: " << state->get_value()->get_name().to_string() << "
" << "Container: " << state->get_container()->get_name().to_string() << "
" << "Type: " << state->get_type()->get_name().to_string() << "
" << "Date: " << state->get_start_time().get_value() << " - " << state->get_end_time().get_value() << "
" << "Duration: " << state->get_duration() << "
"; print_extra_fields("State", state->get_extra_fields()); print_extra_fields("Value", state->get_value()->get_extra_fields()); print_extra_fields("Type", state->get_type()->get_extra_fields()); *Message::get_instance() << Message::endsi; return; } } else { #ifdef USE_ITC if ((container->get_states()!=NULL && !container->get_states()->empty()) ||(container->get_events()!=NULL && !container->get_events()->empty())) #else if (!container->get_events()->empty() || !container->get_states()->empty()) #endif yr -= _container_height+_container_v_space; const std::map *variable_map = container->get_variables(); std::map::const_iterator i = variable_map->begin(); while (yr > _container_height+_container_v_space) { yr -= _container_height+_container_v_space; i++; } if (i != variable_map->end()) { variable = (*i).second; *Message::get_instance() << "
Variable
" << "Container: " << variable->get_container()->get_name().to_string() << "
" << "Type: " << variable->get_type()->get_name().to_string() << "
" << "Value: " << variable->get_value_at(x) << "
" << "Value: " << variable->get_value_at(x) << "
" << "Min: " << variable->get_min().get_value() << "
" << "Max: " << variable->get_max().get_value() << "
"; print_extra_fields("Type", variable->get_type()->get_extra_fields()); *Message::get_instance() << Message::endsi; return; } } *Message::get_instance() << Message::endsi; // Nothing has been found return; } void print_extra_fields(std::string name, const std::map *extra_fields) { if (extra_fields!=NULL &&!extra_fields->empty()) { *Message::get_instance() << "" << name << " extra fields
"; for (std::map::const_iterator i = extra_fields->begin(); i != extra_fields->end(); i++) *Message::get_instance() << "" << (*i).first << ": " << (*i).second->to_string() << "
"; } } const Container *search_container_by_position(const Container *container, double &y) { const Container *result; // Search if the result is a descendant const Container::Vector *children = container->get_view_children();//we want to display only children meant to be displayed if(children->empty())children = container->get_children(); for (Container::VectorIt i = children->begin(); i != children->end(); i++) { if ((result = search_container_by_position(*i, y)) != NULL) return result; } // Calculate the size of the container (without its children) int size = 0; #ifdef USE_ITC if ((container->get_states()!=NULL && !container->get_states()->empty()) ||(container->get_events()!=NULL && !container->get_events()->empty())) #else if (!container->get_states()->empty() || !container->get_events()->empty()) #endif size++; if (container->get_variable_number() > 0) size += container->get_variable_number(); if (children->empty() && size < 1) // Minimum size size = 1; // Test if the position is in this container if (y < size*(_container_height+_container_v_space)) return container; else y -= size*(_container_height+_container_v_space); // The position is outside this container return NULL; } /* * \fn browse_container(T* draw_object, const Container *container, int position, int depth) * \brief Recursive function that browse a container to draw it with a T painting object in position, knowing the current depth in the tree */ int calc_container_positions(const Container *container, int position) { int size = 0; // Draw children const Container::Vector *children = container->get_view_children();//we want to display only children meant to be displayed if( children->empty() ) children = container->get_children(); for (Container::VectorIt i = children->begin(); i != children->end(); i++) { size += calc_container_positions((*i), position+size); } // Store the position to draw links _container_positions[container] = position; // First line after children _container_sizes[container] = size; // First line after children // Use one line for states and events #ifdef USE_ITC if ((container->get_states()!=NULL && !container->get_states()->empty()) ||(container->get_events()!=NULL && !container->get_events()->empty())){ #else if (!container->get_states()->empty() || !container->get_events()->empty()) { #endif size++; } // Use one line for each variable if (container->get_variable_number() > 0) { size += container->get_variable_number(); } return size; } /*! * \brief Tries to find a link passing by x and y in the container */ const Link* get_link(const Container *container, Element_pos x, Element_pos y, Element_pos d) { const Link::Vector *link_list; Link *link; double a, b, c; // Equation: ax + by + c = 0 double x1, x2, y1, y2; if(!container) return NULL; // Browse links link_list = container->get_links(); for (Link::VectorIt it = link_list->begin(); it != link_list->end(); it++) { link = *it; double srcpos = _container_positions[link->get_source()]; double dstpos = _container_positions[link->get_destination()]; double srcsize = _container_sizes[link->get_source()]; double dstsize = _container_sizes[link->get_destination()]; x1 = link->get_start_time().get_value(); x2 = link->get_end_time().get_value(); y1 = (srcpos + 0.5 * srcsize)*(_container_height+_container_v_space); y2 = (dstpos + 0.5 * dstsize)*(_container_height+_container_v_space); if (((x1-d <= x && x <= x2+d) || (x2-d <= x && x <= x1+d)) && ((y1-d <= y && y <= y2+d) || (y2-d <= y && y <= y1+d))) { // Test the interval a = y1 - y2; b = x2 - x1; c = -(a*x1 + b*y1); double e = a*x + b*y + c; if (e*e/(a*a + b*b) < d*d) // Test the distance return link; } } return NULL; } /* * \brief Returns the event that occurs at the time x in the container */ const Event *find_event(const Container *container, Element_pos x, Element_pos d) { if(!container || container->get_events()==NULL) return NULL; Node *node = container->get_events()->get_root(); while(node) { Element_pos t = node->get_element()->get_time().get_value(); if (x < t) { if (t - x < d) return node->get_element(); node = node->get_left_child(); } else { if (x - t < d) return node->get_element(); node = node->get_right_child(); } } return NULL; } /* * \brief Returns the state at the time x */ const State * find_state(const Container *container, Element_pos x) { if(!container || container->get_states()==NULL) return NULL; Node *node = container->get_states()->get_root(); while(node) { Element_pos t = node->get_element()->get_time().get_value(); if (x < t) { if (node->get_element()->get_left_state() && node->get_element()->get_left_state()->get_start_time().get_value() < x) return node->get_element()->get_left_state(); node = node->get_left_child(); } else { if (node->get_element()->get_right_state() && x < node->get_element()->get_right_state()->get_end_time().get_value()) return node->get_element()->get_right_state(); node = node->get_right_child(); } } return NULL; } bool link_is_in_set(Link * link, std::vector *set_container, Interval * interval ){ const Container * src = link->get_source(); const Container * dest = link->get_destination(); for(unsigned int i = 0 ; i < set_container->size() ; i++){ if(src == (*set_container)[i]){ for(unsigned int j = 0 ; j < set_container->size() ; j++) if(dest == (*set_container)[j]) if( (interval->_left.get_value() < link->get_start_time().get_value() && interval->_right.get_value() > link->get_end_time().get_value()) || (interval->_left.get_value() < link->get_end_time().get_value() && interval->_right.get_value() > link->get_start_time().get_value())) return true; } } return false; } bool is_in_set(const Container * c, std::vector *set_container){ if(!c || !set_container) return false; for(unsigned int i = 0 ; isize() ; i++ ) if(c==(*set_container)[i]) return true; return false; } void add( std::vector *container,std::stack *containers){ while (!containers->empty()) { const Container * c = containers->top(); containers->pop(); const Container::Vector *children = c->get_view_children();//we want to display only children meant to be displayed if(children->empty())children = c->get_children(); for (Container::VectorIt i = children->begin(); i != children->end(); i++){ containers->push(*i); container->push_back(*i); } add(container,containers); } } template void draw_text_variable_values(T* render, std::map* var_map, double date){ std::map::const_iterator it=var_map->begin(); const std::map::const_iterator it_end=var_map->end(); while(it!=it_end){ render->draw_text_value((*it).first,(*it).second, -1); it++; } } }; #endif