#pragma once #include #include #include #include #include #include #include #include namespace reanimated { struct Rect { double width, height; }; struct Frame { std::optional x, y, width, height; Frame(jsi::Runtime &runtime, const jsi::Object &newStyle) { if (newStyle.hasProperty(runtime, "originX")) { x = newStyle.getProperty(runtime, "originX").asNumber(); } if (newStyle.hasProperty(runtime, "originY")) { y = newStyle.getProperty(runtime, "originY").asNumber(); } if (newStyle.hasProperty(runtime, "width")) { width = newStyle.getProperty(runtime, "width").asNumber(); } if (newStyle.hasProperty(runtime, "height")) { height = newStyle.getProperty(runtime, "height").asNumber(); } } }; struct UpdateValues { Props::Shared newProps; Frame frame; }; struct Snapshot { double x, y, width, height, windowWidth, windowHeight; Snapshot(const ShadowView &shadowView, Rect window) { const auto &frame = shadowView.layoutMetrics.frame; x = frame.origin.x; y = frame.origin.y; width = frame.size.width; height = frame.size.height; windowWidth = window.width; windowHeight = window.height; } }; typedef enum ExitingState { UNDEFINED = 1, WAITING = 2, ANIMATING = 4, DEAD = 8, MOVED = 16, DELETED = 32, } ExitingState; struct MutationNode; /** Represents a view that was either removed or had a child removed from the ShadowTree */ struct Node { std::vector> children, unflattenedChildren; std::shared_ptr parent, unflattenedParent; Tag tag; void removeChildFromUnflattenedTree(std::shared_ptr child); void applyMutationToIndices(ShadowViewMutation mutation); void insertChildren(std::vector> &newChildren); void insertUnflattenedChildren( std::vector> &newChildren); virtual bool isMutationMode(); explicit Node(const Tag tag) : tag(tag) {} Node(Node &&node) : children(std::move(node.children)), unflattenedChildren(std::move(node.unflattenedChildren)), tag(node.tag) {} Node(Node &node) : children(node.children), unflattenedChildren(node.unflattenedChildren), tag(node.tag) {} virtual ~Node() = default; }; /** Represents a view that was removed from the ShadowTree */ struct MutationNode : public Node { ShadowViewMutation mutation; ExitingState state = UNDEFINED; explicit MutationNode(ShadowViewMutation &mutation) : Node(mutation.oldChildShadowView.tag), mutation(mutation) {} MutationNode(ShadowViewMutation &mutation, Node &&node) : Node(std::move(node)), mutation(mutation) {} bool isMutationMode() override; }; struct SurfaceManager { mutable std::unordered_map< SurfaceId, std::shared_ptr>> props_; mutable std::unordered_map windows_; std::unordered_map &getUpdateMap(SurfaceId surfaceId); void updateWindow(SurfaceId surfaceId, double windowWidth, double windowHeight); Rect getWindow(SurfaceId surfaceId); }; static inline void updateLayoutMetrics( LayoutMetrics &layoutMetrics, Frame &frame) { // we use optional's here to avoid overwriting non-animated values if (frame.width) { layoutMetrics.frame.size.width = *frame.width; } if (frame.height) { layoutMetrics.frame.size.height = *frame.height; } if (frame.x) { layoutMetrics.frame.origin.x = *frame.x; } if (frame.y) { layoutMetrics.frame.origin.y = *frame.y; } } static inline bool isRNSScreen(std::shared_ptr node) { const auto &componentName = node->mutation.oldChildShadowView.componentName; return !std::strcmp(componentName, "RNSScreenStack") || !std::strcmp(componentName, "RNSScreen") || !std::strcmp(componentName, "RNSModalScreen"); } static inline bool hasLayoutChanged(const ShadowViewMutation &mutation) { return mutation.oldChildShadowView.layoutMetrics.frame != mutation.newChildShadowView.layoutMetrics.frame; } static inline void mergeAndSwap( std::vector> &A, std::vector> &B) { std::vector> merged; auto it1 = A.begin(), it2 = B.begin(); while (it1 != A.end() && it2 != B.end()) { if ((*it1)->mutation.index < (*it2)->mutation.index) { merged.push_back(*it1); it1++; } else { merged.push_back(*it2); it2++; } } while (it1 != A.end()) { merged.push_back(*it1); it1++; } while (it2 != B.end()) { merged.push_back(*it2); it2++; } std::swap(A, merged); } } // namespace reanimated