packages feed

settings 0.1.0.1 → 0.2.0.0

raw patch · 6 files changed

+33/−167 lines, 6 files

Files

ChangeLog view
@@ -1,15 +1,15 @@ The changes are recorded by the version control system, Darcs. To see a log quickly from the terminal, run: -  $ darcs changes --repo http://darcs.rel4tion.org/repos/settings+  $ darcs changes --repo http://dev.rel4tion.org/fr33domlover/settings -There is also a web interface at <http://darcs.rel4tion.org> which, among other+There is also a web interface at <http://dev.rel4tion.org> which, among other things, can display the history log.  To see the log in a local clone, first get a copy of the repository if you haven't yet: -  $ darcs get http://darcs.rel4tion.org/repos/settings+  $ darcs get http://dev.rel4tion.org/fr33domlover/settings  Then move into the newly created directory and run darcs: 
NEWS view
@@ -3,6 +3,29 @@   +settings 0.2.0.0 -- 2015-09-17+==============================++General, build and documentation changes:++* (None)++New APIs, features and enhancements:++* Remove persistence API, this is now provided by the json-state package++Bug fixes:++* (None)++Dependency changes:++* (None)+++++ settings 0.1.0.1 -- 2015-09-14 ============================== 
settings.cabal view
@@ -1,5 +1,5 @@ name:                settings-version:             0.1.0.1+version:             0.2.0.0 synopsis:            Runtime-editable program settings. description:   This library aims to be a tool for constructing a settings management UI on@@ -27,17 +27,16 @@  source-repository head   type:                darcs-  location:            http://darcs.rel4tion.org/repos/settings/+  location:            http://dev.rel4tion.org/fr33domlover/settings  library   exposed-modules:     Data.Settings                      , Data.Settings.Interface                      , Data.Settings.Option-                     , Data.Settings.Persist                      , Data.Settings.Section                      , Data.Settings.Route                      , Data.Settings.Types-  other-modules:       Control.Debounce+  -- other-modules:          -- other-extensions:       build-depends:       aeson                      , aeson-pretty         >=0.7
− src/Control/Debounce.hs
@@ -1,61 +0,0 @@-{- This file is part of settings.- -- - Written in 2015 by fr33domlover <fr33domlover@rel4tion.org>.- -- - ♡ Copying is an act of love. Please copy, reuse and share.- -- - The author(s) have dedicated all copyright and related and neighboring- - rights to this software to the public domain worldwide. This software is- - distributed without any warranty.- -- - You should have received a copy of the CC0 Public Domain Dedication along- - with this software. If not, see- - <http://creativecommons.org/publicdomain/zero/1.0/>.- -}---- | This is similar to the same module from "auto-update" package, except here--- the caller can pass a parameter to the debounced action. Also, the returned--- action comes in 2 versions.------ The first is non-blocking at the cost of a small chance a parameter isn't--- passed and is instead discarded. This can happen if the action is called--- from different threads simultanously. One empties the 'MVar', and the other--- happens to fill it first, and then the parameter the former thread passed is--- discarded. If you run the action from a single thread, there is no problem,--- or if missing at a hopefully small chance isn't a problem.------ The second is blocking, but only in the small chance described above.--- Otherwise it doesn't block in practice.------ Also, exceptions aren't handled. This includes async exceptions and any--- exceptions thrown by the given action.-module Control.Debounce-    ( mkDebounce-    )-where--import Control.Monad (forever, void)-import Control.Concurrent (forkIO, threadDelay)-import Control.Concurrent.MVar-import Data.Time.Units--mkDebounce :: TimeUnit t-           => t               -- ^ Time delay between calls to the action-           -> (a -> IO ())    -- ^ Action to perform-           -> IO ( a -> IO () --   Never-blocking version-                 , a -> IO () --   Possibly-blocking version-                 )-mkDebounce interval action = do-    paramVar <- newEmptyMVar-    let run = forkIO $ forever $ do-            param <- takeMVar paramVar-            action param-            threadDelay $ fromInteger $ toMicroseconds interval-        actNB param = do-            tryTakeMVar paramVar-            void $ tryPutMVar paramVar param-        actPB param = do-            tryTakeMVar paramVar-            putMVar paramVar param-    run-    return (actNB, actPB)
src/Data/Settings.hs view
@@ -37,11 +37,9 @@ -- -- The idea is that you freely use whatever you like for the settings values, -- and the settings tree is a UI component added on top without interfering--- with your program logic code. Persistence using periodic exports to JSON is--- provided in the "Data.Settings.Persist" module, but you can use any other--- solution as needed, e.g. the acid-state package. The persistence module is--- unrelated to the settings tree, and should probably move into its own--- package and get some extra features missing right now, like version control.+-- with your program logic code. Persistence using simple periodic exports to+-- JSON is available in the @json-state@ package, but you can use any other+-- solution as needed, e.g. the acid-state package. -- -- == Settings Tree Basics --@@ -266,9 +264,6 @@ -- The last argument is a callback action to be run when a successful set or -- reset of the value occurs. ----- We are done with the basics. Another 2 aspects of the library are settings--- tree modification and persistence.--- -- == Settings Tree Dynamic Modification -- -- Modification simply requires holding the tree as application state, and@@ -276,37 +271,4 @@ -- API in "Data.Settings.Section" for working with the settings tree, and since -- unordered maps are being used, you may also find "Data.HashMap.Lazy" useful -- (from unordered-containers package).------ == Settings Persistence------ Finally, persistence. "Data.Settings.Persist" provides a function for--- loading the settings value from a JSON file, and a function which generates--- a safe scalable saver function. The JSON files are written using the--- @aeson-pretty@ package, so that they are easy to read and modify manually if--- needed.------ The save function generator, @mkSaveSettings@, returns a function which--- saves settings when called, but only at most once in @t@, the time interval--- passed to the generator. For example, if you pass an interval of 3 seconds,--- you can safely call the generated save function even 100 times a second, and--- the JSON file will still get updated just once in 3 seconds, avoiding an--- overload of file I/O.------ The actual saving happens in a dedicated worker thread, so even when a save--- does occur, it won't block the caller thread. You can, for example, call the--- save function in the callback you pass to @mkOptionS@. The generator can be--- called once at program start, and the returned save function saved in--- application state.------ Using the persistence module requires that you define @FromJSON@ and--- @ToJSON@ instances for your settings type, see the @aeson@ package.------ Note that while this simple periodic save-to-file method can serve a simple--- standalone application well, it won't work if you wish your settings to be--- shared by multiple applications and allow them to read and write settings at--- the same time. If that's the case, check out the @acid-state@ package, and--- other persistence related packages.-module Data.Settings-    (-    )-where+module Data.Settings where
− src/Data/Settings/Persist.hs
@@ -1,57 +0,0 @@-{- This file is part of settings.- -- - Written in 2015 by fr33domlover <fr33domlover@rel4tion.org>.- -- - ♡ Copying is an act of love. Please copy, reuse and share.- -- - The author(s) have dedicated all copyright and related and neighboring- - rights to this software to the public domain worldwide. This software is- - distributed without any warranty.- -- - You should have received a copy of the CC0 Public Domain Dedication along- - with this software. If not, see- - <http://creativecommons.org/publicdomain/zero/1.0/>.- -}--module Data.Settings.Persist-    ( mkSaveSettings-    , loadSettings-    )-where--import Control.Debounce (mkDebounce)-import Control.Monad (liftM)-import qualified Data.ByteString.Lazy as B-import Data.Aeson (FromJSON, ToJSON, eitherDecode)-import Data.Aeson.Encode.Pretty (encodePretty)-import Data.Time.Units (TimeUnit)-import System.IO.Error (tryIOError)--saveAction :: ToJSON s => FilePath -> s -> IO ()-saveAction file s = B.writeFile file $ encodePretty s---- | Prepare a save action which writes settings into a JSON file. This action--- defers the work to a separate dedicated thread, and ensures the file isn't--- saved more than once within the given time interval.------ The action is non-blocking but there is a chance a save is missed if saves--- are triggered ------ You can call the returned action from your UI thread as a reaction to a--- settings change, without worrying about delay or IO load.-mkSaveSettings :: (TimeUnit t, ToJSON s) => t -> FilePath -> IO (s -> IO ())-mkSaveSettings interval file =-    liftM fst $ mkDebounce interval (saveAction file)---- | Try to load settings from a file.------ If an error occurs, 'Left' a pair is returned. The boolean indicates whether--- reading the file failed ('False') or parsing the content failed ('True').--- The string is an error description.------ If the operation succeeds, 'Right' the loaded settings are returned.-loadSettings :: FromJSON s => FilePath -> IO (Either (Bool, String) s)-loadSettings file = do-    errOrStr <- tryIOError (B.readFile file)-    let pairOrStr = either (Left . (,) False . show) Right errOrStr-    return $ pairOrStr >>= either (Left . (,) True) Right . eitherDecode