From 7c9877f9070911092f7a1672940e0a89e76b68af Mon Sep 17 00:00:00 2001 From: Jens Nolte <git@queezle.net> Date: Mon, 27 Sep 2021 13:13:14 +0200 Subject: [PATCH] Generate (empty) send functions for all messages --- src/Quasar/Wayland/Protocol/Core.hs | 4 +++ src/Quasar/Wayland/Protocol/TH.hs | 47 +++++++++++++++++++++++------ 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/Quasar/Wayland/Protocol/Core.hs b/src/Quasar/Wayland/Protocol/Core.hs index 839963b..51f7e33 100644 --- a/src/Quasar/Wayland/Protocol/Core.hs +++ b/src/Quasar/Wayland/Protocol/Core.hs @@ -31,6 +31,7 @@ module Quasar.Wayland.Protocol.Core ( -- * Low-level protocol interaction sendMessage, + objectSendMessage, newObject, -- ** WireCallbacks @@ -577,6 +578,9 @@ sendMessage object message = do putWord32host objectIdWord putWord32host $ (fromIntegral msgSize `shiftL` 16) .|. fromIntegral opcode +objectSendMessage :: forall s i. IsInterfaceSide s i => Object s i -> WireUp s i -> STM () +objectSendMessage object@(Object protocol _ _ _ _) message = runProtocolM protocol $ sendMessage object message + receiveMessages :: IsSide s => ProtocolM s () receiveMessages = receiveRawMessage >>= \case diff --git a/src/Quasar/Wayland/Protocol/TH.hs b/src/Quasar/Wayland/Protocol/TH.hs index 8683ec2..ac71b06 100644 --- a/src/Quasar/Wayland/Protocol/TH.hs +++ b/src/Quasar/Wayland/Protocol/TH.hs @@ -112,8 +112,8 @@ interfaceDecs interface = do iName = interfaceN interface iT = interfaceT interface instanceDecs = [ - tySynInstD (tySynEqn Nothing (appT (conT ''Requests) iT) (orVoid (requestsT interface))), - tySynInstD (tySynEqn Nothing (appT (conT ''Events) iT) (orVoid (eventsT interface))), + tySynInstD (tySynEqn Nothing (appT (conT ''Requests) iT) (orUnit (requestsT interface))), + tySynInstD (tySynEqn Nothing (appT (conT ''Events) iT) (orUnit (eventsT interface))), tySynInstD (tySynEqn Nothing (appT (conT ''WireRequest) iT) wireRequestT), tySynInstD (tySynEqn Nothing (appT (conT ''WireEvent) iT) eT), tySynInstD (tySynEqn Nothing (appT (conT ''InterfaceName) iT) (litT (strTyLit interface.name))), @@ -156,6 +156,38 @@ interfaceDecs interface = do eventRecordD :: Q Dec eventRecordD = messageRecordD (eventsName interface) eventContexts + objectName = mkName "object" + objectP = varP objectName + objectE = varE objectName + + interfaceSideInstanceDs :: InterfaceSpec -> Q [Dec] + interfaceSideInstanceDs interface = execWriterT do + tellQ $ instanceD (pure []) ([t|IsInterfaceSide 'Client $iT|]) [createProxyD Client] + tellQ $ instanceD (pure []) ([t|IsInterfaceSide 'Server $iT|]) [createProxyD Server] + where + iT = interfaceT interface + createProxyD :: Side -> Q Dec + createProxyD Client = funD 'createProxy [clause [objectP] (normalB requestsProxyE) (sendMessageProxy <$> requestContexts)] + createProxyD Server = funD 'createProxy [clause [objectP] (normalB eventsProxyE) (sendMessageProxy <$> eventContexts)] + requestsProxyE :: Q Exp + requestsProxyE + | length interface.requests > 0 = recConE (requestsName interface) (sendMessageProxyField <$> requestContexts) + | otherwise = [|()|] + eventsProxyE :: Q Exp + eventsProxyE + | length interface.events > 0 = recConE (eventsName interface) (sendMessageProxyField <$> eventContexts) + | otherwise = [|()|] + + sendMessageProxyField :: MessageContext -> Q (Name, Exp) + sendMessageProxyField msg = (mkName msg.msgSpec.name,) <$> varE (sendMessageFunctionName msg) + + sendMessageFunctionName :: MessageContext -> Name + sendMessageFunctionName msg = mkName $ "send_" <> msg.msgSpec.name + + sendMessageProxy :: MessageContext -> Q Dec + sendMessageProxy msg = funD (sendMessageFunctionName msg) [clause [] (normalB [|undefined|]) []] + + messageRecordD :: Name -> [MessageContext] -> Q Dec messageRecordD name messageContexts = dataD (cxt []) name [] Nothing [con] [] where @@ -169,14 +201,6 @@ messageRecordD name messageContexts = dataD (cxt []) name [] Nothing [con] [] returnType = buildTupleType $ sequence $ catMaybes $ argumentReturnType <$> msg.msgSpec.arguments -interfaceSideInstanceDs :: InterfaceSpec -> Q [Dec] -interfaceSideInstanceDs interface = execWriterT do - tellQ $ instanceD (pure []) ([t|IsInterfaceSide 'Client $iT|]) [createProxyD Client] - tellQ $ instanceD (pure []) ([t|IsInterfaceSide 'Server $iT|]) [createProxyD Server] - where - iT = interfaceT interface - createProxyD :: Side -> Q Dec - createProxyD side = funD 'createProxy [clause [] (normalB [|undefined|]) []] interfaceN :: InterfaceSpec -> Name @@ -200,6 +224,9 @@ eventsT interface = if (length interface.events) > 0 then Just (conT (eventsName orVoid :: Maybe (Q Type) -> Q Type orVoid = fromMaybe [t|Void|] +orUnit :: Maybe (Q Type) -> Q Type +orUnit = fromMaybe [t|()|] + data MessageContext = MessageContext { -- GitLab