solved the block end problem, commiting mostly to save all those neat debug statement...
[clinton/Smoothieware.git] / src / libs / RingBuffer.h
CommitLineData
4cff3ded
AW
1/*
2 This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
3 Smoothie is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
4 Smoothie is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
5 You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
6
7 With chucks taken from http://en.wikipedia.org/wiki/Circular_buffer, see licence there also
8*/
9
10#ifndef RINGBUFFER_H
11#define RINGBUFFER_H
12
13
14template<class kind, int length> class RingBuffer {
15 public:
16 RingBuffer();
17 int size();
18 int capacity();
13e4a3f9 19 int next_block_index(int index);
ded56b35 20 int prev_block_index(int index);
4cff3ded
AW
21 void push_back(kind object);
22 void pop_front(kind &object);
23 void get( int index, kind &object);
24 kind* get_ref( int index);
25 void delete_first();
26
27 kind buffer[length];
28 int head;
29 int tail;
30};
31
32
33template<class kind, int length> RingBuffer<kind, length>::RingBuffer(){
34 this->head = this->tail = 0;
35}
36
37template<class kind, int length> int RingBuffer<kind, length>::capacity(){
38 return length-1;
39}
40
41template<class kind, int length> int RingBuffer<kind, length>::size(){
42return((this->head>this->tail)?length:0)+this->tail-head;
43}
44
13e4a3f9
AW
45template<class kind, int length> int RingBuffer<kind, length>::next_block_index(int index){
46 index++;
47 if (index == length) { index = 0; }
48 return(index);
49}
50
ded56b35
AW
51template<class kind, int length> int RingBuffer<kind, length>::prev_block_index(int index){
52 if (index == 0) { index = length; }
53 index--;
54 return(index);
55}
56
4cff3ded
AW
57template<class kind, int length> void RingBuffer<kind, length>::push_back(kind object){
58 this->buffer[this->tail] = object;
59 this->tail = (tail+1)&(length-1);
60}
61
62template<class kind, int length> void RingBuffer<kind, length>::get(int index, kind &object){
63 int j= 0;
64 int k= this->head;
65 while (k != this->tail){
66 if (j == index) break;
67 j++;
68 k= (k + 1) & (length - 1);
69 }
4464301d
AW
70 // TODO : this checks wether we are asked a value out of range
71 //if (k == this->tail){
72 // return NULL;
73 //}
4cff3ded
AW
74 object = this->buffer[k];
75}
76
77
78template<class kind, int length> kind* RingBuffer<kind, length>::get_ref(int index){
79 int j= 0;
80 int k= this->head;
81 while (k != this->tail){
82 if (j == index) break;
83 j++;
84 k= (k + 1) & (length - 1);
85 }
4464301d 86 // TODO : this checks wether we are asked a value out of range
4cff3ded
AW
87 if (k == this->tail){
88 return NULL;
89 }
90 return &(this->buffer[k]);
91}
92
93template<class kind, int length> void RingBuffer<kind, length>::pop_front(kind &object){
94 object = this->buffer[this->head];
95 this->head = (this->head+1)&(length-1);
96}
97
98template<class kind, int length> void RingBuffer<kind, length>::delete_first(){
13e4a3f9
AW
99 //kind dummy;
100 //this->pop_front(dummy);
101 this->head = (this->head+1)&(length-1);
4cff3ded
AW
102}
103
104
105#endif