Skip to content

Commit

Permalink
Introduce SampleLegacyModule example in RNTester (#38008)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #38008

Introduce a legacy module (+ example) in RNTester.

In the future, SampleLegacyModule will be used to:
- Showcase the TurboModule interop layer in RNTester, once Bridgeless mode is ready
- E2E Test the TurboModule interop layer.

The TurboModule interop layer is just an extension to the TurboModule system that allows the system to create legacy modules. Unlike regular TurboModules, these legacy modules don't need codegen for JavaScript -> native method dispatch.

Changelog: [Internal]

Reviewed By: cipolleschi

Differential Revision: D46874160

fbshipit-source-id: f9810d0bdb3bd0c0a74099fcb6f74ca547977a53
  • Loading branch information
RSNara authored and facebook-github-bot committed Jun 22, 2023
1 parent 7920ae8 commit a1b64b7
Show file tree
Hide file tree
Showing 5 changed files with 462 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* 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.
*/

#import <UIKit/UIKit.h>

#import <React/RCTAssert.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTInvalidating.h>
#import <React/RCTUtils.h>

@interface RCTSampleLegacyModule : NSObject <RCTBridgeModule, RCTInvalidating>
@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
/*
* 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.
*/

#import "RCTSampleLegacyModule.h"

@implementation RCTSampleLegacyModule {
RCTBridge *_bridge;
}

// Backward-compatible export
RCT_EXPORT_MODULE()

// Backward-compatible queue configuration
+ (BOOL)requiresMainQueueSetup
{
return YES;
}

- (void)setBridge:(RCTBridge *)bridge
{
_bridge = bridge;
}

- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}

// Backward compatible invalidation
- (void)invalidate
{
// Actually do nothing here.
NSLog(@"Invalidating RCTSampleTurboModule...");
}

- (NSDictionary *)getConstants
{
__block NSDictionary *constants;
RCTUnsafeExecuteOnMainQueueSync(^{
UIScreen *mainScreen = UIScreen.mainScreen;
CGSize screenSize = mainScreen.bounds.size;

constants = @{
@"const1" : @YES,
@"const2" : @(screenSize.width),
@"const3" : @"something",
};
});

return constants;
}

// TODO: Remove once fully migrated to TurboModule.
- (NSDictionary *)constantsToExport
{
return [self getConstants];
}

RCT_EXPORT_METHOD(voidFunc)
{
// Nothing to do
}

RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSNumber *, getBool : (BOOL)arg)
{
return @(arg);
}

RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSNumber *, getEnum : (double)arg)
{
return @(arg);
}

RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSNumber *, getNumber : (double)arg)
{
return @(arg);
}

RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSNumber *, getFloat : (float)arg)
{
return @(arg);
}

RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSNumber *, getInt : (int)arg)
{
return @(arg);
}

RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSNumber *, getLongLong : (int64_t)arg)
{
return @(arg);
}

RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSNumber *, getUnsignedLongLong : (uint64_t)arg)
{
return @(arg);
}

RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSNumber *, getNSInteger : (NSInteger)arg)
{
return @(arg);
}

RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSNumber *, getNSUInteger : (NSUInteger)arg)
{
return @(arg);
}

RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSArray<id<NSObject>> *, getArray : (NSArray *)arg)
{
return arg;
}

RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, getObject : (NSDictionary *)arg)
{
return arg;
}

RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSString *, getString : (NSString *)arg)
{
return arg;
}

RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSNumber *, getNSNumber : (nonnull NSNumber *)arg)
{
return arg;
}

RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, getUnsafeObject : (NSDictionary *)arg)
{
return arg;
}

RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSNumber *, getRootTag : (double)arg)
{
return @(arg);
}

RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, getValue : (double)x y : (NSString *)y z : (NSDictionary *)z)
{
return @{
@"x" : @(x),
@"y" : y ?: [NSNull null],
@"z" : z ?: [NSNull null],
};
}

RCT_EXPORT_METHOD(getValueWithCallback : (RCTResponseSenderBlock)callback)
{
if (!callback) {
return;
}
callback(@[ @"value from callback!" ]);
}

RCT_EXPORT_METHOD(getValueWithPromise
: (BOOL)error resolve
: (RCTPromiseResolveBlock)resolve reject
: (RCTPromiseRejectBlock)reject)
{
if (!resolve || !reject) {
return;
}

if (error) {
reject(
@"code_1",
@"intentional promise rejection",
[NSError errorWithDomain:@"RCTSampleTurboModule" code:1 userInfo:nil]);
} else {
resolve(@"result!");
}
}

RCT_EXPORT_METHOD(voidFuncThrows)
{
NSException *myException = [NSException exceptionWithName:@"Excepption"
reason:@"Intentional exception from ObjC voidFuncThrows"
userInfo:nil];
@throw myException;
}

RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, getObjectThrows : (NSDictionary *)arg)
{
NSException *myException = [NSException exceptionWithName:@"Excepption"
reason:@"Intentional exception from ObjC getObjectThrows"
userInfo:nil];
@throw myException;
}

RCT_EXPORT_METHOD(promiseThrows
: (BOOL)error resolve
: (RCTPromiseResolveBlock)resolve reject
: (RCTPromiseRejectBlock)reject)
{
NSException *myException = [NSException exceptionWithName:@"Excepption"
reason:@"Intentional exception from ObjC promiseThrows"
userInfo:nil];
@throw myException;
}

RCT_EXPORT_METHOD(voidFuncAssert)
{
RCTAssert(false, @"Intentional assert from ObjC voidFuncAssert");
}

RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, getObjectAssert : (NSDictionary *)arg)
{
RCTAssert(false, @"Intentional assert from ObjC getObjectAssert");
return arg;
}

RCT_EXPORT_METHOD(promiseAssert
: (BOOL)error resolve
: (RCTPromiseResolveBlock)resolve reject
: (RCTPromiseRejectBlock)reject)
{
RCTAssert(false, @"Intentional assert from ObjC promiseAssert");
}

@end
29 changes: 29 additions & 0 deletions packages/rn-tester/js/examples/TurboModule/LegacyModuleExample.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* 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.
*
* @format
* @flow
*/

'use strict';

const React = require('react');
const {
default: SampleLegacyModuleExample,
} = require('./SampleLegacyModuleExample');

exports.displayName = (undefined: ?string);
exports.title = 'Legacy Native Module';
exports.category = 'Basic';
exports.description = 'Usage of legacy Native Module';
exports.examples = [
{
title: 'SampleLegacyModule',
render: function (): React.Element<any> {
return <SampleLegacyModuleExample />;
},
},
];
Loading

0 comments on commit a1b64b7

Please sign in to comment.