I was thinking it had to be Mutable. But as it turns out, Observables allow you to mutate immutable objects (if that makes sense)
Iβm doing something like:
using Observables, GeometryBasics
struct Particle2D{T<:Real}
position::Observable{Point{2, T}}
velocity::Observable{Point{2, T}}
acceleration::Observable{Point{2, T}}
mass::T
charge::T
shape::Observable
size::Observable{T}
alpha::Observable{T}
function Particle2D(
position::Point{2, T}=Point2i(0,0),
velocity::Point{2, T}=Point2i(0,0),
acceleration::Point{2, T}=Point2i(0,0),
mass::T=1,
charge::T=1,
shape=GeometryBasics.Circle,
size::T=1,
alpha::T=1
) where {T<:Real}
new{T}(Observable(position), Observable(velocity), Observable(acceleration), mass, charge, Observable(shape), Observable(size), Observable(alpha))
end
function Particle2D(
position::Point{2, <:Real}=Point2i(0,0),
velocity::Point{2, <:Real}=Point2i(0,0),
acceleration::Point{2, <:Real}=Point2i(0,0),
mass::Real=1,
charge::Real=1,
shape=GeometryBasics.Circle,
size::Real=10,
alpha::Real=1
)
super_T = promote_type(
eltype(position),
eltype(velocity),
eltype(acceleration),
typeof(mass),
typeof(charge),
typeof(size),
typeof(alpha)
)
new{super_T}(
Observable(convert(Point{2, super_T}, position)),
Observable(convert(Point{2, super_T}, velocity)),
Observable(convert(Point{2, super_T}, acceleration)),
convert(super_T, mass),
convert(super_T, charge),
Observable(shape),
Observable(convert(super_T, size)),
Observable(convert(super_T, alpha))
)
end
end
"""
julia> Particle2D()
Particle2D{Int64}(Observable([0, 0]), Observable([0, 0]), Observable([0, 0]), 1, 1, Observable(Circle), Observable(10), Observable(1))
julia> Particle2D(Point(1,2))
Particle2D{Int64}(Observable([1, 2]), Observable([0, 0]), Observable([0, 0]), 1, 1, Observable(Circle), Observable(10), Observable(1))
julia> @benchmark Particle2D()
BenchmarkTools.Trial: 10000 samples with 168 evaluations.
Range (min β¦ max): 644.048 ns β¦ 23.988 ΞΌs β GC (min β¦ max): 0.00% β¦ 95.21%
Time (median): 676.786 ns β GC (median): 0.00%
Time (mean Β± Ο): 768.488 ns Β± 1.027 ΞΌs β GC (mean Β± Ο): 9.29% Β± 6.68%
βββββββ
ββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββ
ββββββ
β
ββ
ββ
ββ
ββββββββ
β
β β
644 ns Histogram: log(frequency) by time 1.1 ΞΌs <
Memory estimate: 1.36 KiB, allocs estimate: 27.
---
julia> @benchmark Particle2D().position[] += [1,2]
BenchmarkTools.Trial: 10000 samples with 98 evaluations.
Range (min β¦ max): 793.878 ns β¦ 61.263 ΞΌs β GC (min β¦ max): 0.00% β¦ 97.09%
Time (median): 905.102 ns β GC (median): 0.00%
Time (mean Β± Ο): 1.095 ΞΌs Β± 2.381 ΞΌs β GC (mean Β± Ο): 12.22% Β± 5.54%
ββββββββββ
βββββββββ β β β β
ββββββββββββββββββββββββββ
βββ
β
ββ
β
ββ
β
β
βββββββββββββββββββββ
ββ β
794 ns Histogram: log(frequency) by time 1.92 ΞΌs <
Memory estimate: 1.56 KiB, allocs estimate: 32.
"""
as for position, velocity, acceleration⦠i guess I should name them pos, vel, acc to begin with.
I can not redefine since I do need Observables and need to redefine it, but it happens with immutable structs too somehow! Thanks for that!