Convert RCTImageLoader to TurboModules [4/N]

Summary:
This diff adds a JS spec for RCTImageLoader, and conforms to it in ObjC++. Since RCTImageLoader isn't called from JS, the js spec is empty. Since `/CoreModules/` is the only dir in OSS which supports TM, move the ObjC++ impl there.

The change in `NativeExceptionsManager.js` fixes a weird bug I was hitting in codegen, where the codegen cpp file wouldn't compile due to unused variable.

Reviewed By: JoshuaGross

Differential Revision: D16495674

fbshipit-source-id: 191897b87730a6b0b96022eedc6412551fae04a6
This commit is contained in:
Peter Argany 2019-08-15 11:27:29 -07:00 коммит произвёл Facebook Github Bot
Родитель 6c3b01d07f
Коммит 30c1196d7d
10 изменённых файлов: 104 добавлений и 55 удалений

Просмотреть файл

@ -29,7 +29,8 @@ export type ExceptionData = {
stack: Array<StackFrame>,
id: number,
isFatal: boolean,
extraData?: ?{},
// flowlint-next-line unclear-type:off
extraData?: Object,
};
export interface Spec extends TurboModule {

Просмотреть файл

@ -855,12 +855,6 @@ namespace facebook {
return facebook::react::managedPointer<JS::NativeExceptionsManager::StackFrame>(json);
}
@end
@implementation RCTCxxConvert (NativeExceptionsManager_ExceptionDataExtraData)
+ (RCTManagedPointer *)JS_NativeExceptionsManager_ExceptionDataExtraData:(id)json
{
return facebook::react::managedPointer<JS::NativeExceptionsManager::ExceptionDataExtraData>(json);
}
@end
@implementation RCTCxxConvert (NativeExceptionsManager_ExceptionData)
+ (RCTManagedPointer *)JS_NativeExceptionsManager_ExceptionData:(id)json
{
@ -1082,6 +1076,19 @@ namespace facebook {
}
} // namespace react
} // namespace facebook
namespace facebook {
namespace react {
NativeImageLoaderSpecJSI::NativeImageLoaderSpecJSI(id<RCTTurboModule> instance, std::shared_ptr<JSCallInvoker> jsInvoker)
: ObjCTurboModule("ImageLoader", instance, jsInvoker) {
}
} // namespace react

Просмотреть файл

@ -880,21 +880,6 @@ namespace JS {
+ (RCTManagedPointer *)JS_NativeExceptionsManager_StackFrame:(id)json;
@end
namespace JS {
namespace NativeExceptionsManager {
struct ExceptionDataExtraData {
ExceptionDataExtraData(NSDictionary *const v) : _v(v) {}
private:
NSDictionary *_v;
};
}
}
@interface RCTCxxConvert (NativeExceptionsManager_ExceptionDataExtraData)
+ (RCTManagedPointer *)JS_NativeExceptionsManager_ExceptionDataExtraData:(id)json;
@end
namespace JS {
namespace NativeExceptionsManager {
struct ExceptionData {
@ -905,7 +890,7 @@ namespace JS {
facebook::react::LazyVector<JS::NativeExceptionsManager::StackFrame> stack() const;
double id_() const;
bool isFatal() const;
folly::Optional<JS::NativeExceptionsManager::ExceptionDataExtraData> extraData() const;
id<NSObject> _Nullable extraData() const;
ExceptionData(NSDictionary *const v) : _v(v) {}
private:
@ -1099,6 +1084,21 @@ namespace facebook {
};
} // namespace react
} // namespace facebook
@protocol NativeImageLoaderSpec <RCTBridgeModule, RCTTurboModule>
@end
namespace facebook {
namespace react {
/**
* ObjC++ class for module 'ImageLoader'
*/
class JSI_EXPORT NativeImageLoaderSpecJSI : public ObjCTurboModule {
public:
NativeImageLoaderSpecJSI(id<RCTTurboModule> instance, std::shared_ptr<JSCallInvoker> jsInvoker);
};
} // namespace react
} // namespace facebook
namespace JS {
namespace NativeImagePickerIOS {
@ -2682,7 +2682,6 @@ inline folly::Optional<bool> JS::NativeExceptionsManager::StackFrame::collapse()
id const p = _v[@"collapse"];
return RCTBridgingToOptionalBool(p);
}
inline NSString *JS::NativeExceptionsManager::ExceptionData::message() const
{
id const p = _v[@"message"];
@ -2718,10 +2717,10 @@ inline bool JS::NativeExceptionsManager::ExceptionData::isFatal() const
id const p = _v[@"isFatal"];
return RCTBridgingToBool(p);
}
inline folly::Optional<JS::NativeExceptionsManager::ExceptionDataExtraData> JS::NativeExceptionsManager::ExceptionData::extraData() const
inline id<NSObject> _Nullable JS::NativeExceptionsManager::ExceptionData::extraData() const
{
id const p = _v[@"extraData"];
return (p == nil ? folly::none : folly::make_optional(JS::NativeExceptionsManager::ExceptionDataExtraData(p)));
return p;
}
inline folly::Optional<bool> JS::NativeFrameRateLogger::SpecSetGlobalOptionsOptions::debug() const
{

Просмотреть файл

@ -0,0 +1,20 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
* @format
*/
'use strict';
import type {TurboModule} from '../TurboModule/RCTExport';
import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry';
export interface Spec extends TurboModule {
+getConstants: () => {||};
}
export default TurboModuleRegistry.getEnforcing<Spec>('ImageLoader');

Просмотреть файл

@ -377,4 +377,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 060903e270072f1e192b064848e6c34528af1c87
COCOAPODS: 1.6.1
COCOAPODS: 1.7.1

Просмотреть файл

@ -38,9 +38,13 @@ rn_apple_library(
["-D PIC_MODIFIER=@PLT"],
)],
plugins = react_module_plugin_providers(
name = "PlatformConstants",
native_class_func = "RCTPlatformCls",
),
name = "ImageLoader",
native_class_func = "RCTImageLoaderCls",
) +
react_module_plugin_providers(
name = "PlatformConstants",
native_class_func = "RCTPlatformCls",
),
preprocessor_flags = OBJC_ARC_PREPROCESSOR_FLAGS + get_debug_preprocessor_flags() + rn_debug_flags() + [
"-DRN_DISABLE_OSS_PLUGIN_HEADER",
],

Просмотреть файл

@ -29,6 +29,7 @@ extern "C" {
Class RCTCoreModulesClassProvider(const char *name);
// Lookup functions
Class RCTImageLoaderCls(void);
Class RCTPlatformCls(void);
#ifdef __cplusplus

Просмотреть файл

@ -17,7 +17,8 @@
#import <unordered_map>
static std::unordered_map<std::string, Class (*)(void)> sCoreModuleClassMap = {
{"PlatformConstants", RCTPlatformCls},
{"ImageLoader", RCTImageLoaderCls},
{"PlatformConstants", RCTPlatformCls},
};
Class RCTCoreModulesClassProvider(const char *name) {

Просмотреть файл

@ -10,13 +10,12 @@
#import <UIKit/UIKit.h>
#import <React/RCTConvert.h>
#import <React/RCTLog.h>
#import <React/RCTUtils.h>
#import <React/RCTImageLoader.h>
#import <React/RCTImageStoreManager.h>
#import <React/RCTImageUtils.h>
#import <React/RCTImageLoaderProtocol.h>
#import <React/RCTLog.h>
#import <React/RCTUtils.h>
@implementation RCTImageEditingManager

Просмотреть файл

@ -5,20 +5,22 @@
* LICENSE file in the root directory of this source tree.
*/
#import <stdatomic.h>
#import <objc/runtime.h>
#import <atomic>
#import <ImageIO/ImageIO.h>
#import <FBReactNativeSpec/FBReactNativeSpec.h>
#import <React/RCTConvert.h>
#import <React/RCTDefines.h>
#import <React/RCTImageCache.h>
#import <React/RCTImageLoader.h>
#import <React/RCTImageUtils.h>
#import <React/RCTLog.h>
#import <React/RCTNetworking.h>
#import <React/RCTUtils.h>
#import <React/RCTImageCache.h>
#import <React/RCTImageUtils.h>
#import "CoreModulesPlugins.h"
static NSInteger RCTImageBytesForImage(UIImage *image)
{
@ -26,6 +28,10 @@ static NSInteger RCTImageBytesForImage(UIImage *image)
return image.images ? image.images.count * singleImageBytes : singleImageBytes;
}
@interface RCTImageLoader() <NativeImageLoaderSpec>
@end
@implementation UIImage (React)
- (NSInteger)reactDecodedImageBytes
@ -385,7 +391,7 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
BOOL cacheResult = [loadHandler respondsToSelector:@selector(shouldCacheLoadedImages)] ?
[loadHandler shouldCacheLoadedImages] : YES;
__block atomic_bool cancelled = ATOMIC_VAR_INIT(NO);
auto cancelled = std::make_shared<std::atomic<int>>(0);
__block dispatch_block_t cancelLoad = nil;
__block NSLock *cancelLoadLock = [NSLock new];
void (^completionHandler)(NSError *, id, NSURLResponse *) = ^(NSError *error, id imageOrData, NSURLResponse *response) {
@ -399,11 +405,11 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
// Most loaders do not return on the main thread, so caller is probably not
// expecting it, and may do expensive post-processing in the callback
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (!atomic_load(&cancelled)) {
if (!std::atomic_load(cancelled.get())) {
completionBlock(error, imageOrData, cacheResult, response);
}
});
} else if (!atomic_load(&cancelled)) {
} else if (!std::atomic_load(cancelled.get())) {
completionBlock(error, imageOrData, cacheResult, response);
}
};
@ -430,8 +436,8 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
__weak RCTImageLoader *weakSelf = self;
dispatch_async(_URLRequestQueue, ^{
__typeof(self) strongSelf = weakSelf;
if (atomic_load(&cancelled) || !strongSelf) {
return;
if (atomic_load(cancelled.get()) || !strongSelf) {
return;
}
if (loadHandler) {
@ -471,7 +477,7 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
});
return ^{
BOOL alreadyCancelled = atomic_fetch_or(&cancelled, 1);
BOOL alreadyCancelled = atomic_fetch_or(cancelled.get(), 1);
if (alreadyCancelled) {
return;
}
@ -605,11 +611,11 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
partialLoadBlock:(RCTImageLoaderPartialLoadBlock)partialLoadBlock
completionBlock:(RCTImageLoaderCompletionBlock)completionBlock
{
__block atomic_bool cancelled = ATOMIC_VAR_INIT(NO);
auto cancelled = std::make_shared<std::atomic<int>>(0);
__block dispatch_block_t cancelLoad = nil;
__block NSLock *cancelLoadLock = [NSLock new];
dispatch_block_t cancellationBlock = ^{
BOOL alreadyCancelled = atomic_fetch_or(&cancelled, 1);
BOOL alreadyCancelled = atomic_fetch_or(cancelled.get(), 1);
if (alreadyCancelled) {
return;
}
@ -625,7 +631,7 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
__weak RCTImageLoader *weakSelf = self;
void (^completionHandler)(NSError *, id, BOOL, NSURLResponse *) = ^(NSError *error, id imageOrData, BOOL cacheResult, NSURLResponse *response) {
__typeof(self) strongSelf = weakSelf;
if (atomic_load(&cancelled) || !strongSelf) {
if (std::atomic_load(cancelled.get()) || !strongSelf) {
return;
}
@ -685,17 +691,17 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
return ^{};
}
__block atomic_bool cancelled = ATOMIC_VAR_INIT(NO);
auto cancelled = std::make_shared<std::atomic<int>>(0);
void (^completionHandler)(NSError *, UIImage *) = ^(NSError *error, UIImage *image) {
if (RCTIsMainQueue()) {
// Most loaders do not return on the main thread, so caller is probably not
// expecting it, and may do expensive post-processing in the callback
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (!atomic_load(&cancelled)) {
if (!std::atomic_load(cancelled.get())) {
completionBlock(error, clipped ? RCTResizeImageIfNeeded(image, size, scale, resizeMode) : image);
}
});
} else if (!atomic_load(&cancelled)) {
} else if (!std::atomic_load(cancelled.get())) {
completionBlock(error, clipped ? RCTResizeImageIfNeeded(image, size, scale, resizeMode) : image);
}
};
@ -717,7 +723,7 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
// Do actual decompression on a concurrent background queue
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (!atomic_load(&cancelled)) {
if (!std::atomic_load(cancelled.get())) {
// Decompress the image data (this may be CPU and memory intensive)
UIImage *image = RCTDecodeImageWithData(data, size, scale, resizeMode);
@ -774,7 +780,7 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
});
return ^{
atomic_store(&cancelled, YES);
std::atomic_store(cancelled.get(), 1);
};
}
}
@ -795,8 +801,8 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
case kCGImagePropertyOrientationRightMirrored:
// swap width and height
size = (CGSize){
[meta[(id)kCGImagePropertyPixelHeight] doubleValue],
[meta[(id)kCGImagePropertyPixelWidth] doubleValue],
[meta[(id)kCGImagePropertyPixelHeight] floatValue],
[meta[(id)kCGImagePropertyPixelWidth] floatValue],
};
break;
case kCGImagePropertyOrientationUp:
@ -805,8 +811,8 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
case kCGImagePropertyOrientationDownMirrored:
default:
size = (CGSize){
[meta[(id)kCGImagePropertyPixelWidth] doubleValue],
[meta[(id)kCGImagePropertyPixelHeight] doubleValue],
[meta[(id)kCGImagePropertyPixelWidth] floatValue],
[meta[(id)kCGImagePropertyPixelHeight] floatValue],
};
break;
}
@ -937,6 +943,12 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
}
}
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModuleWithJsInvoker:
(std::shared_ptr<facebook::react::JSCallInvoker>)jsInvoker
{
return std::make_shared<facebook::react::NativeImageLoaderSpecJSI>(self, jsInvoker);
}
@end
/**
@ -953,3 +965,8 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
}
@end
Class RCTImageLoaderCls(void)
{
return RCTImageLoader.class;
}