aboutsummaryrefslogtreecommitdiff
path: root/Spear/Sys/Timer.hs
blob: a44f7f905e2d5e340917283854ac1ee7cba46172 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
{-# INCLUDE "Timer/Timer.h" #-}
{-# LINE 1 "Timer.hsc" #-}
{-# LANGUAGE CPP, ForeignFunctionInterface, BangPatterns #-}
{-# LINE 2 "Timer.hsc" #-}
module Spear.Sys.Timer
(
	Timer
,	initialiseTimingSubsystem
,	newTimer
,	tick
,	reset
,	stop
,	start
,	sleep
,	getTime
,	getDelta
,	isRunning
)
where


import Foreign
import Foreign.C.Types
import Control.Monad
import System.IO.Unsafe



{-# LINE 28 "Timer.hsc" #-}
type TimeReading = CDouble

{-# LINE 30 "Timer.hsc" #-}

data Timer = Timer {
    getBaseTime     :: TimeReading
,   getPausedTime   :: TimeReading
,   getStopTime     :: TimeReading
,   getPrevTime     :: TimeReading
,   getCurTime      :: TimeReading
,   getDeltaTime    :: CFloat
,   getRunning      :: CChar
}



{-# LINE 43 "Timer.hsc" #-}


instance Storable Timer where
    sizeOf _    = (48)
{-# LINE 47 "Timer.hsc" #-}
	alignment _	= alignment (undefined :: TimeReading)
	
	peek ptr = do
		baseTime <- (\hsc_ptr -> peekByteOff hsc_ptr 0) ptr
{-# LINE 51 "Timer.hsc" #-}
		pausedTime <- (\hsc_ptr -> peekByteOff hsc_ptr 8) ptr
{-# LINE 52 "Timer.hsc" #-}
		stopTime <- (\hsc_ptr -> peekByteOff hsc_ptr 16) ptr
{-# LINE 53 "Timer.hsc" #-}
		prevTime <- (\hsc_ptr -> peekByteOff hsc_ptr 24) ptr
{-# LINE 54 "Timer.hsc" #-}
		curTime <- (\hsc_ptr -> peekByteOff hsc_ptr 32) ptr
{-# LINE 55 "Timer.hsc" #-}
		deltaTime <- (\hsc_ptr -> peekByteOff hsc_ptr 40) ptr
{-# LINE 56 "Timer.hsc" #-}
		stopped <- (\hsc_ptr -> peekByteOff hsc_ptr 44) ptr
{-# LINE 57 "Timer.hsc" #-}
		return $ Timer baseTime pausedTime stopTime prevTime curTime deltaTime stopped
		
	poke ptr (Timer baseTime pausedTime stopTime prevTime curTime deltaTime stopped) = do
		(\hsc_ptr -> pokeByteOff hsc_ptr 0) ptr baseTime
{-# LINE 61 "Timer.hsc" #-}
		(\hsc_ptr -> pokeByteOff hsc_ptr 8) ptr pausedTime
{-# LINE 62 "Timer.hsc" #-}
		(\hsc_ptr -> pokeByteOff hsc_ptr 16) ptr stopTime
{-# LINE 63 "Timer.hsc" #-}
		(\hsc_ptr -> pokeByteOff hsc_ptr 24) ptr prevTime
{-# LINE 64 "Timer.hsc" #-}
		(\hsc_ptr -> pokeByteOff hsc_ptr 32) ptr curTime
{-# LINE 65 "Timer.hsc" #-}
		(\hsc_ptr -> pokeByteOff hsc_ptr 40) ptr deltaTime
{-# LINE 66 "Timer.hsc" #-}
		(\hsc_ptr -> pokeByteOff hsc_ptr 44) ptr stopped
{-# LINE 67 "Timer.hsc" #-}


foreign import ccall "Timer.h timer_initialise_subsystem"
	c_timer_initialise_subsystem :: IO ()
	
foreign import ccall "Timer.h timer_initialise_timer"
	c_timer_initialise_timer :: Ptr Timer -> IO ()

foreign import ccall "Timer.h timer_tick"
	c_timer_tick :: Ptr Timer -> IO ()

foreign import ccall "Timer.h timer_reset"
	c_timer_reset :: Ptr Timer -> IO ()

foreign import ccall "Timer.h timer_stop"
	c_timer_stop :: Ptr Timer -> IO ()

foreign import ccall "Timer.h timer_start"
	c_timer_start :: Ptr Timer -> IO ()

foreign import ccall "Timer.h timer_sleep"
	c_timer_sleep :: CFloat -> IO ()

foreign import ccall "Timer.h timer_get_time"
	c_timer_get_time :: Ptr Timer -> IO (CFloat)

foreign import ccall "Timer.h timer_get_delta"
	c_timer_get_delta :: Ptr Timer -> IO (CFloat)

foreign import ccall "Timer.h timer_is_running"
	c_timer_is_running :: Ptr Timer -> IO (CChar)


-- | Initialises the timing subsystem.
initialiseTimingSubsystem :: IO ()
initialiseTimingSubsystem = c_timer_initialise_subsystem


-- | Creates a timer.
newTimer :: Timer
newTimer = unsafePerformIO . alloca $ \tptr -> do
	c_timer_initialise_timer tptr
	t <- peek tptr
	return t


-- | Updates the timer.
tick :: Timer -> IO (Timer)
tick t = alloca $ \tptr -> do
	poke tptr t
	c_timer_tick tptr
	t' <- peek tptr
	return t'


-- | Resets the timer.
reset :: Timer -> IO (Timer)
reset t = alloca $ \tptr -> do
	poke tptr t
	c_timer_reset tptr
	t' <- peek tptr
	return t'


-- | Stops the timer.
stop :: Timer -> IO (Timer)
stop t = alloca $ \tptr -> do
	poke tptr t
	c_timer_stop tptr
	t' <- peek tptr
	return t'


-- | Starts the timer.
start :: Timer -> IO (Timer)
start t = alloca $ \tptr -> do
	poke tptr t
	c_timer_start tptr
	t' <- peek tptr
	return t'


-- | Puts the caller thread to sleep for the given number of seconds.
sleep :: Float -> IO ()
sleep = c_timer_sleep . realToFrac


-- | Gets the timer's total running time.
getTime :: Timer -> Float
getTime t = unsafePerformIO . alloca $ \tptr -> do
	poke tptr t
	time <- c_timer_get_time tptr
	return (realToFrac time)


-- | Gets the timer's delta since the last tick.
getDelta :: Timer -> Float
getDelta t = unsafePerformIO . alloca $ \tptr -> do
	poke tptr t
	dt <- c_timer_get_delta tptr
	return (realToFrac dt)


-- | Returns true if the timer is running, false otherwise.
isRunning :: Timer -> Bool
isRunning t = unsafePerformIO . alloca $ \tptr -> do
	poke tptr t
	running <- c_timer_is_running tptr
	return (running /= 0)