Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1de1e89

Browse files
Oleksii Dykanfacebook-github-bot
authored andcommitted
Comparable CKCG actions
Reviewed By: cuva Differential Revision: D26980011 fbshipit-source-id: 9745e7d93343984b88e881a72a4b4db2a9785cbe
1 parent 05621a2 commit 1de1e89

4 files changed

Lines changed: 61 additions & 16 deletions

File tree

ComponentKit/Core/Action/CKAction.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ template<typename... T>
111111
class CKAction : public CKActionBase {
112112
/** This constructor is private to forbid direct usage. Use actionFromBlock. */
113113
CKAction<T...>(void(^block)(CKComponent *, T...)) noexcept : CKActionBase((dispatch_block_t)block) {};
114+
115+
CKAction<T...>(void(^block)(CKComponent *, T...), void *functionPointer, CKScopedResponder *responder, CKScopedResponderKey key) noexcept
116+
: CKActionBase((dispatch_block_t)block, functionPointer, responder, key) {};
114117

115118
public:
116119
CKAction<T...>() noexcept : CKActionBase() {};
@@ -166,6 +169,10 @@ class CKAction : public CKActionBase {
166169
static CKAction<T...> unsafeActionForController(const CK::BaseSpecContext &context, SEL selector) {
167170
return CKAction<T...>{selector, nodeFromContext(context)};
168171
}
172+
173+
static CKAction<T...> unsafeActionWithIdentifier(void(^block)(CKComponent *, T...), void *functionPointer, CKScopedResponder *responder, CKScopedResponderKey key) {
174+
return CKAction<T...>(block, functionPointer, responder, key);
175+
}
169176

170177
/** Like actionFromBlock, but allows passing a block that doesn't take a sender component. */
171178
static CKAction<T...> actionFromSenderlessBlock(void (^block)(T...)) {
@@ -253,7 +260,7 @@ class CKAction : public CKActionBase {
253260

254261
void send(CKComponent *sender, CKActionSendBehavior behavior, T... args) const
255262
{
256-
if (_variant == CKActionVariant::Block) {
263+
if (_variant == CKActionVariant::Block || _variant == CKActionVariant::BlockWithIdentifier) {
257264
void (^block)(CKComponent *sender, T... args) = (void (^)(CKComponent *sender, T... args))_block;
258265
block(sender, args...);
259266
return;

ComponentKit/Core/Action/CKAction.mm

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#import <RenderCore/RCAssert.h>
1919
#import <ComponentKit/RCAssociatedObject.h>
2020
#import <ComponentKit/CKCollection.h>
21+
#import <ComponentKit/CKGlobalConfig.h>
2122
#import <ComponentKit/CKMutex.h>
2223

2324
#import "CKComponent+UIView.h"
@@ -36,8 +37,10 @@ void CKConfigureInvocationWithArguments(NSInvocation *invocation, NSInteger inde
3637
// If we are using a scoped action, we are only concerned that the selector and the
3738
// responder unique identifier matches.
3839
&& _scopedResponderAndKey.responder == rhs._scopedResponderAndKey.responder
39-
&& _selector == rhs._selector
40-
&& _block == rhs._block);
40+
&& _selectorOrIdentifier == rhs._selectorOrIdentifier
41+
&& ((CKReadGlobalConfig().actionShouldCompareCustomIdentifier
42+
&& _variant == CKActionVariant::BlockWithIdentifier)
43+
|| _block == rhs._block));
4144
}
4245

4346
CKActionSendBehavior CKActionBase::defaultBehavior() const
@@ -59,6 +62,9 @@ void CKConfigureInvocationWithArguments(NSInvocation *invocation, NSInteger inde
5962
case CKActionVariant::Block:
6063
RCCFailAssert(@"Should not be asking for target for block action.");
6164
return nil;
65+
case CKActionVariant::BlockWithIdentifier:
66+
RCCFailAssert(@"Should not be asking for target for block action.");
67+
return nil;
6268
}
6369
}
6470

@@ -67,7 +73,7 @@ void CKConfigureInvocationWithArguments(NSInvocation *invocation, NSInteger inde
6773
_scopedResponderAndKey({}),
6874
_block(NULL),
6975
_variant(CKActionVariant::RawSelector),
70-
_selector(nullptr) {}
76+
_selectorOrIdentifier(nullptr) {}
7177

7278
CKActionBase::CKActionBase(const CKActionBase&) = default;
7379

@@ -76,7 +82,7 @@ void CKConfigureInvocationWithArguments(NSInvocation *invocation, NSInteger inde
7682
_scopedResponderAndKey({}),
7783
_block(NULL),
7884
_variant(CKActionVariant::TargetSelector),
79-
_selector(selector) {}
85+
_selectorOrIdentifier(selector) {}
8086

8187
CKActionBase::CKActionBase(const CKComponentScope &scope, SEL selector) noexcept
8288
: CKActionBase(selector, scope.node()) { }
@@ -87,7 +93,7 @@ void CKConfigureInvocationWithArguments(NSInvocation *invocation, NSInteger inde
8793
_block(NULL),
8894

8995
_variant(CKActionVariant::Responder),
90-
_selector(selector)
96+
_selectorOrIdentifier(selector)
9197
{
9298
RCCAssertNotNil(node.scopeHandle, @"You are creating an action that will not fire because you have an invalid scope handle.");
9399
}
@@ -97,36 +103,54 @@ void CKConfigureInvocationWithArguments(NSInvocation *invocation, NSInteger inde
97103
_scopedResponderAndKey({}),
98104
_block(NULL),
99105
_variant(CKActionVariant::RawSelector),
100-
_selector(selector) {}
106+
_selectorOrIdentifier(selector) {}
101107

102108
CKActionBase::CKActionBase(dispatch_block_t block) noexcept
103109
: _target(nil),
104110
_scopedResponderAndKey({}),
105111
_block(block),
106112
_variant(CKActionVariant::Block),
107-
_selector(NULL) {}
113+
_selectorOrIdentifier(NULL) {}
114+
115+
CKActionBase::CKActionBase(dispatch_block_t block, void *functionPointer, CKScopedResponder *responder, CKScopedResponderKey key) noexcept
116+
: _target(nil),
117+
_scopedResponderAndKey(CKActionBase::ScopedResponderAndKey{responder, key}),
118+
_block(block),
119+
_variant(CKActionVariant::BlockWithIdentifier),
120+
_selectorOrIdentifier(functionPointer) {};
108121

109122
CKActionBase::operator bool() const noexcept {
110-
return _selector != NULL || _block != NULL || _scopedResponderAndKey.responder != nil;
123+
return _block != NULL || _selectorOrIdentifier != NULL || _scopedResponderAndKey.responder != nil;
111124
}
112125

113126
CKActionBase::~CKActionBase() {}
114127

115128
SEL CKActionBase::selector() const noexcept {
116-
return _selector;
129+
if (_variant == CKActionVariant::BlockWithIdentifier || _variant == CKActionVariant::Block) {
130+
return nil;
131+
}
132+
return (SEL)_selectorOrIdentifier;
117133
}
118134

119135
std::string CKActionBase::identifier() const noexcept
120136
{
121137
switch (_variant) {
122138
case CKActionVariant::RawSelector:
123-
return std::string(sel_getName(_selector)) + "-Selector";
139+
return std::string(sel_getName((SEL)_selectorOrIdentifier)) + "-Selector";
124140
case CKActionVariant::TargetSelector:
125-
return std::string(sel_getName(_selector)) + "-TargetSelector-" + std::to_string((long)_target);
141+
return std::string(sel_getName((SEL)_selectorOrIdentifier)) + "-TargetSelector-" + std::to_string((long)_target);
126142
case CKActionVariant::Responder:
127-
return std::string(sel_getName(_selector)) + "-Responder-" + std::to_string((long)_scopedResponderAndKey.responder);
143+
return std::string(sel_getName((SEL)_selectorOrIdentifier)) + "-Responder-" + std::to_string((long)_scopedResponderAndKey.responder);
128144
case CKActionVariant::Block:
129-
return std::string(sel_getName(_selector)) + "-Block-" + std::to_string((long)_block);
145+
return "Block-" + std::to_string((long)_block);
146+
case CKActionVariant::BlockWithIdentifier:
147+
if (CKReadGlobalConfig().actionShouldUseCustomIdentifierInIdentifierString) {
148+
return std::string("BlockWithIdentifier-") + std::to_string((long)_scopedResponderAndKey.responder) +
149+
"-" + std::to_string((long)_selectorOrIdentifier);
150+
} else {
151+
return std::string("BlockWithIdentifier-") + std::to_string((long)_scopedResponderAndKey.responder) +
152+
"-" + std::to_string((long)_block);
153+
}
130154
}
131155
}
132156

ComponentKit/Core/Action/CKComponentActionInternal.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ class CKActionBase {
5454
RawSelector,
5555
TargetSelector,
5656
Responder,
57-
Block
57+
Block,
58+
BlockWithIdentifier
5859
};
5960

6061
CKActionBase() noexcept;
@@ -68,6 +69,7 @@ class CKActionBase {
6869
CKActionBase(SEL selector) noexcept;
6970

7071
CKActionBase(dispatch_block_t block) noexcept;
72+
CKActionBase(dispatch_block_t block, void *functionPointer, CKScopedResponder *responder, CKScopedResponderKey key) noexcept;
7173

7274
~CKActionBase();
7375

@@ -83,7 +85,7 @@ class CKActionBase {
8385
ScopedResponderAndKey _scopedResponderAndKey;
8486
dispatch_block_t _block;
8587
CKActionVariant _variant;
86-
SEL _selector;
88+
void *_selectorOrIdentifier;
8789

8890
static CKComponent *componentFromContext(const CK::BaseSpecContext &context) noexcept;
8991
static CKTreeNode *nodeFromContext(const CK::BaseSpecContext &context) noexcept;

RenderCore/Config/CKGlobalConfig.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,18 @@ struct CKGlobalConfig {
6161
Enables caching of the layout for reused components.
6262
*/
6363
BOOL enableLayoutCaching = NO;
64+
/**
65+
In Specs we provide a custom identifier, which is a function pointer to the
66+
handler function. This bool enables using this identifier in == operator
67+
instead of comparing blocks.
68+
*/
69+
BOOL actionShouldCompareCustomIdentifier = NO;
70+
71+
/**
72+
Flag to use the custom identifer provided by the spec instead of block pointer
73+
when generating an identifier string for an action
74+
*/
75+
BOOL actionShouldUseCustomIdentifierInIdentifierString = NO;
6476
};
6577

6678
CKGlobalConfig CKReadGlobalConfig();

0 commit comments

Comments
 (0)