Skip to content

Commit

Permalink
[0.72] Port #11718 and #11849 to 0.72 (#11913)
Browse files Browse the repository at this point in the history
* Get StructInfo<T>::FieldMap lazy initialized (#11718)

* Get StructInfo<T>::FieldMap lazy initialized

* yarn format

* Change files

* Add REACT_MODULE_NOREG which is REACT_MODULE but without auto registration (#11849)

* #define REACT_MODULE_NOREG

* yarn format

* Add unit test

* ...

* ...

* Change files

* Change files
  • Loading branch information
ZihanChen-MSFT committed Jul 20, 2023
1 parent 39eae21 commit 4765f49
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Port #11718 and #11849 to 0.72",
"packageName": "react-native-windows",
"email": "53799235+ZihanChen-MSFT@users.noreply.github.com",
"dependentChangeType": "patch"
}
12 changes: 12 additions & 0 deletions vnext/Microsoft.ReactNative.Cxx.UnitTests/NativeModuleTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,18 @@ TEST_CLASS (NativeModuleTest) {
m_module = React::ReactNonAbiValue<SimpleNativeModule>::GetPtrUnsafe(m_moduleObject);
}

TEST_METHOD(EnsureReactModuleAutoRegistered) {
bool registered = false;
auto current = React::ModuleRegistration::Head();
while (current) {
if (wcscmp(current->ModuleName(), L"SimpleNativeModule") == 0) {
registered = true;
}
current = current->Next();
}
TestCheck(registered);
}

TEST_METHOD(TestMethodCall_Add) {
m_builderMock.Call1(L"Add", std::function<void(int)>([](int result) noexcept { TestCheck(result == 8); }), 3, 5);
TestCheck(m_builderMock.IsResolveCallbackCalled());
Expand Down
2 changes: 1 addition & 1 deletion vnext/Microsoft.ReactNative.Cxx/JSValueReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ inline void ReadValue(IJSValueReader const &reader, /*out*/ JSValueArray &value)
template <class T, std::enable_if_t<!std::is_void_v<decltype(GetStructInfo(static_cast<T *>(nullptr)))>, int>>
inline void ReadValue(IJSValueReader const &reader, /*out*/ T &value) noexcept {
if (reader.ValueType() == JSValueType::Object) {
const auto &fieldMap = StructInfo<T>::FieldMap;
const auto &fieldMap = StructInfo<T>::GetFieldMap();
hstring propertyName;
while (reader.GetNextObjectProperty(/*out*/ propertyName)) {
auto it = fieldMap.find(std::wstring_view(propertyName));
Expand Down
2 changes: 1 addition & 1 deletion vnext/Microsoft.ReactNative.Cxx/JSValueWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ inline void WriteCustomDirectEventTypeConstant(IJSValueWriter const &writer, std
template <class T, std::enable_if_t<!std::is_void_v<decltype(GetStructInfo(static_cast<T *>(nullptr)))>, int>>
inline void WriteValue(IJSValueWriter const &writer, T const &value) noexcept {
writer.WriteObjectBegin();
for (const auto &fieldEntry : StructInfo<T>::FieldMap) {
for (const auto &fieldEntry : StructInfo<T>::GetFieldMap()) {
writer.WritePropertyName(fieldEntry.first);
fieldEntry.second.WriteField(writer, &value);
}
Expand Down
22 changes: 22 additions & 0 deletions vnext/Microsoft.ReactNative.Cxx/ModuleRegistration.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,28 @@
INTERNAL_REACT_RECOMPOSER_4( \
(__VA_ARGS__, INTERNAL_REACT_MODULE_3_ARGS, INTERNAL_REACT_MODULE_2_ARGS, INTERNAL_REACT_MODULE_1_ARG, ))

// Another version of REACT_MODULE but does not do auto registration
#define INTERNAL_REACT_MODULE_NOREG_3_ARGS(moduleStruct, moduleName, eventEmitterName) \
struct moduleStruct; \
template <class TRegistry> \
constexpr void GetReactModuleInfo(moduleStruct *, TRegistry &registry) noexcept { \
registry.RegisterModule( \
moduleName, eventEmitterName, winrt::Microsoft::ReactNative::ReactAttributeId<__COUNTER__>{}); \
}

#define INTERNAL_REACT_MODULE_NOREG_2_ARGS(moduleStruct, moduleName) \
INTERNAL_REACT_MODULE_NOREG_3_ARGS(moduleStruct, moduleName, L"")

#define INTERNAL_REACT_MODULE_NOREG_1_ARG(moduleStruct) \
INTERNAL_REACT_MODULE_NOREG_2_ARGS(moduleStruct, L## #moduleStruct)

#define INTERNAL_REACT_MODULE_NOREG(...) \
INTERNAL_REACT_RECOMPOSER_4( \
(__VA_ARGS__, \
INTERNAL_REACT_MODULE_NOREG_3_ARGS, \
INTERNAL_REACT_MODULE_NOREG_2_ARGS, \
INTERNAL_REACT_MODULE_NOREG_1_ARG, ))

// Provide meta data information about struct member.
// For each member with a 'custom attribute' macro we create a static method to provide meta data.
// The member Id is generated as a ReactMemberId<__COUNTER__> type.
Expand Down
5 changes: 5 additions & 0 deletions vnext/Microsoft.ReactNative.Cxx/NativeModules.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
#define REACT_MODULE(/* moduleStruct, [opt] moduleName, [opt] eventEmitterName */...) \
INTERNAL_REACT_MODULE(__VA_ARGS__)(__VA_ARGS__)

// REACT_MODULE_NOREG is REACT_MODULE without auto registration
// they have the same arguments
#define REACT_MODULE_NOREG(/* moduleStruct, [opt] moduleName, [opt] eventEmitterName */...) \
INTERNAL_REACT_MODULE_NOREG(__VA_ARGS__)(__VA_ARGS__)

// REACT_INIT(method)
// Arguments:
// - method (required) - the method name the macro is attached to.
Expand Down
8 changes: 4 additions & 4 deletions vnext/Microsoft.ReactNative.Cxx/StructInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,12 @@ void FieldWriter(IJSValueWriter const &writer, const void *obj, const uintptr_t

template <class T>
struct StructInfo {
static const FieldMap FieldMap;
static const FieldMap &GetFieldMap() {
static const FieldMap fieldMap = GetStructInfo(static_cast<T *>(nullptr));
return fieldMap;
}
};

template <class T>
/*static*/ const FieldMap StructInfo<T>::FieldMap = GetStructInfo(static_cast<T *>(nullptr));

template <int I>
using ReactFieldId = std::integral_constant<int, I>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ struct CppTurboModuleSpec : TurboModuleSpec {
}
};

REACT_MODULE(CppTurboModule)
REACT_MODULE_NOREG(CppTurboModule)
struct CppTurboModule {
using ModuleSpec = CppTurboModuleSpec;

Expand Down Expand Up @@ -558,6 +558,18 @@ struct CppTurboModulePackageProvider : winrt::implements<CppTurboModulePackagePr
} // namespace

TEST_CLASS (TurboModuleTests) {
TEST_METHOD(EnsureReactModuleNotAutoRegistered) {
bool registered = false;
auto current = ModuleRegistration::Head();
while (current) {
if (wcscmp(current->ModuleName(), L"CppTurboModule") == 0) {
registered = true;
}
current = current->Next();
}
TestCheck(!registered);
}

TEST_METHOD(ExecuteSampleTurboModule) {
TestEventService::Initialize();

Expand Down

0 comments on commit 4765f49

Please sign in to comment.