|
5 | 5 |
|
6 | 6 | module Main where |
7 | 7 |
|
8 | | -import Foreign.C (CInt) |
9 | | -import SDL |
10 | | -import Weigh |
| 8 | +import qualified Data.Vector.Storable as SV |
| 9 | +import qualified Data.Vector.Storable.Mutable as SVM |
| 10 | +import Foreign.C (CInt) |
| 11 | +import Foreign.Ptr |
| 12 | +import Foreign.Storable |
| 13 | +import SDL |
| 14 | +import Weigh |
11 | 15 |
|
12 | 16 | -- | Main entry point. |
13 | 17 | main :: IO () |
@@ -109,6 +113,22 @@ main = |
109 | 113 | "Allocated >4KB! Allocations should be constant." |
110 | 114 | else Nothing) |
111 | 115 | | i <- [1, 10, 100, 1000, 2000] |
| 116 | + ]) |
| 117 | + wgroup |
| 118 | + "animated rects" |
| 119 | + (sequence_ |
| 120 | + [ validateAction |
| 121 | + ("animated rects " ++ show i) |
| 122 | + pollEventAnimRectsTest |
| 123 | + i |
| 124 | + (\weight -> |
| 125 | + if weightGCs weight > 0 |
| 126 | + then Just "Non-zero number of garbage collections!" |
| 127 | + else if weightAllocatedBytes weight > 5000 |
| 128 | + then Just |
| 129 | + "Allocated >4KB! Allocations should be constant." |
| 130 | + else Nothing) |
| 131 | + | i <- [1, 10, 100, 1000, 2000, 3000] |
112 | 132 | ])) |
113 | 133 |
|
114 | 134 | -- | Test that merely polling does not allocate or engage the GC. |
@@ -237,3 +257,81 @@ pollEventAnimRectTest iters = do |
237 | 257 | w :: CInt |
238 | 258 | h :: CInt |
239 | 259 | (w, h) = (100, 100) |
| 260 | + |
| 261 | +-------------------------------------------------------------------------------- |
| 262 | +-- Animated rects test |
| 263 | + |
| 264 | +data Square = Square |
| 265 | + { squareV :: !(V2 CInt) |
| 266 | + , squareP :: !(V2 CInt) |
| 267 | + } |
| 268 | + |
| 269 | +instance Storable Square where |
| 270 | + sizeOf _ = sizeOf (undefined :: V2 CInt) * 2 |
| 271 | + alignment _ = 1 |
| 272 | + poke ptr (Square x y) = do |
| 273 | + poke (castPtr ptr) x |
| 274 | + poke (plusPtr ptr (sizeOf x)) y |
| 275 | + peek ptr = do |
| 276 | + x <- peek (castPtr ptr) |
| 277 | + y <- peek (plusPtr ptr (sizeOf x)) |
| 278 | + pure (Square x y) |
| 279 | + |
| 280 | +-- | Animate a rectangle on the screen for n iterations. |
| 281 | +pollEventAnimRectsTest :: CInt -> IO () |
| 282 | +pollEventAnimRectsTest iters = do |
| 283 | + initializeAll |
| 284 | + window <- |
| 285 | + createWindow |
| 286 | + "pollEventAnimRectsTest" |
| 287 | + defaultWindow {windowInitialSize = defaultWindowSize} |
| 288 | + renderer <- createRenderer window (-1) defaultRenderer |
| 289 | + squares <- |
| 290 | + SV.unsafeThaw |
| 291 | + (SV.fromList |
| 292 | + [ Square (V2 2 1) (V2 0 0) |
| 293 | + , Square (V2 3 2) (V2 300 200) |
| 294 | + , Square (V2 1 1) (V2 100 500) |
| 295 | + , Square (V2 1 1) (V2 400 100) |
| 296 | + , Square (V2 1 2) (V2 200 400) |
| 297 | + , Square (V2 2 1) (V2 250 0) |
| 298 | + , Square (V2 1 2) (V2 300 500) |
| 299 | + , Square (V2 1 2) (V2 230 100) |
| 300 | + , Square (V2 1 1) (V2 200 490) |
| 301 | + ]) |
| 302 | + let go :: CInt -> IO () |
| 303 | + go !0 = pure () |
| 304 | + go !i = do |
| 305 | + _ <- pollEvent |
| 306 | + rendererDrawColor renderer $= V4 40 40 40 255 |
| 307 | + clear renderer |
| 308 | + rendererDrawColor renderer $= V4 255 255 255 255 |
| 309 | + let animateSquare si = do |
| 310 | + Square (V2 xv yv) p@(V2 x y) <- SVM.read squares si |
| 311 | + let xv' |
| 312 | + | x + w > mw = -xv |
| 313 | + | x < 0 = -xv |
| 314 | + | otherwise = xv |
| 315 | + yv' |
| 316 | + | y + h > mh = -yv |
| 317 | + | y < 0 = -yv |
| 318 | + | otherwise = yv |
| 319 | + v' = V2 xv' yv' |
| 320 | + p' = p + v' |
| 321 | + SVM.write squares si (Square v' p') |
| 322 | + fillRect renderer (Just (Rectangle (P p') (V2 w h))) |
| 323 | + let loop 0 = pure () |
| 324 | + loop si = animateSquare si>>loop (si-1) |
| 325 | + loop (SVM.length squares - 1) |
| 326 | + present renderer |
| 327 | + go (i - 1) |
| 328 | + go iters |
| 329 | + where |
| 330 | + defaultWindowSize :: V2 CInt |
| 331 | + defaultWindowSize = V2 800 600 |
| 332 | + mw :: CInt |
| 333 | + mh :: CInt |
| 334 | + V2 mw mh = defaultWindowSize |
| 335 | + w :: CInt |
| 336 | + h :: CInt |
| 337 | + (w, h) = (100, 100) |
0 commit comments