Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds option for non-ABI TurboModule provider #12383

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "Adds option for non-ABI TurboModule provider",
"packageName": "react-native-windows",
"email": "[email protected]",
"dependentChangeType": "patch"
}
24 changes: 24 additions & 0 deletions vnext/Microsoft.ReactNative.Cxx/IJsiNonAbiHostObject.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#pragma once

#include "jsi/jsi.h"
#include "winrt/Microsoft.ReactNative.h"

namespace winrt::Microsoft::ReactNative::implementation {

struct JsiNonAbiHostObject : winrt::implements<JsiNonAbiHostObject, IJsiNonAbiHostObject> {
public: // IReactNonAbiHostObject
JsiNonAbiHostObject(std::shared_ptr<facebook::jsi::HostObject> const &hostObject) noexcept
: m_hostObject{hostObject} {}

std::shared_ptr<facebook::jsi::HostObject> HostObject() const noexcept {
return m_hostObject;
}

private:
std::shared_ptr<facebook::jsi::HostObject> m_hostObject;
};

} // namespace winrt::Microsoft::ReactNative::implementation
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
<ClInclude Include="$(MSBuildThisFileDirectory)NativeModules.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)ReactDispatcher.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)ReactNonAbiValue.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)IJsiNonAbiHostObject.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)ReactNotificationService.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)ReactPropertyBag.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)ReactContext.h" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
<ClInclude Include="$(MSBuildThisFileDirectory)NativeModules.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)ReactDispatcher.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)ReactNonAbiValue.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)IJsiNonAbiHostObject.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)ReactNotificationService.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)ReactPropertyBag.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)ReactContext.h" />
Expand Down
18 changes: 18 additions & 0 deletions vnext/Microsoft.ReactNative/IJsiNonAbiHostObject.idl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#include "DocString.h"

namespace Microsoft.ReactNative
{
[webhosthidden]
[uuid("62bb563d-865a-4131-b576-f91c90c7b6f7")] // uuid needed for empty interfaces
[version(0)]
[experimental]
DOC_STRING(
"The @IJsiNonAbiHostObject helps register C++ TurboModules to JSI runtime instances "
"that bypass ABI via @ReactModuleProvider. Since React Native Windows already uses "
"@IReactNonAbiValue internally to represent attributed native modules, this wrapper "
"is needed to have an alternate interface to type check against.")
interface IJsiNonAbiHostObject {}
} // namespace Microsoft.ReactNative
17 changes: 16 additions & 1 deletion vnext/Microsoft.ReactNative/TurboModulesProvider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@
#include "pch.h"
#include "TurboModulesProvider.h"
#include <ReactCommon/TurboModuleUtils.h>
#include "IJsiNonAbiHostObject.h"
#include "JSDispatcherWriter.h"
#include "JsiApi.h"
#include "JsiReader.h"
#include "JsiWriter.h"
#include "ReactNonAbiValue.h"
#ifdef __APPLE__
#include "Crash.h"
#else
Expand Down Expand Up @@ -106,12 +108,18 @@ class TurboModuleImpl : public facebook::react::TurboModule {
m_providedModule(reactModuleProvider(m_moduleBuilder.as<IReactModuleBuilder>())) {
if (auto hostObject = m_providedModule.try_as<IJsiHostObject>()) {
m_hostObjectWrapper = std::make_shared<implementation::HostObjectWrapper>(hostObject);
} else if (auto nonAbiHostObject = m_providedModule.try_as<IJsiNonAbiHostObject>()) {
const auto nonAbiHostObjectImpl =
winrt::get_self<winrt::Microsoft::ReactNative::implementation::JsiNonAbiHostObject>(nonAbiHostObject);
m_nonAbiHostObject = nonAbiHostObjectImpl->HostObject();
}
}

std::vector<facebook::jsi::PropNameID> getPropertyNames(facebook::jsi::Runtime &rt) override {
if (m_hostObjectWrapper) {
return m_hostObjectWrapper->getPropertyNames(rt);
} else if (m_nonAbiHostObject) {
return m_nonAbiHostObject->getPropertyNames(rt);
}

std::vector<facebook::jsi::PropNameID> propertyNames;
Expand All @@ -137,6 +145,8 @@ class TurboModuleImpl : public facebook::react::TurboModule {
facebook::jsi::Value get(facebook::jsi::Runtime &runtime, const facebook::jsi::PropNameID &propName) override {
if (m_hostObjectWrapper) {
return m_hostObjectWrapper->get(runtime, propName);
} else if (m_nonAbiHostObject) {
return m_nonAbiHostObject->get(runtime, propName);
}

// it is not safe to assume that "runtime" never changes, so members are not cached here
Expand Down Expand Up @@ -380,7 +390,11 @@ class TurboModuleImpl : public facebook::react::TurboModule {
void set(facebook::jsi::Runtime &rt, const facebook::jsi::PropNameID &name, const facebook::jsi::Value &value)
override {
if (m_hostObjectWrapper) {
return m_hostObjectWrapper->set(rt, name, value);
m_hostObjectWrapper->set(rt, name, value);
return;
} else if (m_nonAbiHostObject) {
m_nonAbiHostObject->set(rt, name, value);
return;
}

facebook::react::TurboModule::set(rt, name, value);
Expand Down Expand Up @@ -409,6 +423,7 @@ class TurboModuleImpl : public facebook::react::TurboModule {
winrt::com_ptr<TurboModuleBuilder> m_moduleBuilder;
IInspectable m_providedModule;
std::shared_ptr<implementation::HostObjectWrapper> m_hostObjectWrapper;
std::shared_ptr<facebook::jsi::HostObject> m_nonAbiHostObject;
Comment on lines 425 to +426
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Up for debate, but we could presumably just have one shared_ptr here, since implementation::HostObjectWrapper derives from facebook::jsi::HostObject

std::weak_ptr<facebook::react::LongLivedObjectCollection> m_longLivedObjectCollection;
};

Expand Down
1 change: 1 addition & 0 deletions vnext/Shared/Shared.vcxitems
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,7 @@
<Midl Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\ReactCoreInjection.idl" />
<Midl Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\ReactInstanceSettings.idl" />
<Midl Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\ReactNativeHost.idl" />
<Midl Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\IJsiNonAbiHostObject.idl" />
<Midl Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\RedBoxHandler.idl" />
</ItemGroup>
<ItemGroup Condition="'$(UseFabric)' == 'true' OR '$(IncludeFabricInterface)' == 'true'">
Expand Down
1 change: 1 addition & 0 deletions vnext/Shared/Shared.vcxitems.filters
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,7 @@
<Midl Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\ReactCoreInjection.idl" />
<Midl Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\ReactInstanceSettings.idl" />
<Midl Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\ReactNativeHost.idl" />
<Midl Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\IJsiNonAbiHostObject.idl" />
<Midl Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\RedBoxHandler.idl" />
</ItemGroup>
</Project>