hotswap-0.1.9.2: src/System/Plugins/Hotswap.hs
module System.Plugins.Hotswap (
Plugin (..),
newPlugin,
usePlugin,
usePluginIO,
reloadPlugin,
readPlugin,
withPlugin,
withPluginIO
) where
import System.Plugins.Load
import Data.IORef
data Plugin a = Plugin {
pluginObject :: FilePath, -- ^ Path to object
pluginIncludes :: [FilePath], -- ^ Include paths.
pluginDataName :: String, -- ^ Name of the symbol to find.
pluginData :: IORef a, -- ^ Loaded data.
pluginModule :: IORef Module -- ^ Loaded module.
}
-- | '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' for plugins returning IO.
usePluginIO :: Plugin (a -> IO b) -> a -> IO b
usePluginIO plug x = do
pf <- readPlugin plug
pf x
-- | '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
pd <- readPlugin plug
putPlugin plug (f pd)
-- | 'withPlugin' for functions returning IO.
withPluginIO :: Plugin a -> (a -> IO a) -> IO ()
withPluginIO plug f = do
pd <- readPlugin plug
r <- f pd
putPlugin plug r
-- | Create a new plugin. 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
mref <- newIORef m
return $! Plugin obj incs name fref mref
_ -> error "no such module or function"
-- | Reload a plugin in-place.
reloadPlugin :: Plugin a -> IO ()
reloadPlugin (Plugin _ _ name fref mref) = do
m <- readIORef mref
plugin <- reload m name
case plugin of
LoadSuccess newm newf -> do
writeIORef mref newm
writeIORef fref newf
_ -> error "no such module or function"
-- | Read the 'pluginData' 'IORef'.
readPlugin :: Plugin a -> IO a
readPlugin = readIORef . pluginData
-- | Replace the contents of the 'pluginData'.
putPlugin :: Plugin a -> a -> IO ()
putPlugin = writeIORef . pluginData