add RingBuffer class -- FIFO but optimized for larger volumes of data
This commit is contained in:
parent
7a12237cec
commit
9c3749bfa0
117
src/FIFO.h
117
src/FIFO.h
|
@ -24,6 +24,7 @@
|
|||
|
||||
namespace melonDS
|
||||
{
|
||||
|
||||
template<typename T, u32 NumEntries>
|
||||
class FIFO
|
||||
{
|
||||
|
@ -191,5 +192,121 @@ private:
|
|||
u32 ReadPos, WritePos;
|
||||
};
|
||||
|
||||
template<u32 Size>
|
||||
class RingBuffer
|
||||
{
|
||||
public:
|
||||
void Clear()
|
||||
{
|
||||
NumOccupied = 0;
|
||||
ReadPos = 0;
|
||||
WritePos = 0;
|
||||
memset(Buffer, 0, Size);
|
||||
}
|
||||
|
||||
|
||||
void DoSavestate(Savestate* file)
|
||||
{
|
||||
file->Var32(&NumOccupied);
|
||||
file->Var32(&ReadPos);
|
||||
file->Var32(&WritePos);
|
||||
|
||||
file->VarArray(Buffer, Size);
|
||||
}
|
||||
|
||||
|
||||
bool Write(const void* data, u32 len)
|
||||
{
|
||||
if (!CanFit(len)) return false;
|
||||
|
||||
if ((WritePos + len) >= Size)
|
||||
{
|
||||
u32 part1 = Size - WritePos;
|
||||
memcpy(&Buffer[WritePos], data, part1);
|
||||
if (len > part1)
|
||||
memcpy(Buffer, &((u8*)data)[part1], len - part1);
|
||||
WritePos = len - part1;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&Buffer[WritePos], data, len);
|
||||
WritePos += len;
|
||||
}
|
||||
|
||||
NumOccupied += len;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Read(void* data, u32 len)
|
||||
{
|
||||
if (NumOccupied < len) return false;
|
||||
|
||||
u32 readpos = ReadPos;
|
||||
if ((readpos + len) >= Size)
|
||||
{
|
||||
u32 part1 = Size - readpos;
|
||||
memcpy(data, &Buffer[readpos], part1);
|
||||
if (len > part1)
|
||||
memcpy(&((u8*)data)[part1], Buffer, len - part1);
|
||||
ReadPos = len - part1;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(data, &Buffer[readpos], len);
|
||||
ReadPos += len;
|
||||
}
|
||||
|
||||
NumOccupied -= len;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Peek(void* data, u32 offset, u32 len)
|
||||
{
|
||||
if (NumOccupied < len) return false;
|
||||
|
||||
u32 readpos = ReadPos + offset;
|
||||
if (readpos >= Size) readpos -= Size;
|
||||
|
||||
if ((readpos + len) >= Size)
|
||||
{
|
||||
u32 part1 = Size - readpos;
|
||||
memcpy(data, &Buffer[readpos], part1);
|
||||
if (len > part1)
|
||||
memcpy(&((u8*)data)[part1], Buffer, len - part1);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(data, &Buffer[readpos], len);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Skip(u32 len)
|
||||
{
|
||||
if (NumOccupied < len) return false;
|
||||
|
||||
ReadPos += len;
|
||||
if (ReadPos >= Size)
|
||||
ReadPos -= Size;
|
||||
|
||||
NumOccupied -= len;
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 Level() const { return NumOccupied; }
|
||||
bool IsEmpty() const { return NumOccupied == 0; }
|
||||
bool IsFull() const { return NumOccupied >= Size; }
|
||||
|
||||
bool CanFit(u32 num) const { return ((NumOccupied + num) <= Size); }
|
||||
|
||||
private:
|
||||
u8 Buffer[Size] = {0};
|
||||
u32 NumOccupied = 0;
|
||||
u32 ReadPos = 0, WritePos = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue