packages feed

hotswap 0.1.9.3 → 0.1.9.12

raw patch · 2 files changed

+67/−11 lines, 2 filesPVP: minor bump suggested

API additions: PVP suggests at least a minor version bump

API changes (from Hackage documentation)

+ System.Plugins.Hotswap: runPlugin :: Plugin (IO a) -> IO a

Files

hotswap.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                hotswap-version:             0.1.9.3+version:             0.1.9.12 synopsis:            Simple code hotswapping. description:         A simple, high-level interface to plugins. homepage:            https://github.com/mikeplus64/hotswap@@ -20,4 +20,4 @@   hs-source-dirs:      src   exposed-modules:     System.Plugins.Hotswap   -- other-modules:       -  build-depends:       base ==4.5.*, plugins ==1.5.*+  build-depends:       base == 4.5.*, plugins == 1.5.*
src/System/Plugins/Hotswap.hs view
@@ -3,6 +3,7 @@     newPlugin,     usePlugin,      usePluginIO,+    runPlugin,     reloadPlugin,      readPlugin,      withPlugin,@@ -11,7 +12,7 @@ ) where  import System.Plugins.Load-import Data.IORef +import Data.IORef  data Plugin a = Plugin {     pluginObject       :: FilePath,    -- ^ Path to object@@ -24,16 +25,16 @@ -- | 'usePlugin' provides a simple way to use plugins of type 'Plugin (a -> b)', ie, only  -- single argumented ones. usePlugin :: Plugin (a -> b) -> a -> IO b-usePlugin plug x = do-    pf <- readPlugin plug-    return (pf x)+usePlugin plug x = fmap ($ x) (readPlugin plug)  -- | 'usePlugin' for plugins returning IO. usePluginIO :: Plugin (a -> IO b) -> a -> IO b-usePluginIO plug x = do-    pf <- readPlugin plug-    pf x+usePluginIO plug x = readPlugin plug >>= ($ x) +-- | 'runPlugin' runs an 'IO a' returning 'Plugin'.+runPlugin :: Plugin (IO a) -> IO a+runPlugin plug = readPlugin plug >>= id+ -- | 'withPlugin' provides a way to run a function on a plugin, modifying the plugin in-place. withPlugin :: Plugin a -> (a -> a) -> IO () withPlugin plug f = do@@ -47,11 +48,11 @@     r  <- f pd     putPlugin plug r --- | Create a new plugin. Don't use this to reload plugins.+-- | Create a new plugin, expecting a type. Don't use this to reload plugins. newPlugin :: FilePath -> [FilePath] -> String -> IO (Plugin a) newPlugin obj incs name = do     plugin <- load_ obj incs name-+         case plugin of         LoadSuccess m f -> do             fref <- newIORef f@@ -69,6 +70,7 @@         LoadSuccess newm newf -> do             writeIORef mref newm             writeIORef fref newf+         _ -> error "no such module or function"  -- | Read the 'pluginData' 'IORef'.@@ -78,3 +80,57 @@ -- | Replace the contents of the 'pluginData'. putPlugin :: Plugin a -> a -> IO () putPlugin = writeIORef . pluginData++{-+data Hotswap a = Hotswap {+    hotswapThread :: IORef (Maybe ThreadId),+    hotswapPlugin :: Plugin a -- something seems wrong about passing this around all the time, but alas...+}++-- | Automatically poll the filesystem for changes in the specified 'Plugin''s object file, and+-- reload the plugin if necessary.+newHotswap :: Plugin a -> IO (Hotswap a)+newHotswap plug = do+    ht  <- forkHotswapThread plug+    ref <- newIORef (Just ht)+    return $ Hotswap ref plug++-- | 'newHotswap', only returning the ThreadId.+forkHotswapThread :: Plugin a -> IO ThreadId+forkHotswapThread plug = do+    md5 <- md5File $ pluginObject plug+    forkIO (loop md5)+  where+    md5File  = fmap md5sum . B.readFile++    loop old = do+        threadDelay 100000+        new <- md5File $ pluginObject plug+        if new == old+            then loop new+            else do+                reloadPlugin plug+                loop new++-- | Restart a 'Hotswap' from one that was killed, otherwise, do nothing.+restartHotswap :: Hotswap a -> IO ()+restartHotswap (Hotswap h p) = do+    r <- readIORef h++    case r of+        Nothing -> do+            thread <- forkHotswapThread p+            writeIORef h (Just thread)++        _ -> return ()++killHotswap :: Hotswap a -> IO ()+killHotswap (Hotswap h _) = do+    r <- readIORef h++    case r of +        Just thread -> do+            killThread thread+            writeIORef h Nothing+        _ -> return ()+-}