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/>.
7 With chucks taken from http://en.wikipedia.org/wiki/Circular_buffer, see licence there also
14 template<class kind
, int length
> class RingBuffer
{
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
);
25 void get( int index
, kind
&object
);
26 kind
* get_ref( int index
);
36 template<class kind
, int length
> RingBuffer
<kind
, length
>::RingBuffer(){
37 this->tail
= this->head
= 0;
40 template<class kind
, int length
> int RingBuffer
<kind
, length
>::capacity(){
44 template<class kind
, int length
> int RingBuffer
<kind
, length
>::size(){
45 //return((this->tail>this->head)?length:0)+this->head-tail;
47 int i
= head
- tail
+ ((tail
> head
)?length
:0);
52 template<class kind
, int length
> int RingBuffer
<kind
, length
>::next_block_index(int index
){
54 if (index
== length
) { index
= 0; }
58 template<class kind
, int length
> int RingBuffer
<kind
, length
>::prev_block_index(int index
){
59 if (index
== 0) { index
= length
; }
64 template<class kind
, int length
> void RingBuffer
<kind
, length
>::push_back(kind object
){
65 this->buffer
[this->head
] = object
;
66 this->head
= (head
+1)&(length
-1);
69 template<class kind
, int length
> kind
* RingBuffer
<kind
, length
>::get_head_ref(){
70 return &(buffer
[head
]);
73 template<class kind
, int length
> kind
* RingBuffer
<kind
, length
>::get_tail_ref(){
74 return &(buffer
[tail
]);
77 template<class kind
, int length
> void RingBuffer
<kind
, length
>::get(int index
, kind
&object
){
80 while (k
!= this->head
){
81 if (j
== index
) break;
83 k
= (k
+ 1) & (length
- 1);
85 // TODO : this checks wether we are asked a value out of range
86 //if (k == this->head){
89 object
= this->buffer
[k
];
93 template<class kind
, int length
> kind
* RingBuffer
<kind
, length
>::get_ref(int index
){
96 while (k
!= this->head
){
97 if (j
== index
) break;
99 k
= (k
+ 1) & (length
- 1);
101 // TODO : this checks wether we are asked a value out of range
102 if (k
== this->head
){
105 return &(this->buffer
[k
]);
108 template<class kind
, int length
> void RingBuffer
<kind
, length
>::pop_front(kind
&object
){
109 object
= this->buffer
[this->tail
];
110 this->tail
= (this->tail
+1)&(length
-1);
113 template<class kind
, int length
> void RingBuffer
<kind
, length
>::delete_tail(){
115 //this->pop_front(dummy);
116 this->tail
= (this->tail
+1)&(length
-1);