#ifndef ENVIRONNEMENT_QUEUE_SORT_QUEUE_H #define ENVIRONNEMENT_QUEUE_SORT_QUEUE_H #include #include #include "Parameters.h" #include "Queue.h" namespace environnement { namespace queue { /* * Cicurlar queue, sort by delay */ template class Sort_Queue : public Queue { // *****[ variables ]***** protected : uint32_t _ptr_read; // pointer of the next slot to read protected : uint32_t _ptr_write; // pointer of the next slot to write // *****[ constructor ]***** public : Sort_Queue (std::string name, Parameters * param) : Queue (name,param->_size) { }; // *****[ destructor ]***** public : ~Sort_Queue () { }; // *****[ reset ]***** // Reset the queue in the empty state public : void reset () { _ptr_read = 0; _ptr_write = 0; Queue ::_nb_slot = 0; }; // *****[ transition ]***** // Decrease the delay at all cycle public : void transition () { for (uint32_t it = 0; it < Queue ::_nb_slot; it ++) { uint32_t ptr = (_ptr_read + it)%Queue ::_size; if (Queue ::_slot[ptr]._delay != 0) Queue ::_slot[ptr] ._delay --; } } // *****[ read ]***** // return the n-eme slot. // (first = 0) public : slot_t read (uint32_t num) { if (num >= Queue ::_nb_slot) { std::cerr << " {ERROR} can't read because : num (" << num << ") >= nb_slot (" << Queue ::_nb_slot << ")" << std::endl; exit(1); } return Queue ::_slot[(_ptr_read + num)%Queue ::_size]; }; // *****[ pop ]***** // read the queue, and update the pointer public : T pop () { return pop (0); } // *****[ pop ]***** // read the queue, and update the pointer public : T pop (uint32_t num) { if (num >= Queue ::_nb_slot) { std::cerr << " {ERROR} can't read because : num (" << num << ") >= nb_slot (" << Queue ::_nb_slot << ")" << std::endl; exit(1); } T val = Queue ::_slot [(_ptr_read+num)%Queue ::_size]._data; // Reorganize the queue for (uint32_t it = 0; it < num; it ++) { uint32_t ptr = (_ptr_read + num - it )%Queue ::_size; uint32_t _ptr_next = (ptr-1)%Queue ::_size; Queue ::_slot [ptr] = Queue ::_slot [_ptr_next]; } Queue ::_nb_slot --; _ptr_read = (_ptr_read+1)%Queue ::_size; return val; } // *****[ push ]***** // Push a new value (they must have a slot free) // Is sort by delay public : bool push (uint32_t delay, T val) { // If full -> quit if (Queue ::_nb_slot == Queue ::_size) return false; uint32_t ptr = _ptr_write; // Scan the fill to find the good position (keep the sort) for (uint32_t it = 0; it < Queue ::_nb_slot; it ++) { uint32_t _ptr_scan = (ptr-1)%Queue ::_size; if (Queue ::_slot[_ptr_scan]._delay <= delay) break; //find // reformor the queue Queue ::_slot [ptr] = Queue ::_slot [_ptr_scan]; ptr = _ptr_scan; } Queue ::_slot [ptr] = slot_t (delay,val); _ptr_write = (_ptr_write+1)%Queue ::_size; // update the pointer Queue ::_nb_slot ++; return true; } // *****[ print ]***** public : friend std::ostream& operator<< (std::ostream& output, const Sort_Queue & x) { output << "<" << x._name << ">" << std::endl; output << " * ptr_read : " << x._ptr_read << std::endl; output << " * ptr_write : " << x._ptr_write << std::endl; output << " * nb_slot : " << x._nb_slot << std::endl; output << " * size : " << x._size << std::endl; for (uint32_t it = 0; it < x._nb_slot; it ++) { uint32_t ptr = (x._ptr_read+it)%x._size; output << x._slot [ptr] << std::endl; } return output; }; }; }; }; #endif