Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
nature.jl 4.36 KiB
### Persefone.jl - a model of agricultural landscapes and ecosystems in Europe.
###
### This file is responsible for managing the animal modules and contains functions
### and types integrating the nature submodel with the rest of Persefone.
###


## An enum used to assign a sex to each animal
@enum Sex hermaphrodite male female
#XXX hermaphrodite probably is not needed and its implementation is iffy

"""
    Animal

This is the generic agent type for all animals. Individual species are created
using the [`@species`](@ref) macro. In addition to user-defined, species-specific
fields, all species contain the following fields:

- `id` An integer unique identifier for this individual.
- `sex` male, female, or hermaphrodite.
- `parents` The IDs of the individual's parents.
- `pos` An (x, y) coordinate tuple.
- `age` The age of the individual in days.
- `phase` The update function to be called during the individual's current life phase.
- `energy` A [DEBparameters](@ref) struct for calculating energy budgets.
- `offspring` A vector containing the IDs of an individual's children.
- `territory` A vector of coordinates that comprise the individual's territory.
"""
abstract type Animal <: ModelAgent end

"""
    speciesof(animal)

Return the species name of this animal as a string.
"""
function speciesof(a::Union{Animal,Type})
    # strip out the module name if necessary (`Persefone.<species>`)
    (a isa Animal) && (a = typeof(a))
    spstrings = split(string(a), ".")
    length(spstrings) == 1 ? spstrings[1] : spstrings[2]
end

"""
    speciestype(name)

Return the Type of this species.
"""
function speciestype(name::String)
    # get the species Type from its namestring by looking in the module namespace
    speciestype = nothing
    for var in names(Persefone, all=true)
        if string(var) == name && getfield(Persefone, var) isa Type
            speciestype = getfield(Persefone, var)
            break
        end
    end
    isnothing(speciestype) && @error("Species $name is not defined.")
    speciestype
end
    
"""
    animalid(animal)

A small utility function to return a string with the species name and ID of an animal.
"""
function animalid(a::Animal)
    return "$(speciesof(a)) $(a.id)"
end

"""