ezEngine  Milestone 7
StaticRingBuffer_inl.h
1 #pragma once
2 
3 template <typename T, ezUInt32 C>
5 {
6  m_pElements = GetStaticArray();
7  m_uiFirstElement = 0;
8  m_uiCount = 0;
9 }
10 
11 template <typename T, ezUInt32 C>
13 {
14  m_pElements = GetStaticArray();
15  m_uiFirstElement = 0;
16  m_uiCount = 0;
17 
18  *this = rhs;
19 }
20 
21 template <typename T, ezUInt32 C>
23 {
24  Clear();
25 }
26 
27 template <typename T, ezUInt32 C>
29 {
30  Clear();
31 
32  for (ezUInt32 i = 0; i < rhs.GetCount(); ++i)
33  PushBack(rhs[i]);
34 }
35 
36 template <typename T, ezUInt32 C>
38 {
39  if (GetCount() != rhs.GetCount())
40  return false;
41 
42  for (ezUInt32 i = 0; i < m_uiCount; ++i)
43  {
44  if ((*this)[i] != rhs[i])
45  return false;
46  }
47 
48  return true;
49 }
50 
51 template <typename T, ezUInt32 C>
52 EZ_FORCE_INLINE bool ezStaticRingBuffer<T, C>::operator!=(const ezStaticRingBuffer<T, C>& rhs) const
53 {
54  return !(*this == rhs);
55 }
56 
57 template <typename T, ezUInt32 C>
58 void ezStaticRingBuffer<T, C>::PushBack(const T& element)
59 {
60  EZ_ASSERT_DEV(CanAppend(), "The ring-buffer is full, no elements can be appended before removing one.");
61 
62  const ezUInt32 uiLastElement = (m_uiFirstElement + m_uiCount) % C;
63 
64  ezMemoryUtils::CopyConstruct(&m_pElements[uiLastElement], element, 1);
65  ++m_uiCount;
66 }
67 
68 template <typename T, ezUInt32 C>
69 void ezStaticRingBuffer<T, C>::PopFront(ezUInt32 uiElements)
70 {
71  EZ_ASSERT_DEV(m_uiCount >= uiElements, "The ring-buffer contains %i elements, cannot remove %i elements from it.", m_uiCount, uiElements);
72 
73  while (uiElements > 0)
74  {
75  ezMemoryUtils::Destruct(&m_pElements[m_uiFirstElement], 1);
76  ++m_uiFirstElement;
77  m_uiFirstElement %= C;
78  --m_uiCount;
79 
80  --uiElements;
81  }
82 }
83 
84 template <typename T, ezUInt32 C>
85 EZ_FORCE_INLINE const T& ezStaticRingBuffer<T, C>::PeekFront() const
86 {
87  EZ_ASSERT_DEV(!IsEmpty(), "The ring-buffer is empty, cannot peek at the first element.");
88 
89  return m_pElements[m_uiFirstElement];
90 }
91 
92 template <typename T, ezUInt32 C>
94 {
95  EZ_ASSERT_DEV(!IsEmpty(), "The ring-buffer is empty, cannot peek at the first element.");
96 
97  return m_pElements[m_uiFirstElement];
98 }
99 
100 template <typename T, ezUInt32 C>
101 EZ_FORCE_INLINE const T& ezStaticRingBuffer<T, C>::operator[](ezUInt32 uiIndex) const
102 {
103  EZ_ASSERT_DEV(uiIndex < m_uiCount, "The ring-buffer only has %i elements, cannot access element %i.", m_uiCount, uiIndex);
104 
105  return m_pElements[(m_uiFirstElement + uiIndex) % C];
106 }
107 
108 template <typename T, ezUInt32 C>
109 EZ_FORCE_INLINE T& ezStaticRingBuffer<T, C>::operator[](ezUInt32 uiIndex)
110 {
111  EZ_ASSERT_DEV(uiIndex < m_uiCount, "The ring-buffer only has %i elements, cannot access element %i.", m_uiCount, uiIndex);
112 
113  return m_pElements[(m_uiFirstElement + uiIndex) % C];
114 }
115 
116 template <typename T, ezUInt32 C>
117 EZ_FORCE_INLINE ezUInt32 ezStaticRingBuffer<T, C>::GetCount() const
118 {
119  return m_uiCount;
120 }
121 
122 template <typename T, ezUInt32 C>
123 EZ_FORCE_INLINE bool ezStaticRingBuffer<T, C>::IsEmpty() const
124 {
125  return m_uiCount == 0;
126 }
127 
128 template <typename T, ezUInt32 C>
129 EZ_FORCE_INLINE bool ezStaticRingBuffer<T, C>::CanAppend(ezUInt32 uiElements)
130 {
131  return (m_uiCount + uiElements) <= C;
132 }
133 
134 template <typename T, ezUInt32 C>
136 {
137  while (!IsEmpty())
138  PopFront();
139 }
140 
141 template <typename T, ezUInt32 C>
142 EZ_FORCE_INLINE T* ezStaticRingBuffer<T, C>::GetStaticArray()
143 {
144  return reinterpret_cast<T*>(m_Data);
145 }
146