zwirn-0.2.2.1: app/zwirnzi/CI/Config.hs
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module CI.Config where
{-
CommandLine.hs - configuration
Copyright (C) 2023, Martin Gius
This library is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library. If not, see <http://www.gnu.org/licenses/>.
-}
import Conferer as Conf
import Conferer.Source.CLIArgs as Cli
import Conferer.Source.Env as Env
import Conferer.Source.Yaml as Yaml
import Control.Monad (unless)
import qualified Data.ByteString.Lazy.UTF8 as BL
import qualified Data.Text as T
import GHC.Generics (Generic)
import qualified Sound.Tidal.Clock as Clock (ClockConfig (..), defaultConfig)
import System.Directory.OsPath
import System.File.OsPath as F
import System.OsPath
import qualified Zwirn.Language.Compiler as Compiler
import qualified Zwirn.Stream.Target as Stream
import qualified Zwirn.Stream.Types as Stream
data ClockConfig = ClockConfig
{ clockConfigQuantum :: Double,
clockConfigBeatsPerCycle :: Double,
clockConfigFrameTimespan :: Double,
clockConfigEnableLink :: Bool,
clockConfigSkipTicks :: Int,
clockConfigProcessAhead :: Double
}
deriving (Show, Generic)
data TargetConfig = TargetConfig
{ targetConfigName :: T.Text,
targetConfigOSCPath :: T.Text,
targetConfigBusOSCPath :: T.Text,
targetConfigAddress :: String,
targetConfigPort :: Int,
targetConfigBusPort :: Maybe Int
}
deriving (Show, Generic)
data StreamConfig = StreamConfig
{ streamConfigTargets :: [TargetConfig],
streamConfigDefaultTarget :: T.Text,
streamConfigLocalPort :: Int,
streamConfigPrecision :: Rational,
streamConfigClock :: ClockConfig
}
deriving (Show, Generic)
data CiConfig = CiConfig
{ ciConfigBootPath :: FilePath,
ciConfigListener :: Bool,
ciConfigCli :: Bool,
ciConfigOverwriteBuiltin :: Bool,
ciConfigDynamicTypes :: Bool
}
deriving (Generic)
data FullConfig = FullConfig
{ fullConfigCi :: CiConfig,
fullConfigClock :: ClockConfig,
fullConfigStream :: StreamConfig
}
deriving (Generic)
instance DefaultConfig TargetConfig where
configDef = TargetConfig "superdirt" "/dirt/play" "/c_set" "127.0.0.1" 57120 (Just 57110)
instance DefaultConfig CiConfig where
configDef = CiConfig "" False False False False
instance DefaultConfig StreamConfig where
configDef = StreamConfig [configDef] "superdirt" 2323 0.005 configDef
instance DefaultConfig ClockConfig where
configDef = fromClock Clock.defaultConfig
instance DefaultConfig FullConfig where
configDef = FullConfig configDef configDef configDef
instance FromConfig TargetConfig
instance FromConfig CiConfig
instance FromConfig StreamConfig
instance FromConfig ClockConfig
instance FromConfig FullConfig
getConfig :: IO Conf.Config
getConfig = do
home <- getHomeDirectory
configDirPath <- (home <>) <$> encodeUtf "/.config/zwirnzi/"
path <- (home <>) <$> encodeUtf "/.config/zwirnzi/config.yaml"
createDirectoryIfMissing True configDirPath
exists <- doesFileExist path
unless exists (F.writeFile path defaultConfigFile)
decoded <- decodeUtf path
mkConfig'
[]
[ Cli.fromConfig,
Env.fromConfig "zwirnzi",
Yaml.fromFilePath decoded
]
fromClock :: Clock.ClockConfig -> ClockConfig
fromClock (Clock.ClockConfig a b c d e f) = ClockConfig (realToFrac a) (realToFrac b) c d (fromIntegral e) f
toClock :: ClockConfig -> Clock.ClockConfig
toClock (ClockConfig a b c d e f) = Clock.ClockConfig (realToFrac a) (realToFrac b) c d (fromIntegral e) f
toTarget :: TargetConfig -> Stream.TargetConfig
toTarget (TargetConfig a b c d e f) = Stream.TargetConfig a b c d e f
toStream :: StreamConfig -> Stream.StreamConfig
toStream (StreamConfig a b c d e) = Stream.StreamConfig (map toTarget a) b c d (toClock e)
toCiConfig :: CiConfig -> Compiler.CiConfig
toCiConfig (CiConfig _ _ _ x y) = Compiler.CiConfig x y
configPath :: IO String
configPath = do
home <- getHomeDirectory
path <- (home <>) <$> encodeUtf "/.config/zwirnzi/config.yaml"
exists <- doesFileExist path
decoded <- decodeUtf path
if exists then return decoded else return "Config file not found!"
resetConfig :: IO String
resetConfig = do
home <- getHomeDirectory
configDirPath <- (home <>) <$> encodeUtf "/.config/zwirnzi/"
path <- (home <>) <$> encodeUtf "/.config/zwirnzi/config.yaml"
createDirectoryIfMissing True configDirPath
F.writeFile path defaultConfigFile
return "Restored default config."
defaultConfigFile :: BL.ByteString
defaultConfigFile =
BL.fromString "ci:"
<|> " listener: true"
<|> " bootpath: \"\""
<|> " overwritebuiltin: false"
<|> " dynamictypes: false"
<|> "stream:"
<|> " targets:"
<|> " - name: \"superdirt\""
<|> " oscpath: \"/dirt/play\""
<|> " busoscpath: \"/c_set\""
<|> " address: \"127.0.0.1\""
<|> " port: 57120"
<|> " busport: 57110"
<|> " defaulttarget: \"superdirt\""
<|> " localport: 52323"
<|> " precision: 0.005"
<|> " clock:"
<|> " quantum: 4"
<|> " beatspercycle: 4"
<|> " frametimespan: 0.05"
<|> " enablelink: false"
<|> " skipticks: 10"
<|> " processahead: 0.3"
where
(<|>) x y = x <> "\n" <> y
getFile :: String -> IO String
getFile p = do
path <- encodeUtf p
f <- F.readFile path
return $ BL.toString f