3
3
{-# LANGUAGE GADTs #-}
4
4
module Haskell.Ide.Engine.Dispatcher where
5
5
6
- import Control.Concurrent
6
+ import Control.Concurrent.STM.TChan
7
7
import Control.Monad
8
8
import Control.Monad.IO.Class
9
+ import Control.Monad.STM
9
10
import Data.Aeson
10
11
import Data.Either
11
12
import Data.Monoid
@@ -21,26 +22,35 @@ import qualified Data.Map as Map
21
22
22
23
-- | Listen on a Chan for ChannelRequest from the assorted listeners, and route
23
24
-- them through to the appropriate plugin for processing.
24
- dispatcher :: Chan ChannelRequest -> IdeM ()
25
+ dispatcher :: TChan ChannelRequest -> IdeM ()
25
26
dispatcher cin = do
26
27
plugins <- getPlugins
27
28
forever $ do
28
29
debugm " run:top of loop"
29
- req <- liftIO $ readChan cin
30
+ req <- liftIO $ atomically $ readTChan cin
30
31
debugm $ " main loop:got:" ++ show req
31
- resp <- doDispatch plugins req
32
- let cr = CResp (cinPlugin req) (cinReqId req) resp
33
- liftIO $ writeChan (cinReplyChan req) cr
32
+ mresp <- doDispatch plugins req
33
+ case mresp of
34
+ Nothing -> return ()
35
+ Just resp -> liftIO $ sendResponse req resp
36
+
37
+ -- ---------------------------------------------------------------------
38
+
39
+ -- | Send a response from the plugin to the designated reply channel
40
+ sendResponse :: (ValidResponse a ) => ChannelRequest -> IdeResponse a -> IO ()
41
+ sendResponse req resp = do
42
+ let cr = CResp (cinPlugin req) (cinReqId req) (fmap jsWrite resp)
43
+ liftIO $ atomically $ writeTChan (cinReplyChan req) cr
34
44
35
45
-- ---------------------------------------------------------------------
36
46
37
47
-- | Manage the process of looking up the request in the known plugins,
38
48
-- validating the parameters passed and handing off to the appropriate
39
49
-- 'CommandFunc'
40
- doDispatch :: Plugins -> ChannelRequest -> IdeM (IdeResponse Object )
50
+ doDispatch :: Plugins -> ChannelRequest -> IdeM (Maybe ( IdeResponse Object ) )
41
51
doDispatch plugins creq = do
42
52
case Map. lookup (cinPlugin creq) plugins of
43
- Nothing -> return (IdeResponseError (IdeError
53
+ Nothing -> return $ Just (IdeResponseError (IdeError
44
54
UnknownPlugin (" No plugin found for:" <> cinPlugin creq )
45
55
(Just $ toJSON $ cinPlugin creq)))
46
56
Just desc -> do
@@ -49,13 +59,20 @@ doDispatch plugins creq = do
49
59
debugm $ " doDispatch:desc=" ++ show desc
50
60
debugm $ " doDispatch:req=" ++ show req
51
61
case Map. lookup (pn,ideCommand req) (pluginCache plugins) of
52
- Nothing -> return (IdeResponseError (IdeError
62
+ Nothing -> return $ Just (IdeResponseError (IdeError
53
63
UnknownCommand (" No such command:" <> ideCommand req )
54
64
(Just $ toJSON $ ideCommand req)))
55
- Just (Command cdesc cfunc) ->
65
+ Just (Command cdesc cfunc) -> do
56
66
case validateContexts cdesc req of
57
- Left err -> return err
58
- Right ctxs -> fmap jsWrite <$> cfunc ctxs req
67
+ Left err -> return (Just err)
68
+ Right ctxs -> case cfunc of
69
+ CmdSync f -> do
70
+ r <- f ctxs req
71
+ let r2 = fmap jsWrite r
72
+ return (Just r2)
73
+ CmdAsync f -> do
74
+ f (sendResponse creq) ctxs req
75
+ return Nothing
59
76
60
77
-- ---------------------------------------------------------------------
61
78
0 commit comments