There are two ways to define what occurs during an event: defining a function
called doEvent.moduleName, where moduleName is the actual module name.
This approach is the original approach used in SpaDES.core, and it must have an
explicit switch statement branching on eventType.
The newer approach (still experimental) uses defineEvent().
Instead of creating, doEvent.moduleName(), it creates one function
for each event, each with the name doEvent.moduleName.eventName.
This may be a little bit cleaner, but both with still work.
defineEvent(
sim,
eventName = "init",
code,
moduleName = NULL,
envir = parent.frame()
)A simList
Character string of the desired event name to define. Default is "init"
An expression that defines the code to execute during the event. This will
be captured, and pasted into a new function (doEvent.moduleName.eventName),
remaining unevaluated until that new function is called.
Character string of the name of the module. If this function is used within a module, then it will try to find the module name.
An optional environment specifying where to put the resulting
function. The default is the parent.frame(), i.e. the calling environment,
which for an interactive user is the global environment. Placing the function
directly in the module environment (sim[[dotMods]][[moduleName]]) is not yet
implemented; it requires defineEvent() to be integrated into the module
parsing steps. Until then, defineEvent() is intended for standalone use.
Invisibly, the simList supplied as sim. Called for its side effect of
creating the event function doEvent.<moduleName>.<eventName> in envir and
recording its digest in the simList.
sim <- simInit()
#> Setting:
#> options(
#> reproducible.cachePath = '/tmp/RtmpmM1qrr/reproducible/cache'
#> spades.inputPath = '/tmp/RtmpmM1qrr/SpaDES/inputs'
#> spades.outputPath = '/tmp/RtmpmM1qrr/SpaDES/outputs'
#> spades.modulePath = '/tmp/RtmpmM1qrr/SpaDES/modules'
#> spades.scratchPath = '/tmp/RtmpmM1qrr/SpaDES/scratch'
#> )
#> Aug29 22:30:17 simInit Using setDTthreads(1). To change: 'options(spades.DTthreads = X)'.
#> Elapsed time for simInit: 0.03184485 secs
# these put the functions in the parent.frame() which is .GlobalEnv for an interactive user
defineEvent(sim, "init", moduleName = "thisTestModule", code = {
sim <- Init(sim) # initialize
# Now schedule some different event for "current time", i.e., will
# be put in the event queue to run *after* this current event is finished
sim <- scheduleEvent(sim, time(sim), "thisTestModule", "grow")
}, envir = envir(sim))
defineEvent(sim, "grow", moduleName = "thisTestModule", code = {
sim <- grow(sim) # grow
# Now schedule this same event for "current time plus 1", i.e., a "loop"
sim <- scheduleEvent(sim, time(sim) + 1, "thisTestModule", "grow") # for "time plus 1"
})
Init <- function(sim) {
sim$messageToWorld <- "Now the sim has an object in it that can be accessed"
sim$size <- 1 # initializes the size object --> this can be anything, Raster, list, whatever
message(sim$messageToWorld)
return(sim) # returns all the things you added to sim as they are in the simList
}
grow <- function(sim) {
sim$size <- sim$size + 1 # increments the size
message(sim$size)
return(sim)
}
# schedule that first "init" event
sim <- scheduleEvent(sim, 0, "thisTestModule", "init")
# Look at event queue
events(sim) # shows the "init" we just added
#> eventTime moduleName eventType eventPriority
#> <num> <char> <char> <num>
#> 1: 0 checkpoint init 0
#> 2: 0 save init 0
#> 3: 0 progress init 0
#> 4: 0 load init 0
#> 5: 0 thisTestModule init 5
# \donttest{
# this is skipped when running in automated tests; it is fine in interactive use
out <- spades(sim)
#> Aug29 22:30:17 simInit Using setDTthreads(1). To change: 'options(spades.DTthreads = X)'.
#> Aug29 22:30:17 chckpn:init total elpsd: 0.034 secs | 0 checkpoint init 0
#> Aug29 22:30:17 save :init total elpsd: 0.036 secs | 0 save init 0
#> Aug29 22:30:17 prgrss:init total elpsd: 0.038 secs | 0 progress init 0
#> Aug29 22:30:17 load :init total elpsd: 0.04 secs | 0 load init 0
#> Aug29 22:30:17 thsTst:init total elpsd: 0.042 secs | 0 thisTestModule init 5
#> Error in Init(sim): could not find function "Init"
#> Because of an interrupted spades call, the sim object at the time of interruption was saved in
#> SpaDES.core:::savedSimEnv()$.sim
#> It will be deleted on next call to spades().
# }