/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include #include #include namespace facebook::react { static inline bool shouldFirstComeBeforeSecondRemovesOnly( const ShadowViewMutation& lhs, const ShadowViewMutation& rhs) noexcept { // Make sure that removes on the same level are sorted - highest indices must // come first. return (lhs.type == ShadowViewMutation::Type::Remove && lhs.type == rhs.type) && (lhs.parentShadowView.tag == rhs.parentShadowView.tag) && (lhs.index > rhs.index); } static inline void handleShouldFirstComeBeforeSecondRemovesOnly( ShadowViewMutation::List& list) noexcept { std::unordered_map> removeMutationsByTag; ShadowViewMutation::List finalList; for (auto& mutation : list) { if (mutation.type == ShadowViewMutation::Type::Remove) { auto key = std::to_string(mutation.parentShadowView.tag); removeMutationsByTag[key].push_back(mutation); } else { finalList.push_back(mutation); } } if (removeMutationsByTag.size() == 0) { return; } for (auto& mutationsPair : removeMutationsByTag) { if (mutationsPair.second.size() > 1) { std::stable_sort( mutationsPair.second.begin(), mutationsPair.second.end(), &shouldFirstComeBeforeSecondRemovesOnly); } finalList.insert( finalList.begin(), mutationsPair.second.begin(), mutationsPair.second.end()); } list = finalList; } static inline bool shouldFirstComeBeforeSecondMutation( const ShadowViewMutation& lhs, const ShadowViewMutation& rhs) noexcept { if (lhs.type != rhs.type) { // Deletes always come last if (lhs.type == ShadowViewMutation::Type::Delete) { return false; } if (rhs.type == ShadowViewMutation::Type::Delete) { return true; } // Remove comes before insert if (lhs.type == ShadowViewMutation::Type::Remove && rhs.type == ShadowViewMutation::Type::Insert) { return true; } if (rhs.type == ShadowViewMutation::Type::Remove && lhs.type == ShadowViewMutation::Type::Insert) { return false; } // Create comes before insert if (lhs.type == ShadowViewMutation::Type::Create && rhs.type == ShadowViewMutation::Type::Insert) { return true; } if (rhs.type == ShadowViewMutation::Type::Create && lhs.type == ShadowViewMutation::Type::Insert) { return false; } // Remove comes before Update if (lhs.type == ShadowViewMutation::Type::Remove && rhs.type == ShadowViewMutation::Type::Update) { return true; } if (rhs.type == ShadowViewMutation::Type::Remove && lhs.type == ShadowViewMutation::Type::Update) { return false; } } else { // Make sure that removes on the same level are sorted - highest indices // must come first. if (lhs.type == ShadowViewMutation::Type::Remove && lhs.parentShadowView.tag == rhs.parentShadowView.tag) { if (lhs.index > rhs.index) { return true; } else { return false; } } } return false; } std::pair calculateAnimationProgress( uint64_t now, const LayoutAnimation& animation, const AnimationConfig& mutationConfig); } // namespace facebook::react