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 20 public RingBuffer(int capacity) { 21 buffer = (T[]) new Object[capacity]; 22 } 23 24 public boolean isEmpty() { 25 return count == 0; 26 } 27 28 public int size() { 29 return count; 30 } 31 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 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 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 61 public boolean hasNext() { 62 return i < count; 63 } 64 65 public void remove() { 66 throw new UnsupportedOperationException(); 67 } 68 69 public T next() { 70 if (!hasNext()) { 71 throw new NoSuchElementException(); 72 } 73 return buffer[i++]; 74 } 75 } 76 } 77