1 /*	Public domain	*/
2 
3 #include <agar/core/begin.h>
4 
5 #define AG_TIMER_NAME_MAX 16
6 
7 typedef struct ag_timer {
8 	int id;				/* Unique identifier */
9 	void *obj;			/* Parent object */
10 	Uint flags;
11 #define AG_TIMER_SURVIVE_DETACH	0x01	/* Don't cancel on ObjectDetach() */
12 #define AG_TIMER_AUTO_FREE	0x02	/* Free the timer structure on expire */
13 #define AG_TIMER_EXECD		0x04	/* Callback was invoked manually */
14 #define AG_TIMER_RESTART	0x08	/* Queue timer for restart (driver-specific) */
15 	Uint32 tSched;			/* Scheduled expiration time (ticks) */
16 	Uint32 ival;			/* Timer interval in ticks */
17 	Uint32 (*fn)(struct ag_timer *, AG_Event *);
18 	AG_Event fnEvent;
19 	AG_TAILQ_ENTRY(ag_timer) timers;
20 	AG_TAILQ_ENTRY(ag_timer) change;
21 #ifdef AG_LEGACY
22 	Uint32 (*fnLegacy)(void *p, Uint32 ival, void *arg);
23 	void   *argLegacy;
24 #endif
25 	char name[AG_TIMER_NAME_MAX];	/* Name string (optional) */
26 } AG_Timer;
27 
28 typedef Uint32 (*AG_TimerFn)(AG_Timer *, AG_Event *);
29 
30 typedef struct ag_time_ops {
31 	const char *name;
32 	void   (*init)(void);
33 	void   (*destroy)(void);
34 	Uint32 (*getTicks)(void);
35 	void   (*delay)(Uint32);
36 } AG_TimeOps;
37 
38 #define AG_LockTiming()		AG_MutexLock(&agTimerLock)
39 #define AG_UnlockTiming()	AG_MutexUnlock(&agTimerLock)
40 #define AG_GetTicks		agTimeOps->getTicks
41 #define AG_Delay(t)		agTimeOps->delay(t)
42 
43 #ifdef AG_LEGACY
44 typedef AG_Timer AG_Timeout;
45 #endif
46 
47 __BEGIN_DECLS
48 extern struct ag_objectq agTimerObjQ;
49 extern Uint              agTimerCount;
50 extern struct ag_object  agTimerMgr;
51 extern AG_Mutex          agTimerLock;
52 
53 extern const AG_TimeOps *agTimeOps;
54 extern const AG_TimeOps  agTimeOps_dummy;
55 extern const AG_TimeOps  agTimeOps_gettimeofday;
56 extern const AG_TimeOps  agTimeOps_posix;
57 extern const AG_TimeOps  agTimeOps_win32;
58 extern const AG_TimeOps  agTimeOps_renderer;
59 
60 void    AG_SetTimeOps(const AG_TimeOps *);
61 void	AG_InitTimers(void);
62 void	AG_DestroyTimers(void);
63 
64 void      AG_InitTimer(AG_Timer *, const char *, Uint);
65 int       AG_AddTimer(void *, AG_Timer *, Uint32, AG_TimerFn, const char *, ...);
66 AG_Timer *AG_AddTimerAuto(void *, Uint32, AG_TimerFn, const char *, ...);
67 void	  AG_DelTimer(void *, AG_Timer *);
68 int	  AG_ResetTimer(void *, AG_Timer *, Uint32);
69 int	  AG_TimerIsRunning(void *, AG_Timer *);
70 int       AG_TimerWait(void *, AG_Timer *, Uint32);
71 
72 void    AG_ProcessTimeouts(Uint32);
73 
74 /* Execute a timer's associated callback routine. */
75 static __inline__ Uint32
AG_ExecTimerFn(AG_Timer * to)76 AG_ExecTimerFn(AG_Timer *to)
77 {
78 	Uint32 rv;
79 
80 	to->flags |= AG_TIMER_EXECD;
81 	rv = to->fn(to, &to->fnEvent);
82 	to->flags &= ~(AG_TIMER_EXECD);
83 	return (rv);
84 }
85 
86 #ifdef AG_LEGACY
87 void AG_SetTimeout(AG_Timeout *, Uint32 (*)(void *, Uint32, void *), void *, Uint) DEPRECATED_ATTRIBUTE;
88 void AG_ScheduleTimeout(void *, AG_Timeout *, Uint32) DEPRECATED_ATTRIBUTE;
89 # define AG_TIMEOUT_INITIALIZER { -1, NULL, 0, 0, 0, NULL }
90 # define AG_TIMEOUTS_QUEUED() (!AG_TAILQ_EMPTY(&agTimerObjQ))
91 # define AG_CANCEL_ONDETACH	0x10	/* Don't cancel on ObjectDetach() */
92 # define AG_CANCEL_ONLOAD	0x20	/* In queue for execution */
93 # define AG_TimeoutWait(obj,to,d) AG_TimerWait((obj),(to),(d))
94 # define AG_TimeoutIsScheduled(obj,to) AG_TimerIsRunning((obj),(to))
95 # define AG_DelTimeout(obj,to) AG_DelTimer((obj),(to))
96 # define AG_ProcessTimeout(x) AG_ProcessTimeouts(x)
97 # define AG_AddTimeout(p,to,dt) AG_ScheduleTimeout((p),(to),(dt))
98 # define AG_ReplaceTimeout(p,to,dt) AG_ScheduleTimeout((p),(to),(dt))
99 #endif /* AG_LEGACY */
100 __END_DECLS
101 
102 #include <agar/core/close.h>
103