28 jassert (bufferSize > 0);
38 auto vs = validStart.
get();
39 auto ve = validEnd.
get();
40 return ve >= vs ? (ve - vs) : (bufferSize - (vs - ve));
51 jassert (newSize > 0);
58 int& startIndex2,
int& blockSize2)
const noexcept
60 auto vs = validStart.get();
61 auto ve = validEnd.get();
63 auto freeSpace = ve >= vs ? (bufferSize - (ve - vs)) : (vs - ve);
64 numToWrite = jmin (numToWrite, freeSpace - 1);
77 blockSize1 = jmin (bufferSize - ve, numToWrite);
78 numToWrite -= blockSize1;
79 blockSize2 = numToWrite <= 0 ? 0 : jmin (numToWrite, vs);
85 jassert (numWritten >= 0 && numWritten < bufferSize);
87 auto newEnd = validEnd.get() + numWritten;
89 if (newEnd >= bufferSize)
96 int& startIndex2,
int& blockSize2)
const noexcept
98 auto vs = validStart.get();
99 auto ve = validEnd.get();
101 auto numReady = ve >= vs ? (ve - vs) : (bufferSize - (vs - ve));
102 numWanted = jmin (numWanted, numReady);
115 blockSize1 = jmin (bufferSize - vs, numWanted);
116 numWanted -= blockSize1;
117 blockSize2 = numWanted <= 0 ? 0 : jmin (numWanted, ve);
123 jassert (numRead >= 0 && numRead <= bufferSize);
125 auto newStart = validStart.get() + numRead;
127 if (newStart >= bufferSize)
128 newStart -= bufferSize;
130 validStart = newStart;
134 template <AbstractFifo::ReadOrWrite mode>
136 : startIndex1 (other.startIndex1),
137 blockSize1 (other.blockSize1),
138 startIndex2 (other.startIndex2),
139 blockSize2 (other.blockSize2)
144 template <AbstractFifo::ReadOrWrite mode>
145 AbstractFifo::ScopedReadWrite<mode>&
146 AbstractFifo::ScopedReadWrite<mode>::operator= (ScopedReadWrite&& other) noexcept
152 template <AbstractFifo::ReadOrWrite mode>
153 void AbstractFifo::ScopedReadWrite<mode>::swap (ScopedReadWrite& other) noexcept
155 std::swap (other.fifo, fifo);
156 std::swap (other.startIndex1, startIndex1);
157 std::swap (other.blockSize1, blockSize1);
158 std::swap (other.startIndex2, startIndex2);
159 std::swap (other.blockSize2, blockSize2);
162 template class AbstractFifo::ScopedReadWrite<AbstractFifo::ReadOrWrite::read>;
163 template class AbstractFifo::ScopedReadWrite<AbstractFifo::ReadOrWrite::write>;
173 class AbstractFifoTests :
public UnitTest
177 :
UnitTest (
"Abstract Fifo", UnitTestCategories::containers)
180 struct WriteThread :
public Thread
182 WriteThread (AbstractFifo& f,
int* b, Random rng)
183 : Thread (
"fifo writer"), fifo (f), buffer (b), random (rng)
197 while (! threadShouldExit())
199 int num = random.nextInt (2000) + 1;
201 auto writer = fifo.write (num);
203 jassert (writer.blockSize1 >= 0 && writer.blockSize2 >= 0);
204 jassert (writer.blockSize1 == 0
205 || (writer.startIndex1 >= 0 && writer.startIndex1 < fifo.getTotalSize()));
206 jassert (writer.blockSize2 == 0
207 || (writer.startIndex2 >= 0 && writer.startIndex2 < fifo.getTotalSize()));
209 writer.forEach ([
this, &n] (
int index) { this->buffer[index] = n++; });
218 void runTest()
override
220 beginTest (
"AbstractFifo");
223 AbstractFifo fifo (numElementsInArray (buffer));
225 WriteThread writer (fifo, buffer, getRandom());
228 Random r = getRandom();
229 r.combineSeed (12345);
231 for (
int count = 100000; --count >= 0;)
233 int num = r.nextInt (6000) + 1;
235 auto reader = fifo.read (num);
237 if (! (reader.blockSize1 >= 0 && reader.blockSize2 >= 0)
238 && (reader.blockSize1 == 0
239 || (reader.startIndex1 >= 0 && reader.startIndex1 < fifo.getTotalSize()))
240 && (reader.blockSize2 == 0
241 || (reader.startIndex2 >= 0 && reader.startIndex2 < fifo.getTotalSize())))
243 expect (
false,
"prepareToRead returned -ve values");
249 reader.forEach ([&failed, &buffer, &n] (
int index)
251 failed = (buffer[index] != n++) || failed;
256 expect (
false,
"read values were incorrect");
263 static AbstractFifoTests fifoUnitTests;
ScopedReadWrite()=default
void prepareToWrite(int numToWrite, int &startIndex1, int &blockSize1, int &startIndex2, int &blockSize2) const noexcept
int getTotalSize() const noexcept
ScopedRead read(int numToRead) noexcept
void prepareToRead(int numWanted, int &startIndex1, int &blockSize1, int &startIndex2, int &blockSize2) const noexcept
AbstractFifo(int capacity) noexcept
void finishedRead(int numRead) noexcept
int getFreeSpace() const noexcept
void finishedWrite(int numWritten) noexcept
ScopedWrite write(int numToWrite) noexcept
int getNumReady() const noexcept
void setTotalSize(int newSize) noexcept
Type get() const noexcept