This is an automated email from the ASF dual-hosted git repository. moshen pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-weex.git
The following commit(s) were added to refs/heads/master by this push: new c3dda86 [iOS] support reactor protocol to render new 18328bc Merge pull request #3225 from jianhan-he/master c3dda86 is described below commit c3dda86b2b5d916f53db066b83a10a386d483218 Author: linghe.lh <linghe...@alibaba-inc.com> AuthorDate: Thu Jun 11 10:09:33 2020 +0800 [iOS] support reactor protocol to render --- WeexSDK.podspec | 3 +- ios/sdk/WeexSDK.xcodeproj/project.pbxproj | 23 +++- ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm | 10 +- .../Sources/Component/RecycleList/WXJSASTParser.mm | 2 +- .../WeexSDK/Sources/Events/WXComponent+Events.m | 3 + ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.h | 2 + ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m | 21 +++- ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h | 10 ++ ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m | 45 +++++++- .../WeexSDK/Sources/Model/WXSDKInstance_private.h | 2 + .../WeexSDK/Sources/Protocol/WXReactorProtocol.h | 64 +++++++++++ ios/sdk/WeexSDK/Sources/WeexSDK.h | 2 + weex_core/Source/core/render/page/reactor_page.cpp | 127 +++++++++++++++++++++ weex_core/Source/core/render/page/reactor_page.h | 79 +++++++++++++ weex_core/Source/core/render/page/render_page.cpp | 4 - 15 files changed, 380 insertions(+), 17 deletions(-) diff --git a/WeexSDK.podspec b/WeexSDK.podspec index 37fbc1b..8689ebb 100644 --- a/WeexSDK.podspec +++ b/WeexSDK.podspec @@ -107,7 +107,8 @@ Pod::Spec.new do |s| 'weex_core/Source/core/layout/flex_enum.h', 'weex_core/Source/core/layout/layout.h', 'weex_core/Source/core/layout/style.h', - 'weex_core/Source/core/bridge/eagle_bridge.h' + 'weex_core/Source/core/bridge/eagle_bridge.h', + 'weex_core/Source/core/render/page/reactor_page.h' s.module_map = 'WeexSDK.modulemap' diff --git a/ios/sdk/WeexSDK.xcodeproj/project.pbxproj b/ios/sdk/WeexSDK.xcodeproj/project.pbxproj index 470c4ad..d14d0a7 100644 --- a/ios/sdk/WeexSDK.xcodeproj/project.pbxproj +++ b/ios/sdk/WeexSDK.xcodeproj/project.pbxproj @@ -575,6 +575,14 @@ BD88C14C22F02128004467AA /* render_action_update_richtext_child_style.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BD88C14822F02128004467AA /* render_action_update_richtext_child_style.cpp */; }; BD9205FB223651D900EDF93D /* eagle_bridge.h in Headers */ = {isa = PBXBuildFile; fileRef = BD9205F9223651D800EDF93D /* eagle_bridge.h */; settings = {ATTRIBUTES = (Public, ); }; }; BD9205FC223651D900EDF93D /* eagle_bridge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BD9205FA223651D800EDF93D /* eagle_bridge.cpp */; }; + BDB112982459D6C2008492F9 /* WXReactorProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = BDB112972459D6C2008492F9 /* WXReactorProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BDB1129B2459D71E008492F9 /* reactor_page.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BDB112992459D71E008492F9 /* reactor_page.cpp */; }; + BDB1129C2459D71E008492F9 /* reactor_page.h in Headers */ = {isa = PBXBuildFile; fileRef = BDB1129A2459D71E008492F9 /* reactor_page.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BDB1129D2459D802008492F9 /* WXReactorProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = BDB112972459D6C2008492F9 /* WXReactorProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BDB1129E2459D8D3008492F9 /* reactor_page.cpp in Headers */ = {isa = PBXBuildFile; fileRef = BDB112992459D71E008492F9 /* reactor_page.cpp */; }; + BDB1129F2459D8FC008492F9 /* reactor_page.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BDB112992459D71E008492F9 /* reactor_page.cpp */; }; + BDB112A02459D90F008492F9 /* reactor_page.h in Headers */ = {isa = PBXBuildFile; fileRef = BDB1129A2459D71E008492F9 /* reactor_page.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BDBA319B248D0A5200C6EDD0 /* reactor_page.cpp in Headers */ = {isa = PBXBuildFile; fileRef = BDB112992459D71E008492F9 /* reactor_page.cpp */; }; BDEEADBA22F2902E0099F1D7 /* time_calculator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BDEEADB822F2902D0099F1D7 /* time_calculator.cpp */; }; BDEEADBB22F2902E0099F1D7 /* time_calculator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BDEEADB822F2902D0099F1D7 /* time_calculator.cpp */; }; BDEEADBC22F2902E0099F1D7 /* time_calculator.h in Headers */ = {isa = PBXBuildFile; fileRef = BDEEADB922F2902E0099F1D7 /* time_calculator.h */; }; @@ -1331,6 +1339,9 @@ BD88C14822F02128004467AA /* render_action_update_richtext_child_style.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = render_action_update_richtext_child_style.cpp; sourceTree = "<group>"; }; BD9205F9223651D800EDF93D /* eagle_bridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = eagle_bridge.h; sourceTree = "<group>"; }; BD9205FA223651D800EDF93D /* eagle_bridge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = eagle_bridge.cpp; sourceTree = "<group>"; }; + BDB112972459D6C2008492F9 /* WXReactorProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXReactorProtocol.h; sourceTree = "<group>"; }; + BDB112992459D71E008492F9 /* reactor_page.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = reactor_page.cpp; sourceTree = "<group>"; }; + BDB1129A2459D71E008492F9 /* reactor_page.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = reactor_page.h; sourceTree = "<group>"; }; BDEEADB822F2902D0099F1D7 /* time_calculator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = time_calculator.cpp; sourceTree = "<group>"; }; BDEEADB922F2902E0099F1D7 /* time_calculator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = time_calculator.h; sourceTree = "<group>"; }; C401945D1E344E8300D19C31 /* WXFloatCompareTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WXFloatCompareTests.m; sourceTree = "<group>"; }; @@ -1887,6 +1898,7 @@ 77D1611C1C02DD3C0010B15B /* Protocol */ = { isa = PBXGroup; children = ( + BDB112972459D6C2008492F9 /* WXReactorProtocol.h */, D7D6B6E1238E1B1D00BE56DD /* WXDarkSchemeProtocol.h */, 33CE19122153444900CF9670 /* WXJSFrameworkLoadProtocol.h */, 17036A5220FDE7490029AE3D /* WXApmProtocol.h */, @@ -2226,6 +2238,8 @@ B8D66B372125572F003960BD /* page */ = { isa = PBXGroup; children = ( + BDB112992459D71E008492F9 /* reactor_page.cpp */, + BDB1129A2459D71E008492F9 /* reactor_page.h */, 77788B6E2229252C000D5102 /* render_page_base.cpp */, 77788B702229252C000D5102 /* render_page_base.h */, 77788B6F2229252C000D5102 /* render_page_custom.cpp */, @@ -2448,6 +2462,8 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + BDB112982459D6C2008492F9 /* WXReactorProtocol.h in Headers */, + BDB1129C2459D71E008492F9 /* reactor_page.h in Headers */, 77E659F11C0C3612008B8775 /* WXModuleFactory.h in Headers */, F75C591C2313C1FC002FFF94 /* WXStreamModule.h in Headers */, 986CEAA723B230C2004166E0 /* WXEaglePlugin.h in Headers */, @@ -2461,7 +2477,6 @@ 45E0B4C121CB7B82005D1B3B /* WXConvertUtility.h in Headers */, BD88C13F22F02111004467AA /* render_action_remove_child_from_richtext.h in Headers */, BD9205FB223651D900EDF93D /* eagle_bridge.h in Headers */, - BD9205F82236518700EDF93D /* WXDataRenderHandler.h in Headers */, D7D6B6E2238E1B1D00BE56DD /* WXDarkSchemeProtocol.h in Headers */, 7715EB6221A69DD9001F1108 /* WXRichText.h in Headers */, B8D66C1B21255730003960BD /* style.h in Headers */, @@ -2523,6 +2538,7 @@ B8D66C6B21255730003960BD /* render_scroller.h in Headers */, B8D66C6921255730003960BD /* render_mask.h in Headers */, C4C30DE91E1B833D00786B6C /* WXComponent+PseudoClassManagement.h in Headers */, + BDB1129E2459D8D3008492F9 /* reactor_page.cpp in Headers */, 591DD3321D23AD5800BE8709 /* WXErrorView.h in Headers */, B8D66C8D21255730003960BD /* render_creator.h in Headers */, 17C74F0B2072145100AB4CAB /* WXAnalyzerCenter+Transfer.h in Headers */, @@ -2700,6 +2716,8 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + BDB1129D2459D802008492F9 /* WXReactorProtocol.h in Headers */, + BDB112A02459D90F008492F9 /* reactor_page.h in Headers */, DCA4461D1EFA5AAA00D0CFA8 /* WXHandlerFactory.h in Headers */, DCA446101EFA5A8500D0CFA8 /* WXBridgeMethod.h in Headers */, DCA4461A1EFA5AA000D0CFA8 /* WXInvocationConfig.h in Headers */, @@ -2769,6 +2787,7 @@ DCA4459F1EFA56EC00D0CFA8 /* WXURLRewriteProtocol.h in Headers */, DCA445A21EFA570100D0CFA8 /* WXScrollerComponent.h in Headers */, B8D66C7621255730003960BD /* render_object.h in Headers */, + BDBA319B248D0A5200C6EDD0 /* reactor_page.cpp in Headers */, DCA445B71EFA579200D0CFA8 /* WXImgLoaderProtocol.h in Headers */, 1746EA7420E9D253007E55BD /* WXComponent_performance.h in Headers */, B8D66CEB21255B2A003960BD /* WXWebSocketLoader.h in Headers */, @@ -3208,6 +3227,7 @@ 744D61111E49979000B624B3 /* WXFooterComponent.m in Sources */, B8D66C0721255730003960BD /* core_environment.cpp in Sources */, 745B2D6F1E5A8E1E0092D38A /* WXRecyclerUpdateController.m in Sources */, + BDB1129B2459D71E008492F9 /* reactor_page.cpp in Sources */, 745B2D6B1E5A8E1E0092D38A /* WXRecyclerComponent.mm in Sources */, B8D66C0D21255730003960BD /* core_side_in_platform.cpp in Sources */, B8D66C5D21255730003960BD /* render_action_appendtree_createfinish.cpp in Sources */, @@ -3387,6 +3407,7 @@ buildActionMask = 2147483647; files = ( D77286FF22C9B22C00E1DA7D /* eagle_bridge.cpp in Sources */, + BDB1129F2459D8FC008492F9 /* reactor_page.cpp in Sources */, 453F376F219A78D700A03F1D /* WXConvertUtility.mm in Sources */, 453F376E219A789A00A03F1D /* default_request_handler.mm in Sources */, 453F376A219A784F00A03F1D /* http_module.cc in Sources */, diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm b/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm index f232ada..07db550 100644 --- a/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm +++ b/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm @@ -1821,9 +1821,9 @@ static WeexCore::ScriptBridge* jsBridge = nullptr; return nullptr; } -+ (std::vector<std::pair<std::string, std::string>>*)_parseMapValuePairs:(NSDictionary *)data ++ (std::unique_ptr<std::vector<std::pair<std::string, std::string>>>)_parseMapValuePairs:(NSDictionary *)data { - std::vector<std::pair<std::string, std::string>>* result = new std::vector<std::pair<std::string, std::string>>(); + __block std::unique_ptr<std::vector<std::pair<std::string, std::string>>> result = std::make_unique<std::vector<std::pair<std::string, std::string>>>(); [data enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { ConvertToCString(obj, ^(const char * value) { if (value != nullptr) { @@ -1831,7 +1831,7 @@ static WeexCore::ScriptBridge* jsBridge = nullptr; } }); }]; - return result; + return std::move(result); } + (void)callAddElement:(NSString*)pageId parentRef:(NSString*)parentRef data:(NSDictionary*)data index:(int)index @@ -1877,13 +1877,13 @@ static WeexCore::ScriptBridge* jsBridge = nullptr; + (void)callUpdateAttrs:(NSString*)pageId ref:(NSString*)ref data:(NSDictionary*)data { SetConvertCurrentPage(pageId); - WeexCore::RenderManager::GetInstance()->UpdateAttr([pageId UTF8String] ?: "", [ref UTF8String] ?: "", [self _parseMapValuePairs:data]); + WeexCore::RenderManager::GetInstance()->UpdateAttr([pageId UTF8String] ?: "", [ref UTF8String] ?: "", [self _parseMapValuePairs:data].get()); } + (void)callUpdateStyle:(NSString*)pageId ref:(NSString*)ref data:(NSDictionary*)data { SetConvertCurrentPage(pageId); - WeexCore::RenderManager::GetInstance()->UpdateStyle([pageId UTF8String] ?: "", [ref UTF8String] ?: "", [self _parseMapValuePairs:data]); + WeexCore::RenderManager::GetInstance()->UpdateStyle([pageId UTF8String] ?: "", [ref UTF8String] ?: "", [self _parseMapValuePairs:data].get()); } + (void)callAddEvent:(NSString*)pageId ref:(NSString*)ref event:(NSString*)event diff --git a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXJSASTParser.mm b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXJSASTParser.mm index 2d26ff0..c6a69ef 100644 --- a/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXJSASTParser.mm +++ b/ios/sdk/WeexSDK/Sources/Component/RecycleList/WXJSASTParser.mm @@ -427,7 +427,7 @@ static int binaryPrecedence(WXJSToken *token) // 3 digits are only allowed when string starts // with 0, 1, 2, 3 - if (std::string(1, '0123').find(ch) != std::string::npos && + if (std::string("0123").find(ch) != std::string::npos && _index < _length && isOctalDigit(_source[_index])) { code = code * 8 + _source[_index++] - '0'; diff --git a/ios/sdk/WeexSDK/Sources/Events/WXComponent+Events.m b/ios/sdk/WeexSDK/Sources/Events/WXComponent+Events.m index 6e7e6db..34f0c69 100644 --- a/ios/sdk/WeexSDK/Sources/Events/WXComponent+Events.m +++ b/ios/sdk/WeexSDK/Sources/Events/WXComponent+Events.m @@ -416,11 +416,14 @@ if ([removeEventName isEqualToString:@#eventName1]||[removeEventName isEqualToSt return; } if (!CGRectEqualToRect(self.view.frame, CGRectZero)) { + CGPoint pageLocation = [recognizer locationInView:self.weexInstance.rootView]; CGRect frame = [self.view.superview convertRect:self.view.frame toView:self.view.window]; position[@"x"] = @(frame.origin.x/scaleFactor); position[@"y"] = @(frame.origin.y/scaleFactor); position[@"width"] = @(frame.size.width/scaleFactor); position[@"height"] = @(frame.size.height/scaleFactor); + position[@"pageX"] = @(pageLocation.x/scaleFactor); + position[@"pageY"] = @(pageLocation.y/scaleFactor); } [self fireEvent:@"click" params:@{@"position":position}]; } diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.h b/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.h index 5fc9c54..e5fefd3 100644 --- a/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.h +++ b/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.h @@ -252,6 +252,8 @@ extern "C" { - (void)checkJSThread; ++ (NSThread *)jsThread; + @end NS_ASSUME_NONNULL_END diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m b/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m index c5106a2..5c1f455 100644 --- a/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m +++ b/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m @@ -39,6 +39,7 @@ #import "WXExceptionUtils.h" #import "WXSDKEngine.h" #import "WXConfigCenterProtocol.h" +#import "WXReactorProtocol.h" @interface WXBridgeManager () @@ -642,7 +643,16 @@ void WXPerformBlockSyncOnBridgeThreadForInstance(void (^block) (void), NSString* WXLogError(@"Event type and component ref should not be nil"); return; } - + if (instance.useReactor) { + id<WXReactorProtocol> reactorHandler = [WXHandlerFactory handlerForProtocol:NSProtocolFromString(@"WXReactorProtocol")]; + if (reactorHandler) { + [reactorHandler fireEvent:instanceId ref:ref event:type args:params?:@{} domChanges:domChanges?:@{}]; + } else { + WXLogError(@"There is no reactor handler"); + } + return; + } + NSArray *args = @[ref, type, params?:@{}, domChanges?:@{}]; if (handlerArguments) { NSMutableArray *newArgs = [args mutableCopy]; @@ -706,7 +716,14 @@ void WXPerformBlockSyncOnBridgeThreadForInstance(void (^block) (void), NSString* [instance.renderPlugin invokeCallBack:instanceId function:funcId args:strongArgs keepAlive:keepAlive]; }); } - else { + else if (instance.useReactor) { + id<WXReactorProtocol> reactorHandler = [WXHandlerFactory handlerForProtocol:NSProtocolFromString(@"WXReactorProtocol")]; + if (reactorHandler) { + [reactorHandler invokeCallBack:instanceId function:funcId args:args]; + } else { + WXLogError(@"There is no reactor handler"); + } + } else { WXCallJSMethod *method = [[WXCallJSMethod alloc] initWithModuleName:@"jsBridge" methodName:@"callback" arguments:args instance:instance]; [self callJsMethod:method]; } diff --git a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h index fec4ac6..484172b 100644 --- a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h +++ b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h @@ -121,6 +121,11 @@ typedef BOOL (^WXModuleInterceptCallback)(NSString *moduleName, NSString *method @property (nonatomic, strong) NSDictionary* containerInfo; /** +* Params for Canal +**/ +@property (nonatomic, strong) NSMutableDictionary* canalParams; + +/** * Whether this instance is rendered or not. Please MUST not render an instance twice even if you have called destroyInstance. **/ @property (nonatomic, assign, readonly) BOOL isRendered; @@ -388,6 +393,11 @@ typedef enum : NSUInteger { - (NSURL *)completeURL:(NSString *)url; /** +* register jscontext for reactor +*/ +- (void)registerReactorContext:(JSContext*)context; + +/** * jsbundle str ,may be nil (weak) */ - (NSString* _Nullable) bundleTemplate; diff --git a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m index 4879a57..31a51c8 100644 --- a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m +++ b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m @@ -54,6 +54,7 @@ #import "WXDarkSchemeProtocol.h" #import "WXDarkSchemeModule.h" #import <WeexSDK/WXEaglePluginManager.h> +#import "WXReactorProtocol.h" #define WEEX_RENDER_TYPE_PLATFORM @"platform" @@ -164,6 +165,8 @@ typedef enum : NSUInteger { _apmInstance = [[WXApmForInstance alloc] init]; _useBackupJsThread = NO; + _useReactor = NO; + _canalParams = [NSMutableDictionary dictionary]; [self addObservers]; } @@ -339,7 +342,7 @@ typedef enum : NSUInteger { return; } WXLogInfo(@"pageid: %@ renderWithURL: %@", _instanceId, url.absoluteString); - + _renderPlugin = [WXEaglePluginManager renderWithURL:&url]; if (!_renderPlugin) { _renderPlugin = [WXEaglePluginManager renderWithOption:options]; @@ -402,6 +405,21 @@ typedef enum : NSUInteger { } } +- (void)registerReactorContext:(JSContext*)context { + if (!context) { + return; + } + [WXCoreBridge install]; + [self.canalParams setObject:context forKey:@"mainJSContext"]; + + id<WXReactorProtocol> reactorHandler = [WXHandlerFactory handlerForProtocol:NSProtocolFromString(@"WXReactorProtocol")]; + if (reactorHandler) { + [reactorHandler registerJSContext:self.instanceId]; + } else { + WXLogError(@"There is no reactor handler"); + } +} + - (NSString *) bundleTemplate { return self.mainBundleString; @@ -597,7 +615,20 @@ typedef enum : NSUInteger { return; } - [[WXSDKManager bridgeMgr] createInstance:self.instanceId template:mainBundleString options:dictionary data:_jsData]; + if ([dictionary[@"USE_REACTOR"] boolValue]) { + id<WXReactorProtocol> reactorHandler = [WXHandlerFactory handlerForProtocol:NSProtocolFromString(@"WXReactorProtocol")]; + if (reactorHandler) { + _useReactor = YES; + if (![self.canalParams objectForKey:@"mainJSContext"]) { + [reactorHandler registerJSContext:self.instanceId]; + } + [reactorHandler render:self.instanceId source:mainBundleString data:_jsData]; + } else { + WXLogError(@"There is no reactor handler"); + } + } else { + [[WXSDKManager bridgeMgr] createInstance:self.instanceId template:mainBundleString options:dictionary data:_jsData]; + } WX_MONITOR_PERF_SET(WXPTBundleSize, [mainBundleString lengthOfBytesUsingEncoding:NSUTF8StringEncoding], self); @@ -830,7 +861,15 @@ typedef enum : NSUInteger { [WXPrerenderManager removePrerenderTaskforUrl:[self.scriptURL absoluteString]]; [WXPrerenderManager destroyTask:self.instanceId]; - if (!self.renderPlugin) { + + if (_useReactor) { + id<WXReactorProtocol> reactorHandler = [WXHandlerFactory handlerForProtocol:NSProtocolFromString(@"WXReactorProtocol")]; + if (reactorHandler) { + [reactorHandler unregisterJSContext:self.instanceId]; + } else { + WXLogError(@"There is no reactor handler"); + } + } else if (!self.renderPlugin) { [[WXSDKManager bridgeMgr] destroyInstance:self.instanceId]; } diff --git a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance_private.h b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance_private.h index 38e5bb2..6ea7e4d 100644 --- a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance_private.h +++ b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance_private.h @@ -36,6 +36,8 @@ @property (nonatomic, strong) NSString *mainBundleString; @property (nonatomic, weak) id <WXEaglePlugin> renderPlugin; +@property (nonatomic, assign) BOOL useReactor; + // add monitor information @property (nonatomic, strong) NSString *callCreateInstanceContext; @property (nonatomic, strong) NSString *createInstanceContextResult; diff --git a/ios/sdk/WeexSDK/Sources/Protocol/WXReactorProtocol.h b/ios/sdk/WeexSDK/Sources/Protocol/WXReactorProtocol.h new file mode 100644 index 0000000..4ac03f6 --- /dev/null +++ b/ios/sdk/WeexSDK/Sources/Protocol/WXReactorProtocol.h @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +@class JSContext; + +@protocol WXReactorProtocol <NSObject> + +@required + +/** +Weex should register a JSContext to reactor +*/ +- (void)registerJSContext:(NSString *)instanceId; + +/** + Reactor execute js source +*/ +- (void)render:(NSString *)instanceId source:(NSString*)source data:(NSDictionary* _Nullable)data; + +- (void)unregisterJSContext:(NSString *)instanceId; + +/** + When js call Weex NativeModule, invoke callback function + + @param instanceId : weex instance id + @param callbackId : callback function id + @param args : args +*/ +- (void)invokeCallBack:(NSString *)instanceId function:(NSString *)callbackId args:(NSArray * _Nullable)args; + +/** +Native event to js + +@param instanceId : instance id +@param ref : node reference +@param event : event type +@param args : parameters in event object +@param domChanges : dom value changes, used for two-way data binding +*/ +- (void)fireEvent:(NSString *)instanceId ref:(NSString *)ref event:(NSString *)event args:(NSDictionary * _Nullable)args domChanges:(NSDictionary * _Nullable)domChanges; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/sdk/WeexSDK/Sources/WeexSDK.h b/ios/sdk/WeexSDK/Sources/WeexSDK.h index 331ac78..372078a 100644 --- a/ios/sdk/WeexSDK/Sources/WeexSDK.h +++ b/ios/sdk/WeexSDK/Sources/WeexSDK.h @@ -24,6 +24,7 @@ FOUNDATION_EXPORT double WeexSDKVersionNumber; FOUNDATION_EXPORT const unsigned char WeexSDKVersionString[]; #import <WeexSDK/style.h> +#import <WeexSDK/reactor_page.h> #import <WeexSDK/layout.h> #import <WeexSDK/flex_enum.h> #import <WeexSDK/eagle_bridge.h> @@ -49,6 +50,7 @@ FOUNDATION_EXPORT const unsigned char WeexSDKVersionString[]; #import <WeexSDK/WXResourceLoader.h> #import <WeexSDK/WXRefreshComponent.h> #import <WeexSDK/WXRecyclerComponent.h> +#import <WeexSDK/WXReactorProtocol.h> #import <WeexSDK/WXPrerenderManager.h> #import <WeexSDK/WXPageEventNotifyEvent.h> #import <WeexSDK/WXNetworkProtocol.h> diff --git a/weex_core/Source/core/render/page/reactor_page.cpp b/weex_core/Source/core/render/page/reactor_page.cpp new file mode 100644 index 0000000..f151dae --- /dev/null +++ b/weex_core/Source/core/render/page/reactor_page.cpp @@ -0,0 +1,127 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "core/render/page/reactor_page.h" + +#include "core/render/manager/render_manager.h" +#include "core/render/page/render_page.h" +#include "core/render/node/factory/render_creator.h" +#include "core/manager/weex_core_manager.h" + +namespace WeexCore { + +void PostTaskOnComponentThread(const std::function<void()>& callback) { +#if OS_IOS + WeexCoreManager::Instance()->getPlatformBridge()->platform_side()->PostTaskOnComponentThread(callback); +#else + callback(); +#endif +} + +void ReactorPage::CreateBody(const std::string& ref, + const std::string& type, + const std::map<std::string, std::string>& styles, + const std::map<std::string, std::string>& attrs, + const std::vector<std::string>& events) { + RenderManager::GetInstance()->CreatePage(page_id_, [&] (RenderPage* page_instance) -> RenderObject* { +#if OS_IOS + page_instance->set_before_layout_needed(false); // do not need before and after layout on ios platform + page_instance->set_after_layout_needed(false); + page_instance->set_platform_layout_needed(true); +#endif + return CreateRenderObject(ref, type, 0, styles, attrs, events, page_instance->reserve_css_styles(), nullptr); + }); + +} + +void ReactorPage::AddElement(const std::string& ref, + const std::string& type, + const std::map<std::string, std::string>& styles, + const std::map<std::string, std::string>& attrs, + const std::vector<std::string>& events, + const std::string parent_ref, int index) { + RenderManager::GetInstance()->AddRenderObject(page_id_, parent_ref, index, [&] (RenderPage* page_instance) -> RenderObject* { + return CreateRenderObject(ref, type, 0, styles, attrs, events, page_instance->reserve_css_styles(), nullptr); + }); +} + +void ReactorPage::UpdateStyles(const std::string& ref, std::vector<std::pair<std::string, std::string>> styles) { + WeexCore::RenderManager::GetInstance()->UpdateStyle(page_id_, ref, &styles); +} + +void ReactorPage::UpdateAttrs(const std::string& ref, std::vector<std::pair<std::string, std::string>> attrs) { + WeexCore::RenderManager::GetInstance()->UpdateAttr(page_id_, ref, &attrs); +} + +void ReactorPage::CreateFinish() { + WeexCore::WeexCoreManager::Instance()->script_bridge()->core_side()->CreateFinish(page_id_.c_str()); +} + +void ReactorPage::RemoveElement(const std::string& ref) { + WeexCore::WeexCoreManager::Instance()->script_bridge()->core_side()->RemoveElement(page_id_.c_str(), ref.c_str()); +} + +void ReactorPage::CallNativeModule(const std::string& module, + const std::string& method, + const std::string& arguments, + size_t arguments_length, + const std::string& options, + int options_length) { + std::unique_ptr<ValueWithType> ptr = WeexCoreManager::Instance() + ->getPlatformBridge() + ->platform_side() + ->CallNativeModule(page_id_.c_str(), module.c_str(), method.c_str(), arguments.c_str(), static_cast<int>(arguments_length), options.c_str(), options_length); +} + +RenderObject* ReactorPage::CreateRenderObject(const std::string& ref, + const std::string& type, + unsigned index, + const std::map<std::string, std::string>& styles, + const std::map<std::string, std::string>& attrs, + const std::vector<std::string>& events, + bool reserve_styles, + WeexCore::RenderObject* parent) { + if (ref.empty() || type.empty()) { + return nullptr; + } + + RenderObject* render_object = (RenderObject *)RenderCreator::GetInstance()->CreateRender(type, ref); + render_object->set_page_id(page_id_); + if (parent) { + parent->AddRenderObject(index, render_object); + } + + //fill attributes, styles and events + for (const auto& attr : attrs) { + render_object->AddAttr(attr.first, attr.second); + } + for (const auto& style : styles) { + render_object->AddStyle(style.first, style.second, reserve_styles); + } + for (const auto& event : events) { + render_object->AddEvent(event); + } + + render_object->ApplyDefaultStyle(reserve_styles); + render_object->ApplyDefaultAttr(); + return render_object; +} + +} // namespace WeexCore + diff --git a/weex_core/Source/core/render/page/reactor_page.h b/weex_core/Source/core/render/page/reactor_page.h new file mode 100644 index 0000000..577f7e0 --- /dev/null +++ b/weex_core/Source/core/render/page/reactor_page.h @@ -0,0 +1,79 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +#ifndef CORE_RENDER_PAGE_REACTOR_PAGE_H_ +#define CORE_RENDER_PAGE_REACTOR_PAGE_H_ + +#if defined __cplusplus + +#include <string> +#include <map> +#include <functional> + +namespace WeexCore { + +void PostTaskOnComponentThread(const std::function<void()>& callback); + +class RenderObject; + +class ReactorPage { +public: + explicit ReactorPage(const std::string& page_id) + : page_id_(page_id) {} + + void CreateBody(const std::string& ref, + const std::string& type, + const std::map<std::string, std::string>& styles, + const std::map<std::string, std::string>& attrs, + const std::vector<std::string>& events); + + void AddElement(const std::string& ref, + const std::string& type, + const std::map<std::string, std::string>& styles, + const std::map<std::string, std::string>& attrs, + const std::vector<std::string>& events, + const std::string parent_ref, int index=-1); + + void UpdateStyles(const std::string& ref, std::vector<std::pair<std::string, std::string>> styles); + + void UpdateAttrs(const std::string& ref, std::vector<std::pair<std::string, std::string>> attrs); + + void RemoveElement(const std::string& ref); + + void CreateFinish(); + + const std::string& page_id() const {return page_id_;} + + void CallNativeModule(const std::string& module, + const std::string& method, + const std::string& arguments, + size_t arguments_length, + const std::string& options, + int options_length); + +private: + RenderObject* CreateRenderObject(const std::string& ref, const std::string& type, unsigned index, const std::map<std::string, std::string>& styles, const std::map<std::string, std::string>& attrs, const std::vector<std::string>& events, bool reserve_styles, WeexCore::RenderObject* parent); + + const std::string page_id_; +}; + +} // namespace WeexCore + +#endif + +#endif // CORE_RENDER_PAGE_REACTOR_PAGE_H_ diff --git a/weex_core/Source/core/render/page/render_page.cpp b/weex_core/Source/core/render/page/render_page.cpp index 79a3644..cb29d5c 100755 --- a/weex_core/Source/core/render/page/render_page.cpp +++ b/weex_core/Source/core/render/page/render_page.cpp @@ -338,8 +338,6 @@ bool RenderPage::UpdateStyle( if (src != nullptr) { src->clear(); src->shrink_to_fit(); - delete src; - src = nullptr; } if (style != nullptr) { @@ -395,8 +393,6 @@ bool RenderPage::UpdateAttr( if (attrs != nullptr) { attrs->clear(); attrs->shrink_to_fit(); - delete attrs; - attrs = nullptr; } return true;