ssap_app/node_modules/react-native/ReactCommon/react/nativemodule/intersectionobserver/NativeIntersectionObserver.cpp

176 lines
5.4 KiB
C++

/*
* 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 "NativeIntersectionObserver.h"
#include <react/renderer/core/ShadowNode.h>
#include <react/renderer/runtimescheduler/RuntimeSchedulerBinding.h>
#include <react/renderer/uimanager/UIManagerBinding.h>
#include <react/renderer/uimanager/primitives.h>
#ifdef RN_DISABLE_OSS_PLUGIN_HEADER
#include "Plugins.h"
#endif
std::shared_ptr<facebook::react::TurboModule>
NativeIntersectionObserverModuleProvider(
std::shared_ptr<facebook::react::CallInvoker> jsInvoker) {
return std::make_shared<facebook::react::NativeIntersectionObserver>(
std::move(jsInvoker));
}
namespace facebook::react {
namespace {
jsi::Object tokenFromShadowNodeFamily(
jsi::Runtime& runtime,
ShadowNodeFamily::Shared shadowNodeFamily) {
jsi::Object obj(runtime);
// Need to const_cast since JSI only allows non-const pointees
obj.setNativeState(
runtime,
std::const_pointer_cast<ShadowNodeFamily>(std::move(shadowNodeFamily)));
return obj;
}
ShadowNodeFamily::Shared shadowNodeFamilyFromToken(
jsi::Runtime& runtime,
jsi::Object token) {
return token.getNativeState<ShadowNodeFamily>(runtime);
}
} // namespace
NativeIntersectionObserver::NativeIntersectionObserver(
std::shared_ptr<CallInvoker> jsInvoker)
: NativeIntersectionObserverCxxSpec(std::move(jsInvoker)) {}
void NativeIntersectionObserver::observe(
jsi::Runtime& runtime,
NativeIntersectionObserverObserveOptions options) {
observeV2(runtime, std::move(options));
}
void NativeIntersectionObserver::unobserve(
jsi::Runtime& runtime,
IntersectionObserverObserverId intersectionObserverId,
std::shared_ptr<const ShadowNode> targetShadowNode) {
auto token =
tokenFromShadowNodeFamily(runtime, targetShadowNode->getFamilyShared());
unobserveV2(runtime, intersectionObserverId, std::move(token));
}
jsi::Object NativeIntersectionObserver::observeV2(
jsi::Runtime& runtime,
NativeIntersectionObserverObserveOptions options) {
auto intersectionObserverId = options.intersectionObserverId;
auto shadowNode = options.targetShadowNode;
auto shadowNodeFamily = shadowNode->getFamilyShared();
std::optional<ShadowNodeFamily::Shared> observationRootShadowNodeFamily;
if (options.rootShadowNode.has_value()) {
observationRootShadowNodeFamily =
options.rootShadowNode.value()->getFamilyShared();
}
auto thresholds = options.thresholds;
auto rootThresholds = options.rootThresholds;
auto& uiManager = getUIManagerFromRuntime(runtime);
intersectionObserverManager_.observe(
intersectionObserverId,
observationRootShadowNodeFamily,
shadowNodeFamily,
thresholds,
rootThresholds,
uiManager);
return tokenFromShadowNodeFamily(runtime, shadowNodeFamily);
}
void NativeIntersectionObserver::unobserveV2(
jsi::Runtime& runtime,
IntersectionObserverObserverId intersectionObserverId,
jsi::Object targetToken) {
auto shadowNodeFamily =
shadowNodeFamilyFromToken(runtime, std::move(targetToken));
intersectionObserverManager_.unobserve(
intersectionObserverId, shadowNodeFamily);
}
void NativeIntersectionObserver::connect(
jsi::Runtime& runtime,
AsyncCallback<> notifyIntersectionObserversCallback) {
auto& uiManager = getUIManagerFromRuntime(runtime);
intersectionObserverManager_.connect(
*RuntimeSchedulerBinding::getBinding(runtime)->getRuntimeScheduler(),
uiManager,
std::move(notifyIntersectionObserversCallback));
}
void NativeIntersectionObserver::disconnect(jsi::Runtime& runtime) {
auto& uiManager = getUIManagerFromRuntime(runtime);
intersectionObserverManager_.disconnect(
*RuntimeSchedulerBinding::getBinding(runtime)->getRuntimeScheduler(),
uiManager);
}
std::vector<NativeIntersectionObserverEntry>
NativeIntersectionObserver::takeRecords(jsi::Runtime& runtime) {
auto entries = intersectionObserverManager_.takeRecords();
std::vector<NativeIntersectionObserverEntry> nativeModuleEntries;
nativeModuleEntries.reserve(entries.size());
for (const auto& entry : entries) {
nativeModuleEntries.emplace_back(
convertToNativeModuleEntry(entry, runtime));
}
return nativeModuleEntries;
}
NativeIntersectionObserverEntry
NativeIntersectionObserver::convertToNativeModuleEntry(
const IntersectionObserverEntry& entry,
jsi::Runtime& runtime) {
RectAsTuple targetRect = {
entry.targetRect.origin.x,
entry.targetRect.origin.y,
entry.targetRect.size.width,
entry.targetRect.size.height};
RectAsTuple rootRect = {
entry.rootRect.origin.x,
entry.rootRect.origin.y,
entry.rootRect.size.width,
entry.rootRect.size.height};
RectAsTuple intersectionRect = {
entry.intersectionRect.origin.x,
entry.intersectionRect.origin.y,
entry.intersectionRect.size.width,
entry.intersectionRect.size.height};
NativeIntersectionObserverEntry nativeModuleEntry = {
entry.intersectionObserverId,
(*entry.shadowNodeFamily).getInstanceHandle(runtime),
targetRect,
rootRect,
intersectionRect,
entry.isIntersectingAboveThresholds,
entry.time,
};
return nativeModuleEntry;
}
UIManager& NativeIntersectionObserver::getUIManagerFromRuntime(
jsi::Runtime& runtime) {
return UIManagerBinding::getBinding(runtime)->getUIManager();
}
} // namespace facebook::react