monado/src/xrt/auxiliary/util/u_template_historybuf.hpp

74 lines
1.4 KiB
C++
Raw Normal View History

2021-09-03 01:49:56 +00:00
// Copyright 2021, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @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
#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 |
namespace xrt::auxiliary::util {
2021-09-03 01:49:56 +00:00
template <typename T, int maxSize> class HistoryBuffer
2021-09-03 01:49:56 +00:00
{
private:
2021-09-03 01:49:56 +00:00
T internalBuffer[maxSize];
int mTopIdx = 0;
int mLength = 0;
2021-09-03 01:49:56 +00:00
public:
// clang-format off
int topIdx() const noexcept { return mTopIdx; }
int length() const noexcept { return mLength; }
// clang-format on
/* Put something at the top, overwrite whatever was at the back*/
void
push(const T inElement)
{
mTopIdx++;
if (mTopIdx == maxSize) {
mTopIdx = 0;
}
2021-09-03 01:49:56 +00:00
memcpy(&internalBuffer[mTopIdx], &inElement, sizeof(T));
mLength++;
mLength = std::min(mLength, maxSize);
2021-09-03 01:49:56 +00:00
}
T * // Hack comment to fix clang-format
operator[](int inIndex)
{
if (mLength == 0) {
return NULL;
}
assert(inIndex <= maxSize);
assert(inIndex >= 0);
2021-09-03 01:49:56 +00:00
int index = mTopIdx - inIndex;
if (index < 0) {
index = maxSize + index;
}
2021-09-03 01:49:56 +00:00
assert(index >= 0);
if (index > maxSize) {
assert(false);
}
2021-09-03 01:49:56 +00:00
return &internalBuffer[index];
2021-09-03 01:49:56 +00:00
}
};
2021-09-03 01:49:56 +00:00
} // namespace xrt::auxiliary::util