make per UI tick calculation more predictable (#51802)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/51802

changelog: [internal]

avoid conversions when dealing with time in C++ Animated. This makes tests more predictable.

Reviewed By: christophpurrer

Differential Revision: D75813200

fbshipit-source-id: b8934848237e5ea7c350d9a5f0175ac0f9202ffd
This commit is contained in:
Samuel Susla
2025-06-04 05:05:19 -07:00
committed by Facebook GitHub Bot
parent dc7be7c7aa
commit b338a00467
6 changed files with 10 additions and 11 deletions
@@ -61,8 +61,7 @@ test('moving box by 100 points', () => {
}).start();
});
// TODO: this fails with any value below 1022, even though anything above 1000 should be enough.
Fantom.unstable_advanceAnimationsByTime(1022);
Fantom.unstable_advanceAnimationsByTime(1000);
boundingClientRect = viewElement.getBoundingClientRect();
expect(boundingClientRect.x).toBe(100);
@@ -610,7 +610,7 @@ void NativeAnimatedNodesManager::updateNodes(
updatedNodeTags_.clear();
}
bool NativeAnimatedNodesManager::onAnimationFrame(uint64_t timestamp) {
bool NativeAnimatedNodesManager::onAnimationFrame(double timestamp) {
// Run all active animations
auto hasFinishedAnimations = false;
std::set<int> finishedAnimationValueNodes;
@@ -723,12 +723,12 @@ void NativeAnimatedNodesManager::onRender() {
// Step through the animation loop
if (isAnimationUpdateNeeded()) {
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
g_now().time_since_epoch())
.count();
auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(
g_now().time_since_epoch())
.count();
auto containsChange =
onAnimationFrame(static_cast<uint64_t>(ms * TicksPerMs));
onAnimationFrame(static_cast<double>(microseconds) / 1000.0);
if (!containsChange) {
// The last animation tick didn't result in any changes to the UI.
@@ -175,7 +175,7 @@ class NativeAnimatedNodesManager {
private:
void stopRenderCallbackIfNeeded() noexcept;
bool onAnimationFrame(uint64_t timestamp);
bool onAnimationFrame(double timestamp);
bool isAnimationUpdateNeeded() const noexcept;
@@ -70,7 +70,7 @@ void AnimationDriver::runAnimationStep(double renderingTime) {
}
// ticks are 100 nanoseconds, divide by 10000 to get milliseconds.
const auto frameTimeMs = renderingTime / TicksPerMs;
const auto frameTimeMs = renderingTime;
auto restarting = false;
if (startFrameTimeMs_ < 0) {
startFrameTimeMs_ = frameTimeMs;
@@ -50,7 +50,7 @@ class AnimationDriver {
return isComplete_;
}
virtual void runAnimationStep(double renderingTime);
void runAnimationStep(double renderingTime);
virtual void updateConfig(folly::dynamic config);
@@ -58,7 +58,7 @@ bool FrameAnimationDriver::update(double timeDeltaMs, bool /*restarting*/) {
}
const auto startIndex =
static_cast<size_t>(timeDeltaMs / SingleFrameIntervalMs);
static_cast<size_t>(std::ceil(timeDeltaMs / SingleFrameIntervalMs));
assert(startIndex >= 0);
const auto nextIndex = startIndex + 1;