mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
306a8adade
Summary: The callback `dispatchEvent` is called asynchronously on the JavaScript thread, so all data it uses must be copied to the lambda. To work around this constraint we use a shared pointer for the counter. Changelog: [Internal] Fabric-specific internal change. Reviewed By: sammy-SC Differential Revision: D24598840 fbshipit-source-id: fb5581858d54dc806863caf0c7c4f612ed6046e2
78 lines
2.3 KiB
C++
78 lines
2.3 KiB
C++
/*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
#include "ViewEventEmitter.h"
|
|
|
|
namespace facebook {
|
|
namespace react {
|
|
|
|
#pragma mark - Accessibility
|
|
|
|
void ViewEventEmitter::onAccessibilityAction(const std::string &name) const {
|
|
dispatchEvent("accessibilityAction", [name](jsi::Runtime &runtime) {
|
|
auto payload = jsi::Object(runtime);
|
|
payload.setProperty(runtime, "action", name);
|
|
return payload;
|
|
});
|
|
}
|
|
|
|
void ViewEventEmitter::onAccessibilityTap() const {
|
|
dispatchEvent("accessibilityTap");
|
|
}
|
|
|
|
void ViewEventEmitter::onAccessibilityMagicTap() const {
|
|
dispatchEvent("magicTap");
|
|
}
|
|
|
|
void ViewEventEmitter::onAccessibilityEscape() const {
|
|
dispatchEvent("accessibilityEscape");
|
|
}
|
|
|
|
#pragma mark - Layout
|
|
|
|
void ViewEventEmitter::onLayout(const LayoutMetrics &layoutMetrics) const {
|
|
// Due to State Reconciliation, `onLayout` can be called potentially many
|
|
// times with identical layoutMetrics. Ensure that the JS event is only
|
|
// dispatched when the value changes.
|
|
{
|
|
std::lock_guard<std::mutex> guard(layoutMetricsMutex_);
|
|
if (lastLayoutMetrics_ == layoutMetrics) {
|
|
return;
|
|
}
|
|
lastLayoutMetrics_ = layoutMetrics;
|
|
}
|
|
|
|
auto expectedEventCount = ++*eventCounter_;
|
|
|
|
// dispatchUniqueEvent only drops consecutive onLayout events to the same
|
|
// node. We want to drop *any* unprocessed onLayout events when there's a
|
|
// newer one.
|
|
dispatchEvent(
|
|
"layout",
|
|
[frame = layoutMetrics.frame,
|
|
expectedEventCount,
|
|
eventCounter = eventCounter_](jsi::Runtime &runtime) {
|
|
auto actualEventCount = eventCounter->load();
|
|
if (expectedEventCount != actualEventCount) {
|
|
// Drop stale events
|
|
return jsi::Value::null();
|
|
}
|
|
|
|
auto layout = jsi::Object(runtime);
|
|
layout.setProperty(runtime, "x", frame.origin.x);
|
|
layout.setProperty(runtime, "y", frame.origin.y);
|
|
layout.setProperty(runtime, "width", frame.size.width);
|
|
layout.setProperty(runtime, "height", frame.size.height);
|
|
auto payload = jsi::Object(runtime);
|
|
payload.setProperty(runtime, "layout", std::move(layout));
|
|
return jsi::Value(std::move(payload));
|
|
});
|
|
}
|
|
|
|
} // namespace react
|
|
} // namespace facebook
|