aboutsummaryrefslogtreecommitdiff
path: root/src/FIFO.h
blob: 2b2c10207f44e04d29919239d5b76cef7dffd728 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
    Copyright 2016-2020 Arisotura

    This file is part of melonDS.

    melonDS is free software: you can redistribute it and/or modify it under
    the terms of the GNU General Public License as published by the Free
    Software Foundation, either version 3 of the License, or (at your option)
    any later version.

    melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with melonDS. If not, see http://www.gnu.org/licenses/.
*/

#ifndef FIFO_H
#define FIFO_H

#include "types.h"

template<typename T>
class FIFO
{
public:
    FIFO(u32 num)
    {
        NumEntries = num;
        Entries = new T[num];
        Clear();
    }

    ~FIFO()
    {
        delete[] Entries;
    }


    void Clear()
    {
        NumOccupied = 0;
        ReadPos = 0;
        WritePos = 0;
        memset(&Entries[ReadPos], 0, sizeof(T));
    }


    void DoSavestate(Savestate* file)
    {
        file->Var32(&NumOccupied);
        file->Var32(&ReadPos);
        file->Var32(&WritePos);

        file->VarArray(Entries, sizeof(T)*NumEntries);
    }


    void Write(T val)
    {
        if (IsFull()) return;

        Entries[WritePos] = val;

        WritePos++;
        if (WritePos >= NumEntries)
            WritePos = 0;

        NumOccupied++;
    }

    T Read()
    {
        T ret = Entries[ReadPos];
        if (IsEmpty())
            return ret;

        ReadPos++;
        if (ReadPos >= NumEntries)
            ReadPos = 0;

        NumOccupied--;
        return ret;
    }

    T Peek()
    {
        return Entries[ReadPos];
    }

    T Peek(u32 offset)
    {
        u32 pos = ReadPos + offset;
        if (pos >= NumEntries)
            pos -= NumEntries;

        return Entries[pos];
    }

    u32 Level() { return NumOccupied; }
    bool IsEmpty() { return NumOccupied == 0; }
    bool IsFull() { return NumOccupied >= NumEntries; }

    bool CanFit(u32 num) { return ((NumOccupied + num) <= NumEntries); }

private:
    u32 NumEntries;
    T* Entries;
    u32 NumOccupied;
    u32 ReadPos, WritePos;
};

#endif