calamity 0.1.6.2 → 0.1.7.0
raw patch · 9 files changed
+110/−36 lines, 9 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Calamity.Client.Client: Client :: TVar [(InChan ControlMessage, Async (Maybe ()))] -> MVar Int -> Token -> RateLimitState -> InChan CalamityEvent -> OutChan CalamityEvent -> Client
- Calamity.Client.Client: [$sel:eventsIn:Client] :: Client -> InChan CalamityEvent
- Calamity.Client.Client: [$sel:eventsOut:Client] :: Client -> OutChan CalamityEvent
- Calamity.Client.Client: [$sel:numShards:Client] :: Client -> MVar Int
- Calamity.Client.Client: [$sel:rlState:Client] :: Client -> RateLimitState
- Calamity.Client.Client: [$sel:shards:Client] :: Client -> TVar [(InChan ControlMessage, Async (Maybe ()))]
- Calamity.Client.Client: [$sel:token:Client] :: Client -> Token
- Calamity.Client.Client: data Client
- Calamity.Client.Types: EH :: ((Semigroup (EHStorageType t), Monoid (EHStorageType t)) => EHStorageType t) -> EventHandler t
- Calamity.Client.Types: [$sel:unwrapEventHandler:EH] :: EventHandler t -> (Semigroup (EHStorageType t), Monoid (EHStorageType t)) => EHStorageType t
- Calamity.Client.Types: class GetEventHandlers a m
- Calamity.Client.Types: newtype EventHandler t
- Calamity.LogEff: type LogC r = Member LogEff r
- Calamity.LogEff: type LogEff = Di Level Path Message
+ Calamity.Types.LogEff: type LogC r = Member LogEff r
+ Calamity.Types.LogEff: type LogEff = Di Level Path Message
- Calamity.Client.Client: react :: forall s r. (BotC r, InsertEventHandler s (Sem r)) => EHType s (Sem r) -> Sem r ()
+ Calamity.Client.Client: react :: forall (s :: EventType) r. (BotC r, InsertEventHandler s (Sem r)) => EHType s (Sem r) -> Sem r ()
Files
- calamity.cabal +3/−3
- src/Calamity/Client/Client.hs +62/−6
- src/Calamity/Client/Types.hs +10/−5
- src/Calamity/Gateway/Shard.hs +5/−4
- src/Calamity/Gateway/Types.hs +1/−1
- src/Calamity/Internal/Utils.hs +1/−1
- src/Calamity/LogEff.hs +0/−16
- src/Calamity/Types/LogEff.hs +16/−0
- src/Calamity/Types/Tellable.hs +12/−0
calamity.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 508df452f0143768a08aa0154d0b2fdb542f78f4238b4e028793ba91a6865923+-- hash: 0b61f91df75a0a06757763a207ce83d2a9597c059dadd7798a155ace29013568 name: calamity-version: 0.1.6.2+version: 0.1.7.0 synopsis: A library for writing discord bots description: Please see the README on GitHub at <https://github.com/nitros12/calamity#readme> category: Network, Web@@ -63,11 +63,11 @@ Calamity.Internal.SnowflakeMap Calamity.Internal.Updateable Calamity.Internal.Utils- Calamity.LogEff Calamity.Metrics.Eff Calamity.Metrics.Internal Calamity.Metrics.Noop Calamity.Types+ Calamity.Types.LogEff Calamity.Types.Model Calamity.Types.Model.Channel Calamity.Types.Model.Channel.Attachment
src/Calamity/Client/Client.hs view
@@ -2,14 +2,13 @@ -- | The client module Calamity.Client.Client- ( Client(..)- , CalamityEvent(Dispatch, ShutDown)- , react+ ( react , runBotIO , stopBot , sendPresence , events , fire+ , CalamityEvent(Dispatch, ShutDown) , customEvt ) where import Calamity.Cache.Eff@@ -77,6 +76,10 @@ inc outc +-- | Create a bot, run your setup action, and then loop until the bot closes.+--+-- This method has a 'P.Fail' effect to handle fatal errors that happen during+-- setup (bad token, etc). runBotIO :: (P.Members '[P.Embed IO, P.Final IO, P.Fail, CacheEff, MetricEff] r, Typeable r) => Token -> SetupEff r -> P.Sem r () runBotIO token setup = do client <- P.embed $ newClient token@@ -87,30 +90,83 @@ Di.push "calamity-loop" clientLoop Di.push "calamity-stop" finishUp -react :: forall s r. (BotC r, InsertEventHandler s (P.Sem r)) => EHType s (P.Sem r) -> P.Sem r ()+-- | Register an event handler.+--+-- Refer to 'EventType' for what events you can register, and 'EHType' for the+-- parameters the event handlers they receive.+--+-- You'll probably want @TypeApplications@ and need @DataKinds@ enabled to+-- specify the type of @s@.+--+-- ==== Examples+--+-- Reacting to every message:+--+-- @+-- 'react' @\''MessageCreateEvt' '$' \msg -> 'print' '$' "Got message: " '<>' 'show' msg+-- @+--+-- Reacting to a custom event:+--+-- @+-- 'react' @(\''CustomEvt' "my-event" ('Data.Text.Text', 'Message')) $ \(s, m) ->+-- 'void' $ 'Calamity.Tellable.tell' @'Data.Text.Text' m ("Somebody told me to tell you about: " '<>' s)+-- @+--+-- ==== Notes+--+-- This function is pretty bad for giving nasty type errors,+-- since if something doesn't match then 'EHType' might not get substituted,+-- which will result in errors about parameter counts mismatching.+react :: forall (s :: EventType) r. (BotC r, InsertEventHandler s (P.Sem r)) => EHType s (P.Sem r) -> P.Sem r () react handler = let handlers = makeEventHandlers (Proxy @s) (Proxy @(P.Sem r)) handler in P.atomicModify (handlers <>) +-- | Fire an event that the bot will then handle.+--+-- ==== Examples+--+-- Firing an event named \"my-event\":+--+-- @+-- 'fire' '$' 'customEvt' @"my-event" ("aha" :: 'Data.Text.Text', msg)+-- @ fire :: BotC r => CalamityEvent -> P.Sem r () fire e = do inc <- P.asks (^. #eventsIn) P.embed $ writeChan inc e -- | Build a Custom CalamityEvent+--+-- You'll probably want @TypeApplications@ to specify the type of @s@.+--+-- The types of @s@ and @a@ must match up with the event handler you want to+-- receive it.+--+-- ==== Examples+--+-- Building an event named \"my-event\":+--+-- @+-- 'customEvt' @"my-event" ("aha" :: 'Data.Text.Text', msg)+-- @ customEvt :: forall s a. (Typeable s, Typeable a) => a -> CalamityEvent customEvt x = Custom (typeRep $ Proxy @s) (toDyn x) +-- | Get a copy of the event stream. events :: BotC r => P.Sem r (OutChan CalamityEvent) events = do inc <- P.asks (^. #eventsIn) P.embed $ dupChan inc +-- | Set the bot's presence on all shards. sendPresence :: BotC r => StatusUpdateData -> P.Sem r () sendPresence s = do shards <- P.asks (^. #shards) >>= P.embed . readTVarIO for_ shards $ \(inc, _) -> P.embed $ writeChan inc (SendPresence s) +-- | Initiate shutting down the bot. stopBot :: BotC r => P.Sem r () stopBot = do debug "stopping bot"@@ -127,8 +183,8 @@ for_ shards $ \(_, shardThread) -> P.await shardThread debug "bot has stopped" --- | main loop of the client, handles fetching the next event, processing the event--- and invoking it's handler functions+-- | main loop of the client, handles fetching the next event, processing the+-- event and invoking it's handler functions clientLoop :: BotC r => P.Sem r () clientLoop = do outc <- P.asks (^. #eventsOut)
src/Calamity/Client/Types.hs view
@@ -1,22 +1,21 @@ -- | Types for the client module Calamity.Client.Types ( Client(..)+ , EventType(..)+ , EHType , BotC , SetupEff- , EHType , EventHandlers(..)- , EventHandler(..) , InsertEventHandler(..)- , GetEventHandlers(..)- , EventType(..)+ , getEventHandlers , getCustomEventHandlers ) where import Calamity.Cache.Eff import Calamity.Gateway.DispatchEvents ( CalamityEvent(..), ReadyData ) import Calamity.Gateway.Types ( ControlMessage ) import Calamity.HTTP.Internal.Types-import Calamity.LogEff import Calamity.Metrics.Eff+import Calamity.Types.LogEff import Calamity.Types.Model.Channel import Calamity.Types.Model.Guild import Calamity.Types.Model.User@@ -62,6 +61,7 @@ P.AtomicState EventHandlers, P.Embed IO, P.Final IO, P.Async] r , Typeable r) +-- | A concrete effect stack used inside the bot type SetupEff r = P.Sem (LogEff ': P.Reader Client ': P.AtomicState EventHandlers ': P.Async ': r) () -- | A Data Kind used to fire custom events@@ -95,7 +95,10 @@ | TypingStartEvt | UserUpdateEvt | forall s a. CustomEvt s a+ -- ^ A custom event, @s@ is the name and @a@ is the data sent to the handler +-- | A type family to decide what the parameters for an event handler should be+-- determined by the type of event it is handling. type family EHType (d :: EventType) m where EHType 'ReadyEvt m = ReadyData -> m () EHType 'ChannelCreateEvt m = Channel -> m ()@@ -218,6 +221,8 @@ EHInstanceSelector ('CustomEvt _ _) = 'True EHInstanceSelector _ = 'False +-- | A helper typeclass that is used to decide how to register regular+-- events, and custom events which require storing in a map at runtime. class InsertEventHandler a m where makeEventHandlers :: Proxy a -> Proxy m -> EHType a m -> EventHandlers
src/Calamity/Gateway/Shard.hs view
@@ -9,24 +9,25 @@ import Calamity.Gateway.DispatchEvents import Calamity.Gateway.Types import Calamity.Internal.Utils-import Calamity.LogEff import Calamity.Metrics.Eff+import Calamity.Types.LogEff import Calamity.Types.Token import Control.Concurrent import Control.Concurrent.Async-import qualified Control.Concurrent.Chan.Unagi as UC+import qualified Control.Concurrent.Chan.Unagi as UC import Control.Concurrent.STM import Control.Concurrent.STM.TBMQueue import Control.Exception+import qualified Control.Exception.Safe as Ex import Control.Lens import Control.Monad import Control.Monad.State.Lazy import qualified Data.Aeson as A import Data.Functor-import Data.Maybe import Data.IORef+import Data.Maybe import Data.Text.Lazy ( Text, stripPrefix ) import Data.Text.Lazy.Lens import Data.Void@@ -44,7 +45,7 @@ import qualified Polysemy.AtomicState as P import qualified Polysemy.Error as P import qualified Polysemy.Resource as P-import qualified Control.Exception.Safe as Ex+ import Prelude hiding ( error ) import TextShow
src/Calamity/Gateway/Types.hs view
@@ -17,8 +17,8 @@ import Calamity.Gateway.DispatchEvents import Calamity.Internal.AesonThings-import Calamity.LogEff import Calamity.Metrics.Eff+import Calamity.Types.LogEff import Calamity.Types.Model.Guild.Guild import Calamity.Types.Model.Voice import Calamity.Types.Snowflake
src/Calamity/Internal/Utils.hs view
@@ -12,7 +12,7 @@ , Calamity.Internal.Utils.error , swap ) where -import Calamity.LogEff+import Calamity.Types.LogEff import Data.Default.Class import qualified Data.HashMap.Lazy as LH
− src/Calamity/LogEff.hs
@@ -1,16 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}---- | The logging effect we use-module Calamity.LogEff- ( LogEff- , LogC ) where--import qualified Df1--import DiPolysemy--import qualified Polysemy as P--type LogEff = Di Df1.Level Df1.Path Df1.Message--type LogC r = P.Member LogEff r
+ src/Calamity/Types/LogEff.hs view
@@ -0,0 +1,16 @@+{-# LANGUAGE NoImplicitPrelude #-}++-- | The logging effect we use+module Calamity.Types.LogEff+ ( LogEff+ , LogC ) where++import qualified Df1++import DiPolysemy++import qualified Polysemy as P++type LogEff = Di Df1.Level Df1.Path Df1.Message++type LogC r = P.Member LogEff r
src/Calamity/Types/Tellable.hs view
@@ -36,6 +36,7 @@ -- 'intoMsg' @'Text' "A message" '<>' 'intoMsg' @'Embed' ('def' '&' #description '?~' "Embed description") -- @ class ToMessage a where+ -- | Turn @a@ into a 'CreateMessageOptions' builder intoMsg :: a -> Endo CreateMessageOptions -- | Message content, '(<>)' concatenates the content@@ -66,6 +67,17 @@ runToMessage = flip appEndo def . intoMsg -- | Send a message to something that is messageable+--+-- To send a string literal you'll probably want to use @TypeApplication@ to+-- specify the type of @msg@+--+-- ==== Examples+--+-- Sending a string:+--+-- @+-- 'void' $ 'tell' @'Text' m ("Somebody told me to tell you about: " '<>' s)+-- @ tell :: forall msg r t. (BotC r, ToMessage msg, Tellable t) => t -> msg -> P.Sem r (Either RestError Message) tell target (runToMessage -> msg) = P.runError $ do cid <- getChannel target