module ALife.Creatur.Task
(
AgentProgram,
AgentsProgram,
withAgent,
withAgents,
runNoninteractingAgents,
runInteractingAgents,
simpleDaemon,
startupHandler,
shutdownHandler,
exceptionHandler,
noSummary
) where
import ALife.Creatur.Daemon (Daemon(..))
import ALife.Creatur.Universe (Universe, Agent, AgentProgram,
AgentsProgram, writeToLog, lineup, refresh, markDone, endOfRound,
withAgent, withAgents, incTime)
import Control.Conditional (whenM)
import Control.Exception (SomeException)
import Control.Monad (when)
import Control.Monad.State (StateT, execStateT)
import Data.Serialize (Serialize)
simpleDaemon :: Universe u => Daemon u
simpleDaemon = Daemon
{
onStartup = startupHandler,
onShutdown = shutdownHandler,
onException = exceptionHandler,
task = undefined,
username = "",
sleepTime = 100
}
startupHandler :: Universe u => u -> IO u
startupHandler = execStateT (writeToLog $ "Starting")
shutdownHandler :: Universe u => u -> IO ()
shutdownHandler u = do
_ <- execStateT (writeToLog "Shutdown requested") u
return ()
exceptionHandler :: Universe u => u -> SomeException -> IO u
exceptionHandler u x = execStateT (writeToLog ("WARNING: " ++ show x)) u
runNoninteractingAgents
:: (Universe u, Serialize (Agent u))
=> AgentProgram u -> SummaryProgram u -> StateT u IO ()
runNoninteractingAgents agentProgram summaryProgram = do
atEndOfRound summaryProgram
(a:_) <- lineup
markDone a
withAgent agentProgram a
runInteractingAgents
:: (Universe u, Serialize (Agent u))
=> AgentsProgram u -> SummaryProgram u -> StateT u IO ()
runInteractingAgents agentsProgram summaryProgram = do
atEndOfRound summaryProgram
as <- lineup
when (not $ null as) $ markDone (head as)
withAgents agentsProgram as
atEndOfRound
:: Universe u
=> SummaryProgram u -> StateT u IO ()
atEndOfRound summaryProgram = do
whenM endOfRound $ do
writeToLog "End of round"
summaryProgram
refresh
incTime
writeToLog "Beginning of round"
type SummaryProgram u = StateT u IO ()
noSummary :: SummaryProgram u
noSummary = return ()