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
withAgent agentProgram a
markDone a
runInteractingAgents
:: (Universe u, Serialize (Agent u))
=> AgentsProgram u -> SummaryProgram u -> StateT u IO ()
runInteractingAgents agentsProgram summaryProgram = do
atEndOfRound summaryProgram
as <- lineup
withAgents agentsProgram as
when (not $ null as) $ markDone (head 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 ()