-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Description
This proposal is related to the issue #4339 and attempts to solve the described problem in a different way:
Description of problem
Sometimes we store child mobjects of some composed mobject as attributes, while also
.add
-ing them to theself.submobjects
list directly.This is fine in principle, but has the odd side effect of producing "mismatches" when a user updates the attribute by reassinging it, because the actually for rendering relevant
self.submobjects
list still holds a reference to the former attribute value.As an example:
sq = Square() b = BraceText(sq, "hello") # this stores the label in `b.label` b.label = Text("new value") # and here we reassign the label ...
This example still renders as a brace with label
"hello"
, because the reference in theself.submobjects
list is never updated.
Proposed solution
The idea is the same: to have a single reference to each submobject, a single source of truth for them.
It does not make a lot of sense that "basic" Mobjects such as Circle
, Square
, ImageMobject
or ValueTracker
have submobjects. Instead, it makes more sense to take a Circle
and group it inside a Group
or VGroup
containing other Mobjects. This leads me to the idea that maybe only Groups should have submobjects
as such.
Therefore, my idea is:
- The base class
Mobject
does not have.submobjects
. It also does not have methods such as.add()
,.remove()
, etc. - Only
Group
,VGroup
and theirs subclasses have.submobjects
,.add()
,.remove()
, etc. - Groups should be a special Mobject which is more clearly separated from the rest of Mobjects. For example, currently
Axes
is a subclass ofVGroup
andCoordinateSystem
. It should not be a subclass ofVGroup
.Axes
should have another way of exposing its submobjects and should not have.submobjects
,.add()
,.remove()
, etc. See a more detailed description of how to achieve that below.
In this way, if only Groups have submobjects and you can only directly add submobjects to Groups, then we put a stricter limit to the unexpected behaviors which might arise from, say, adding a Mobject which already exists.
We still need Mobjects that contain other Mobjects without necessarily being Groups, like MathTex
and Axes
. Therefore, I propose defining a Mobject.get_submobjects()
or Mobject.get_children()
method.
- For the base class
Mobject
, this should simply return[]
. - Other Mobjects which need children may override it. For example,
Axes.get_children()
would return[self.x_axis, self.y_axis]
.NumberLine.get_children()
would return something like[*super().get_children(), *self.ticks, *self.numbers]
. - Of course,
Circle
does not override the method, so it still returns[]
. Group.get_children()
andVGroup.get_children()
simply returnself.submobjects
.
In this way, by getting rid of .submobjects
where necessary and making .get_submobjects()
or .get_children()
return the already existing references to those submobjects, we ensure that there's effectively one single reference for each one of them, solving the described problem.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status