Skip to content

Commit 531347d

Browse files
authored
Avoid throwing away native module calls (#248)
The current implementation of `JsiDispatchEvent` calls directly into `callFunctionReturnFlushedQueue` to trigger a call into the JS code. Unfortunately, this call returns an array which is a list of native module calls which should be made. But this code is not able to call those native modules since that code is not exposed. So instead, there are just a set of native module calls which never get called. This PR replaces the call to `callFunctionReturnFlushedQueue` with a call directly into the `RCTEventEmitter.receiveEvent` function, which will not do the flush. The flush will be done by the `ExecuteJsi` function, which will correctly flush and call the native modules returned. Fixes #247 ###### Microsoft Reviewers: [Open in CodeFlow](https://portal.fabricbot.ms/api/codeflow?pullrequest=https://github.com/microsoft/react-native-xaml/pull/248) ###### Microsoft Reviewers: [Open in CodeFlow](https://portal.fabricbot.ms/api/codeflow?pullrequest=https://github.com/microsoft/react-native-xaml/pull/248)
1 parent 50523ff commit 531347d

File tree

6 files changed

+16
-12
lines changed

6 files changed

+16
-12
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "Avoid throwing away native module calls.",
4+
"packageName": "react-native-xaml",
5+
"email": "30809111+acoates-ms@users.noreply.github.com",
6+
"dependentChangeType": "patch"
7+
}

package/Codegen/TypeEvents.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public virtual string TransformText()
7676
"atchTheEvent(const EventAttachInfo& eai, const winrt::Windows::Foundation::IInsp" +
7777
"ectable& sender, const T& args) {\r\n auto senderAsFE = sender.try_as<FrameworkEl" +
7878
"ement>();\r\n auto wEN = winrt::to_hstring(eai.jsEventName);\r\n if (eai.xamlMetad" +
79-
"ata.m_callFunctionReturnFlushedQueue.has_value()) {\r\n const auto tag = XamlMe" +
79+
"ata.m_receiveEvent.has_value()) {\r\n const auto tag = XamlMe" +
8080
"tadata::TagFromElement(eai.obj.as<xaml::DependencyObject>());\r\n ExecuteJsi(ea" +
8181
"i.context, [metadata = eai.xamlMetadata.shared_from_this(), tag, senderAsFE, arg" +
8282
"s, eventName = eai.jsEventName](facebook::jsi::Runtime& rt) {\r\n auto objSen" +

package/Codegen/TypeEvents.tt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ template<typename T>
3434
__declspec(noinline) void DispatchTheEvent(const EventAttachInfo& eai, const winrt::Windows::Foundation::IInspectable& sender, const T& args) {
3535
auto senderAsFE = sender.try_as<FrameworkElement>();
3636
auto wEN = winrt::to_hstring(eai.jsEventName);
37-
if (eai.xamlMetadata.m_callFunctionReturnFlushedQueue.has_value()) {
37+
if (eai.xamlMetadata.m_receiveEvent.has_value()) {
3838
const auto tag = XamlMetadata::TagFromElement(eai.obj.as<xaml::DependencyObject>());
3939
ExecuteJsi(eai.context, [metadata = eai.xamlMetadata.shared_from_this(), tag, senderAsFE, args, eventName = eai.jsEventName](facebook::jsi::Runtime& rt) {
4040
auto objSender = std::make_shared<XamlObject>(senderAsFE, metadata);

package/windows/ReactNativeXaml/Codegen/TypeEvents.g.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ template<typename T>
3434
__declspec(noinline) void DispatchTheEvent(const EventAttachInfo& eai, const winrt::Windows::Foundation::IInspectable& sender, const T& args) {
3535
auto senderAsFE = sender.try_as<FrameworkElement>();
3636
auto wEN = winrt::to_hstring(eai.jsEventName);
37-
if (eai.xamlMetadata.m_callFunctionReturnFlushedQueue.has_value()) {
37+
if (eai.xamlMetadata.m_receiveEvent.has_value()) {
3838
const auto tag = XamlMetadata::TagFromElement(eai.obj.as<xaml::DependencyObject>());
3939
ExecuteJsi(eai.context, [metadata = eai.xamlMetadata.shared_from_this(), tag, senderAsFE, args, eventName = eai.jsEventName](facebook::jsi::Runtime& rt) {
4040
auto objSender = std::make_shared<XamlObject>(senderAsFE, metadata);

package/windows/ReactNativeXaml/XamlMetadata.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ void XamlMetadata::SetupEventDispatcher(const IReactContext& reactContext) {
4040
auto batchedBridge = rt.global().getProperty(rt, "__fbBatchedBridge");
4141
if (!batchedBridge.isUndefined() && batchedBridge.isObject()) {
4242
if (auto vm = shared.get()) {
43-
vm->m_callFunctionReturnFlushedQueue = batchedBridge.asObject(rt).getPropertyAsFunction(
44-
rt, "callFunctionReturnFlushedQueue");
43+
auto getCallableModule = batchedBridge.asObject(rt).getPropertyAsFunction(rt, "getCallableModule");
44+
vm->m_eventEmitter = getCallableModule.callWithThis(rt, batchedBridge.asObject(rt), "RCTEventEmitter").asObject(rt);
45+
vm->m_receiveEvent = vm->m_eventEmitter->getPropertyAsFunction(rt, "receiveEvent");
4546
}
4647
}
4748
});
@@ -332,12 +333,7 @@ const EventInfo* XamlMetadata::AttachEvent(const winrt::Microsoft::ReactNative::
332333
}
333334

334335
void XamlMetadata::JsiDispatchEvent(jsi::Runtime& rt, int64_t viewTag, std::string&& eventName, std::shared_ptr<facebook::jsi::Object>& eventData) const noexcept {
335-
auto params = jsi::Array(rt, 3);
336-
params.setValueAtIndex(rt, 0, static_cast<int>(viewTag));
337-
params.setValueAtIndex(rt, 1, eventName);
338-
params.setValueAtIndex(rt, 2, *eventData.get());
339-
340-
m_callFunctionReturnFlushedQueue->call(rt, "RCTEventEmitter", "receiveEvent", params);
336+
m_receiveEvent->callWithThis(rt, *m_eventEmitter, static_cast<int>(viewTag), std::move(eventName), *eventData.get());
341337
}
342338

343339

package/windows/ReactNativeXaml/XamlMetadata.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,8 @@ struct XamlMetadata : std::enable_shared_from_this<XamlMetadata> {
235235
void PopulateCommands(const winrt::Windows::Foundation::Collections::IVector<winrt::hstring>& commands) const;
236236

237237
void JsiDispatchEvent(facebook::jsi::Runtime& rt, int64_t viewTag, std::string&& eventName, std::shared_ptr<facebook::jsi::Object>& eventData) const noexcept;
238-
std::optional<facebook::jsi::Function> m_callFunctionReturnFlushedQueue;
238+
std::optional<facebook::jsi::Function> m_receiveEvent;
239+
std::optional<facebook::jsi::Object> m_eventEmitter;
239240
winrt::Microsoft::ReactNative::IReactDispatcher UIDispatcher() const { return m_reactContext.UIDispatcher(); }
240241
xaml::DependencyObject ElementFromTag(int64_t tag) const { return winrt::Microsoft::ReactNative::XamlUIService::FromContext(m_reactContext).ElementFromReactTag(tag); }
241242
static int64_t TagFromElement(xaml::DependencyObject const& element);

0 commit comments

Comments
 (0)