libsidplayfp  2.0.2
EventScheduler.h
1 /*
2  * This file is part of libsidplayfp, a SID player engine.
3  *
4  * Copyright (C) 2011-2015 Leandro Nini
5  * Copyright (C) 2009 Antti S. Lankila
6  * Copyright (C) 2001 Simon White
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #ifndef EVENTSCHEDULER_H
24 #define EVENTSCHEDULER_H
25 
26 #include "Event.h"
27 
28 #include "sidcxx11.h"
29 
30 
31 namespace libsidplayfp
32 {
33 
40 typedef enum
41 {
42  EVENT_CLOCK_PHI1 = 0,
43  EVENT_CLOCK_PHI2 = 1
44 } event_phase_t;
45 
46 
62 {
63 private:
65  Event *firstEvent;
66 
68  event_clock_t currentTime;
69 
70 private:
76  void schedule(Event &event)
77  {
78  // find the right spot where to tuck this new event
79  Event **scan = &firstEvent;
80  for (;;)
81  {
82  if ((*scan == nullptr) || ((*scan)->triggerTime > event.triggerTime))
83  {
84  event.next = *scan;
85  *scan = &event;
86  break;
87  }
88  scan = &((*scan)->next);
89  }
90  }
91 
92 public:
93  EventScheduler() :
94  firstEvent(nullptr),
95  currentTime(0) {}
96 
106  void schedule(Event &event, unsigned int cycles, event_phase_t phase)
107  {
108  // this strange formulation always selects the next available slot regardless of specified phase.
109  event.triggerTime = currentTime + ((currentTime & 1) ^ phase) + (cycles << 1);
110  schedule(event);
111  }
112 
119  void schedule(Event &event, unsigned int cycles)
120  {
121  event.triggerTime = currentTime + (cycles << 1);
122  schedule(event);
123  }
124 
130  void cancel(Event &event);
131 
135  void reset();
136 
140  void clock()
141  {
142  Event &event = *firstEvent;
143  firstEvent = firstEvent->next;
144  currentTime = event.triggerTime;
145  event.event();
146  }
147 
154  bool isPending(Event &event) const;
155 
162  event_clock_t getTime(event_phase_t phase) const
163  {
164  return (currentTime + (phase ^ 1)) >> 1;
165  }
166 
174  event_clock_t getTime(event_clock_t clock, event_phase_t phase) const
175  {
176  return getTime(phase) - clock;
177  }
178 
184  event_phase_t phase() const { return static_cast<event_phase_t>(currentTime & 1); }
185 };
186 
187 }
188 
189 #endif // EVENTSCHEDULER_H
libsidplayfp::EventScheduler::schedule
void schedule(Event &event, unsigned int cycles)
Definition: EventScheduler.h:119
libsidplayfp::EventScheduler::isPending
bool isPending(Event &event) const
Definition: EventScheduler.cpp:50
libsidplayfp::EventScheduler::cancel
void cancel(Event &event)
Definition: EventScheduler.cpp:35
libsidplayfp::EventScheduler::clock
void clock()
Definition: EventScheduler.h:140
libsidplayfp::EventScheduler
Definition: EventScheduler.h:62
libsidplayfp::EventScheduler::getTime
event_clock_t getTime(event_phase_t phase) const
Definition: EventScheduler.h:162
libsidplayfp::EventScheduler::reset
void reset()
Definition: EventScheduler.cpp:29
libsidplayfp::EventScheduler::schedule
void schedule(Event &event, unsigned int cycles, event_phase_t phase)
Definition: EventScheduler.h:106
libsidplayfp::EventScheduler::phase
event_phase_t phase() const
Definition: EventScheduler.h:184
libsidplayfp::EventScheduler::getTime
event_clock_t getTime(event_clock_t clock, event_phase_t phase) const
Definition: EventScheduler.h:174
libsidplayfp::Event
Definition: Event.h:39