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()
)

Arguments

sim

A simList

eventName

Character string of the desired event name to define. Default is "init"

code

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.

moduleName

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.

envir

An optional environment to specify where to put the resulting function. The default will place a function called doEvent.moduleName.eventName in the module function location, i.e., sim$.mods[[moduleName]]. However, if this location does not exist, then it will place it in the parent.frame(), with a message. Normally, especially, if used within SpaDES module code, this should be left missing.

Examples

sim <- simInit()
#> Setting:
#>   options(
#>     reproducible.cachePath = '/tmp/Rtmp45trFG/reproducible/cache'
#>     spades.inputPath = '/tmp/Rtmp45trFG/SpaDES/inputs'
#>     spades.outputPath = '/tmp/Rtmp45trFG/SpaDES/outputs'
#>     spades.modulePath = '/tmp/Rtmp45trFG/SpaDES/modules'
#>     spades.scratchPath = '/tmp/Rtmp45trFG/SpaDES/scratch'
#>   )
#> Nov21 04:22:26 simInit Using setDTthreads(1). To change: 'options(spades.DTthreads = X)'.
#> Elpsed time for simInit: 0.02536082 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)
#> Nov21 04:22:26 simInit Using setDTthreads(1). To change: 'options(spades.DTthreads = X)'.
#> Nov21 04:22:26 chckpn:init total elpsd: 0.027 secs | 0 checkpoint init 0
#> Nov21 04:22:26 save  :init total elpsd: 0.029 secs | 0 save init 0
#> Nov21 04:22:26 prgrss:init total elpsd: 0.031 secs | 0 progress init 0
#> Nov21 04:22:26 load  :init total elpsd: 0.033 secs | 0 load init 0
#> Nov21 04:22:26 thsTst:init total elpsd: 0.035 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().
# }