UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ui_timer.cpp
Go to the documentation of this file.
1 
5 /*
6 Copyright (C) 2002-2020 UFO: Alien Invasion.
7 
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (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.
16 
17 See the GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 
23 */
24 
25 #include "../cl_shared.h"
26 #include "ui_nodes.h"
27 #include "ui_timer.h"
28 
32 #define UI_TIMER_SLOT_NUMBER 10
33 
38 
44 
50 {
51  assert(timer >= ui_timerSlots && timer < ui_timerSlots + UI_TIMER_SLOT_NUMBER);
52  if (timer->prev) {
53  timer->prev->next = timer->next;
54  } else {
55  ui_firstTimer = timer->next;
56  }
57  if (timer->next) {
58  timer->next->prev = timer->prev;
59  }
60 }
61 
66 static void UI_InsertTimerInActiveList (uiTimer_t* first, uiTimer_t* newTimer)
67 {
68  uiTimer_t* current = first;
69  uiTimer_t* prev = nullptr;
70 
71  /* find insert position */
72  if (current != nullptr) {
73  prev = current->prev;
74  }
75  while (current) {
76  if (newTimer->nextTime < current->nextTime)
77  break;
78  prev = current;
79  current = current->next;
80  }
81 
82  /* insert between previous and current */
83  newTimer->prev = prev;
84  newTimer->next = current;
85  if (current != nullptr) {
86  current->prev = newTimer;
87  }
88  if (prev != nullptr) {
89  prev->next = newTimer;
90  } else {
91  ui_firstTimer = newTimer;
92  }
93 }
94 
98 void UI_HandleTimers (void)
99 {
100  /* is first element is out of date? */
101  while (ui_firstTimer && ui_firstTimer->nextTime <= CL_Milliseconds()) {
103 
104  /* throw event */
105  timer->calledTime++;
106  timer->callback(timer->owner, timer);
107 
108  /* update the sorted list */
109  if (timer->isRunning) {
111  timer->nextTime += timer->delay;
112  UI_InsertTimerInActiveList(timer->next, timer);
113  }
114  }
115 }
116 
123 uiTimer_t* UI_AllocTimer (uiNode_t* node, int firstDelay, timerCallback_t callback)
124 {
125  uiTimer_t* timer = nullptr;
126 
127  /* search empty slot */
128  for (int i = 0; i < UI_TIMER_SLOT_NUMBER; i++) {
129  if (ui_timerSlots[i].callback != nullptr)
130  continue;
131  timer = ui_timerSlots + i;
132  break;
133  }
134  if (timer == nullptr)
135  Com_Error(ERR_FATAL, "UI_AllocTimer: No more timer slot");
136 
137  timer->owner = node;
138  timer->delay = firstDelay;
139  timer->callback = callback;
140  timer->calledTime = 0;
141  timer->prev = nullptr;
142  timer->next = nullptr;
143  timer->isRunning = false;
144  return timer;
145 }
146 
151 {
152  if (timer->isRunning)
153  return;
154  assert(ui_firstTimer != timer && timer->prev == nullptr && timer->next == nullptr);
155  timer->nextTime = CL_Milliseconds() + timer->delay;
156  timer->isRunning = true;
157  UI_InsertTimerInActiveList(ui_firstTimer, timer);
158 }
159 
164 {
165  if (!timer->isRunning)
166  return;
168  timer->prev = nullptr;
169  timer->next = nullptr;
170  timer->isRunning = false;
171 }
172 
177 {
179  timer->prev = nullptr;
180  timer->next = nullptr;
181  timer->owner = nullptr;
182  timer->callback = nullptr;
183 }
184 
185 void UI_ResetTimers (void)
186 {
187  OBJZERO(ui_timerSlots);
188  ui_firstTimer = nullptr;
189 }
190 
191 #ifdef COMPILE_UNITTESTS
192 
197 const uiTimer_t* UI_PrivateGetFirstTimer (void)
198 {
199  return ui_firstTimer;
200 }
201 
202 void UI_PrivateInsertTimerInActiveList (uiTimer_t* first, uiTimer_t* newTimer)
203 {
204  UI_InsertTimerInActiveList(first, newTimer);
205 }
206 
207 #endif
static uiTimer_t ui_timerSlots[UI_TIMER_SLOT_NUMBER]
Timer slot. Only one.
Definition: ui_timer.cpp:37
timerCallback_t callback
Definition: ui_timer.h:42
struct uiTimer_s * prev
Definition: ui_timer.h:38
static void UI_InsertTimerInActiveList(uiTimer_t *first, uiTimer_t *newTimer)
Insert a timer in a sorted linked list of timers. List are ordered from smaller to bigger nextTime va...
Definition: ui_timer.cpp:66
uiTimer_t * UI_AllocTimer(uiNode_t *node, int firstDelay, timerCallback_t callback)
Allocate a new time for a node.
Definition: ui_timer.cpp:123
Definition: common.cpp:82
#define ERR_FATAL
Definition: common.h:210
int delay
Definition: ui_timer.h:45
void Com_Error(int code, const char *fmt,...)
Definition: common.cpp:417
static void UI_RemoveTimerFromActiveList(uiTimer_t *timer)
Remove a timer from the active linked list.
Definition: ui_timer.cpp:49
#define OBJZERO(obj)
Definition: shared.h:178
void UI_HandleTimers(void)
Internal function to handle timers.
Definition: ui_timer.cpp:98
void UI_TimerRelease(uiTimer_t *timer)
Release the timer. It no more exists.
Definition: ui_timer.cpp:176
int nextTime
Definition: ui_timer.h:39
void UI_TimerStop(uiTimer_t *timer)
Stop a timer.
Definition: ui_timer.cpp:163
Atomic structure used to define most of the UI.
Definition: ui_nodes.h:80
uiNode_t * owner
Definition: ui_timer.h:41
void(* timerCallback_t)(uiNode_t *node, struct uiTimer_s *timer)
Definition: ui_timer.h:31
void UI_ResetTimers(void)
Definition: ui_timer.cpp:185
bool isRunning
Definition: ui_timer.h:47
QGL_EXTERN GLint i
Definition: r_gl.h:113
static uiTimer_t * ui_firstTimer
First timer from the timer list. This list is ordered from smaller to bigger nextTime value...
Definition: ui_timer.cpp:43
#define UI_TIMER_SLOT_NUMBER
Number max of timer slot.
Definition: ui_timer.cpp:32
struct uiTimer_s * next
Definition: ui_timer.h:37
int calledTime
Definition: ui_timer.h:43
void UI_TimerStart(uiTimer_t *timer)
Restart a timer.
Definition: ui_timer.cpp:150
static uiTimer_t * timer
Definition: cl_radar.cpp:37
int CL_Milliseconds(void)
Definition: cl_main.cpp:1208