I think the problem happens inside this method. Specially, this line:
push!(nodes, MutableBinaryHeapNode(convert(T, v), i))
because what happens is basically the same as:
julia> struct Wrapper{T}; v :: T; end
julia> vec = Vector{Wrapper{Any}}()
0-element Array{Wrapper{Any},1}
julia> push!(vec, Wrapper(convert(Any, 10)))
ERROR: MethodError: Cannot `convert` an object of type
Wrapper{Int64} to an object of type
Wrapper{Any}
...
In other words, the push!
wraps your value inside a wrapper struct (MutableBinaryHeapNode
more specifically), the code expects that converting your value to the type of the heap (i.e., Any
or SEvents
) they will create a MutableBinaryHeapNode{Any}
(or ...{SEvents}
) and then push it into a vector. However, typeof(convert(Any, s_event_obj))
is typeof(s_event_obj)
not Any
, and therefore the object created is a MutableBinaryHeapNode{typeof(s_event_obj)}
and not a MutableBinaryHeapNode{Any}
and cannot be pushed into a Vector{MutableBinaryHeapNode{Any}}
because it is the wrong type.
I see two workarounds (i.e., not considering a fix in their side):
- You need to use a concrete type instead of an abstract type. What would need you to STOP using a type that is different for each function inside it (i.e., not parametrized by closure). You would need to do:
struct SEvent
callback::Function # or Any
time::Float64
end
- (shameless self-promotion) Use my implementation of a
MutableBinaryHeap
, that I prefer toDataStructures.jl
implementation. It is available in TrackingHeaps.jl (registered package, you can justadd
it). It is fully documented, and have come up recently in this thread.