Allow value extraction from folly::dynamic events (#50032)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/50032

In the new architecture, Android dispatches all events with folly::dynamic payloads. Various other callsites in some host platforms similarly dispatch events with folly::dynamic payloads.

Events disptached with folly::dynamic payloads have alignment with the `EventPayload::extractValue` method, added for integration with other capabilities like native animations.

When combined with a general pupose synchronous listener on facebook::react::EventEmitter, this should allow easier integration with host platform native event animation drivers.

## Changelog

[Internal]

Reviewed By: javache

Differential Revision: D71198197

fbshipit-source-id: 5e49e3b0fb01079870fbc7fc7e74ca0db354cda5
This commit is contained in:
Eric Rozell
2025-03-18 12:12:03 -07:00
committed by Facebook GitHub Bot
parent be92588a7f
commit 9d7cdfef17
3 changed files with 79 additions and 7 deletions
@@ -0,0 +1,44 @@
/*
* 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 "DynamicEventPayload.h"
#include <jsi/JSIDynamic.h>
namespace facebook::react {
DynamicEventPayload::DynamicEventPayload(folly::dynamic&& payload)
: payload_(std::move(payload)) {}
jsi::Value DynamicEventPayload::asJSIValue(jsi::Runtime& runtime) const {
return jsi::valueFromDynamic(runtime, payload_);
}
EventPayloadType DynamicEventPayload::getType() const {
return EventPayloadType::ValueFactory;
}
std::optional<double> DynamicEventPayload::extractValue(
const std::vector<std::string>& path) const {
auto dynamic = payload_;
for (auto& key : path) {
auto type = dynamic.type();
if ((type == folly::dynamic::Type::OBJECT ||
type == folly::dynamic::Type::ARRAY) &&
!dynamic.empty()) {
dynamic = folly::dynamic(dynamic[key]);
}
}
if (dynamic.type() == folly::dynamic::Type::DOUBLE) {
return dynamic.asDouble();
} else if (dynamic.type() == folly::dynamic::Type::INT64) {
return dynamic.asInt();
}
return std::nullopt;
}
} // namespace facebook::react
@@ -0,0 +1,30 @@
/*
* 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 <folly/dynamic.h>
#include <react/renderer/core/EventPayload.h>
namespace facebook::react {
struct DynamicEventPayload : public EventPayload {
explicit DynamicEventPayload(folly::dynamic&& payload);
/*
* EventPayload implementations
*/
jsi::Value asJSIValue(jsi::Runtime& runtime) const override;
EventPayloadType getType() const override;
std::optional<double> extractValue(
const std::vector<std::string>& path) const override;
private:
folly::dynamic payload_;
};
} // namespace facebook::react
@@ -9,9 +9,9 @@
#include <cxxreact/TraceSection.h>
#include <folly/dynamic.h>
#include <jsi/JSIDynamic.h>
#include <jsi/jsi.h>
#include "DynamicEventPayload.h"
#include "RawEvent.h"
namespace facebook::react {
@@ -61,18 +61,16 @@ void EventEmitter::dispatchEvent(
RawEvent::Category category) const {
dispatchEvent(
std::move(type),
[payload](jsi::Runtime& runtime) {
return valueFromDynamic(runtime, payload);
},
std::make_shared<DynamicEventPayload>(folly::dynamic(payload)),
category);
}
void EventEmitter::dispatchUniqueEvent(
std::string type,
const folly::dynamic& payload) const {
dispatchUniqueEvent(std::move(type), [payload](jsi::Runtime& runtime) {
return valueFromDynamic(runtime, payload);
});
dispatchUniqueEvent(
std::move(type),
std::make_shared<DynamicEventPayload>(folly::dynamic(payload)));
}
void EventEmitter::dispatchEvent(