1 package com.jme3.util;
2 
3 import java.util.Iterator;
4 import java.util.NoSuchElementException;
5 
6 /**
7  * Ring buffer (fixed size queue) implementation using a circular array (array
8  * with wrap-around).
9  */
10 // suppress unchecked warnings in Java 1.5.0_6 and later
11 @SuppressWarnings("unchecked")
12 public class RingBuffer<T> implements Iterable<T> {
13 
14     private T[] buffer;          // queue elements
15     private int count = 0;          // number of elements on queue
16     private int indexOut = 0;       // index of first element of queue
17     private int indexIn = 0;       // index of next available slot
18 
19     // cast needed since no generic array creation in Java
RingBuffer(int capacity)20     public RingBuffer(int capacity) {
21         buffer = (T[]) new Object[capacity];
22     }
23 
isEmpty()24     public boolean isEmpty() {
25         return count == 0;
26     }
27 
size()28     public int size() {
29         return count;
30     }
31 
push(T item)32     public void push(T item) {
33         if (count == buffer.length) {
34             throw new RuntimeException("Ring buffer overflow");
35         }
36         buffer[indexIn] = item;
37         indexIn = (indexIn + 1) % buffer.length;     // wrap-around
38         count++;
39     }
40 
pop()41     public T pop() {
42         if (isEmpty()) {
43             throw new RuntimeException("Ring buffer underflow");
44         }
45         T item = buffer[indexOut];
46         buffer[indexOut] = null;                  // to help with garbage collection
47         count--;
48         indexOut = (indexOut + 1) % buffer.length; // wrap-around
49         return item;
50     }
51 
iterator()52     public Iterator<T> iterator() {
53         return new RingBufferIterator();
54     }
55 
56     // an iterator, doesn't implement remove() since it's optional
57     private class RingBufferIterator implements Iterator<T> {
58 
59         private int i = 0;
60 
hasNext()61         public boolean hasNext() {
62             return i < count;
63         }
64 
remove()65         public void remove() {
66             throw new UnsupportedOperationException();
67         }
68 
next()69         public T next() {
70             if (!hasNext()) {
71                 throw new NoSuchElementException();
72             }
73             return buffer[i++];
74         }
75     }
76 }
77