1
1
export ABM, StandardABM, UnkillableABM, FixedMassABM
2
2
using StaticArrays: SizedVector
3
3
4
- ContainerType{A} = Union{AbstractDict{Int,A}, AbstractVector{A}}
4
+ ContainerType{A} = Union{AbstractDict{Int,A},AbstractVector{A}}
5
5
6
6
# And the three implementations here are just variants with different `C` type.
7
7
struct SingleContainerABM{S<: SpaceType ,A<: AbstractAgent ,C<: ContainerType{A} ,F,P,R<: AbstractRNG } <: AgentBasedModel{S,A}
@@ -39,12 +39,12 @@ single container. Offers the variants:
39
39
"""
40
40
function SingleContainerABM (
41
41
:: Type{A} ,
42
- space:: S = nothing ;
43
- container:: Type = Dict{Int},
44
- scheduler:: F = Schedulers. fastest,
45
- properties:: P = nothing ,
46
- rng:: R = Random. default_rng (),
47
- warn = true
42
+ space:: S = nothing ;
43
+ container:: Type = Dict{Int},
44
+ scheduler:: F = Schedulers. fastest,
45
+ properties:: P = nothing ,
46
+ rng:: R = Random. default_rng (),
47
+ warn= true ,
48
48
) where {A<: AbstractAgent ,S<: SpaceType ,F,P,R<: AbstractRNG }
49
49
agent_validator (A, space, warn)
50
50
C = construct_agent_container (container, A)
59
59
construct_agent_container (:: Type{<:Dict} , A) = Dict{Int,A}
60
60
construct_agent_container (:: Type{<:Vector} , A) = Vector{A}
61
61
construct_agent_container (container, A) = throw (
62
- " Unrecognised container $container , please specify either Dict or Vector."
62
+ " Unrecognised container $container , please specify either Dict or Vector." ,
63
63
)
64
64
65
65
"""
@@ -101,13 +101,13 @@ in the given `agent_vector`.
101
101
"""
102
102
function FixedMassABM (
103
103
agents:: AbstractVector{A} ,
104
- space:: S = nothing ;
105
- scheduler:: F = Schedulers. fastest,
106
- properties:: P = nothing ,
107
- rng:: R = Random. default_rng (),
108
- warn = true
109
- ) where {A<: AbstractAgent , S<: SpaceType ,F,P,R<: AbstractRNG }
110
- C = SizedVector{length (agents), A}
104
+ space:: S = nothing ;
105
+ scheduler:: F = Schedulers. fastest,
106
+ properties:: P = nothing ,
107
+ rng:: R = Random. default_rng (),
108
+ warn= true ,
109
+ ) where {A<: AbstractAgent ,S<: SpaceType ,F,P,R<: AbstractRNG }
110
+ C = SizedVector{length (agents),A}
111
111
fixed_agents = C (agents)
112
112
# Validate that agent ID is the same as its order in the vector.
113
113
for (i, a) in enumerate (agents)
@@ -120,11 +120,11 @@ end
120
120
# ######################################################################################
121
121
# %% Model accessing api
122
122
# ######################################################################################
123
- nextid (model:: SingleContainerABM{<:SpaceType,A,Dict{Int, A}} ) where {A} = getfield (model, :maxid )[] + 1
123
+ nextid (model:: SingleContainerABM{<:SpaceType,A,Dict{Int,A}} ) where {A} = getfield (model, :maxid )[] + 1
124
124
nextid (model:: SingleContainerABM{<:SpaceType,A,Vector{A}} ) where {A} = nagents (model) + 1
125
125
nextid (:: SingleContainerABM{<:SpaceType,A,<:SizedVector} ) where {A} = error (" There is no `nextid` in a `FixedMassABM`. Most likely an internal error." )
126
126
127
- function add_agent_to_model! (agent, model:: SingleContainerABM{<:SpaceType,A,Dict{Int, A}} ) where {A<: AbstractAgent }
127
+ function add_agent_to_model! (agent, model:: SingleContainerABM{<:SpaceType,A,Dict{Int,A}} ) where {A<: AbstractAgent }
128
128
if haskey (agent_container (model), agent. id)
129
129
error (" Can't add agent to model. There is already an agent with id=$(agent. id) " )
130
130
else
@@ -133,7 +133,9 @@ function add_agent_to_model!(agent, model::SingleContainerABM{<:SpaceType,A,Dict
133
133
# Only the `Dict` implementation actually uses the `maxid` field.
134
134
# The `Vector` one uses the defaults, and the `Sized` one errors anyways.
135
135
maxid = getfield (model, :maxid )
136
- if maxid[] < agent. id; maxid[] = agent. id; end
136
+ if maxid[] < agent. id
137
+ maxid[] = agent. id
138
+ end
137
139
return
138
140
end
139
141
@@ -144,12 +146,12 @@ function add_agent_to_model!(agent, model::SingleContainerABM{<:SpaceType,A,Vect
144
146
end
145
147
146
148
function remove_agent_from_model! (agent:: A , model:: SingleContainerABM{<:SpaceType,A,<:AbstractDict{Int,A}} ) where {A<: AbstractAgent }
147
- delete! (agent_container (model), agent. id)
149
+ return delete! (agent_container (model), agent. id)
148
150
end
149
151
function remove_agent_from_model! (:: A , model:: SingleContainerABM{<:SpaceType,A,<:AbstractVector} ) where {A<: AbstractAgent }
150
- error (
151
- " Cannot remove agents stored in $(containertype (model)) . " *
152
- " Use the vanilla `SingleContainerABM` to be able to remove agents."
152
+ return error (
153
+ " Cannot remove agents stored in $(containertype (model)) . " *
154
+ " Use the vanilla `SingleContainerABM` to be able to remove agents." ,
153
155
)
154
156
end
155
157
@@ -188,18 +190,18 @@ end
188
190
do_checks(agent, space)
189
191
Helper function for `agent_validator`.
190
192
"""
191
- function do_checks (:: Type{A} , space:: S , warn:: Bool ) where {A<: AbstractAgent , S<: SpaceType }
193
+ function do_checks (:: Type{A} , space:: S , warn:: Bool ) where {A<: AbstractAgent ,S<: SpaceType }
192
194
if warn
193
195
isbitstype (A) &&
194
- @warn " Agent type is not mutable, and most library functions assume that it is."
196
+ @warn " Agent type is not mutable, and most library functions assume that it is."
195
197
end
196
198
(any (isequal (:id ), fieldnames (A)) && fieldnames (A)[1 ] == :id ) ||
197
- throw (ArgumentError (" First field of agent type must be `id` (and should be of type `Int`)." ))
199
+ throw (ArgumentError (" First field of agent type must be `id` (and should be of type `Int`)." ))
198
200
fieldtype (A, :id ) <: Integer ||
199
- throw (ArgumentError (" `id` field in agent type must be of type `Int`." ))
201
+ throw (ArgumentError (" `id` field in agent type must be of type `Int`." ))
200
202
if space != = nothing
201
203
(any (isequal (:pos ), fieldnames (A)) && fieldnames (A)[2 ] == :pos ) ||
202
- throw (ArgumentError (" Second field of agent type must be `pos` when using a space." ))
204
+ throw (ArgumentError (" Second field of agent type must be `pos` when using a space." ))
203
205
# Check `pos` field in A has the correct type
204
206
pos_type = fieldtype (A, :pos )
205
207
space_type = typeof (space)
0 commit comments