Commit 9f66ad9c authored by Clément Vuchener's avatar Clément Vuchener

Ajout des arbres binaires

parent bef9fd8d
......@@ -43,6 +43,7 @@ HEADERS += message/Message.hpp \
trace/Container.hpp \
trace/ContainerType.hpp \
trace/DrawTrace.hpp \
trace/DrawTree.hpp \
trace/Entity.hpp \
trace/EntityType.hpp \
trace/EntityValue.hpp \
......@@ -64,7 +65,10 @@ HEADERS += message/Message.hpp \
trace/values/Name.hpp \
trace/values/String.hpp \
trace/values/Value.hpp \
trace/values/Values.hpp
trace/values/Values.hpp \
trace/tree/BinaryTree.hpp \
trace/tree/Node.hpp \
trace/tree/Interval.hpp
FORMS += interface/info_window.ui interface/main_window.ui interface/maquette.ui interface/option_export_window.ui
SOURCES += message/Message.cpp \
message/Errors.cpp \
......@@ -106,5 +110,6 @@ SOURCES += message/Message.cpp \
trace/values/Hex.cpp \
trace/values/Integer.cpp \
trace/values/Name.cpp \
trace/values/String.cpp
trace/values/String.cpp \
trace/tree/Interval.cpp
RESOURCES += interface/vite.qrc
......@@ -2,7 +2,8 @@
#include <iostream>
Container::Container(Name name, Date creation_time, ContainerType *type, Container *parent):
_name(name), _creation_time(creation_time), _destruction_time(0.0), _type(type), _parent(parent), _n_variables(0) {
_name(name), _creation_time(creation_time), _destruction_time(0.0), _type(type), _parent(parent),
_n_variables(0), _event_tree(0), _n_events(0), _n_states(0) {
}
template <class T>
......@@ -22,7 +23,7 @@ Container::~Container() {
clear_list<State>(_states);
// Delete events
clear_list<Event>(_events);
delete _event_tree;
// Delete links
clear_list<Link>(_links);
......@@ -166,8 +167,8 @@ const list<State *> *Container::get_states() const {
return &_states;
}
const list<Event *> *Container::get_events() const {
return &_events;
BinaryTree<Event> *Container::get_events() const {
return _event_tree;
}
const list<Link *> *Container::get_links() const {
......@@ -193,5 +194,6 @@ void Container::destroy(const Date &time) {
void Container::finish(const Date &time) {
if (_destruction_time.get_value() == 0.0)
destroy(time);
_event_tree = new BinaryTree<Event>(_events, _n_events);
}
......@@ -11,6 +11,7 @@ using std::list;
using std::map;
#include <stack>
using std::stack;
#include "tree/BinaryTree.hpp"
#include "values/Values.hpp"
......@@ -37,13 +38,14 @@ private:
ContainerType *_type;
Container *_parent;
list<Container *> _children;
int _n_states;
unsigned int _n_states;
list<State *> _states;
int _n_events;
unsigned int _n_events;
list<Event *> _events;
BinaryTree<Event> *_event_tree;
list<Link *> _links;
map<VariableType *, Variable *> _variables;
int _n_variables;
unsigned int _n_variables;
/*
* Temporary stores states before complete definition
......@@ -219,7 +221,7 @@ public:
* \fn get_events() const
* \brief Get the event list
*/
const list<Event *> *get_events() const;
BinaryTree<Event> *get_events() const;
/*!
* \fn get_links() const
......
......@@ -12,6 +12,7 @@
//#include "../render/render_opengl.hpp"
#include "../message/Message.hpp"
#include "DrawTree.hpp"
/*!
* \class DrawTrace
......@@ -214,7 +215,7 @@ public:
const Container *container;
const list<State *> *state_list;
State *state;
const list<Event *> *event_list;
BinaryTree<Event> *event_tree;
Event *event;
const list<Link *> *link_list;
Link *link;
......@@ -233,8 +234,8 @@ public:
position = _container_positions[container];
state_list = container->get_states();
event_list = container->get_events();
if (!state_list->empty() || !event_list->empty()) {
event_tree = container->get_events();
if (!state_list->empty() || !event_tree->empty()) {
// Browse states
for (list<State *>::const_iterator i = state_list->begin();
i != state_list->end();
......@@ -257,16 +258,19 @@ public:
draw_state(draw_object, state->get_start_time().get_value(), state->get_end_time().get_value(), position, 0.7, 0.7, 0.75);
}
}/* end for */
// Browse events
for (list<Event *>::const_iterator i = event_list->begin();
DrawTree<T, Event>(draw_object, position, 0.0,
_container_height, _container_v_space, _state_height, _state_v_space)
.draw_tree(event_tree, &Interval(Date(0.0), Date(500.0)));
/*for (list<Event *>::const_iterator i = event_list->begin();
i != event_list->end();
i++) {
event = *i;
/* Call the object state drawing function */
// Call the object state drawing function
draw_event(draw_object, event->get_time().get_value(), position);
}/* end for */
}*/
}
......@@ -355,10 +359,10 @@ public:
* \param time Time of the event
* \param position Line where the event is drawn
*/
inline void draw_event(T *draw_object, double time, int position) {
/*inline void draw_event(T *draw_object, double time, int position) {
Element_pos y = position*(_container_height+_container_v_space) + _container_v_space/2;
draw_object->draw_event(time, y, _state_height);
}
}*/
/*!
* \brief Draw a point of a variable curve
......
#ifndef DRAWTREE_HPP
#define DRAWTREE_HPP
#include "tree/BinaryTree.hpp"
#include "Event.hpp"
template<class D, class E>
class DrawTree {
private:
D *_draw_object;
int _position;
double _min_size;
Element_pos _container_height;
Element_pos _container_v_space;
Element_pos _state_height;
Element_pos _state_v_space;
public:
DrawTree(D *draw_object, int position, double min_size,
Element_pos container_height, Element_pos container_v_space,
Element_pos state_height, Element_pos state_v_space):
_draw_object(draw_object), _position(position), _min_size(min_size),
_container_height(container_height), _container_v_space(container_v_space),
_state_height(state_height), _state_v_space(state_v_space) {
}
/*
*\fn browse_draw_tree_root(E * draw_object, Interval * I, BinaryTree * tree)
*\brief Function called to draw on ViTE the elements of a tree
*\param draw_object :
*\param I : The interval we have to draw the tree
*\param tree : The tree we want to draw
*/
void draw_tree(BinaryTree<E> *tree, Interval *I){
Node<E> *node = tree->get_root();
if (node)
browse_tree(I, node);
}
/*
*\fn browse_draw_tree(E * draw_object, Interval * I, Node * node)
*\brief Function called to draw on ViTE a node
*\param draw_object :
*\param I : The interval we have to draw node
*\param node : The node we want to draw
*/
void browse_tree(Interval * I, Node<E> * node);
/*!
* \brief Draw a state
* \param starttime Time when the state begins
* \param endtime Time when the state ends
* \param r Red value of the state color
* \param g Green value of the state color
* \param b Blue value of the state color
*/
inline void draw_state(double starttime, double endtime, double r, double g, double b) {
Element_pos y = _position*(_container_height+_container_v_space) + _container_v_space/2;
_draw_object->draw_state(starttime, endtime, y, _state_height, r, g, b);
}
/*!
* \brief Draw an event
* \param time Time of the event
*/
inline void draw_event(double time) {
Element_pos y = _position*(_container_height+_container_v_space) + _container_v_space/2;
_draw_object->draw_event(time, y, _state_height);
}
/*
* \fn display_busy(Interval *I)
* \brief Function that display a purple squarre in the interval selected
*/
inline void draw_busy(Interval *I) {
draw_state(I->_left.get_value(), I->_right.get_value(), 0.2, 0.2, 0.2);
}
};
template<class D, class E>
struct DrawNode {
static void draw_node(DrawTree<D, E> *draw, Node<E> *node) { }
};
template<class D>
struct DrawNode<D, Event> {
static void draw_node(DrawTree<D, Event> *draw, Node<Event> *node) {
draw->draw_event(node->get_element()->get_time().get_value());
}
};
template<class D, class E>
void DrawTree<D, E>::browse_tree(Interval * I, Node<E> * node) {
bool displayed = false;// To remember if node has already been displayed
int n_children;
// If the tree has 2 children
if (node->get_right_child())
n_children = 2;
// Else if only a left child
else if (node->get_left_child())
n_children = 1;
// Else no child
else
n_children = 0;
// If the node is in the interval
if(node->get_element()->get_time() <= I->_right &&
node->get_element()->get_time() >= I->_left) {
// If the node can be displayed (interval is wide enought)
if (I->_right - I->_left > _min_size) {
// Launching in both children
if (n_children >= 1)
browse_tree(new Interval(I->_left, node->get_element()->get_time()),
node->get_left_child());
if (n_children >= 2)
browse_tree(new Interval(node->get_element()->get_time(), I->_right),
node->get_right_child());
// If node's left son has a conflict on it's left side
if(n_children >= 1 && node->get_left_child()->_left_interval) {
// Setting the node's left interval as busy
node->_left_interval = new Interval(node->get_left_child()->_left_interval->_left,
node->get_left_child()->_left_interval->_right);
}
// Else no problem on the left
else {
node->_left_interval = NULL;
}
if(n_children >= 2 &&
node->get_left_child()->_right_interval &&
node->get_right_child()->_left_interval) {
// If node is too close of the problematic area by both sides
if(node->get_element()->get_time() - node->get_left_child()->_right_interval->_right < _min_size &&
node->get_right_child()->_left_interval->_left - node->get_element()->get_time() < _min_size) {
// Drawing a crowded area
draw_busy(new Interval(node->get_left_child()->_right_interval->_left,
node->get_right_child()->_left_interval->_right));
displayed = true;
delete node->get_left_child()->_right_interval;
if (node->get_left_child()->_right_interval != node->get_right_child()->_left_interval)
delete node->get_right_child()->_left_interval;
node->get_right_child()->_left_interval = NULL;
node->get_left_child()->_right_interval = NULL;
}
}
// Else if problem possible with the left child : it's right interval
else if (n_children >= 1 && node->get_left_child()->_right_interval) {
// If node is in the problematic area
if(node->get_element()->get_time() - node->get_left_child()->_right_interval->_right < _min_size) {
displayed = true;
draw_busy(new Interval(node->get_left_child()->_right_interval->_left,
node->get_element()->get_time()));
delete node->get_left_child()->_right_interval;
node->get_left_child()->_right_interval = NULL;
}
else {
draw_busy(node->get_left_child()->_right_interval);
}
}
// Else if problem possible with the right child : it's left interval
else if (n_children >= 2 && node->get_right_child()->_left_interval) {
if(node->get_right_child()->_left_interval->_left - node->get_element()->get_time() < _min_size) {
displayed = true;
draw_busy(new Interval(node->get_element()->get_time(),
node->get_right_child()->_left_interval->_right));
delete node->get_right_child()->_left_interval;
node->get_right_child()->_left_interval = NULL;
}
else {
draw_busy(node->get_right_child()->_left_interval);
}
}
// If node's right son has a conflict on it's right side
if(n_children >= 2 && node->get_right_child()->_right_interval) {
// Setting the node's right interval as busy
node->_right_interval = node->get_right_child()->_right_interval;
}
// Else no problem on the right
else {
node->_right_interval = NULL;
}
// Making sur node has been displayed
if(!displayed) {
DrawNode<D, E>::draw_node(this, node);
}
} // end if has enough space
else {
// Cannot display node so his both busy interval are the same and value I
node->_left_interval = I;
node->_right_interval = I;
}
} //end if is in the interval
else {
// If node is after the interval
if(n_children >= 1 && node->get_element()->get_time()>I->_right) {
browse_tree(I, node->get_left_child());
node->_left_interval = node->get_left_child()->_left_interval;
node->_right_interval = NULL;
}
// Else he is before
else if (n_children >= 2) {
browse_tree(I, node->get_right_child());
node->_left_interval = NULL;
node->_right_interval = node->get_right_child()->_right_interval;
}
} // end else is in the interval
}
#endif
/*
*
*\file tree/BinaryTree.hpp
* \brief File that contains the definition of a binary tree. A binary tree is a node, and pointers to others binary trees (father and children).
*\author COULOMB Kevin
*\date 03/09
*
*/
#ifndef BINARYTREE_HPP
#define BINARYTREE_HPP
#include <iostream>
#include "Node.hpp"
#include "Interval.hpp"
template <class E>
class BinaryTree{
private :
// BinaryTree <E> * _current;
Node <E> * _current;
/*
*
*\brief To visit the tree
*
*/
BinaryTree <E> *_father;
BinaryTree <E> *_left_child;
BinaryTree <E> *_right_child;
public :
/*
*
*\fn BinaryTree<E> ()
*\brief Default constructor
*
*/
BinaryTree<E>(){
_father = NULL;
_left_child = NULL;
_right_child = NULL;
_current = new Node<E>();
}
/*
*
*\fn set_current_node( BinaryTree * event )
*\brief Set the current node
*
*/
void set_current_node( Node <E> * node ){
this->_current = node;
}
/*
*
*\fn get_event()
*\brief Return the event field
*
*/
Node <E> *get_current(){
return _current;
}
/*
*
*\fn set_father( BinaryTree * )
*\brief Set the father's node
*
*/
void set_father( BinaryTree <E> * father ){
this->_father = father;
}
/*
*
*\fn get_father()
*\brief Returns the father
*
*/
BinaryTree <E> * get_father(){
return _father;
}
/*
*
*\fn has_father()
*\brief Returns if the current node has a father
*
*/
bool has_father(){
return (_father == NULL);
}
/*
*
*\fn has_father()
*\brief Returns if the current node has a father
*
*/
bool has_children(){
return !((_left_child == NULL)&&(_right_child==NULL));
}
/*
*
*\fn set_left_child( BinaryTree * child )
*\brief Set only the left child to child
*
*/
void set_left_child( BinaryTree <E> * child ){
this->_left_child = child;
}
/*
*
*\fn set_right_child( BinaryTree * child )
*\brief Set only the right child to child
*
*/
void set_right_child( BinaryTree <E> * child ){
this->_right_child = child;
}
/*
*
*\fn get_left_child()
*\brief Return only the left child
*
*/
BinaryTree <E> * get_left_child(){
return _left_child;
}
/*!
* \file BinaryTree.hpp
*/
/*
*
*\fn get_right_child()
*\brief Return only the right child
*
*/
BinaryTree <E> * get_right_child(){
return _right_child;
}
template<typename E>
class BinaryTree;
/*
*
*\fn set_children ( BinaryTree * leftChild , BinaryTree * rightChild)
*\brief Calling setleft and set right, set the 2 children
*
*/
void set_children ( BinaryTree <E> * leftChild , BinaryTree <E> * rightChild){
this->_left_child = leftChild;
this->_right_child = rightChild;
}
#include "Node.hpp"
#include <list>
/*
*
*\fn get_children()
*\brief Return a pointer to a structure that contain respectively the left then the right child
*
*/
BinaryTree <E> * get_children(){
BinaryTree<E> * res[2];
res[0] = get_left_child();
res[1] = get_right_child();
return res;
}
#include <iostream>
/*!
* \class BinaryTree
* \brief Store a tree made from a list
*/
template<typename E>
class BinaryTree {
private:
Node<E> *_root;
public:
/*!
* \brief Constructor
* \param list List from which the tree is made
* \param size Number of element in the list
*/
BinaryTree(std::list<E *> &list, unsigned int size) {
if (size == 0 || list.empty()) {
_root = NULL;
return;
}
// Calculate n and m as size = 2^n - 1 + m and m < 2^n
int n = 0;
int a = 1;
while (size >= 2*a - 1) {
a *= 2;
n++;
}
int m = size - a + 1;
// Initialize the array
Node<E> **temp = new Node<E> *[n+1];
int start = 0;
int i = 0;
for (i = 0; i < n+1; i++)
temp[i] = NULL;
i = 0;
// Reads elements from the list and empty it
while (!list.empty()) {
E *element = list.front();
list.pop_front();
while (temp[i]) // Find the first free element in temp
i++;
temp[i] = new Node<E>(element);
if (i == 0 && m > 0) { // The node is a leaf and its depth is n+1
m--;
if (m == 0)
start = 1;
}
if (i < n && temp[i+1]) { // The node has a parent
temp[i]->_parent = temp[i+1];
temp[i+1]->_right_child = temp[i];
}
if (i > 0 && temp[i-1]) { // The node is not a leaf
temp[i]->_left_child = temp[i-1];
temp[i-1]->_parent = temp[i];
while (i > 0) {
i--;
temp[i] = NULL;
}
i = start;
}
}
_root = temp[n-1+start];
delete[] temp;
}
/*!
* \brief Destructor
*/
~BinaryTree() {
// TODO: Delete all nodes
}
/*!
* \brief Get the root node of the tree
*/
Node<E> *get_root() const {
return _root;
}
bool empty() const{
return _root == NULL;
}
};
#endif
#include "Interval.hpp"
Interval::Interval(){
_left_side = 0;
_right_side = 100;
// _interval = new Interval[4];
}
void Interval::set_left( time left ){
_left_side = left;
}
Interval::Interval(): _left(0.0), _right(0.0) {
void Interval::set_right( time right ){
_right_side = right;
}
time Interval::get_left (){
return _left_side;
}
Interval::Interval(Date left, Date right): _left(left), _right(right) {
time Interval::get_right (){
return _right_side;
}
......@@ -10,23 +10,16 @@
#ifndef INTERVAL_HPP
#define INTERVAL_HPP
#include "../../interface/resource.hpp"
#include "../values/Date.hpp"
class Interval{
private :
Times _left_side;
Times _right_side;
public :
public:
Date _left;
Date _right;
Interval();
void set_left( Times left );
void set_light( Times right );
Times get_left () const;
Times get_right () const;
Interval(Date left, Date right);
};
......
/*
J'ai besoin d'ajouter a la structure node :