From 051f62b3867d327a197ea330869ba20759a78f6d Mon Sep 17 00:00:00 2001 From: Tortar <68152031+Tortar@users.noreply.github.com> Date: Sun, 23 Jun 2024 19:01:24 +0200 Subject: [PATCH] Update DynamicSumTypes to 2.0 (#1050) --- Project.toml | 4 ++-- docs/src/api.md | 2 ++ src/core/agents.jl | 42 ++++++++++++++++++++++++++++++++++++--- src/simulations/sample.jl | 14 ++++++------- 4 files changed, 50 insertions(+), 12 deletions(-) diff --git a/Project.toml b/Project.toml index a981989f6e..d0e8a8a0ae 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "Agents" uuid = "46ada45e-f475-11e8-01d0-f70cc89e6671" authors = ["George Datseris", "Tim DuBois", "Aayush Sabharwal", "Ali Vahdati", "Adriano Meligrana"] -version = "6.0.15" +version = "6.0.16" [deps] CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" @@ -47,7 +47,7 @@ DataFrames = "0.21, 0.22, 1" DataStructures = "0.18" Distributed = "1" Distributions = "0.25" -DynamicSumTypes = "1" +DynamicSumTypes = "2" Downloads = "1" GraphMakie = "0.5" Graphs = "1.4" diff --git a/docs/src/api.md b/docs/src/api.md index 06a32d8657..af4811c96b 100644 --- a/docs/src/api.md +++ b/docs/src/api.md @@ -34,6 +34,8 @@ AbstractAgent @multiagent kindof allkinds +@dispatch +@finalize_dispatch ``` ### Minimal agent types diff --git a/src/core/agents.jl b/src/core/agents.jl index 5692772d41..bed0a3a1b6 100644 --- a/src/core/agents.jl +++ b/src/core/agents.jl @@ -1,4 +1,4 @@ -export AbstractAgent, @agent, @multiagent, @dispatch, NoSpaceAgent, kindof, allkinds +export AbstractAgent, @agent, @multiagent, @dispatch, @finalize_dispatch, NoSpaceAgent, kindof, allkinds using DynamicSumTypes: allkinds ########################################################################################### @@ -341,13 +341,15 @@ function _multiagent(version, struct_repr) a_specs = :(begin $(agent_specs_with_base...) end) if version == QuoteNode(:opt_speed) expr = quote - DynamicSumTypes.@sum_structs :opt_speed $t $a_specs + DynamicSumTypes.@sum_structs :on_fields $t $a_specs Agents.ismultiagentcompacttype(::Type{$(namify(new_type))}) = true + DynamicSumTypes.export_variants($(namify(t))) end elseif version == QuoteNode(:opt_memory) expr = quote - DynamicSumTypes.@sum_structs :opt_memory $t $a_specs + DynamicSumTypes.@sum_structs :on_types $t $a_specs Agents.ismultiagentsumtype(::Type{$(namify(new_type))}) = true + DynamicSumTypes.export_variants($(namify(t))) end else error("The version of @multiagent chosen was not recognized, use either `:opt_speed` or `:opt_memory` instead.") @@ -438,7 +440,41 @@ end A macro to enable multiple-dispatch-like behavior for the function `f`, for various agent kinds generated via the [`@multiagent`](@ref) macro. For an illustration of its usage see the [Tutorial](@ref). + +If you are creating your own module/package that uses Agents.jl, and you +are using `@dispatch` inside it, then you need to put [`@finalize_dispatch`](@ref)`()` +before the module end (but after all `@dispatch` calls). """ macro dispatch(f_def) return esc(:(DynamicSumTypes.@pattern $f_def)) end + +""" + @finalize_dispatch + +A macro to finalize the definitions of the methods generated by the +`@dispatch` macro when used in a module. It just needs to be used +once at the end of the module if no `@dispatch` method is used inside +of it. Otherwise use it also before the invocations of the methods. + +## Examples + +```julia +module SomeModel + +@multiagent struct MultiAgent(NoSpaceAgent) + @subagent SubAgent1 end + @subagent SubAgent2 end +end + +@dispatch MethodSub1(::SubAgent1) = 1 +@dispatch MethodSub1(::SubAgent2) = 1 + +@finalize_dispatch() + +end +``` +""" +macro finalize_dispatch() + return esc(:(DynamicSumTypes.@finalize_patterns)) +end diff --git a/src/simulations/sample.jl b/src/simulations/sample.jl index 158ce817cb..53d21e6c39 100644 --- a/src/simulations/sample.jl +++ b/src/simulations/sample.jl @@ -104,21 +104,21 @@ function replicate!(agent::AbstractAgent, model; kwargs...) end function copy_agent(agent::A, model, id_new; kwargs...) where {A<:AbstractAgent} - if ismultiagentsumtype(A) - args_sum_t = new_args_sum_t(agent, model; kwargs...) - newagent = kindconstructor(agent)(id_new, args_sum_t...) + if ismultiagenttype(A) + args = ismultiagentsumtype(A) ? new_args_sum_t(agent, model; kwargs...) : new_args_t(agent, model; kwargs...) + newagent = variant_constructor(agent)(id_new, args...) else - args_t = new_args_t(agent, model; kwargs...) - newagent = A(id_new, args_t...) + args = new_args_t(agent, model; kwargs...) + newagent = A(id_new, args...) end return newagent end function new_args_t(agent, model; kwargs...) # the id is always the first field - fields_no_id = fieldnames(typeof(agent))[2:end] + fields_no_id = propertynames(agent)[2:end] if isempty(kwargs) - new_args = (getfield(agent, x) for x in fields_no_id) + new_args = (getproperty(agent, x) for x in fields_no_id) else kwargs_nt = NamedTuple(kwargs) new_args = (choose_arg(x, kwargs_nt, agent) for x in fields_no_id)