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_ITERATOR_IMPL
19#define TIA_DELAY_QUEUE_ITERATOR_IMPL
20
21#include "bspf.hxx"
22#include "DelayQueue.hxx"
23#include "DelayQueueMember.hxx"
24#include "DelayQueueIterator.hxx"
25
26template<unsigned length, unsigned capacity>
27class DelayQueueIteratorImpl : public DelayQueueIterator
28{
29 public:
30 explicit DelayQueueIteratorImpl(const DelayQueue<length, capacity>& delayQueue);
31
32 public:
33
34 bool isValid() const override;
35
36 uInt8 delay() const override;
37
38 uInt8 address() const override;
39
40 uInt8 value() const override;
41
42 bool next() override;
43
44 private:
45 uInt8 currentIndex() const;
46
47 private:
48 const DelayQueue<length, capacity>& myDelayQueue;
49 uInt8 myDelayCycle;
50 uInt8 myIndex;
51};
52
53// ############################################################################
54// Implementation
55// ############################################################################
56
57// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
58template<unsigned length, unsigned capacity>
59DelayQueueIteratorImpl<length, capacity>::DelayQueueIteratorImpl(
60 const DelayQueue<length, capacity>& delayQueue
61)
62 : myDelayQueue(delayQueue),
63 myDelayCycle(0),
64 myIndex(0)
65{
66 while (myDelayQueue.myMembers[currentIndex()].mySize == 0 && isValid())
67 myDelayCycle++;
68}
69
70// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
71template<unsigned length, unsigned capacity>
72bool DelayQueueIteratorImpl<length, capacity>::isValid() const
73{
74 return myDelayCycle < length;
75}
76
77// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
78template<unsigned length, unsigned capacity>
79uInt8 DelayQueueIteratorImpl<length, capacity>::delay() const
80{
81 if (!isValid()) {
82 throw runtime_error("delay called on invalid DelayQueueInterator");
83 }
84
85 return myDelayCycle;
86}
87
88// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
89template<unsigned length, unsigned capacity>
90uInt8 DelayQueueIteratorImpl<length, capacity>::address() const
91{
92 if (!isValid()) {
93 throw runtime_error("address called on invalid DelayQueueInterator");
94 }
95
96 return myDelayQueue.myMembers[currentIndex()].myEntries[myIndex].address;
97}
98
99// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
100template<unsigned length, unsigned capacity>
101uInt8 DelayQueueIteratorImpl<length, capacity>::value() const
102{
103 if (!isValid()) {
104 throw runtime_error("value called on invalid DelayQueueInterator");
105 }
106
107 return myDelayQueue.myMembers[currentIndex()].myEntries[myIndex].value;
108}
109
110// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
111template<unsigned length, unsigned capacity>
112bool DelayQueueIteratorImpl<length, capacity>::next()
113{
114 if (!isValid()) return false;
115
116 if (++myIndex < myDelayQueue.myMembers[currentIndex()].mySize)
117 return true;
118
119 myIndex = 0;
120
121 do {
122 ++myDelayCycle;
123 } while (myDelayQueue.myMembers[currentIndex()].mySize == 0 && isValid());
124
125 return isValid();
126}
127
128// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
129template<unsigned length, unsigned capacity>
130uInt8 DelayQueueIteratorImpl<length, capacity>::currentIndex() const
131{
132 return (myDelayQueue.myIndex + myDelayCycle) % length;
133}
134
135#endif // TIA_DELAY_QUEUE_ITERATOR_IMPL
136