1 | //============================================================================ |
---|---|
2 | // |
3 | // SSSS tt lll lll |
4 | // SS SS tt ll ll |
5 | // SS tttttt eeee ll ll aaaa |
6 | // SSSS tt ee ee ll ll aa |
7 | // SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" |
8 | // SS SS tt ee ll ll aa aa |
9 | // SSSS ttt eeeee llll llll aaaaa |
10 | // |
11 | // Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony |
12 | // and the Stella Team |
13 | // |
14 | // See the file "License.txt" for information on usage and redistribution of |
15 | // this file, and for a DISCLAIMER OF ALL WARRANTIES. |
16 | //============================================================================ |
17 | |
18 | #ifndef TIA_DELAY_QUEUE_MEMBER |
19 | #define TIA_DELAY_QUEUE_MEMBER |
20 | |
21 | #include "Serializable.hxx" |
22 | #include "bspf.hxx" |
23 | |
24 | template<unsigned capacity> |
25 | class DelayQueueMember : public Serializable { |
26 | |
27 | public: |
28 | struct Entry { |
29 | uInt8 address; |
30 | uInt8 value; |
31 | |
32 | Entry() : address(0), value(0) { } |
33 | }; |
34 | |
35 | public: |
36 | DelayQueueMember(); |
37 | |
38 | public: |
39 | void push(uInt8 address, uInt8 value); |
40 | |
41 | void remove(uInt8 address); |
42 | |
43 | void clear(); |
44 | |
45 | /** |
46 | Serializable methods (see that class for more information). |
47 | */ |
48 | bool save(Serializer& out) const override; |
49 | bool load(Serializer& in) override; |
50 | |
51 | public: |
52 | Entry myEntries[capacity]; |
53 | uInt8 mySize; |
54 | |
55 | private: |
56 | DelayQueueMember(const DelayQueueMember<capacity>&) = delete; |
57 | DelayQueueMember(DelayQueueMember<capacity>&&) = delete; |
58 | DelayQueueMember<capacity>& operator=(const DelayQueueMember<capacity>&) = delete; |
59 | DelayQueueMember<capacity>& operator=(DelayQueueMember<capacity>&&) = delete; |
60 | |
61 | }; |
62 | |
63 | // ############################################################################ |
64 | // Implementation |
65 | // ############################################################################ |
66 | |
67 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
68 | template<unsigned capacity> |
69 | DelayQueueMember<capacity>::DelayQueueMember() |
70 | : mySize(0) |
71 | { |
72 | } |
73 | |
74 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
75 | template<unsigned capacity> |
76 | void DelayQueueMember<capacity>::push(uInt8 address, uInt8 value) |
77 | { |
78 | if (mySize == capacity) throw runtime_error("delay queue overflow"); |
79 | |
80 | myEntries[mySize].address = address; |
81 | myEntries[mySize++].value = value; |
82 | } |
83 | |
84 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
85 | template<unsigned capacity> |
86 | void DelayQueueMember<capacity>::remove(uInt8 address) |
87 | { |
88 | uInt8 index; |
89 | |
90 | for (index = 0; index < mySize; ++index) { |
91 | if (myEntries[index].address == address) break; |
92 | } |
93 | |
94 | if (index < mySize) { |
95 | for (uInt8 i = index + 1; i < mySize; ++i) { |
96 | myEntries[i-1] = myEntries[i]; |
97 | } |
98 | |
99 | --mySize; |
100 | } |
101 | } |
102 | |
103 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
104 | template<unsigned capacity> |
105 | void DelayQueueMember<capacity>::clear() |
106 | { |
107 | mySize = 0; |
108 | } |
109 | |
110 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
111 | template<unsigned capacity> |
112 | bool DelayQueueMember<capacity>::save(Serializer& out) const |
113 | { |
114 | try |
115 | { |
116 | out.putByte(mySize); |
117 | for(uInt8 i = 0; i < mySize; ++i) |
118 | { |
119 | const Entry& e = myEntries[i]; |
120 | out.putByte(e.address); |
121 | out.putByte(e.value); |
122 | } |
123 | } |
124 | catch(...) |
125 | { |
126 | cerr << "ERROR: TIA_DelayQueueMember::save"<< endl; |
127 | return false; |
128 | } |
129 | |
130 | return true; |
131 | } |
132 | |
133 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
134 | template<unsigned capacity> |
135 | bool DelayQueueMember<capacity>::load(Serializer& in) |
136 | { |
137 | try |
138 | { |
139 | mySize = in.getByte(); |
140 | if (mySize > capacity) throw new runtime_error("invalid delay queue size"); |
141 | for(uInt32 i = 0; i < mySize; ++i) |
142 | { |
143 | Entry& e = myEntries[i]; |
144 | e.address = in.getByte(); |
145 | e.value = in.getByte(); |
146 | } |
147 | } |
148 | catch(...) |
149 | { |
150 | cerr << "ERROR: TIA_DelayQueueMember::load"<< endl; |
151 | return false; |
152 | } |
153 | |
154 | return true; |
155 | } |
156 | |
157 | #endif // TIA_DELAY_QUEUE_MEMBER |
158 |