Skip to content

Commit 42df6c7

Browse files
Special case compute_identity edges to forward ref types (#5302)
* special case `compute_identity` edges to forward ref types * update changelog * fix format --------- Co-authored-by: Simon <sdanisch@protonmail.com>
1 parent 8479f1b commit 42df6c7

File tree

3 files changed

+69
-0
lines changed

3 files changed

+69
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- Fixed `Symlog10` to work correctly with lower or upper thresholds smaller than 1, and adds a `linscale` argument [#5279](https://github.com/MakieOrg/Makie.jl/pull/5279)
88
- Fixed `xlims!`/`ylims!` not fully propagating to linked axis [#5239](https://github.com/MakieOrg/Makie.jl/pull/5239)
99
- Added support for plotting units with DynamicQuantities.jl [#5280](https://github.com/MakieOrg/Makie.jl/pull/5280)
10+
- Adjusted compute nodes to keep unspecialized types when transitioning from one graph to another [#5302](https://github.com/MakieOrg/Makie.jl/pull/5302)
1011

1112
## [0.24.6] - 2025-08-19
1213

ComputePipeline/src/ComputePipeline.jl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,30 @@ end
736736

737737
compute_identity(inputs, changed, cached) = values(inputs)
738738

739+
function TypedEdge(edge::ComputeEdge, f::typeof(compute_identity), inputs)
740+
if length(inputs) != length(edge.outputs)
741+
error("A `compute_identity` callback requires the length of inputs and outputs to match.")
742+
end
743+
744+
# use input refs as output refs so we don't even need to evaluate the callback
745+
for i in eachindex(values(inputs))
746+
edge.outputs[i].value = inputs[i]
747+
edge.outputs[i].dirty = true
748+
end
749+
750+
return TypedEdge(f, inputs, edge.inputs_dirty, inputs, edge.outputs)
751+
end
752+
753+
function resolve!(edge::TypedEdge{IT, OT, typeof(compute_identity)}) where {IT, OT}
754+
# outputs are identical to inputs, so just copy the input state. To be safe
755+
# don't overwrite any `dirty = true` state with false (maybe a problem if
756+
# the input gets resolved?)
757+
for i in eachindex(edge.inputs_dirty)
758+
edge.output_nodes[i].dirty |= edge.inputs_dirty[i]
759+
end
760+
return
761+
end
762+
739763
"""
740764
add_input!([callback], compute_graph, name::Symbol, node::Computed)
741765

ComputePipeline/test/unit_tests.jl

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,3 +799,47 @@ end
799799
e3 = graph2.merged3.parent
800800
@test e3.inputs == [graph1.a1, graph2.a2]
801801
end
802+
803+
@testset "compute_identity" begin
804+
graph1 = ComputeGraph()
805+
add_input!(graph1, :a1, Ref{Any}(1))
806+
map!(x -> Ref{Any}(x), graph1, :a1, :b1)
807+
808+
graph2 = ComputeGraph()
809+
add_input!(graph2, :b1, graph1.b1)
810+
graph2.b1[]
811+
@test graph2.b1.value isa Ref{Any}
812+
813+
edge = graph2.b1.parent
814+
@test edge.callback == ComputePipeline.compute_identity
815+
@test length(edge.inputs) == length(edge.outputs)
816+
for (in, out) in zip(edge.inputs, edge.outputs)
817+
@test in.value === out.value
818+
@test !ComputePipeline.isdirty(in)
819+
@test !ComputePipeline.isdirty(out)
820+
end
821+
822+
update!(graph1, a1 = 5.0)
823+
824+
for (in, out) in zip(edge.inputs, edge.outputs)
825+
@test in.value === out.value
826+
@test ComputePipeline.isdirty(in)
827+
@test ComputePipeline.isdirty(out)
828+
end
829+
830+
graph1.b1[]
831+
832+
for (in, out) in zip(edge.inputs, edge.outputs)
833+
@test in.value === out.value
834+
@test !ComputePipeline.isdirty(in)
835+
@test ComputePipeline.isdirty(out)
836+
end
837+
838+
graph2.b1[]
839+
840+
for (in, out) in zip(edge.inputs, edge.outputs)
841+
@test in.value === out.value
842+
@test !ComputePipeline.isdirty(in)
843+
@test !ComputePipeline.isdirty(out)
844+
end
845+
end

0 commit comments

Comments
 (0)