1// Copyright 2018-present 650 Industries. All rights reserved. 2 3#import <objc/runtime.h> 4 5#import <ABI47_0_0ExpoModulesCore/ABI47_0_0EXViewManagerAdapterClassesRegistry.h> 6#import <ABI47_0_0ExpoModulesCore/ABI47_0_0EXViewManagerAdapter.h> 7 8static const NSString *viewManagerAdapterModuleNamePrefix = @"ViewManagerAdapter_"; 9 10static IMP directEventBlockImplementation = nil; 11static dispatch_once_t directEventBlockImplementationOnceToken; 12 13@interface ABI47_0_0EXViewManagerAdapterClassesRegistry () 14 15@property (nonatomic, strong) NSMutableDictionary<Class, Class> *viewManagerAdaptersClasses; 16 17@end 18 19@implementation ABI47_0_0EXViewManagerAdapterClassesRegistry 20 21- (instancetype)init 22{ 23 if (self = [super init]) { 24 _viewManagerAdaptersClasses = [NSMutableDictionary dictionary]; 25 } 26 return self; 27} 28 29- (Class)viewManagerAdapterClassForViewManager:(ABI47_0_0EXViewManager *)viewManager 30{ 31 Class viewManagerClass = [viewManager class]; 32 if (_viewManagerAdaptersClasses[viewManagerClass] == nil) { 33 _viewManagerAdaptersClasses[(id <NSCopying>)viewManagerClass] = [self.class createViewManagerAdapterClassForViewManager:viewManager]; 34 } 35 return _viewManagerAdaptersClasses[viewManagerClass]; 36} 37 38+ (Class)createViewManagerAdapterClassForViewManager:(ABI47_0_0EXViewManager *)viewManager 39{ 40 const char *viewManagerClassName = [[viewManagerAdapterModuleNamePrefix stringByAppendingString:[viewManager viewName]] UTF8String]; 41 Class viewManagerAdapterClass = objc_allocateClassPair([ABI47_0_0EXViewManagerAdapter class], viewManagerClassName, 0); 42 Class metaClass = object_getClass(viewManagerAdapterClass); 43 44 [self _ensureDirectEventBlockImplementationIsPresent]; 45 46 for (NSString *eventName in [viewManager supportedEvents]) { 47 class_addMethod(metaClass, NSSelectorFromString([@"propConfig_" stringByAppendingString:eventName]), directEventBlockImplementation, "@@:"); 48 } 49 50 IMP viewManagerImp = imp_implementationWithBlock(^{ 51 return viewManager; 52 }); 53 class_addMethod(viewManagerAdapterClass, NSSelectorFromString(@"viewManager"), viewManagerImp, "@@:"); 54 55 return viewManagerAdapterClass; 56} 57 58+ (void)_ensureDirectEventBlockImplementationIsPresent 59{ 60 dispatch_once(&directEventBlockImplementationOnceToken, ^{ 61 directEventBlockImplementation = imp_implementationWithBlock(^{ 62 return @[@"ABI47_0_0RCTDirectEventBlock"]; 63 }); 64 }); 65} 66 67@end 68