{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeFamilies #-} module Types.UserData where import Affection import Control.Concurrent.STM import qualified SDL import NanoVG hiding (V2(..), V3(..)) import qualified Data.Map.Strict as M import qualified Data.Text as T import Data.Ecstasy import Control.Concurrent.MVar import Control.Monad.Trans.Resource import Types.StateData import Types.ImgId import Types.FontId import Types.Animation import Types.Entity data UserData = UserData { state :: MVar State , subsystems :: Subsystems , assetIcons :: MVar (M.Map IconId Image) , assetImages :: MVar (M.Map ImgId Image) , assetFonts :: MVar (M.Map FontId T.Text) , assetAnimations :: MVar (M.Map AnimId Animation) , controls :: MVar Controller , translation :: MVar Translation , nano :: Context , uuid :: MVar [UUID] , worldState :: MVar (SystemState Entity (AffectionState AffectionData ResIO)) , stateData :: MVar StateData , stateMVar :: MVar ( SystemState Entity (AffectionState AffectionData ResIO) , StateData ) , stateProgress :: MVar (Float, T.Text) , threadContext :: MVar (Maybe SDL.GLContext) , window :: MVar (Maybe SDL.Window) , joyCache :: MVar [JoystickMessage] , joyUUID :: MVar UUID , doNextStep :: MVar Bool } data Controller = NoController | Keyboard | Joystick SDL.Joystick deriving (Eq, Show) data State = Load | Menu SubMenu | Main SubMain deriving (Eq, Show) data SubMain = WorldMap | MindMap deriving (Eq, Show) data SubMenu = Connect | Adjust Action Controller deriving (Eq, Show) defaultJoyTranslation :: M.Map JoypadAction Action defaultJoyTranslation = M.fromList [ (ButtonAction 0 SDL.JoyButtonPressed, ActActivate) , (ButtonAction 7 SDL.JoyButtonPressed, ActSwitchMap) , (AxisAction 1 AxisNegative, ActUp 1) , (AxisAction 1 AxisPositive, ActDown 1) , (AxisAction 0 AxisNegative, ActLeft 1) , (AxisAction 0 AxisPositive, ActRight 1) ] defaultKbdTranslation :: M.Map SDL.Keycode Action defaultKbdTranslation = M.fromList [ (SDL.KeycodeSpace, ActActivate) , (SDL.KeycodeF1, ActSwitchMap) , (SDL.KeycodeW, ActUp 1) , (SDL.KeycodeS, ActDown 1) , (SDL.KeycodeA, ActLeft 1) , (SDL.KeycodeD, ActRight 1) ] data Translation = JoyTranslation (M.Map JoypadAction Action) | KbdTranslation (M.Map SDL.Keycode Action) | NoTranslation deriving (Show, Eq) data Action = ActActivate | ActSwitchMap | ActUp Double | ActDown Double | ActLeft Double | ActRight Double deriving (Show, Eq) data JoypadAction = ButtonAction Word8 SDL.JoyButtonState | AxisAction Word8 AxisAlign -- | HatAction Word SDL.JoyHatPosition deriving (Show, Eq, Ord) data AxisAlign = AxisPositive | AxisNegative | AxisNeutral deriving (Show, Eq, Ord) data Subsystems = Subsystems { subWindow :: SubWindow , subMouse :: SubMouse , subkeyboard :: SubKeyboard , subJoypad :: SubJoypad , subTranslator :: SubTranslator } data ActionMessage = ActionMessage { amAction :: Action , amTime :: Double } deriving (Eq, Show) instance Message ActionMessage where msgTime (ActionMessage _ t) = t newtype SubWindow = SubWindow (TVar [(UUID, WindowMessage -> Affection())]) newtype SubMouse = SubMouse (TVar [(UUID, MouseMessage -> Affection ())]) newtype SubKeyboard = SubKeyboard (TVar [(UUID, KeyboardMessage -> Affection ())]) newtype SubJoypad = SubJoypad (TVar [(UUID, JoystickMessage -> Affection ())]) newtype SubTranslator = SubTranslator (TVar [(UUID, ActionMessage -> Affection ())]) instance Participant SubWindow where type Mesg SubWindow = WindowMessage partSubscribers (SubWindow t) = generalSubscribers t partSubscribe (SubWindow t) = generalSubscribe t partUnSubscribe (SubWindow t) = generalUnSubscribe t instance SDLSubsystem SubWindow where consumeSDLEvents = consumeSDLWindowEvents instance Participant SubMouse where type Mesg SubMouse = MouseMessage partSubscribers (SubMouse t) = generalSubscribers t partSubscribe (SubMouse t) = generalSubscribe t partUnSubscribe (SubMouse t) = generalUnSubscribe t instance SDLSubsystem SubMouse where consumeSDLEvents = consumeSDLMouseEvents instance Participant SubKeyboard where type Mesg SubKeyboard = KeyboardMessage partSubscribers (SubKeyboard t) = generalSubscribers t partSubscribe (SubKeyboard t) = generalSubscribe t partUnSubscribe (SubKeyboard t) = generalUnSubscribe t instance SDLSubsystem SubKeyboard where consumeSDLEvents = consumeSDLKeyboardEvents instance Participant SubJoypad where type Mesg SubJoypad = JoystickMessage partSubscribers (SubJoypad t) = generalSubscribers t partSubscribe (SubJoypad t) = generalSubscribe t partUnSubscribe (SubJoypad t) = generalUnSubscribe t instance SDLSubsystem SubJoypad where consumeSDLEvents = consumeSDLJoystickEvents instance Participant SubTranslator where type Mesg SubTranslator = ActionMessage partSubscribers (SubTranslator t) = generalSubscribers t partSubscribe (SubTranslator t) = generalSubscribe t partUnSubscribe (SubTranslator t) = generalUnSubscribe t generalSubscribers :: TVar [(UUID, msg -> Affection ())] -> Affection [(msg -> Affection ())] generalSubscribers t = do subTups <- liftIO $ readTVarIO t return $ map snd subTups generalSubscribe :: TVar [(UUID, msg -> Affection ())] -> (msg -> Affection ()) -> Affection UUID generalSubscribe t funct = do uu <- genUUID liftIO $ atomically $ modifyTVar' t ((uu, funct) :) return uu generalUnSubscribe :: TVar [(UUID, msg -> Affection ())] -> UUID -> Affection () generalUnSubscribe t uu = liftIO $ atomically $ modifyTVar' t (filter (`filterMsg` uu)) where filterMsg (u, _) p = u /= p