module System.Plugins.Hotswap (
Plugin (..),
newPlugin,
usePlugin,
usePluginIO,
reloadPlugin,
readPlugin,
withPlugin,
withPluginIO,
putPlugin
) where
import System.Plugins.Load
import Data.IORef
data Plugin a = Plugin {
pluginObject :: FilePath,
pluginIncludes :: [FilePath],
pluginDataName :: String,
pluginData :: IORef a,
pluginModule :: IORef Module
}
usePlugin :: Plugin (a -> b) -> a -> IO b
usePlugin plug x = do
pf <- readPlugin plug
return (pf x)
usePluginIO :: Plugin (a -> IO b) -> a -> IO b
usePluginIO plug x = do
pf <- readPlugin plug
pf x
withPlugin :: Plugin a -> (a -> a) -> IO ()
withPlugin plug f = do
pd <- readPlugin plug
putPlugin plug (f pd)
withPluginIO :: Plugin a -> (a -> IO a) -> IO ()
withPluginIO plug f = do
pd <- readPlugin plug
r <- f pd
putPlugin plug r
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"
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"
readPlugin :: Plugin a -> IO a
readPlugin = readIORef . pluginData
putPlugin :: Plugin a -> a -> IO ()
putPlugin = writeIORef . pluginData