2021-09-03 01:49:56 +00:00
|
|
|
// Copyright 2021, Collabora, Ltd.
|
|
|
|
// SPDX-License-Identifier: BSL-1.0
|
|
|
|
/*!
|
|
|
|
* @file
|
2021-09-15 07:11:10 +00:00
|
|
|
* @brief Ringbuffer implementation for keeping track of the past state of things
|
2021-09-03 01:49:56 +00:00
|
|
|
* @author Moses Turner <moses@collabora.com>
|
|
|
|
* @ingroup drv_ht
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2021-09-15 07:11:10 +00:00
|
|
|
#include <algorithm>
|
2021-09-03 01:49:56 +00:00
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
|
|
|
|
//| -4 | -3 | -2 | -1 | Top | Garbage |
|
|
|
|
// OR
|
|
|
|
//| -4 | -3 | -2 | -1 | Top | -7 | -6 | -5 |
|
|
|
|
|
2021-09-15 07:11:10 +00:00
|
|
|
namespace xrt::auxiliary::util {
|
2021-09-03 01:49:56 +00:00
|
|
|
|
2021-09-15 07:11:10 +00:00
|
|
|
template <typename T, int maxSize> struct HistoryBuffer
|
2021-09-03 01:49:56 +00:00
|
|
|
{
|
|
|
|
T internalBuffer[maxSize];
|
|
|
|
int topIdx = 0;
|
2021-09-15 07:11:10 +00:00
|
|
|
int length = 0;
|
2021-09-03 01:49:56 +00:00
|
|
|
|
|
|
|
/* Put something at the top, overwrite whatever was at the back*/
|
|
|
|
void
|
|
|
|
push(const T inElement);
|
|
|
|
|
|
|
|
T *operator[](int inIndex);
|
2021-09-15 07:11:10 +00:00
|
|
|
|
|
|
|
// Lazy convenience.
|
|
|
|
T *
|
|
|
|
last();
|
2021-09-03 01:49:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T, int maxSize>
|
|
|
|
void
|
2021-09-15 07:11:10 +00:00
|
|
|
HistoryBuffer<T, maxSize>::push(const T inElement)
|
2021-09-03 01:49:56 +00:00
|
|
|
{
|
|
|
|
topIdx++;
|
|
|
|
if (topIdx == maxSize) {
|
|
|
|
topIdx = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(&internalBuffer[topIdx], &inElement, sizeof(T));
|
2021-09-15 07:11:10 +00:00
|
|
|
length++;
|
|
|
|
length = std::min(length, maxSize);
|
|
|
|
// U_LOG_E("new length is %zu", length);
|
2021-09-03 01:49:56 +00:00
|
|
|
}
|
|
|
|
|
2021-09-15 07:11:10 +00:00
|
|
|
template <typename T, int maxSize> T *HistoryBuffer<T, maxSize>::operator[](int inIndex)
|
2021-09-03 01:49:56 +00:00
|
|
|
{
|
2021-09-15 07:11:10 +00:00
|
|
|
if (length == 0) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2021-09-03 01:49:56 +00:00
|
|
|
assert(inIndex <= maxSize);
|
|
|
|
assert(inIndex >= 0);
|
|
|
|
|
|
|
|
int index = topIdx - inIndex;
|
|
|
|
if (index < 0) {
|
|
|
|
index = maxSize + index;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(index >= 0);
|
|
|
|
if (index > maxSize) {
|
|
|
|
assert(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
return &internalBuffer[index];
|
|
|
|
}
|
2021-09-15 07:11:10 +00:00
|
|
|
} // namespace xrt::auxiliary::util
|