libsidplayfp 1.8.8
EventScheduler.h
1/*
2 * This file is part of libsidplayfp, a SID player engine.
3 *
4 * Copyright (C) 2011-2012 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
29template< class This >
30class EventCallback: public Event
31{
32private:
33 typedef void (This::*Callback) ();
34
35private:
36 This &m_this;
37 Callback const m_callback;
38
39private:
40 void event() { (m_this.*m_callback)(); }
41
42public:
43 EventCallback(const char * const name, This &_this, Callback callback) :
44 Event(name),
45 m_this(_this),
46 m_callback(callback) {}
47};
48
49
56{
57private:
59 event_clock_t currentTime;
60
62 Event *firstEvent;
63
64private:
70 void schedule(Event &event)
71 {
72 // find the right spot where to tuck this new event
73 Event **scan = &firstEvent;
74 for (;;)
75 {
76 if (*scan == 0 || (*scan)->triggerTime > event.triggerTime)
77 {
78 event.next = *scan;
79 *scan = &event;
80 break;
81 }
82 scan = &((*scan)->next);
83 }
84 }
85
86protected:
87 void schedule(Event &event, unsigned int cycles,
88 event_phase_t phase)
89 {
90 // this strange formulation always selects the next available slot regardless of specified phase.
91 event.triggerTime = currentTime + ((currentTime & 1) ^ phase) + (cycles << 1);
92 schedule(event);
93 }
94
95 void schedule(Event &event, unsigned int cycles)
96 {
97 event.triggerTime = currentTime + (cycles << 1);
98 schedule(event);
99 }
100
101 void cancel(Event &event);
102
103public:
104 EventScheduler () :
105 currentTime(0),
106 firstEvent(0) {}
107
111 void reset();
112
116 void clock()
117 {
118 Event &event = *firstEvent;
119 firstEvent = firstEvent->next;
120 currentTime = event.triggerTime;
121 event.event();
122 }
123
127 bool isPending(Event &event) const;
128
129 event_clock_t getTime(event_phase_t phase) const
130 {
131 return (currentTime + (phase ^ 1)) >> 1;
132 }
133
134 event_clock_t getTime(event_clock_t clock, event_phase_t phase) const
135 {
136 return getTime (phase) - clock;
137 }
138
139 event_phase_t phase() const { return (event_phase_t) (currentTime & 1); }
140};
141
142#endif // EVENTSCHEDULER_H
Definition: EventScheduler.h:31
Definition: event.h:108
Definition: EventScheduler.h:56
void reset()
Definition: EventScheduler.cpp:26
void schedule(Event &event, unsigned int cycles, event_phase_t phase)
Definition: EventScheduler.h:87
void schedule(Event &event, unsigned int cycles)
Definition: EventScheduler.h:95
event_clock_t getTime(event_phase_t phase) const
Definition: EventScheduler.h:129
event_phase_t phase() const
Definition: EventScheduler.h:139
void clock()
Definition: EventScheduler.h:116
void cancel(Event &event)
Definition: EventScheduler.cpp:32
event_clock_t getTime(event_clock_t clock, event_phase_t phase) const
Definition: EventScheduler.h:134
bool isPending(Event &event) const
Definition: EventScheduler.cpp:47
Definition: event.h:51