diff --git a/dom/include/dom/dom_manager.h b/dom/include/dom/dom_manager.h index 9f34f51104c..da57955f68e 100644 --- a/dom/include/dom/dom_manager.h +++ b/dom/include/dom/dom_manager.h @@ -41,6 +41,8 @@ #include "footstone/base_timer.h" #include "footstone/worker.h" +#define HIPPY_EXPERIMENT_LAYER_OPTIMIZATION + namespace hippy { inline namespace dom { @@ -140,8 +142,12 @@ class DomManager : public std::enable_shared_from_this { friend class DomNode; uint32_t id_; +#ifdef HIPPY_EXPERIMENT_LAYER_OPTIMIZATION std::shared_ptr optimized_render_manager_; - std::weak_ptr render_manager_; + std::shared_ptr render_manager_; +#else + std::shared_ptr render_manager_; +#endif std::unordered_map> timer_map_; std::shared_ptr task_runner_; std::shared_ptr worker_; diff --git a/dom/include/dom/layer_optimized_render_manager.h b/dom/include/dom/layer_optimized_render_manager.h index 73c76d3d2ba..ce683c0cc47 100644 --- a/dom/include/dom/layer_optimized_render_manager.h +++ b/dom/include/dom/layer_optimized_render_manager.h @@ -28,6 +28,7 @@ inline namespace dom { class LayerOptimizedRenderManager : public RenderManager { public: LayerOptimizedRenderManager(std::shared_ptr render_manager); + inline std::shared_ptr GetInternalNativeRenderManager() { return render_manager_; } void CreateRenderNode(std::weak_ptr root_node, std::vector>&& nodes) override; void UpdateRenderNode(std::weak_ptr root_node, std::vector>&& nodes) override; diff --git a/dom/src/dom/dom_manager.cc b/dom/src/dom/dom_manager.cc index 138b06bfdd2..74d81826d92 100644 --- a/dom/src/dom/dom_manager.cc +++ b/dom/src/dom/dom_manager.cc @@ -18,8 +18,6 @@ * limitations under the License. */ -#define EXPERIMENT_LAYER_OPTIMIZATION - #include "dom/dom_manager.h" #include @@ -54,11 +52,11 @@ using Deserializer = footstone::value::Deserializer; using HippyValueArrayType = footstone::value::HippyValue::HippyValueArrayType; void DomManager::SetRenderManager(const std::weak_ptr& render_manager) { -#ifdef EXPERIMENT_LAYER_OPTIMIZATION +#ifdef HIPPY_EXPERIMENT_LAYER_OPTIMIZATION optimized_render_manager_ = std::make_shared(render_manager.lock()); render_manager_ = optimized_render_manager_; #else - render_manager_ = render_manager; + render_manager_ = render_manager.lock(); #endif } @@ -125,7 +123,7 @@ void DomManager::DeleteDomNodes(const std::weak_ptr& weak_root_node, } void DomManager::EndBatch(const std::weak_ptr& weak_root_node) { - auto render_manager = render_manager_.lock(); + auto render_manager = render_manager_; FOOTSTONE_DCHECK(render_manager); if (!render_manager) { return; @@ -187,7 +185,7 @@ void DomManager::DoLayout(const std::weak_ptr& weak_root_node) { if (!root_node) { return; } - auto render_manager = render_manager_.lock(); + auto render_manager = render_manager_; // check render_manager, measure text dependent render_manager FOOTSTONE_DCHECK(render_manager); if (!render_manager) { diff --git a/framework/ios/base/bridge/HippyBridge+Private.h b/framework/ios/base/bridge/HippyBridge+Private.h index 7f6ef573704..684f7f93b33 100644 --- a/framework/ios/base/bridge/HippyBridge+Private.h +++ b/framework/ios/base/bridge/HippyBridge+Private.h @@ -42,6 +42,7 @@ class RenderManager; @protocol HippyBridgeInternal /// The C++ version of RenderManager instance, bridge holds +/// One NativeRenderManager holds multiple Uimanager instance. @property (nonatomic, assign) std::shared_ptr renderManager; /// URI Loader diff --git a/framework/ios/base/bridge/HippyBridge.mm b/framework/ios/base/bridge/HippyBridge.mm index 8a7d72e16d6..fcf3d33117b 100644 --- a/framework/ios/base/bridge/HippyBridge.mm +++ b/framework/ios/base/bridge/HippyBridge.mm @@ -47,7 +47,6 @@ #import "HippyLog.h" #import "HippyOCToHippyValue.h" #import "HippyUtils.h" -#import "UIView+RenderManager.h" #import "TypeConverter.h" #import "VFSUriLoader.h" #import "HippyBase64DataHandler.h" @@ -55,11 +54,14 @@ #import "HippyRootView.h" #import "UIView+Hippy.h" #import "UIView+MountEvent.h" +#import "HippyUIManager.h" +#import "HippyUIManager+Private.h" #include "dom/animation/animation_manager.h" #include "dom/dom_manager.h" #include "dom/scene.h" #include "dom/render_manager.h" +#include "dom/layer_optimized_render_manager.h" #include "driver/scope.h" #include "footstone/worker_manager.h" #include "vfs/uri_loader.h" @@ -267,19 +269,6 @@ - (void)dealloc { } } -- (void)setUpNativeRenderManager { - auto engineResource = [[HippyJSEnginesMapper defaultInstance] JSEngineResourceForKey:self.engineKey]; - auto domManager = engineResource->GetDomManager(); - //Create NativeRenderManager - auto nativeRenderManager = std::make_shared(); - nativeRenderManager->Initialize(); - //set dom manager - nativeRenderManager->SetDomManager(domManager); - nativeRenderManager->SetVFSUriLoader([self createURILoaderIfNeeded]); - nativeRenderManager->SetHippyBridge(self); - _renderManager = nativeRenderManager; -} - - (std::shared_ptr)createURILoaderIfNeeded { if (!_uriLoader) { auto uriHandler = std::make_shared(); @@ -474,7 +463,6 @@ - (void)setUp { [self addImageProviderClass:[HippyDefaultImageProvider class]]; [self setVfsUriLoader:[self createURILoaderIfNeeded]]; - [self setUpNativeRenderManager]; // Load pending js bundles [self loadPendingVendorBundleURLIfNeeded]; @@ -684,12 +672,6 @@ - (void)innerLoadInstanceForRootView:(NSNumber *)rootTag withProperties:(NSDicti HippyLogInfo(@"[HP PERF] End loading instance for HippyBridge(%p)", self); } -- (void)sendRootSizeChangedEvent:(NSNumber *)tag params:(NSDictionary *)params { - NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:params]; - [dic setObject:tag forKey:@"rootViewId"]; - [self sendEvent:@"onSizeChanged" params:dic]; -} - - (void)setVfsUriLoader:(std::weak_ptr)uriLoader { [_javaScriptExecutor setUriLoader:uriLoader]; #ifdef ENABLE_INSPECTOR @@ -1252,8 +1234,6 @@ - (void)setSnapShotData:(NSData *)data { #pragma mark - - -//FIXME: θ°ƒζ•΄δΌ˜εŒ– - (void)setRootView:(UIView *)rootView { auto engineResource = [[HippyJSEnginesMapper defaultInstance] JSEngineResourceForKey:self.engineKey]; auto domManager = engineResource->GetDomManager(); @@ -1269,21 +1249,38 @@ - (void)setRootView:(UIView *)rootView { _rootNode->SetRootSize(rootView.frame.size.width, rootView.frame.size.height); _rootNode->SetRootOrigin(rootView.frame.origin.x, rootView.frame.origin.y); - //set rendermanager for dommanager - if (domManager->GetRenderManager().lock() != _renderManager) { - domManager->SetRenderManager(_renderManager); + // Create NativeRenderManager if needed + auto renderManager = domManager->GetRenderManager().lock(); + std::shared_ptr nativeRenderManager; + if (!renderManager) { + // Register RenderManager to DomManager + nativeRenderManager = std::make_shared(self.moduleName.UTF8String); + domManager->SetRenderManager(nativeRenderManager); + } else { +#ifdef HIPPY_EXPERIMENT_LAYER_OPTIMIZATION + auto opRenderManager = std::static_pointer_cast(renderManager); + nativeRenderManager = std::static_pointer_cast(opRenderManager->GetInternalNativeRenderManager()); +#else + nativeRenderManager = std::static_pointer_cast(renderManager); +#endif /* HIPPY_EXPERIMENT_LAYER_OPTIMIZATION */ } + _renderManager = nativeRenderManager; + + // Create UIManager if needed and register it to NativeRenderManager + // Note that one NativeRenderManager may have multiple UIManager, + // and one UIManager may have multiple rootViews, + // But one HippyBridge can only have one UIManager. + HippyUIManager *uiManager = self.uiManager; + if (!uiManager) { + uiManager = [[HippyUIManager alloc] init]; + [uiManager setDomManager:domManager]; + [uiManager setBridge:self]; + self.uiManager = uiManager; + } + //bind rootview and root node - _renderManager->RegisterRootView(rootView, _rootNode); + _renderManager->RegisterRootView(rootView, _rootNode, uiManager); - __weak HippyBridge *weakBridge = self; - auto cb = [weakBridge](int32_t tag, NSDictionary *params){ - HippyBridge *strongBridge = weakBridge; - if (strongBridge) { - [strongBridge sendRootSizeChangedEvent:@(tag) params:params]; - } - }; - _renderManager->SetRootViewSizeChangedEvent(cb); //setup necessary params for bridge [self setupDomManager:domManager rootNode:_rootNode]; } @@ -1309,8 +1306,6 @@ - (void)resetRootSize:(CGSize)size { domManager->PostTask(hippy::dom::Scene(std::move(ops))); } - - @end void HippyBridgeFatal(NSError *error, HippyBridge *bridge) { diff --git a/renderer/native/ios/renderer/HippyUIManager+Private.h b/renderer/native/ios/renderer/HippyUIManager+Private.h index 83286ef3aff..a58630579da 100644 --- a/renderer/native/ios/renderer/HippyUIManager+Private.h +++ b/renderer/native/ios/renderer/HippyUIManager+Private.h @@ -28,10 +28,8 @@ #include #include -class VFSUriLoader; namespace hippy { inline namespace dom { -class RenderManager; class DomManager; class DomArgument; class RootNode; @@ -53,22 +51,11 @@ class HippyValue; /// DomManager instance @property (nonatomic, readonly) std::weak_ptr domManager; -/// VFSUriLoader instance -@property (nonatomic, assign) std::weak_ptr vfsUriLoader; - @end @interface HippyUIManager (Private) -/// Set hippy::RenderManager -/// - Parameter renderManager: hippy::RenderManager -- (void)registRenderManager:(std::weak_ptr)renderManager; - -/// Get hippy::RenderManager -- (std::weak_ptr)renderManager; - - - (void)registerRootView:(UIView *)rootView asRootNode:(std::weak_ptr)rootNode; - (void)unregisterRootViewFromTag:(NSNumber *)rootTag; diff --git a/renderer/native/ios/renderer/HippyUIManager.h b/renderer/native/ios/renderer/HippyUIManager.h index 5d9c3b22755..d10ce61ca39 100644 --- a/renderer/native/ios/renderer/HippyUIManager.h +++ b/renderer/native/ios/renderer/HippyUIManager.h @@ -66,8 +66,15 @@ HIPPY_EXTERN NSString *const HippyUIManagerDidEndBatchNotification; /// The HippyUIManager responsible for updating the view hierarchy. @interface HippyUIManager : NSObject +/// HippyBridge instance @property (nonatomic, weak) HippyBridge *bridge; + +/// View Registry of all nodes @property (nonatomic, readonly) HippyComponentMap *viewRegistry; + +/// Specify whether UI hierarchy will be created instantly. +/// When setting YES, UI hierarchy will not be created automatically, +/// default is NO. @property (nonatomic, assign) BOOL uiCreationLazilyEnabled; @@ -142,7 +149,7 @@ HIPPY_EXTERN NSString *const HippyUIManagerDidEndBatchNotification; @interface HippyBridge (HippyUIManager) /// The current HippyUIManager instance -@property (nonatomic, readonly) HippyUIManager *uiManager; +@property (nonatomic, strong) HippyUIManager *uiManager; /// A custom touch handler for gesture special processing /// You can use it when you need to modify Hippy's default gesture handling logic diff --git a/renderer/native/ios/renderer/HippyUIManager.mm b/renderer/native/ios/renderer/HippyUIManager.mm index a91f31beb13..8643e9f0568 100644 --- a/renderer/native/ios/renderer/HippyUIManager.mm +++ b/renderer/native/ios/renderer/HippyUIManager.mm @@ -41,8 +41,6 @@ #import "RenderVsyncManager.h" #import "UIView+DomEvent.h" #import "UIView+Hippy.h" -#import "UIView+Render.h" -#import "UIView+RenderManager.h" #import "HippyBridgeModule.h" #import "HippyModulesSetup.h" #import "NativeRenderManager.h" @@ -50,6 +48,7 @@ #import "HippyModuleData.h" #import "HippyModuleMethod.h" #import "HippyBridge+Private.h" +#import "HippyJSExecutor.h" #import "dom/root_node.h" #import "objc/runtime.h" #import @@ -185,15 +184,12 @@ @interface HippyUIManager() { // Listeners such as ScrollView/ListView etc. witch will listen to start layout event // The implementation here needs to be improved to provide a registration mechanism. NSHashTable> *_componentTransactionListeners; - - std::weak_ptr _renderManager; std::mutex _renderQueueLock; NSMutableDictionary *_viewManagers; NSArray *_extraComponents; NSMutableArray> *_imageProviders; - std::function _rootViewSizeChangedCb; } @@ -209,7 +205,6 @@ @interface HippyUIManager() { @implementation HippyUIManager @synthesize domManager = _domManager; -@synthesize vfsUriLoader = _vfsUriLoader; #pragma mark Life cycle @@ -251,14 +246,6 @@ - (void)dealloc { #pragma mark Setter & Getter -- (void)registRenderManager:(std::weak_ptr)renderManager { - _renderManager = renderManager; -} - -- (std::weak_ptr)renderManager { - return _renderManager; -} - - (void)setDomManager:(std::weak_ptr)domManager { _domManager = domManager; } @@ -335,7 +322,6 @@ - (void)registerRootView:(UIView *)rootView asRootNode:(std::weak_ptr) [rootView addObserver:self forKeyPath:@"frame" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:NULL]; - rootView.renderManager = [self renderManager]; CGRect frame = rootView.frame; // Register shadow view @@ -392,19 +378,22 @@ - (void)observeValueForKeyPath:(NSString *)keyPath @"width": @(CGRectGetWidth(curFrame)), @"height": @(CGRectGetHeight(curFrame)), @"rootViewId": rootTag }; + static const char *hippyOnSizeChangedKey = "onSizeChanged"; auto value = std::make_shared([params toHippyValue]); - auto event = std::make_shared("onSizeChanged", rootNode, NO, NO, value); + auto event = std::make_shared(hippyOnSizeChangedKey, rootNode, NO, NO, value); __weak HippyUIManager *weakSelf = self; std::function func = [weakSelf, rootNode, event, rootTag](){ rootNode->HandleEvent(event); HippyUIManager *strongSelf = weakSelf; if (strongSelf) { - [strongSelf domEventDidHandle:"onSizeChanged" forNode:[rootTag intValue] onRoot:[rootTag intValue]]; + [strongSelf domEventDidHandle:hippyOnSizeChangedKey forNode:[rootTag intValue] onRoot:[rootTag intValue]]; } }; domManager->PostTask(hippy::Scene({func})); - if (_rootViewSizeChangedCb) { - _rootViewSizeChangedCb([rootTag intValue], params); + + HippyBridge *bridge = self.bridge; + if (bridge) { + [bridge sendEvent:@(hippyOnSizeChangedKey) params:params]; } } } @@ -527,7 +516,6 @@ - (UIView *)createViewFromShadowView:(HippyShadowView *)shadowView { view.viewName = viewName; view.rootTag = rootTag; view.hippyShadowView = shadowView; - view.renderManager = [self renderManager]; [componentData setProps:props forView:view]; // Must be done before bgColor to prevent wrong default } } @@ -1169,24 +1157,26 @@ - (void)addEventName:(const std::string &)name }]; } else if (name == kVSyncKey) { std::string name_ = name; - auto weakDomManager = self.domManager; + __weak __typeof(self)weakSelf = self; [self domNodeForComponentTag:node_id onRootNode:rootNode resultNode:^(std::shared_ptr node) { if (node) { //for kVSyncKey event, node is rootnode - NSString *vsyncKey = [NSString stringWithFormat:@"%p-%d", self, node_id]; + __strong __typeof(weakSelf)strongSelf = weakSelf; + NSString *vsyncKey = [NSString stringWithFormat:@"%p-%d", strongSelf, node_id]; auto event = std::make_shared(name_, node); std::weak_ptr weakNode = node; [[RenderVsyncManager sharedInstance] registerVsyncObserver:^{ - auto domManager = weakDomManager.lock(); - if (domManager) { - std::function func = [weakNode, event](){ - auto strongNode = weakNode.lock(); - if (strongNode) { - strongNode->HandleEvent(event); - } - }; - domManager->PostTask(hippy::Scene({func})); + __strong __typeof(weakSelf)strongSelf = weakSelf; + HippyBridge *bridge = strongSelf.bridge; + if (!bridge) { + return; } + [bridge.javaScriptExecutor executeBlockOnJavaScriptQueue:^{ + auto strongNode = weakNode.lock(); + if (strongNode) { + strongNode->HandleEvent(event); + } + }]; } forKey:vsyncKey]; } }]; @@ -1488,12 +1478,8 @@ - (NSDictionary *)mergeProps:(NSDictionary *)newProps oldProps:(NSDictionary *)o return tmpProps; } -- (void)setRootViewSizeChangedEvent:(std::function)cb { - _rootViewSizeChangedCb = cb; -} - - (void)domEventDidHandle:(const std::string &)eventName forNode:(int32_t)tag onRoot:(int32_t)rootTag { - + // no op } #pragma mark Debug Methods @@ -1522,12 +1508,11 @@ - (void)domEventDidHandle:(const std::string &)eventName forNode:(int32_t)tag on @implementation HippyBridge (HippyUIManager) - (HippyUIManager *)uiManager { - auto renderManager = [self renderManager]; - if (renderManager) { - auto nativeRenderManager = std::static_pointer_cast(renderManager); - return nativeRenderManager->GetHippyUIManager(); - } - return nil; + return objc_getAssociatedObject(self, @selector(uiManager)); +} + +- (void)setUiManager:(HippyUIManager *)uiManager { + objc_setAssociatedObject(self, @selector(uiManager), uiManager, OBJC_ASSOCIATION_RETAIN); } - (id)customTouchHandler { diff --git a/renderer/native/ios/renderer/NativeRenderManager.h b/renderer/native/ios/renderer/NativeRenderManager.h index e1a1011905b..a4f8c4f19d7 100644 --- a/renderer/native/ios/renderer/NativeRenderManager.h +++ b/renderer/native/ios/renderer/NativeRenderManager.h @@ -25,32 +25,25 @@ #include #include - +#include #include "dom/render_manager.h" @class UIView, HippyUIManager; -class VFSUriLoader; namespace hippy { inline namespace dom { class RootNode; } } -@protocol HippyImageProviderProtocol; - /** * NativeRenderManager is used to manager view creation, update and delete for Native UI */ -class NativeRenderManager : public hippy::RenderManager ,public std::enable_shared_from_this { +class NativeRenderManager : public hippy::RenderManager, public std::enable_shared_from_this { public: - NativeRenderManager(); - NativeRenderManager(HippyUIManager *uiManager): hippy::RenderManager("NativeRenderManager"), renderImpl_(uiManager){} - + NativeRenderManager(const std::string& name); ~NativeRenderManager(); - - void Initialize(); /** * create views from dom nodes @@ -142,24 +135,19 @@ class NativeRenderManager : public hippy::RenderManager ,public std::enable_shar * @discussion Caller can get callback block from id by DomNode::GetCallback function */ void CallFunction(std::weak_ptr root_node, - std::weak_ptr dom_node, const std::string &name, + std::weak_ptr dom_node, + const std::string &name, const DomArgument& param, uint32_t cb) override; - - /** - * Register custom ui component - * - * @param extraComponents a map of custom ui components - */ - void RegisterExtraComponent(NSArray *extraComponents); /** - * Regitster a root view + * Regitster a root view and register UIManager instance to RenderManager * * @param view a specitified view as root view * @param root_node root node for root view + * @param uiManager HippyUIManager instance */ - void RegisterRootView(UIView *view, std::weak_ptr root_node); + void RegisterRootView(UIView *view, std::weak_ptr root_node, HippyUIManager *uiManager); /** * Unregister a root view @@ -168,58 +156,15 @@ class NativeRenderManager : public hippy::RenderManager ,public std::enable_shar */ void UnregisterRootView(uint32_t id); - /** - * Get all registered root views - * - * @return a copy array of root views - */ - NSArray *rootViews(); - - /** - * set dom manager for render manager - * - * @param dom_manager weak pointer of dom manager - */ - void SetDomManager(std::weak_ptr dom_manager); - - /** - * Specify whether ui hierarchy should be created instantly - * - * @param enabled true means ui will not be created until it is required - * @discussion when true, ui hierarchy will not be created automatically, default is false - */ - void SetUICreationLazilyEnabled(bool enabled); - - /** - * Set vfs uri loader of CPP version - * - *@param loader vfs url loader instance - */ - void SetVFSUriLoader(std::shared_ptr loader); - - /** - * Set HippyBridge pointer to renderManager - * - *@param bridge HippyBridge instance - */ - void SetHippyBridge(HippyBridge *bridge); - - /** - * Set root view size changed event callback - * - *@param cb callback - */ - void SetRootViewSizeChangedEvent(std::function cb); - /** * Get HippyUIManager variable * * @return A HippyUIManager instance */ - HippyUIManager *GetHippyUIManager(); + HippyUIManager *GetHippyUIManager(uint32_t rootId); private: - HippyUIManager *renderImpl_; + std::unordered_map _uiManagerMap; }; #endif /* NativeRenderManager_h */ diff --git a/renderer/native/ios/renderer/NativeRenderManager.mm b/renderer/native/ios/renderer/NativeRenderManager.mm index 17d3e5eb5c5..9cecc59fc49 100644 --- a/renderer/native/ios/renderer/NativeRenderManager.mm +++ b/renderer/native/ios/renderer/NativeRenderManager.mm @@ -26,9 +26,9 @@ #import "HippyShadowText.h" #import "RenderVsyncManager.h" #import "HippyAssert.h" - #include "dom/dom_manager.h" #include "dom/layout_node.h" +#include "dom/root_node.h" using HippyValue = footstone::value::HippyValue; using RenderManager = hippy::RenderManager; @@ -39,42 +39,55 @@ using CallFunctionCallback = hippy::CallFunctionCallback; using RootNode = hippy::RootNode; -NativeRenderManager::NativeRenderManager(): hippy::RenderManager("NativeRenderManager") { -} -void NativeRenderManager::Initialize() { - renderImpl_ = [[HippyUIManager alloc] init]; - [renderImpl_ registRenderManager:weak_from_this()]; -} +NativeRenderManager::NativeRenderManager(const std::string& name): hippy::RenderManager(name) {} void NativeRenderManager::CreateRenderNode(std::weak_ptr root_node, std::vector> &&nodes) { @autoreleasepool { - HippyAssert(renderImpl_, @"renderImpl_ is null, did you forget to call Initialize()?"); - [renderImpl_ createRenderNodes:std::move(nodes) onRootNode:root_node]; + auto rootNode = root_node.lock(); + if (rootNode) { + HippyUIManager *uiManager = _uiManagerMap[rootNode->GetId()]; + HippyAssertParam(uiManager); + [uiManager createRenderNodes:std::move(nodes) onRootNode:root_node]; + } } } void NativeRenderManager::UpdateRenderNode(std::weak_ptr root_node, std::vector>&& nodes) { @autoreleasepool { - HippyAssert(renderImpl_, @"renderImpl_ is null, did you forget to call Initialize()?"); - [renderImpl_ updateRenderNodes:std::move(nodes) onRootNode:root_node]; + auto rootNode = root_node.lock(); + if (rootNode) { + HippyUIManager *uiManager = _uiManagerMap[rootNode->GetId()]; + HippyAssertParam(uiManager); + [uiManager updateRenderNodes:std::move(nodes) onRootNode:root_node]; + } + } } void NativeRenderManager::DeleteRenderNode(std::weak_ptr root_node, std::vector>&& nodes) { @autoreleasepool { - HippyAssert(renderImpl_, @"renderImpl_ is null, did you forget to call Initialize()?"); - [renderImpl_ deleteRenderNodesIds:std::move(nodes) onRootNode:root_node]; + auto rootNode = root_node.lock(); + if (rootNode) { + HippyUIManager *uiManager = _uiManagerMap[rootNode->GetId()]; + HippyAssertParam(uiManager); + [uiManager deleteRenderNodesIds:std::move(nodes) onRootNode:root_node]; + } } } void NativeRenderManager::UpdateLayout(std::weak_ptr root_node, const std::vector>& nodes) { @autoreleasepool { - HippyAssert(renderImpl_, @"renderImpl_ is null, did you forget to call Initialize()?"); + auto rootNode = root_node.lock(); + if (!rootNode) { + return; + } + HippyUIManager *uiManager = _uiManagerMap[rootNode->GetId()]; + HippyAssertParam(uiManager); using DomNodeUpdateInfoTuple = std::tuple; std::vector nodes_infos; nodes_infos.reserve(nodes.size()); @@ -84,7 +97,7 @@ DomNodeUpdateInfoTuple nodeUpdateInfo = std::make_tuple(tag, layoutResult); nodes_infos.push_back(nodeUpdateInfo); } - [renderImpl_ updateNodesLayout:nodes_infos onRootNode:root_node]; + [uiManager updateNodesLayout:nodes_infos onRootNode:root_node]; } } @@ -94,19 +107,29 @@ int32_t to_pid, int32_t index) { @autoreleasepool { - HippyAssert(renderImpl_, @"renderImpl_ is null, did you forget to call Initialize()?"); - [renderImpl_ renderMoveViews:std::move(moved_ids) - fromContainer:from_pid - toContainer:to_pid - index:index - onRootNode:root_node]; + auto rootNode = root_node.lock(); + if (!rootNode) { + return; + } + HippyUIManager *uiManager = _uiManagerMap[rootNode->GetId()]; + HippyAssertParam(uiManager); + [uiManager renderMoveViews:std::move(moved_ids) + fromContainer:from_pid + toContainer:to_pid + index:index + onRootNode:root_node]; } } void NativeRenderManager::MoveRenderNode(std::weak_ptr root_node, std::vector>&& nodes) { @autoreleasepool { - HippyAssert(renderImpl_, @"renderImpl_ is null, did you forget to call Initialize()?"); + auto rootNode = root_node.lock(); + if (!rootNode) { + return; + } + HippyUIManager *uiManager = _uiManagerMap[rootNode->GetId()]; + HippyAssertParam(uiManager); // Check whether all nodes have the same pid uint32_t firstPid = nodes[0]->GetPid(); bool allSamePid = std::all_of(nodes.begin(), nodes.end(), @@ -116,7 +139,7 @@ if (allSamePid) { // If all nodes have the same pid, call directly - [renderImpl_ renderMoveNodes:std::move(nodes) onRootNode:root_node]; + [uiManager renderMoveNodes:std::move(nodes) onRootNode:root_node]; } else { // If not, group them by pid and then call for each group std::map>> pidNodeMap; @@ -124,7 +147,7 @@ pidNodeMap[node->GetPid()].push_back(node); } for (auto& pair : pidNodeMap) { - [renderImpl_ renderMoveNodes:std::move(pair.second) onRootNode:root_node]; + [uiManager renderMoveNodes:std::move(pair.second) onRootNode:root_node]; } } } @@ -133,8 +156,13 @@ void NativeRenderManager::EndBatch(std::weak_ptr root_node) { @autoreleasepool { TDF_PERF_LOG("NativeRenderManager::EndBatch Begin"); - HippyAssert(renderImpl_, @"renderImpl_ is null, did you forget to call Initialize()?"); - [renderImpl_ batchOnRootNode:root_node]; + auto rootNode = root_node.lock(); + if (!rootNode) { + return; + } + HippyUIManager *uiManager = _uiManagerMap[rootNode->GetId()]; + HippyAssertParam(uiManager); + [uiManager batchOnRootNode:root_node]; TDF_PERF_LOG("NativeRenderManager::EndBatch End"); } @@ -150,11 +178,16 @@ std::weak_ptr dom_node, const std::string& name) { @autoreleasepool { - HippyAssert(renderImpl_, @"renderImpl_ is null, did you forget to call Initialize()?"); + auto rootNode = root_node.lock(); + if (!rootNode) { + return; + } + HippyUIManager *uiManager = _uiManagerMap[rootNode->GetId()]; + HippyAssertParam(uiManager); auto node = dom_node.lock(); if (node) { int32_t tag = node->GetId(); - [renderImpl_ addEventName:name forDomNodeId:tag onRootNode:root_node]; + [uiManager addEventName:name forDomNodeId:tag onRootNode:root_node]; } } }; @@ -163,19 +196,29 @@ std::weak_ptr dom_node, const std::string &name) { @autoreleasepool { - HippyAssert(renderImpl_, @"renderImpl_ is null, did you forget to call Initialize()?"); + auto rootNode = root_node.lock(); + if (!rootNode) { + return; + } + HippyUIManager *uiManager = _uiManagerMap[rootNode->GetId()]; + HippyAssertParam(uiManager); auto node = dom_node.lock(); if (node) { int32_t node_id = node->GetId(); - [renderImpl_ removeEventName:name forDomNodeId:node_id onRootNode:root_node]; + [uiManager removeEventName:name forDomNodeId:node_id onRootNode:root_node]; } } } void NativeRenderManager::RemoveVSyncEventListener(std::weak_ptr root_node) { @autoreleasepool { - HippyAssert(renderImpl_, @"renderImpl_ is null, did you forget to call Initialize()?"); - [renderImpl_ removeVSyncEventOnRootNode:root_node]; + auto rootNode = root_node.lock(); + if (!rootNode) { + return; + } + HippyUIManager *uiManager = _uiManagerMap[rootNode->GetId()]; + HippyAssertParam(uiManager); + [uiManager removeVSyncEventOnRootNode:root_node]; } } @@ -185,81 +228,58 @@ const DomArgument& param, uint32_t cb) { @autoreleasepool { - HippyAssert(renderImpl_, @"renderImpl_ is null, did you forget to call Initialize()?"); + auto rootNode = root_node.lock(); + if (!rootNode) { + return; + } + HippyUIManager *uiManager = _uiManagerMap[rootNode->GetId()]; + HippyAssertParam(uiManager); std::shared_ptr node = dom_node.lock(); if (node) { HippyValue hippy_value; param.ToObject(hippy_value); - [renderImpl_ dispatchFunction:name viewName:node->GetViewName() - viewTag:node->GetId() onRootNode:root_node params:hippy_value - callback:node->GetCallback(name, cb)]; + [uiManager dispatchFunction:name + viewName:node->GetViewName() + viewTag:node->GetId() + onRootNode:root_node + params:hippy_value + callback:node->GetCallback(name, cb)]; } EndBatch(root_node); } } -void NativeRenderManager::RegisterExtraComponent(NSArray *extraComponents) { +void NativeRenderManager::RegisterRootView(UIView *view, + std::weak_ptr root_node, + HippyUIManager *uiManager) { @autoreleasepool { - HippyAssert(renderImpl_, @"renderImpl_ is null, did you forget to call Initialize()?"); - [renderImpl_ registerExtraComponent:extraComponents]; - } -} - -void NativeRenderManager::RegisterRootView(UIView *view, std::weak_ptr root_node) { - @autoreleasepool { - HippyAssert(renderImpl_, @"renderImpl_ is null, did you forget to call Initialize()?"); - [renderImpl_ registerRootView:view asRootNode:root_node]; - } -} - -void NativeRenderManager::UnregisterRootView(uint32_t id) { - @autoreleasepool { - HippyAssert(renderImpl_, @"renderImpl_ is null, did you forget to call Initialize()?"); - [renderImpl_ unregisterRootViewFromTag:@(id)]; - } -} - -NSArray *NativeRenderManager::rootViews() { - @autoreleasepool { - HippyAssert(renderImpl_, @"renderImpl_ is null, did you forget to call Initialize()?"); - return [renderImpl_ rootViews]; - } -} - -void NativeRenderManager::SetDomManager(std::weak_ptr dom_manager) { - @autoreleasepool { - HippyAssert(renderImpl_, @"renderImpl_ is null, did you forget to call Initialize()?"); - [renderImpl_ setDomManager:dom_manager]; + auto rootNode = root_node.lock(); + if (!rootNode) { + return; + } + HippyAssertParam(uiManager); + _uiManagerMap[rootNode->GetId()] = uiManager; + [uiManager registerRootView:view asRootNode:root_node]; } } -void NativeRenderManager::SetUICreationLazilyEnabled(bool enabled) { - HippyAssert(renderImpl_, @"renderImpl_ is null, did you forget to call Initialize()?"); - renderImpl_.uiCreationLazilyEnabled = enabled; -} - -void NativeRenderManager::SetVFSUriLoader(std::shared_ptr loader) { +void NativeRenderManager::UnregisterRootView(uint32_t rootId) { @autoreleasepool { - HippyAssert(renderImpl_, @"renderImpl_ is null, did you forget to call Initialize()?"); - renderImpl_.vfsUriLoader = loader; + HippyUIManager *uiManager = _uiManagerMap[rootId]; + HippyAssertParam(uiManager); + [uiManager unregisterRootViewFromTag:@(rootId)]; + _uiManagerMap.erase(rootId); } } -void NativeRenderManager::SetHippyBridge(HippyBridge *bridge) { - HippyAssert(renderImpl_, @"renderImpl_ is null, did you forget to call Initialize()?"); - renderImpl_.bridge = bridge; -} - -void NativeRenderManager::SetRootViewSizeChangedEvent(std::function cb) { - [renderImpl_ setRootViewSizeChangedEvent:cb]; -} - -HippyUIManager *NativeRenderManager::GetHippyUIManager() { - return renderImpl_; +HippyUIManager *NativeRenderManager::GetHippyUIManager(uint32_t rootId) { + return _uiManagerMap[rootId]; } NativeRenderManager::~NativeRenderManager() { - [renderImpl_ invalidate]; - renderImpl_ = nil; + for (auto &pair : _uiManagerMap) { + [pair.second invalidate]; + } + _uiManagerMap.clear(); } diff --git a/renderer/native/ios/renderer/UIView+Render.h b/renderer/native/ios/renderer/UIView+Render.h deleted file mode 100644 index 3c8972b98ca..00000000000 --- a/renderer/native/ios/renderer/UIView+Render.h +++ /dev/null @@ -1,36 +0,0 @@ -/*! - * iOS SDK - * - * Tencent is pleased to support the open source community by making - * Hippy available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. - * All rights reserved. - * - * Licensed 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 - -NS_ASSUME_NONNULL_BEGIN - -@class HippyUIManager; - -@interface UIView (Render) - -/// Convenient method to get HippyUIManager instance -- (HippyUIManager *)uiManager; - -@end - -NS_ASSUME_NONNULL_END diff --git a/renderer/native/ios/renderer/UIView+Render.mm b/renderer/native/ios/renderer/UIView+Render.mm deleted file mode 100644 index bc1cfcf579d..00000000000 --- a/renderer/native/ios/renderer/UIView+Render.mm +++ /dev/null @@ -1,71 +0,0 @@ -/*! - * iOS SDK - * - * Tencent is pleased to support the open source community by making - * Hippy available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. - * All rights reserved. - * - * Licensed 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 "UIView+Render.h" -#import "HippyUIManager.h" -#import "UIView+RenderManager.h" -#import "NativeRenderManager.h" -#import "dom/render_manager.h" -#include - - -@implementation UIView (Render) - -- (HippyUIManager *)uiManager { - auto renderManager = [self renderManager].lock(); - if (renderManager) { - auto nativeRenderManager = std::static_pointer_cast(renderManager); - return nativeRenderManager->GetHippyUIManager(); - } - return nil; -} - -@end - - -#pragma mark - - -@interface RenderManagerWrapper : NSObject - -/// holds weak_ptr of hippy::RenderManager -@property (nonatomic, assign) std::weak_ptr renderManager; - -@end - -@implementation RenderManagerWrapper - -@end - -@implementation UIView (HippyRenderManager) - -- (void)setRenderManager:(std::weak_ptr)renderManager { - RenderManagerWrapper *wrapper = [[RenderManagerWrapper alloc] init]; - wrapper.renderManager = renderManager; - objc_setAssociatedObject(self, @selector(renderManager), wrapper, OBJC_ASSOCIATION_RETAIN_NONATOMIC); -} - -- (std::weak_ptr)renderManager { - RenderManagerWrapper *wrapper = objc_getAssociatedObject(self, _cmd); - return wrapper.renderManager; -} - -@end diff --git a/renderer/native/ios/renderer/UIView+RenderManager.h b/renderer/native/ios/renderer/UIView+RenderManager.h deleted file mode 100644 index ed4cb516c6c..00000000000 --- a/renderer/native/ios/renderer/UIView+RenderManager.h +++ /dev/null @@ -1,47 +0,0 @@ -/*! - * iOS SDK - * - * Tencent is pleased to support the open source community by making - * Hippy available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. - * All rights reserved. - * - * Licensed 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 UIView_RenderManager_h -#define UIView_RenderManager_h - -#import -#include - -NS_ASSUME_NONNULL_BEGIN - -namespace hippy { -inline namespace dom { -class RenderManager; -}; -}; - - -@interface UIView (HippyRenderManager) - -/// Get the hippy::RenderManager instance -@property(nonatomic, assign) std::weak_ptr renderManager; - -@end - -NS_ASSUME_NONNULL_END - -#endif /* UIView_RenderManager_h */ diff --git a/renderer/native/ios/renderer/component/listview/HippyNextBaseListView.mm b/renderer/native/ios/renderer/component/listview/HippyNextBaseListView.mm index 40daabd1b53..21c2c78b867 100644 --- a/renderer/native/ios/renderer/component/listview/HippyNextBaseListView.mm +++ b/renderer/native/ios/renderer/component/listview/HippyNextBaseListView.mm @@ -31,7 +31,6 @@ #import "HippyShadowView.h" #import "UIView+DirectionalLayout.h" #import "UIView+Hippy.h" -#import "UIView+Render.h" #import "HippyShadowListView.h" static NSString *const kCellIdentifier = @"HippyListCellIdentifier"; @@ -49,8 +48,8 @@ @implementation HippyNextBaseListView #pragma mark - Life Cycle -- (instancetype)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { +- (instancetype)initWithBridge:(HippyBridge *)bridge { + if (self = [super initWithBridge:bridge]) { _isInitialListReady = NO; self.preloadItemNumber = 1; } @@ -221,7 +220,7 @@ - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView forIndexPath:indexPath]; HippyShadowView *headerRenderObject = [self.dataSource headerForSection:section]; if (headerRenderObject && [headerRenderObject isKindOfClass:[HippyShadowView class]]) { - UIView *headerView = [self.uiManager createViewForShadowListItem:headerRenderObject]; + UIView *headerView = [self.bridge.uiManager createViewForShadowListItem:headerRenderObject]; CGRect frame = headerView.frame; frame.origin = CGPointZero; headerView.frame = frame; @@ -273,7 +272,7 @@ - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cell cellView = cachedVisibleCellView; HippyLogTrace(@"🟒 use cached visible cellView at %@ for %@", indexPath, shadowView.hippyTag); } else { - cellView = [self.uiManager createViewForShadowListItem:shadowView]; + cellView = [self.bridge.uiManager createViewForShadowListItem:shadowView]; [_cachedWeakCellViews setObject:cellView forKey:shadowView.hippyTag]; HippyLogTrace(@"🟑 create cellView at %@ for %@", indexPath, shadowView.hippyTag); } diff --git a/renderer/native/ios/renderer/component/listview/HippyNextBaseListViewManager.mm b/renderer/native/ios/renderer/component/listview/HippyNextBaseListViewManager.mm index 48d57088841..71ad81c91b2 100644 --- a/renderer/native/ios/renderer/component/listview/HippyNextBaseListViewManager.mm +++ b/renderer/native/ios/renderer/component/listview/HippyNextBaseListViewManager.mm @@ -48,7 +48,7 @@ @implementation HippyNextBaseListViewManager HIPPY_EXPORT_VIEW_PROPERTY(horizontal, BOOL) - (UIView *)view { - return [[HippyNextBaseListView alloc] init]; + return [[HippyNextBaseListView alloc] initWithBridge:self.bridge]; } - (HippyShadowView *)shadowView { diff --git a/renderer/native/ios/renderer/component/smartViewPager/NativeRenderSmartViewPagerView.mm b/renderer/native/ios/renderer/component/smartViewPager/NativeRenderSmartViewPagerView.mm index a10ca363f35..6c9fa2613d4 100644 --- a/renderer/native/ios/renderer/component/smartViewPager/NativeRenderSmartViewPagerView.mm +++ b/renderer/native/ios/renderer/component/smartViewPager/NativeRenderSmartViewPagerView.mm @@ -29,7 +29,6 @@ #import "NativeRenderSmartViewPagerView.h" #import "HippyScrollProtocol.h" #import "UIView+MountEvent.h" -#import "UIView+Render.h" #import "UIView+Hippy.h" #include @@ -59,8 +58,8 @@ - (void)setPreviousMargin:(CGFloat)previousMargin nextMargin:(CGFloat)nextMargin @implementation NativeRenderSmartViewPagerView #pragma mark Life Cycle -- (instancetype)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { +- (instancetype)initWithBridge:(HippyBridge *)bridge { + if (self = [super initWithBridge:bridge]) { _isInitialListReady = NO; _dataSource = [[HippyNextBaseListViewDataSource alloc] initWithDataSource:nil itemViewName:[self compoentItemName] @@ -357,7 +356,7 @@ - (void)collectionView:(UICollectionView *)collectionView NSIndexPath *adjustIndexPath = [NSIndexPath indexPathForRow:cellIndex inSection:indexPath.section]; HippyWaterfallViewCell *hpCell = (HippyWaterfallViewCell *)cell; HippyShadowView *renderObject = [_dataSource cellForIndexPath:adjustIndexPath]; - UIView *cellView = [self.uiManager createViewForShadowListItem:renderObject]; + UIView *cellView = [self.bridge.uiManager createViewForShadowListItem:renderObject]; hpCell.cellView = cellView; cellView.parent = self; } diff --git a/renderer/native/ios/renderer/component/waterfalllist/HippyWaterfallView.h b/renderer/native/ios/renderer/component/waterfalllist/HippyWaterfallView.h index 7af72dc98d6..c25df712d16 100644 --- a/renderer/native/ios/renderer/component/waterfalllist/HippyWaterfallView.h +++ b/renderer/native/ios/renderer/component/waterfalllist/HippyWaterfallView.h @@ -21,7 +21,7 @@ */ #import - +#import "HippyBridge.h" #import "HippyCollectionViewWaterfallLayout.h" #import "HippyComponent.h" #import "HippyScrollableProtocol.h" @@ -56,6 +56,9 @@ typedef NS_ENUM(NSInteger, NativeRenderScrollState) { BOOL _allowNextScrollNoMatterWhat; } +/// Weak ref of HippyBridge +@property (nonatomic, weak, readonly) HippyBridge *bridge; + /** * Content inset for HippyWaterfallView */ @@ -116,6 +119,12 @@ typedef NS_ENUM(NSInteger, NativeRenderScrollState) { @property (nonatomic, copy) HippyDirectEventBlock onRefresh; @property (nonatomic, copy) HippyDirectEventBlock onExposureReport; +/// Init method +/// - Parameter bridge: HippyBridge instance +- (instancetype)initWithBridge:(HippyBridge *)bridge NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE; +- (instancetype)initWithCoder:(NSCoder *)coder NS_UNAVAILABLE; + /** * Initial collection view */ diff --git a/renderer/native/ios/renderer/component/waterfalllist/HippyWaterfallView.mm b/renderer/native/ios/renderer/component/waterfalllist/HippyWaterfallView.mm index 6545dff75a0..41e6e53a94e 100644 --- a/renderer/native/ios/renderer/component/waterfalllist/HippyWaterfallView.mm +++ b/renderer/native/ios/renderer/component/waterfalllist/HippyWaterfallView.mm @@ -29,7 +29,6 @@ #import "HippyWaterfallViewDataSource.h" #import "HippyShadowView.h" #import "HippyUIManager.h" -#import "UIView+Render.h" #import "HippyWaterfallViewCell.h" #import "HippyRootView.h" #import "HippyShadowListView.h" @@ -62,8 +61,9 @@ @implementation HippyWaterfallView { @synthesize contentSize; -- (instancetype)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { +- (instancetype)initWithBridge:(id)bridge { + if (self = [super initWithFrame:CGRectZero]) { + _bridge = bridge; self.backgroundColor = [UIColor clearColor]; _scrollListeners = [NSHashTable weakObjectsHashTable]; _scrollEventThrottle = 100.f; @@ -266,7 +266,7 @@ - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cell if (cachedCellView) { cellView = cachedCellView; } else { - cellView = [self.uiManager createViewForShadowListItem:shadowView]; + cellView = [self.bridge.uiManager createViewForShadowListItem:shadowView]; [_cachedWeakCellViews setObject:cellView forKey:shadowView.hippyTag]; }