module Main where import Control.Event import Control.Concurrent (threadDelay) import Control.Concurrent.STM import System.Time secDelay :: Integer secDelay = 5 waitForEvents :: Int waitForEvents = 7 tol :: Int tol = 2 -- seconds main = do -- runTest "testOneEvent" testOneEvent -- runTest "testManyEvents 50" (testManyEvents 50) -- runTest "testDeletingEvents 50" (testDeletingEvents 50) -- runTest "testOnTime [8,1]" (testOnTime [8,1]) runTest "testOnTime [8,4,2]" (testOnTime [8,4,2]) -- runTest "testOnTime [2,4,8]" (testOnTime [2,4,8]) -- runTest "testOnTime [1,1,1,1...]" (testOnTime (take 20 (repeat 1))) runTest :: String -> (IO Bool) -> IO () runTest label test = do putStrLn $ "Running test '" ++ label ++ "'" res <- test putStrLn $ "Test completed: " ++ (show res) testOneEvent :: IO Bool testOneEvent = do tv <- newTVarIO False sys <- initEventSystem (TOD sec picosec) <- getClockTime let clk = TOD (sec + secDelay) picosec addEvent sys clk (atomically (writeTVar tv True)) threadDelay $ waitForEvents * 10^6 atomically (readTVar tv >>= return) testManyEvents :: Int -> IO Bool testManyEvents nrEvts = do tv <- newTVarIO nrEvts sys <- initEventSystem (TOD sec picosec) <- getClockTime let clks = map (\_ -> TOD (sec + secDelay) picosec) [1..nrEvts] mapM_ (\clk -> addEvent sys clk (atomically (readTVar tv >>= \x ->writeTVar tv (x - 1)))) clks threadDelay $ waitForEvents*10^6 atomically (readTVar tv >>= return . (==0)) testDeletingEvents :: Int -> IO Bool testDeletingEvents nrEvents = do tv <- newTVarIO nrEvents sys <- initEventSystem (TOD sec picosec) <- getClockTime let clks = map (\_ -> TOD (sec + secDelay) picosec) [1..nrEvents] ids <- mapM (\clk -> addEvent sys clk (atomically (readTVar tv >>= \x ->writeTVar tv (x - 1)))) clks mapM_ (cancelEvent sys) ids threadDelay $ waitForEvents*10^6 atomically (readTVar tv >>= return . (==nrEvents)) testOnTime :: [Integer] -> IO Bool testOnTime delays = do tv <- newTVarIO (length delays) sys <- initEventSystem -- atomically (setEventPreprocessing sys neverForkEvents) (TOD sec picosec) <- getClockTime let clks = map (\d -> TOD (sec + d) picosec) delays mapM_ (\clk -> addEvent sys clk (theTimeIsNow clk tv)) clks threadDelay $ fromIntegral $ (maximum delays + fromIntegral tol)*10^6 atomically (readTVar tv >>= return . (==length delays)) theTimeIsNow :: ClockTime -> TVar Int -> IO () theTimeIsNow clk tv = do now <- getClockTime let (TimeDiff _ _ _ _ _ sec _) = diffClockTimes now clk if sec > tol then do putStrLn ("Time error of " ++ (show sec) ++ " seconds") atomically (readTVar tv >>= \x -> writeTVar tv (x-1)) else return ()