You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by ky...@apache.org on 2018/11/08 03:30:29 UTC
[incubator-weex] branch master updated: [Core] Let affine types of
"scroller", "list",
"waterfall" match RenderList logic. Autodetect subclass when registering a
component and register its affine type. (#1723)
This is an automated email from the ASF dual-hosted git repository.
kyork 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 f1117e5 [Core] Let affine types of "scroller", "list", "waterfall" match RenderList logic. Autodetect subclass when registering a component and register its affine type. (#1723)
f1117e5 is described below
commit f1117e56db6a9b72997f6a5d61372e1dc0c2ac7e
Author: wqyfavor <wq...@163.com>
AuthorDate: Thu Nov 8 11:30:22 2018 +0800
[Core] Let affine types of "scroller", "list", "waterfall" match RenderList logic. Autodetect subclass when registering a component and register its affine type. (#1723)
---
ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.h | 4 ++
ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm | 10 ++++
.../WeexSDK/Sources/Component/WXCellComponent.mm | 4 +-
.../Sources/Component/WXComponent_internal.h | 2 +
ios/sdk/WeexSDK/Sources/Engine/WXSDKEngine.m | 13 +++++
.../WeexSDK/Sources/Manager/WXComponentFactory.h | 10 ++++
.../WeexSDK/Sources/Manager/WXComponentFactory.m | 56 +++++++++++++++++++++-
ios/sdk/WeexSDK/Sources/Model/WXComponent.mm | 5 ++
.../core/render/node/factory/render_creator.cpp | 49 +++++++++++++++----
.../core/render/node/factory/render_creator.h | 8 ++++
weex_core/Source/core/render/node/render_list.cpp | 3 +-
11 files changed, 150 insertions(+), 14 deletions(-)
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.h b/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.h
index aa7e5a7..c611eb1 100644
--- a/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.h
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.h
@@ -193,6 +193,10 @@ namespace WeexCore
+ (void)registerModules:(NSDictionary *)modules;
++ (void)registerComponentAffineType:(NSString *)type asType:(NSString *)baseType;
+
++ (BOOL)isComponentAffineType:(NSString *)type asType:(NSString *)baseType;
+
@end
#endif
diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm b/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm
index 41c5d80..793601e 100644
--- a/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm
+++ b/ios/sdk/WeexSDK/Sources/Bridge/WXCoreBridge.mm
@@ -876,6 +876,16 @@ static WeexCore::ScriptBridge* jsBridge = nullptr;
}
}
++ (void)registerComponentAffineType:(NSString *)type asType:(NSString *)baseType
+{
+ WeexCore::RenderCreator::GetInstance()->RegisterAffineType([type UTF8String] ?: "", [baseType UTF8String] ?: "");
+}
+
++ (BOOL)isComponentAffineType:(NSString *)type asType:(NSString *)baseType
+{
+ return WeexCore::RenderCreator::GetInstance()->IsAffineType([type UTF8String] ?: "", [baseType UTF8String] ?: "");
+}
+
+ (void)setDefaultDimensionIntoRoot:(NSString*)pageId width:(CGFloat)width height:(CGFloat)height
isWidthWrapContent:(BOOL)isWidthWrapContent
isHeightWrapContent:(BOOL)isHeightWrapContent
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXCellComponent.mm b/ios/sdk/WeexSDK/Sources/Component/WXCellComponent.mm
index 7d1cbf2..1a3b294 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXCellComponent.mm
+++ b/ios/sdk/WeexSDK/Sources/Component/WXCellComponent.mm
@@ -138,7 +138,7 @@
For water-fall(aka UICollectionView), we must ignore left value generated by layout engine.
*/
- if ([self.supercomponent.type isEqualToString:@"waterfall"]) {
+ if ([self.supercomponent _isAffineTypeAs:@"waterfall"]) {
return !CGSizeEqualToSize(frame.size, _calculatedFrame.size);
}
else {
@@ -148,7 +148,7 @@
- (void)_assignCalculatedFrame:(CGRect)frame
{
- if ([self.supercomponent.type isEqualToString:@"waterfall"]) {
+ if ([self.supercomponent _isAffineTypeAs:@"waterfall"]) {
frame.origin = CGPointZero;
}
else {
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h b/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
index f485a18..fc7658d 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
+++ b/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
@@ -283,4 +283,6 @@ typedef id (^WXDataBindingBlock)(NSDictionary *data, BOOL *needUpdate);
- (void)_buildViewHierarchyLazily;
+- (BOOL)_isAffineTypeAs:(NSString *)type;
+
@end
diff --git a/ios/sdk/WeexSDK/Sources/Engine/WXSDKEngine.m b/ios/sdk/WeexSDK/Sources/Engine/WXSDKEngine.m
index be187db..b5d7e00 100644
--- a/ios/sdk/WeexSDK/Sources/Engine/WXSDKEngine.m
+++ b/ios/sdk/WeexSDK/Sources/Engine/WXSDKEngine.m
@@ -82,6 +82,17 @@
# pragma mark Component Register
++ (void)_registerAffineTypes
+{
+ /* register weex core types that should match RenderList or RenderScroller.
+ "list" and "waterfall" must be registered before "scroller" because "WXListComponent" and "WXRecyclerComponent"
+ are both subclasses of "WXScrollerComponent".
+ */
+ [WXComponentFactory registerBaseType:@"list" withClass:NSClassFromString(@"WXListComponent")];
+ [WXComponentFactory registerBaseType:@"waterfall" withClass:NSClassFromString(@"WXRecyclerComponent")];
+ [WXComponentFactory registerBaseType:@"scroller" withClass:NSClassFromString(@"WXScrollerComponent")];
+}
+
// register some default components when the engine initializes.
+ (void)_registerDefaultComponents
{
@@ -117,6 +128,8 @@
[self registerComponent:@"recycle-list" withClass:NSClassFromString(@"WXRecycleListComponent")];
[self registerComponent:@"cell-slot" withClass:NSClassFromString(@"WXCellSlotComponent") withProperties: @{@"append":@"tree", @"isTemplate":@YES}];
+ // other non-default components should be checked with affine-base types.
+ [self _registerAffineTypes];
}
+ (void)registerComponent:(NSString *)name withClass:(Class)clazz
diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXComponentFactory.h b/ios/sdk/WeexSDK/Sources/Manager/WXComponentFactory.h
index 73b08e1..f9fe89e 100644
--- a/ios/sdk/WeexSDK/Sources/Manager/WXComponentFactory.h
+++ b/ios/sdk/WeexSDK/Sources/Manager/WXComponentFactory.h
@@ -32,6 +32,16 @@
@interface WXComponentFactory : NSObject
/**
+ * @abstract Register an affine base type to weex core. So that all subclasses of clazz will use this type to render.
+ * For example: WXNestedListComponent is a subclass of WXListComponent and uses type of 'nested-list'.
+ * It should be rendered using RenderList in weexcore.
+ *
+ * @param typeName weex core type identifier
+ * @param clazz The WXComponent subclass to register
+ */
++ (void)registerBaseType:(NSString *)typeName withClass:(Class)clazz;
+
+/**
* @abstract Register a component for a given name
*
* @param name The component name to register;
diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXComponentFactory.m b/ios/sdk/WeexSDK/Sources/Manager/WXComponentFactory.m
index 0101d7a..3b86e01 100644
--- a/ios/sdk/WeexSDK/Sources/Manager/WXComponentFactory.m
+++ b/ios/sdk/WeexSDK/Sources/Manager/WXComponentFactory.m
@@ -20,9 +20,21 @@
#import "WXComponentFactory.h"
#import "WXAssert.h"
#import "WXLog.h"
-
+#import "WXCoreBridge.h"
+#import "WXComponent.h"
#import <objc/runtime.h>
+@interface WXComponentBaseType : NSObject
+
+@property (nonatomic, strong) NSString* type;
+@property (nonatomic, strong) Class clazz;
+
+@end
+
+@implementation WXComponentBaseType
+
+@end
+
@implementation WXComponentConfig
- (instancetype)initWithName:(NSString *)name class:(NSString *)clazz pros:(NSDictionary *)pros
@@ -46,6 +58,7 @@
@implementation WXComponentFactory
{
+ NSMutableArray<WXComponentBaseType*> *_baseTypes;
NSMutableDictionary *_componentConfigs;
NSLock *_configLock;
}
@@ -64,6 +77,7 @@
- (instancetype)init
{
if(self = [super init]){
+ _baseTypes = [NSMutableArray array];
_componentConfigs = [NSMutableDictionary dictionary];
_configLock = [[NSLock alloc] init];
}
@@ -87,6 +101,11 @@
return [[self sharedInstance] configWithComponentName:name];
}
++ (void)registerBaseType:(NSString *)typeName withClass:(Class)clazz
+{
+ [[self sharedInstance] registerBaseType:typeName withClass:clazz];
+}
+
+ (void)registerComponent:(NSString *)name withClass:(Class)clazz withPros:(NSDictionary *)pros
{
[[self sharedInstance] registerComponent:name withClass:clazz withPros:pros];
@@ -214,6 +233,38 @@
return config;
}
+- (void)registerBaseType:(NSString *)typeName withClass:(Class)clazz
+{
+ if ([typeName length] > 0 && clazz != Nil) {
+ WXComponentBaseType* typePair = [[WXComponentBaseType alloc] init];
+ typePair.type = typeName;
+ typePair.clazz = clazz;
+ [_baseTypes addObject:typePair];
+ }
+}
+
+- (void)registerAffineType:(NSString *)typeName withClass:(Class)clazz
+{
+ // iterates super classes of clazz and check if any super class matches registerd base types
+ if ([_baseTypes count] > 0 && [typeName length] > 0 && clazz != Nil) {
+ Class supercls = [clazz superclass];
+ while (supercls) {
+ if (supercls == [WXComponent class]) {
+ break;
+ }
+
+ for (WXComponentBaseType* typePair in _baseTypes) {
+ if (supercls == typePair.clazz) {
+ WXLogInfo(@"Type '%@' is registerd as affine type of '%@' because '%@' is subclass of '%@'.", typeName, typePair.type, clazz, supercls);
+ [WXCoreBridge registerComponentAffineType:typeName asType:typePair.type];
+ return; // done, use the first found affine type
+ }
+ }
+ supercls = [supercls superclass];
+ }
+ }
+}
+
- (void)registerComponent:(NSString *)name withClass:(Class)clazz withPros:(NSDictionary *)pros
{
WXAssert(name && clazz, @"name or clazz must not be nil for registering component.");
@@ -230,7 +281,7 @@
config = [[WXComponentConfig alloc] initWithName:name class:NSStringFromClass(clazz) pros:pros];
[_componentConfigs setValue:config forKey:name];
[config registerMethods];
-
+ [self registerAffineType:name withClass:clazz];
[_configLock unlock];
}
@@ -248,6 +299,7 @@
if(config){
[_componentConfigs setValue:config forKey:name];
[config registerMethods];
+ [self registerAffineType:name withClass:NSClassFromString(clazz)];
}
}
[_configLock unlock];
diff --git a/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm b/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm
index 95ac414..43fda8b 100644
--- a/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm
+++ b/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm
@@ -493,6 +493,11 @@ static BOOL bNeedRemoveEvents = YES;
}
}
+- (BOOL)_isAffineTypeAs:(NSString *)type
+{
+ return [WXCoreBridge isComponentAffineType:_type asType:type];
+}
+
- (CALayer *)layer
{
return _layer;
diff --git a/weex_core/Source/core/render/node/factory/render_creator.cpp b/weex_core/Source/core/render/node/factory/render_creator.cpp
index 8632110..0bfc8ee 100644
--- a/weex_core/Source/core/render/node/factory/render_creator.cpp
+++ b/weex_core/Source/core/render/node/factory/render_creator.cpp
@@ -31,22 +31,35 @@ namespace WeexCore {
RenderCreator *RenderCreator::g_pInstance = nullptr;
-IRenderObject *RenderCreator::CreateRender(const std::string &type,
- const std::string &ref) {
- IRenderFactory *factory;
+IRenderFactory *RenderCreator::CreateFactory(const std::string &type) {
if (type == kRenderText) {
- factory = new RenderTextFactory();
+ return new RenderTextFactory();
} else if (type == kRenderList || type == kRenderWaterfall ||
type == kRenderRecycleList) {
- factory = new RenderListFactory();
+ return new RenderListFactory();
} else if (type == kRenderMask) {
- factory = new RenderMaskFactory();
+ return new RenderMaskFactory();
} else if (type == kRenderScroller) {
- factory = new RenderScrollerFactory();
+ return new RenderScrollerFactory();
} else if (type == kRenderAppBar) {
- factory = new RenderAppBarFactory();
+ return new RenderAppBarFactory();
} else {
- factory = new RenderCommonFactory();
+ // search for affine types
+ auto findAffine = affineTypes_.find(type);
+ if (findAffine != affineTypes_.end()) {
+ return CreateFactory(findAffine->second);
+ }
+ else {
+ return new RenderCommonFactory();
+ }
+ }
+}
+
+IRenderObject *RenderCreator::CreateRender(const std::string &type,
+ const std::string &ref) {
+ IRenderFactory *factory = CreateFactory(type);
+ if (factory == nullptr) {
+ return nullptr;
}
IRenderObject *render = factory->CreateRender();
@@ -55,4 +68,22 @@ IRenderObject *RenderCreator::CreateRender(const std::string &type,
delete factory;
return render;
}
+
+void RenderCreator::RegisterAffineType(const std::string &type, const std::string& asType) {
+ if (!type.empty() && !asType.empty()) {
+ affineTypes_[type] = asType;
+ }
+}
+
+bool RenderCreator::IsAffineType(const std::string &type, const std::string& asType) {
+ if (type == asType) {
+ return true;
+ }
+
+ auto findAffine = affineTypes_.find(type);
+ if (findAffine == affineTypes_.end()) {
+ return false;
+ }
+ return IsAffineType(findAffine->second, asType);
+}
} // namespace WeexCore
diff --git a/weex_core/Source/core/render/node/factory/render_creator.h b/weex_core/Source/core/render/node/factory/render_creator.h
index f5dddfc..b3775d1 100644
--- a/weex_core/Source/core/render/node/factory/render_creator.h
+++ b/weex_core/Source/core/render/node/factory/render_creator.h
@@ -20,10 +20,12 @@
#define CORE_RENDER_NODE_FACTORY_RENDER_CREATOR_H_
#include <string>
+#include <map>
namespace WeexCore {
class IRenderObject;
+class IRenderFactory;
class RenderCreator {
private:
@@ -51,10 +53,16 @@ class RenderCreator {
return g_pInstance;
}
+ IRenderFactory *CreateFactory(const std::string &type);
IRenderObject *CreateRender(const std::string &type, const std::string &ref);
+
+ void RegisterAffineType(const std::string &type, const std::string& asType);
+ bool IsAffineType(const std::string &type, const std::string& asType);
private:
static RenderCreator *g_pInstance;
+
+ std::map<std::string, std::string> affineTypes_; // affineTypes_[A] = B means A is rendered like B
};
} // namespace WeexCore
diff --git a/weex_core/Source/core/render/node/render_list.cpp b/weex_core/Source/core/render/node/render_list.cpp
index ec6284c..ed05abc 100644
--- a/weex_core/Source/core/render/node/render_list.cpp
+++ b/weex_core/Source/core/render/node/render_list.cpp
@@ -26,6 +26,7 @@
#include "core/render/node/render_list.h"
#include "core/render/node/render_object.h"
#include "core/render/page/render_page.h"
+#include "core/render/node/factory/render_creator.h"
namespace WeexCore {
@@ -261,7 +262,7 @@ int RenderList::AddRenderObject(int index, RenderObject *child) {
void RenderList::AddRenderObjectWidth(RenderObject *child,
const bool updating) {
- if (type() == kRenderWaterfall || type() == kRenderRecycleList) {
+ if ((RenderCreator::GetInstance()->IsAffineType(type(), kRenderWaterfall)) || type() == kRenderRecycleList) {
if (child->type() == kRenderHeader || child->type() == kRenderFooter) {
child->ApplyStyle(WIDTH, to_string(this->available_width_), updating);
} else if (child->is_sticky()) {