@@ -9,13 +9,13 @@ import System.Mem.Weak
99import Data.Foldable
1010import Data.Traversable
1111import Control.Monad hiding (mapM, mapM_, forM_, forM, sequence)
12+import Control.Monad.Identity hiding (mapM, mapM_, forM_, forM, sequence)
1213import Control.Monad.Reader hiding (mapM, mapM_, forM_, forM, sequence)
1314import GHC.Exts
1415import Control.Applicative -- Unconditionally import, because otherwise it breaks on GHC 7.10.1RC2
1516import Data.Dependent.Map (DMap, DSum (..))
1617import qualified Data.Dependent.Map as DMap
1718import Data.GADT.Compare
18−import Data.Functor.Misc
1919import Data.Maybe
2020import Data.IntMap (IntMap)
2121import qualified Data.IntMap as IntMap
@@ -139,7 +139,7 @@ scheduleClear r = EventM $ do
139139 clears <- asks eventEnvClears
140140 liftIO $ modifyIORef' clears (SomeMaybeIORef r :)
141141
142−scheduleRootClear :: IORef (DMap k) -> EventM ()
142+scheduleRootClear :: IORef (DMap k Identity) -> EventM ()
143143scheduleRootClear r = EventM $ do
144144 clears <- asks eventEnvRootClears
145145 liftIO $ modifyIORef' clears (SomeDMapIORef r :)
@@ -223,8 +223,8 @@ data RootSubscribed a
223223 }
224224
225225data Root (k :: * -> *)
226− = Root { rootOccurrence :: !(IORef (DMap k)) -- The currently-firing occurrence of this event
227− , rootSubscribed :: !(IORef (DMap (WrapArg RootSubscribed k)))
226+ = Root { rootOccurrence :: !(IORef (DMap k Identity)) -- The currently-firing occurrence of this event
227+ , rootSubscribed :: !(IORef (DMap k RootSubscribed))
228228 , rootInit :: !(forall a. k a -> RootTrigger a -> IO (IO ()))
229229 }
230230
@@ -251,12 +251,12 @@ data Push a b
251251 }
252252
253253data MergeSubscribed k
254− = MergeSubscribed { mergeSubscribedOccurrence :: !(IORef (Maybe (DMap k)))
255− , mergeSubscribedAccum :: !(IORef (DMap k)) -- This will accumulate occurrences until our height is reached, at which point it will be transferred to mergeSubscribedOccurrence
254+ = MergeSubscribed { mergeSubscribedOccurrence :: !(IORef (Maybe (DMap k Identity)))
255+ , mergeSubscribedAccum :: !(IORef (DMap k Identity)) -- This will accumulate occurrences until our height is reached, at which point it will be transferred to mergeSubscribedOccurrence
256256 , mergeSubscribedHeight :: !(IORef Int)
257− , mergeSubscribedSubscribers :: !(IORef [WeakSubscriber (DMap k)])
257+ , mergeSubscribedSubscribers :: !(IORef [WeakSubscriber (DMap k Identity)])
258258 , mergeSubscribedSelf :: !Any -- Hold all our Subscribers in memory
259− , mergeSubscribedParents :: !(DMap (WrapArg EventSubscribed k))
259+ , mergeSubscribedParents :: !(DMap k EventSubscribed)
260260#ifdef DEBUG_NODEIDS
261261 , mergeSubscribedNodeId :: Int
262262#endif
@@ -264,7 +264,7 @@ data MergeSubscribed k
264264
265265--TODO: DMap sucks; we should really write something better (with a functor for the value as well as the key)
266266data Merge k
267− = Merge { mergeParents :: !(DMap (WrapArg Event k))
267+ = Merge { mergeParents :: !(DMap k Event)
268268 , mergeSubscribed :: !(IORef (Maybe (MergeSubscribed k))) --TODO: Can we replace this with an unsafePerformIO thunk?
269269 }
270270
@@ -283,16 +283,16 @@ instance GCompare k => GCompare (FanSubscriberKey k) where
283283 GGT -> GGT
284284
285285data FanSubscribed k
286− = FanSubscribed { fanSubscribedSubscribers :: !(IORef (DMap (FanSubscriberKey k)))
287− , fanSubscribedParent :: !(EventSubscribed (DMap k))
288− , fanSubscribedSelf :: {-# NOUNPACK #-} (Subscriber (DMap k))
286+ = FanSubscribed { fanSubscribedSubscribers :: !(IORef (DMap (FanSubscriberKey k) Identity))
287+ , fanSubscribedParent :: !(EventSubscribed (DMap k Identity))
288+ , fanSubscribedSelf :: {-# NOUNPACK #-} (Subscriber (DMap k Identity))
289289#ifdef DEBUG_NODEIDS
290290 , fanSubscribedNodeId :: Int
291291#endif
292292 }
293293
294294data Fan k
295− = Fan { fanParent :: !(Event (DMap k))
295+ = Fan { fanParent :: !(Event (DMap k Identity))
296296 , fanSubscribed :: !(IORef (Maybe (FanSubscribed k)))
297297 }
298298
@@ -354,7 +354,7 @@ deRefWeakSubscriber ws = case ws of
354354data Subscriber a
355355 = forall b. SubscriberPush !(a -> EventM (Maybe b)) (PushSubscribed a b)
356356 | forall k. GCompare k => SubscriberMerge !(k a) (MergeSubscribed k) --TODO: Can we inline the GCompare?
357− | forall k. (GCompare k, a ~ DMap k) => SubscriberFan (FanSubscribed k)
357+ | forall k. (GCompare k, a ~ DMap k Identity) => SubscriberFan (FanSubscribed k)
358358 | SubscriberHold !(Hold a)
359359 | SubscriberSwitch (SwitchSubscribed a)
360360 | forall b. a ~ Event b => SubscriberCoincidenceOuter (CoincidenceSubscribed b)
@@ -374,7 +374,7 @@ data Event a
374374 = forall k. GCompare k => EventRoot !(k a) !(Root k)
375375 | EventNever
376376 | forall b. EventPush !(Push b a)
377− | forall k. (GCompare k, a ~ DMap k) => EventMerge !(Merge k)
377+ | forall k. (GCompare k, a ~ DMap k Identity) => EventMerge !(Merge k)
378378 | forall k. GCompare k => EventFan !(k a) !(Fan k)
379379 | EventSwitch !(Switch a)
380380 | EventCoincidence !(Coincidence a)
@@ -393,7 +393,7 @@ data EventSubscribed a
393393 = EventSubscribedRoot {-# NOUNPACK #-} (RootSubscribed a)
394394 | EventSubscribedNever
395395 | forall b. EventSubscribedPush !(PushSubscribed b a)
396− | forall k. (GCompare k, a ~ DMap k) => EventSubscribedMerge !(MergeSubscribed k)
396+ | forall k. (GCompare k, a ~ DMap k Identity) => EventSubscribedMerge !(MergeSubscribed k)
397397 | forall k. GCompare k => EventSubscribedFan !(k a) !(FanSubscribed k)
398398 | EventSubscribedSwitch !(SwitchSubscribed a)
399399 | EventSubscribedCoincidence !(CoincidenceSubscribed a)
@@ -424,7 +424,7 @@ newSubscriberHold :: Hold a -> IO (Subscriber a)
424424newSubscriberHold h = return $! SubscriberHold h
425425
426426{-# NOINLINE newSubscriberFan #-}
427−newSubscriberFan :: GCompare k => FanSubscribed k -> IO (Subscriber (DMap k))
427+newSubscriberFan :: GCompare k => FanSubscribed k -> IO (Subscriber (DMap k Identity))
428428newSubscriberFan subd = return $! SubscriberFan subd
429429
430430{-# NOINLINE newSubscriberSwitch #-}
@@ -519,7 +519,7 @@ propagateAndUpdateSubscribersRef subscribersRef a = do
519519 liftIO $ modifyIORef' subscribersRef (++stillAlive)
520520
521521-- Propagate the given event occurrence; before cleaning up, run the given action, which may read the state of events and behaviors
522−run :: [DSum RootTrigger] -> ResultM b -> IO b
522+run :: [DSum RootTrigger Identity] -> ResultM b -> IO b
523523run roots after = do
524524 when debugPropagate $ putStrLn "Running an event frame"
525525 result <- runFrame $ do
@@ -532,7 +532,7 @@ run roots after = do
532532 then do scheduleRootClear occRef
533533 return $ Just r
534534 else return Nothing
535− forM_ (catMaybes rootsToPropagate) $ \(RootTrigger (subscribersRef, _, _) :=> a) -> do
535+ forM_ (catMaybes rootsToPropagate) $ \(RootTrigger (subscribersRef, _, _) :=> Identity a) -> do
536536 propagateAndUpdateSubscribersRef subscribersRef a
537537 delayedRef <- EventM $ asks eventEnvDelayedMerges
538538 let go = do
@@ -565,7 +565,7 @@ run roots after = do
565565
566566data SomeMaybeIORef = forall a. SomeMaybeIORef (IORef (Maybe a))
567567
568−data SomeDMapIORef = forall k. SomeDMapIORef (IORef (DMap k))
568+data SomeDMapIORef = forall k. SomeDMapIORef (IORef (DMap k Identity))
569569
570570data SomeAssignment = forall a. SomeAssignment (Hold a) a
571571
@@ -611,7 +611,7 @@ propagate a subscribers = do
611611 SubscriberMerge k subscribed -> do
612612 when debugPropagate $ liftIO $ putStrLn $ "SubscriberMerge" <> showNodeId subscribed
613613 oldM <- liftIO $ readIORef $ mergeSubscribedAccum subscribed
614− liftIO $ writeIORef (mergeSubscribedAccum subscribed) $ DMap.insertWith (error "Same key fired multiple times for") k a oldM
614+ liftIO $ writeIORef (mergeSubscribedAccum subscribed) $ DMap.insertWith (error "Same key fired multiple times for") k (Identity a) oldM
615615 when (DMap.null oldM) $ do -- Only schedule the firing once
616616 height <- liftIO $ readIORef $ mergeSubscribedHeight subscribed
617617 --TODO: assertions about height
@@ -622,17 +622,19 @@ propagate a subscribers = do
622622 subs <- liftIO $ readIORef $ fanSubscribedSubscribers subscribed
623623 when debugPropagate $ liftIO $ putStrLn $ "SubscriberFan" <> showNodeId subscribed <> ": " ++ show (DMap.size subs) ++ " keys subscribed, " ++ show (DMap.size a) ++ " keys firing"
624624 --TODO: We need a better DMap intersection; here, we are assuming that the number of firing keys is small and the number of subscribers is large
625− forM_ (DMap.toList a) $ \(k :=> v) -> case DMap.lookup (FanSubscriberKey k) subs of
625+ forM_ (DMap.toList a) $ \(k :=> Identity v) -> case DMap.lookup (FanSubscriberKey k) subs of
626626 Nothing -> do
627627 when debugPropagate $ liftIO $ putStrLn "No subscriber for key"
628628 return ()
629− Just subsubs -> do
629+ Just (Identity subsubs) -> do
630630 _ <- propagate v subsubs --TODO: use the value of this
631631 return ()
632632 --TODO: The following is way too slow to do all the time
633− subs' <- liftIO $ forM (DMap.toList subs) $ ((\(FanSubscriberKey k :=> subsubs) -> do
633+ subs' <- liftIO $ forM (DMap.toList subs) $ ((\(FanSubscriberKey k :=> Identity subsubs) -> do
634634 subsubs' <- traverseAndCleanWeakList_ (liftIO . deRefWeakSubscriber) subsubs (const $ return ())
635− return $ if null subsubs' then Nothing else Just $ FanSubscriberKey k :=> subsubs') :: DSum (FanSubscriberKey k) -> IO (Maybe (DSum (FanSubscriberKey k))))
635+ return $ if null subsubs'
636+ then Nothing
637+ else Just $ FanSubscriberKey k :=> Identity subsubs') :: DSum (FanSubscriberKey k) Identity -> IO (Maybe (DSum (FanSubscriberKey k) Identity)))
636638 liftIO $ writeIORef (fanSubscribedSubscribers subscribed) $ DMap.fromDistinctAscList $ catMaybes subs'
637639 SubscriberHold h -> do
638640 invalidators <- liftIO $ readIORef $ holdInvalidators h
@@ -731,7 +733,7 @@ readBehaviorTracked b = case b of
731733
732734readEvent :: Event a -> ResultM (Maybe a)
733735readEvent e = case e of
734− EventRoot k r -> liftIO $ liftM (DMap.lookup k) $ readIORef $ rootOccurrence r
736+ EventRoot k r -> liftIO . liftM (fmap runIdentity . DMap.lookup k) . readIORef $ rootOccurrence r
735737 EventNever -> return Nothing
736738 EventPush p -> do
737739 subscribed <- getPushSubscribed p
@@ -747,7 +749,7 @@ readEvent e = case e of
747749 return result
748750 EventFan k f -> do
749751 parentOcc <- readEvent $ fanParent f
750− return $ DMap.lookup k =<< parentOcc
752+ return . fmap runIdentity $ DMap.lookup k =<< parentOcc
751753 EventSwitch s -> do
752754 subscribed <- getSwitchSubscribed s
753755 liftIO $ do
@@ -794,7 +796,7 @@ subscribeEventSubscribed es ws = case es of
794796 modifyIORef' (pushSubscribedSubscribers subscribed) (ws:)
795797 EventSubscribedFan k subscribed -> do
796798 when debugSubscribe $ liftIO $ putStrLn $ "subscribeEventSubscribed Fan"
797− modifyIORef' (fanSubscribedSubscribers subscribed) $ DMap.insertWith (++) (FanSubscriberKey k) [ws]
799+ modifyIORef' (fanSubscribedSubscribers subscribed) $ DMap.insertWith (liftA2 (++)) (FanSubscriberKey k) (Identity [ws])
798800 EventSubscribedMerge subscribed -> do
799801 when debugSubscribe $ liftIO $ putStrLn $ "subscribeEventSubscribed Merge"
800802 modifyIORef' (mergeSubscribedSubscribers subscribed) (ws:)
@@ -812,7 +814,7 @@ getEventSubscribedOcc es = case es of
812814 EventSubscribedPush subscribed -> readIORef $ pushSubscribedOccurrence subscribed
813815 EventSubscribedFan k subscribed -> do
814816 parentOcc <- getEventSubscribedOcc $ fanSubscribedParent subscribed
815− let occ = DMap.lookup k =<< parentOcc
817+ let occ = fmap runIdentity $ DMap.lookup k =<< parentOcc
816818 return occ
817819 EventSubscribedMerge subscribed -> readIORef $ mergeSubscribedOccurrence subscribed
818820 EventSubscribedSwitch subscribed -> readIORef $ switchSubscribedOccurrence subscribed
@@ -841,18 +843,18 @@ noinlineFalse = False
841843getRootSubscribed :: GCompare k => k a -> Root k -> EventM (RootSubscribed a)
842844getRootSubscribed k r = do
843845 mSubscribed <- liftIO $ readIORef $ rootSubscribed r
844− case DMap.lookup (WrapArg k) mSubscribed of
846+ case DMap.lookup k mSubscribed of
845847 Just subscribed -> return subscribed
846848 Nothing -> liftIO $ do
847849 subscribersRef <- newIORef []
848− subscribed <- newRootSubscribed (liftM (DMap.lookup k) $ readIORef $ rootOccurrence r) subscribersRef
850+ subscribed <- newRootSubscribed (liftM (fmap runIdentity . DMap.lookup k) $ readIORef $ rootOccurrence r) subscribersRef
849851 -- Strangely, init needs the same stuff as a RootSubscribed has, but it must not be the same as the one that everyone's subscribing to, or it'll leak memory
850852 uninit <- rootInit r k $ RootTrigger (subscribersRef, rootOccurrence r, k)
851853 addFinalizer subscribed $ do
852854 when noinlineFalse $ putStr "" -- For some reason, without this line, the finalizer will run earlier than it should
853855-- putStrLn "Uninit root"
854856 uninit
855− liftIO $ modifyIORef' (rootSubscribed r) $ DMap.insert (WrapArg k) subscribed
857+ liftIO $ modifyIORef' (rootSubscribed r) $ DMap.insert k subscribed
856858 return subscribed
857859
858860-- When getPushSubscribed returns, the PushSubscribed returned will have a fully filled-in
@@ -894,11 +896,11 @@ getMergeSubscribed m = {-# SCC "getMergeSubscribed.entire" #-} do
894896 subscribedUnsafe <- liftIO $ unsafeInterleaveIO $ readIORef subscribedRef
895897 s <- liftIO $ newBox subscribedUnsafe
896898 ws <- liftIO $ mkWeakPtrWithDebug s "SubscriberMerge"
897− subscribers :: [(Any, Maybe (DSum k), Int, DSum (WrapArg EventSubscribed k))] <- forM (DMap.toList $ mergeParents m) $ {-# SCC "getMergeSubscribed.a" #-} \(WrapArg k :=> e) -> {-# SCC "getMergeSubscribed.a1" #-} do
899+ subscribers :: [(Any, Maybe (DSum k Identity), Int, DSum k EventSubscribed)] <- forM (DMap.toList $ mergeParents m) $ {-# SCC "getMergeSubscribed.a" #-} \(k :=> e) -> {-# SCC "getMergeSubscribed.a1" #-} do
898900 parentSubd <- {-# SCC "getMergeSubscribed.a.parentSubd" #-} subscribe e $ WeakSubscriberMerge k ws
899901 parentOcc <- {-# SCC "getMergeSubscribed.a.parentOcc" #-} liftIO $ getEventSubscribedOcc parentSubd
900902 height <- {-# SCC "getMergeSubscribed.a.height" #-} liftIO $ readIORef $ eventSubscribedHeightRef parentSubd
901− return $ {-# SCC "getMergeSubscribed.a.returnVal" #-} (unsafeCoerce s :: Any, fmap (k :=>) parentOcc, height, WrapArg k :=> parentSubd)
903+ return $ {-# SCC "getMergeSubscribed.a.returnVal" #-} (unsafeCoerce s :: Any, fmap ((k :=>) . Identity) parentOcc, height, k :=> parentSubd)
902904 let dm = DMap.fromDistinctAscList $ catMaybes $ map (\(_, x, _, _) -> x) subscribers
903905 subscriberHeights = map (\(_, _, x, _) -> x) subscribers
904906 myHeight =
@@ -1048,7 +1050,7 @@ getCoincidenceSubscribed c = do
10481050 liftIO $ writeIORef (coincidenceSubscribed c) $ Just subscribed
10491051 return subscribed
10501052
1051−merge :: GCompare k => DMap (WrapArg Event k) -> Event (DMap k)
1053+merge :: GCompare k => DMap k Event -> Event (DMap k Identity)
10521054merge m = EventMerge $ Merge
10531055 { mergeParents = m
10541056 , mergeSubscribed = unsafeNewIORef m Nothing
@@ -1056,7 +1058,7 @@ merge m = EventMerge $ Merge
10561058
10571059newtype EventSelector k = EventSelector { select :: forall a. k a -> Event a }
10581060
1059−fan :: GCompare k => Event (DMap k) -> EventSelector k
1061+fan :: GCompare k => Event (DMap k Identity) -> EventSelector k
10601062fan e =
10611063 let f = Fan
10621064 { fanParent = e
@@ -1154,7 +1156,7 @@ invalidateSubscriberHeight ws = do
11541156 SubscriberFan subscribed -> do
11551157 when debugInvalidateHeight $ putStrLn $ "invalidateSubscriberHeight: SubscriberFan" <> showNodeId subscribed
11561158 subscribers <- readIORef $ fanSubscribedSubscribers subscribed
1157− forM_ (DMap.toList subscribers) $ ((\(FanSubscriberKey _ :=> v) -> mapM_ invalidateSubscriberHeight v) :: DSum (FanSubscriberKey k) -> IO ())
1159+ forM_ (DMap.toList subscribers) $ ((\(FanSubscriberKey _ :=> Identity v) -> mapM_ invalidateSubscriberHeight v) :: DSum (FanSubscriberKey k) Identity -> IO ())
11581160 when debugInvalidateHeight $ putStrLn $ "invalidateSubscriberHeight: SubscriberFan" <> showNodeId subscribed <> " done"
11591161 SubscriberHold _ -> return ()
11601162 SubscriberSwitch subscribed -> do
@@ -1205,7 +1207,7 @@ recalculateSubscriberHeight ws = do
12051207 SubscriberFan subscribed -> do
12061208 when debugInvalidateHeight $ putStrLn $ "recalculateSubscriberHeight: SubscriberFan" <> showNodeId subscribed
12071209 subscribers <- readIORef $ fanSubscribedSubscribers subscribed
1208− forM_ (DMap.toList subscribers) $ ((\(FanSubscriberKey _ :=> v) -> mapM_ recalculateSubscriberHeight v) :: DSum (FanSubscriberKey k) -> IO ())
1210+ forM_ (DMap.toList subscribers) $ ((\(FanSubscriberKey _ :=> Identity v) -> mapM_ recalculateSubscriberHeight v) :: DSum (FanSubscriberKey k) Identity -> IO ())
12091211 when debugInvalidateHeight $ putStrLn $ "recalculateSubscriberHeight: SubscriberFan" <> showNodeId subscribed <> " done"
12101212 SubscriberHold _ -> return ()
12111213 SubscriberSwitch subscribed -> do
@@ -1237,7 +1239,7 @@ recalculateCoincidenceHeight subscribed = do
12371239
12381240calculateMergeHeight :: MergeSubscribed k -> IO Int
12391241calculateMergeHeight subscribed = if DMap.null (mergeSubscribedParents subscribed) then return 0 else do
1240− heights <- forM (DMap.toList $ mergeSubscribedParents subscribed) $ \(WrapArg _ :=> es) -> do
1242+ heights <- forM (DMap.toList $ mergeSubscribedParents subscribed) $ \(_ :=> es) -> do
12411243 readIORef $ eventSubscribedHeightRef es
12421244 return $ if any (== invalidHeight) heights then invalidHeight else succ $ Prelude.maximum heights --TODO: Replace 'any' with invalidHeight-preserving 'maximum'
12431245
@@ -1316,7 +1318,7 @@ instance R.Reflex Spider where
13161318 constant = SpiderBehavior . BehaviorConst
13171319 push f = SpiderEvent. push f . unSpiderEvent
13181320 pull = SpiderBehavior . pull
1319− merge = SpiderEvent . merge . (unsafeCoerce :: DMap (WrapArg (R.Event Spider) k) -> DMap (WrapArg Event k))
1321+ merge = SpiderEvent . merge . (unsafeCoerce :: DMap k (R.Event Spider) -> DMap k Event)
13201322 fan e = R.EventSelector $ SpiderEvent . select (fan (unSpiderEvent e))
13211323 switch = SpiderEvent . switch . (unsafeCoerce :: Behavior (R.Event Spider a) -> Behavior (Event a)) . unSpiderBehavior
13221324 coincidence = SpiderEvent . coincidence . (unsafeCoerce :: Event (R.Event Spider a) -> Event (Event a)) . unSpiderEvent
@@ -1340,7 +1342,7 @@ instance R.MonadHold Spider EventM where
13401342 {-# INLINE hold #-}
13411343 hold v0 e = SpiderBehavior <$> hold v0 (unSpiderEvent e)
13421344
1343−data RootTrigger a = forall k. GCompare k => RootTrigger (IORef [WeakSubscriber a], IORef (DMap k), k a)
1345+data RootTrigger a = forall k. GCompare k => RootTrigger (IORef [WeakSubscriber a], IORef (DMap k Identity), k a)
13441346newtype SpiderEventHandle a = SpiderEventHandle { unEventHandle :: Event a }
13451347
13461348instance R.MonadSubscribeEvent Spider SpiderHostFrame where