I either have a bug in my code, or a misunderstanding of the Julia language.
I have two struct types: an Ellipse
and a Circle
. In order to simplify my code, I have a single drawing function that draws an ellipse. Since the function expects an ellipse, the circle has its own ellipse field, with the x-radius and the y-radius of the circle’s ellipse set to the circle’s radius. When I call the circle’s draw function, it calls the draw function for the circle’s ellipse. To reiterate, an ellipse is one of the circle’s fields.
I have a function called “setPos” that updates a shape’s position. This is where things go wrong…but not in the debugger.
function setPos(solidShape::Union{Rect, Ellipse, Circle, Polygon}, coords::PsychoCoords)
solidShape._pos = SDLcoords(solidShape.win, coords)
solidShape.pos = coords
if typeof(solidShape) == "Circle"
setPos(solidShape.circlesEllipse, coords)
#solidShape.circlesEllipse._pos = solidShape._pos # update the ellipse owned by the circle
#solidShape.circlesEllipse.pos = solidShape.pos # update the ellipse owned by the circle
end
end
The first part of the function update’s the circle’s (or any of the shapes’) positions (pos and _pos). The second part checks to see if it is a Circle
, and if so, it update’s its ellipse’s positions. You can see that I’ve tried to do it two ways: by directly accessing the ellipse’s fields, and by calling the setPos function.
In the debugger, I can see that the circle’s positions update, as do its ellipse’s positions. However, the animations do not reflect that. Furthermore, if I run it in the REPL and insert some println() statements to print out the positions of the circle and its ellipse, its clear that the circle’s positions updates, but not the position’s of its ellipse. It’s as if the ellipse has its initial values from when it was initially made. I’m left scratching my head. Why do they update in the debugger but nowhere else?
I can get the circle’s ellipse’s position to update if I replace the ellipse struct with a new instance. It’s inelegant and hacky, but it works, and I don’t like it. You can see an example of this below, and the original code of the draw(::Circle)
function is commented-out.
function draw(Circ::Circle)
#draw(Circ.circlesEllipse)
circlesEllipse = Ellipse(Circ.win, Circ.pos, Circ.rad, Circ.rad, lineWidth=Circ.lineWidth,lineColor=Circ.lineColor,fillColor=Circ.fillColor, fill=Circ.fill)
draw(circlesEllipse)
end
What am I missing? Why does the circle’s ellipse struct field not update? Both are mutable structs, and nearly identical.
mutable struct Circle
win::Window
pos::PsychoCoords
rad::Union{Int64, Float64} # radius in pixels of the aa-ellipse
lineWidth::Int64
lineColor::PsychoColor # these will need to change to floats to handle Psychopy colors
fillColor::PsychoColor # these will need to change to floats to handle Psychopy colors
fill::Bool # these will need to change to floats to handle Psychopy colors
circlesEllipse::Ellipse
_lineColor::Vector{Int64}
_fillColor::Vector{Int64}
_pos::Vector{Int64}
_rad::Int64
function Circle(win::Window,
pos::PsychoCoords = [10,10], # position
rad::Union{Int64, Float64} = 20; # Horizontal radius in pixels of the aa-ellipse
lineWidth::Int64 = 1,
lineColor::PsychoColor = fill(128, (4)),
fillColor::PsychoColor = fill(128, (4)),
fill::Bool = false
)
_lineColor = colorToSDL(win, lineColor)
_fillColor = colorToSDL(win, fillColor)
circlesEllipse = Ellipse(win, pos, rad, rad, lineWidth=lineWidth,lineColor=lineColor,fillColor=fillColor, fill=fill)
new(win,
pos,
rad,
lineWidth,
lineColor, # these will need to change to floats to handle Psychopy colors
fillColor, # these will be Psychopy colors
fill,
circlesEllipse,
_lineColor,
_fillColor,
_pos,
_rad
)
end
end
mutable struct Ellipse
win::Window
pos::PsychoCoords
....