diff options
author | Thomas White <taw@physics.org> | 2023-12-14 14:35:29 +0100 |
---|---|---|
committer | Thomas White <taw@physics.org> | 2024-02-06 16:59:34 +0100 |
commit | 1340c96cc8af6df9a5d587649d5e2334fc94497d (patch) | |
tree | dd66d6fe5f5f09b858ac1af6041d2cd77379e1e8 | |
parent | 371d46c0a9bc0ba1a279cfea561e389c755292ef (diff) |
Prevent adding a PeakList to two different images
This is kind-of-OK in C, but will break Julia's memory management.
-rw-r--r-- | julia/CrystFEL/src/image.jl | 7 | ||||
-rw-r--r-- | julia/CrystFEL/src/peaklist.jl | 13 |
2 files changed, 17 insertions, 3 deletions
diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index 868afdc4..4f126c28 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -53,7 +53,7 @@ function Base.getproperty(image::Image, name::Symbol) if pl == C_NULL throw(ErrorException("Image doesn't have a peak list")) else - PeakList(pl) + PeakList(pl, true) end end else @@ -70,7 +70,12 @@ function Base.setproperty!(image::Image, name::Symbol, val) idata = unsafe_load(image.internalptr) if name === :peaklist if val isa PeakList + if val.in_image + throw(ArgumentError("PeakList is already in an image. "* + "Add a copy (use `deepcopy`) instead.")) + end setproperty!(idata, name, val.internalptr) + val.in_image = true unsafe_store!(image.internalptr, idata) else throw(ArgumentError("Must be a PeakList")) diff --git a/julia/CrystFEL/src/peaklist.jl b/julia/CrystFEL/src/peaklist.jl index f8c9b407..1735de5e 100644 --- a/julia/CrystFEL/src/peaklist.jl +++ b/julia/CrystFEL/src/peaklist.jl @@ -14,8 +14,9 @@ end mutable struct InternalPeakList end -struct PeakList +mutable struct PeakList internalptr::Ptr{InternalPeakList} + in_image # if true, this PeakList belongs to an Image struct end @@ -24,10 +25,18 @@ function PeakList() if out == C_NULL throw(ArgumentError("Failed to create peak list")) end - PeakList(out) + PeakList(out, false) end +function Base.deepcopy(peaklist::PeakList) + out = @ccall libcrystfel.image_feature_list_copy(peaklist.internalptr::Ptr{InternalPeakList})::Ptr{InternalPeakList} + if out == C_NULL + throw(ErrorException("Failed to copy peak list")) + end + PeakList(out, false) +end + function Base.length(peaklist::PeakList) @ccall libcrystfel.image_feature_count(peaklist.internalptr::Ptr{InternalPeakList})::Cint end |