MLP219: updater lifetime spans many subsequent plays¶
qual reports MLP219 when a mobject updater registered on every
path provably stays registered — no remove_updater /
clear_updaters or unknown updater write intervenes — while its host
lives in the scene family across many rendering plays. Every covered
frame pays the updater invocation and keeps the host in Cairo's moving
scope.
- Default severity:
info - Minimum confidence:
medium(a lifetime estimate, not a defect proof) - Implementation phase:
3 - Fix: none
Thresholds (documented constants in
rules/performance/updater_waste.rs):
MLP219_MIN_LIVE_SECONDS = 5.0— proven lower bound of the covered play durations;MLP219_MIN_COVERED_PLAYS = 3— "many subsequent plays".
Covered plays are those after the registration where the host's family
membership is Present, the play renders frames (a play, or a
provably dynamic wait), and the play does not animate the host
itself (animations suspend their targets' updaters, DESIGN 3.2).
Unknown durations open the upper bound instead of being fabricated.
Per the binding DESIGN 7.3 gate the rule never claims the updater is unused — static analysis cannot prove when the effect stops being needed. It reports the estimated live span only; if the whole span is intended, the cost is the intended cost.
Wrong¶
class Demo(Scene):
def construct(self):
square = Square()
self.add(square)
square.add_updater(spin) # needed for the first play only
self.play(intro, run_time=2)
self.play(middle, run_time=2) # spin still runs every frame
self.play(outro, run_time=2)