@@ -18,58 +18,65 @@ import HSTorChat.Protocol
1818data UI = UI
1919 { _myonion :: Onion
2020 , _mystatus :: BuddyStatus
21- , _buddies :: MVar [Buddy ]
21+ , _buddies :: MVar [ObjRef Buddy ]
2222 , _pending :: MVar [PendingConnection ]
2323 } deriving Typeable
2424
2525-- Signals
2626data ChatMsgReady deriving Typeable
27+ data BuddiesChanged deriving Typeable
2728
2829instance DefaultClass UI where
2930 classMembers = [
31+ defPropertySigRO " buddies" (Proxy :: Proxy BuddiesChanged )
32+ (readMVar . _buddies . fromObjRef :: ObjRef UI -> IO [ObjRef Buddy ])
3033 -- | Return Onion address for this instance of HSTorChat.
31- defMethod " onion" (return . _myonion . fromObjRef :: ObjRef UI -> IO Onion )
34+ , defMethod " onion" (return . _myonion . fromObjRef :: ObjRef UI -> IO Onion )
3235 -- | Send a message to a buddy.
3336 , defMethod " sendMsg" sendMsg
3437 -- | Add a new buddy.
3538 , defMethod " newBuddy" newBuddy
36- -- | Access the context object (ObjRef UI) in qml callbacks.
37- , defPropertyRO " self" (return :: ObjRef UI -> IO (ObjRef UI ))
38- -- | Called when a new message arrives from a buddy.
39- , defSignal " msgReady" (Proxy :: Proxy ChatMsgReady )
4039 ]
4140
4241instance DefaultClass ChatMsg where
4342 classMembers = [
4443 defPropertyRO " buddy" (return . T. pack . buddy . fromObjRef)
4544 , defPropertyRO " text" (return . T. pack . text . fromObjRef)
45+ , defPropertyRO " fromme" (return . fromme . fromObjRef)
46+ ]
47+
48+ instance DefaultClass Buddy where
49+ classMembers = [
50+ defPropertyRO " onion" (return . T. pack . _onion . fromObjRef)
51+ , defPropertyRO " status" (return . T. pack . show . _status . fromObjRef)
52+ , defPropertySigRO " msgs" (Proxy :: Proxy ChatMsgReady )
53+ (readMVar . _msgs . fromObjRef :: ObjRef Buddy -> IO [ObjRef ChatMsg ])
4654 ]
4755
4856instance Marshal ChatMsg where
4957 type MarshalMode ChatMsg c d = ModeObjFrom ChatMsg c
5058 marshaller = fromMarshaller fromObjRef
5159
60+ instance Marshal Buddy where
61+ type MarshalMode Buddy c d = ModeObjFrom Buddy c
62+ marshaller = fromMarshaller fromObjRef
63+
5264instance SignalKeyClass ChatMsgReady where
53- type SignalParams ChatMsgReady = ObjRef ChatMsg -> IO ()
65+ type SignalParams ChatMsgReady = IO ()
66+
67+ instance SignalKeyClass BuddiesChanged where
68+ type SignalParams BuddiesChanged = IO ()
5469
5570-- | This method is called when the user enters
5671-- a msg in a chat window. The handle for the buddy
5772-- is accessed and used to send the message.
58- --
59- -- TODO: Pass Buddy instead of Text -> Text
60- sendMsg :: ObjRef UI -> T. Text -> T. Text -> IO ()
61- sendMsg ui onion msg = do
62- let ui' = fromObjRef ui
63- buds <- readMVar $ _buddies ui'
64- sendMsgTo buds
73+ sendMsg :: ObjRef UI -> ObjRef Buddy -> T. Text -> IO ()
74+ sendMsg _ bud msg = do saveMsg $ ChatMsg (T. unpack msg) (_onion $ fromObjRef bud) True
75+ fireSignal (Proxy :: Proxy ChatMsgReady ) bud
76+ hPutStrLn (_outConn $ fromObjRef bud) $ formatMsg $ Message msg
6577 where
66- sendMsgTo [] = putStrLn " Unable to send message. No buddies."
67- sendMsgTo buds = do
68- -- Filter proper buddy from list.
69- let thebuddy = head $ filter (\ b -> _onion b == T. unpack onion) buds
70-
71- -- | TODO: Reschedule if send is not succesful.
72- hPutStrLn (_outConn thebuddy) $ formatMsg $ Message msg
78+ saveMsg cmsg = modifyMVar_ (_msgs $ fromObjRef bud) (\ ms -> do m <- newObjectDC cmsg
79+ return (m: ms))
7380
7481newBuddy :: ObjRef UI -> T. Text -> IO ()
7582newBuddy ui onion = do
@@ -110,7 +117,7 @@ handleRequest ui iHdl = do
110117 b' <- readMVar (_buddies ui')
111118 -- Send Ping if this Buddy is new or Offline.
112119 when ((not $ any ((== key) . _pcookie) p') &&
113- (not $ any ((/= Offline ) . _status) b' )
120+ (not $ any ((/= Offline ) . _status) ( map fromObjRef b') )
114121 ) $ hPutStrLn oHdl $ formatMsg $ Ping (_myonion ui') cky
115122
116123 mapM_ (hPutStrLn oHdl . formatMsg) [ Pong key
@@ -140,25 +147,22 @@ handleRequest ui iHdl = do
140147 -- | A pending connection exists. Verify and start the buddy
141148 pendingConnection (PendingConnection cke o oHdl: pcs) = do
142149
143- let b = Buddy (T. unpack o) iHdl oHdl cke Available
144- ui' = fromObjRef ui
150+ ms <- newMVar []
151+ b <- newObjectDC $ Buddy (T. unpack o) iHdl oHdl cke Available ms
152+ let ui' = fromObjRef ui
145153
146154 modifyMVar_ (_buddies ui') (\ bs -> return (b: bs))
147- -- effectively, remove this pending connection from
148- -- _pending.
149- modifyMVar_ (_pending ui') (\ _ -> return pcs)
150-
151- -- A new Buddy has been identified.
152- m <- newObjectDC $ ChatMsg (" A connection to " ++ T. unpack o ++ " has been established." ) $ T. unpack o
153-
154- -- TODO: Emit the `ProtocolMsg Message` constructor directly.
155- -- Remove the Msg class and modify MsgReady sig.
156- fireSignal (Proxy :: Proxy ChatMsgReady ) ui m
155+ fireSignal (Proxy :: Proxy BuddiesChanged ) ui
157156
157+ -- remove the pending connection.
158+ modifyMVar_ (_pending ui') (\ _ -> return pcs)
158159 runBuddy ui b
159160
160- runBuddy :: ObjRef UI -> Buddy -> IO ()
161- runBuddy ui (Buddy onion iHdl oHdl cky st) = do
161+ runBuddy :: ObjRef UI -> ObjRef Buddy -> IO ()
162+ runBuddy ui objb = do
163+ let b = fromObjRef objb
164+ iHdl = _inConn b
165+ oHdl = _outConn b
162166
163167 txt <- hGetLine iHdl
164168 rdy <- hReady oHdl
@@ -176,12 +180,12 @@ runBuddy ui (Buddy onion iHdl oHdl cky st) = do
176180 , Status Available
177181 ]
178182 Right (Message msg) -> do
179- -- TODO: Emit the `ProtocolMsg Message` directly.
180- m <- newObjectDC $ ChatMsg ( T. unpack msg) onion
181- fireSignal (Proxy :: Proxy ChatMsgReady ) ui m
183+ cmsg <- newObjectDC $ ChatMsg ( T. unpack msg) (_onion b) False
184+ modifyMVar_ (_msgs b) ( \ ms -> return (cmsg : ms))
185+ fireSignal (Proxy :: Proxy ChatMsgReady ) objb
182186
183187 Right p -> print p
184188
185189 hFlush iHdl
186190 hFlush oHdl
187- runBuddy ui $ Buddy onion iHdl oHdl cky st
191+ runBuddy ui objb
0 commit comments