Basic 3D printing support working, a gigaton of bugfixes
[clinton/Smoothieware.git] / src / libs / RingBuffer.h
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
14 template<class kind, int length> class RingBuffer {
15 public:
16 RingBuffer();
17 int size();
18 int capacity();
19 int next_block_index(int index);
20 int prev_block_index(int index);
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
33 template<class kind, int length> RingBuffer<kind, length>::RingBuffer(){
34 this->head = this->tail = 0;
35 }
36
37 template<class kind, int length> int RingBuffer<kind, length>::capacity(){
38 return length-1;
39 }
40
41 template<class kind, int length> int RingBuffer<kind, length>::size(){
42 return((this->head>this->tail)?length:0)+this->tail-head;
43 }
44
45 template<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
51 template<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
57 template<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
62 template<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 }
70 if (k == this->tail){
71 //return NULL;
72 }
73 object = this->buffer[k];
74 }
75
76
77 template<class kind, int length> kind* RingBuffer<kind, length>::get_ref(int index){
78 int j= 0;
79 int k= this->head;
80 while (k != this->tail){
81 if (j == index) break;
82 j++;
83 k= (k + 1) & (length - 1);
84 }
85 if (k == this->tail){
86 return NULL;
87 }
88 return &(this->buffer[k]);
89 }
90
91 template<class kind, int length> void RingBuffer<kind, length>::pop_front(kind &object){
92 object = this->buffer[this->head];
93 this->head = (this->head+1)&(length-1);
94 }
95
96 template<class kind, int length> void RingBuffer<kind, length>::delete_first(){
97 //kind dummy;
98 //this->pop_front(dummy);
99 this->head = (this->head+1)&(length-1);
100 }
101
102
103 #endif