Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
f6b8e5137This file is pinned to the selected release. Download the original to open it in your design tool.
/******************************************************************************
* Copyright (C) Leap Motion, Inc. 2011-2018. *
* Leap Motion proprietary and confidential. *
* *
* Use subject to the terms of the Leap Motion SDK Agreement available at *
* https://developer.leapmotion.com/sdk_agreement, or another agreement *
* between Leap Motion and you, your company or other organization. *
******************************************************************************/
namespace LeapInternal {
//TODO add test for thread safety
/**
* A Limited capacity, circular LIFO buffer that wraps around
* when full. Supports indexing to get older items. Array-backed.
* *
* Unlike many collections, objects are never removed, just overwritten when
* the buffer cycles back to their array location.
*
* Object types used must have default parameterless constructor. It should be obvious that
* such default objects are invalid. I.e. for Leap API objects, the IsValid property should be false.
*/
public class CircularObjectBuffer<T> where T : new() {
private T[] array;
private int current = 0;
private object locker = new object();
public int Count { get; private set; }
public int Capacity { get; private set; }
public bool IsEmpty { get; private set; }
public CircularObjectBuffer(int capacity) {
Capacity = capacity;
array = new T[this.Capacity];
current = 0;
Count = 0;
IsEmpty = true;
}
/** Put an item at the head of the list. Once full, this will overwrite the oldest item. */
public virtual void Put(ref T item) {
lock (locker) {
if (!IsEmpty) {
current++;
if (current >= Capacity) {
current = 0;
}
}
if (Count < Capacity)
Count++;
lock (array) {
array[current] = item;
}
IsEmpty = false;
}
}
/** Get the item indexed backward from the head of the list */
public void Get(out T t, int index = 0) {
lock (locker) {
if (IsEmpty || (index > Count - 1) || index < 0) {
t = new T(); //default(T);
} else {
int effectiveIndex = current - index;
if (effectiveIndex < 0) {
effectiveIndex += Capacity;
}
t = array[effectiveIndex];
}
}
}
/** Increase */
public void Resize(int newCapacity) {
lock (locker) {
if (newCapacity <= Capacity) {
return;
}
T[] newArray = new T[newCapacity];
int j = 0;
for (int i = Count - 1; i >= 0; i--) {
T t;
Get(out t, i);
newArray[j++] = t;
}
this.array = newArray;
this.Capacity = newCapacity;
}
}
}
}