Skip to content

Commit cfdc1dc

Browse files
committed
fix: make Atom.hasAnimation side-effect free
Previously, Atom.hasAnimation would call Atom.update, which would in turn call the Atom's change listeners if the Atom was in an animation. However, This would cause infinite recursion loop in cases where Atom.hasAnimation is called inside of or as a result of a change listener. This method simply does not need to call change listeners, as neither its name nor its documentation implies it has side-effects, it doesn't even lock the Atom as by design, TOCTOU errors can't happen on Atoms.
1 parent bbdeb32 commit cfdc1dc

File tree

1 file changed

+10
-3
lines changed

1 file changed

+10
-3
lines changed

src/data.zig

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -341,10 +341,17 @@ pub fn Atom(comptime T: type) type {
341341
}
342342
}
343343

344-
/// Returns true if there is currently an animation playing.
345-
pub fn hasAnimation(self: *Self) bool {
344+
/// Returns true if there is currently an animation playing. This method doesn't lock the
345+
/// Atom.
346+
pub fn hasAnimation(self: *const Self) bool {
346347
if (!isAnimatable) return false;
347-
return self.update();
348+
switch (self.value) {
349+
.Animated => |animation| {
350+
const now = std.time.Instant.now() catch return false;
351+
return now.since(animation.start) < @as(u64, animation.duration) * std.time.ns_per_ms;
352+
},
353+
.Single => return false,
354+
}
348355
}
349356

350357
/// Starts an animation on the atom, from the current value to the `target` value. The

0 commit comments

Comments
 (0)