mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-10 16:29:55 +00:00
Upgrade ASLayoutElementContext to an Object #trivial (#344)
* Upgrade ASLayoutElementContext to an object * Address feedback from Huy
This commit is contained in:
parent
05e9bdd092
commit
c9e4b98a55
@ -317,10 +317,10 @@ ASPrimitiveTraitCollectionDeprecatedImplementation
|
||||
[self cancelLayoutTransition];
|
||||
|
||||
BOOL didCreateNewContext = NO;
|
||||
ASLayoutElementContext context = ASLayoutElementGetCurrentContext();
|
||||
if (ASLayoutElementContextIsNull(context)) {
|
||||
context = ASLayoutElementContextMake(ASLayoutElementContextDefaultTransitionID);
|
||||
ASLayoutElementSetCurrentContext(context);
|
||||
ASLayoutElementContext *context = ASLayoutElementGetCurrentContext();
|
||||
if (context == nil) {
|
||||
context = [[ASLayoutElementContext alloc] init];
|
||||
ASLayoutElementPushContext(context);
|
||||
didCreateNewContext = YES;
|
||||
}
|
||||
|
||||
@ -341,7 +341,7 @@ ASPrimitiveTraitCollectionDeprecatedImplementation
|
||||
}
|
||||
|
||||
if (didCreateNewContext) {
|
||||
ASLayoutElementClearCurrentContext();
|
||||
ASLayoutElementPopContext();
|
||||
}
|
||||
|
||||
// If our new layout's desired size for self doesn't match current size, ask our parent to update it.
|
||||
@ -457,8 +457,8 @@ ASPrimitiveTraitCollectionDeprecatedImplementation
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
if (ASHierarchyStateIncludesLayoutPending(_hierarchyState)) {
|
||||
ASLayoutElementContext context = ASLayoutElementGetCurrentContext();
|
||||
if (ASLayoutElementContextIsNull(context) || _pendingTransitionID != context.transitionID) {
|
||||
ASLayoutElementContext *context = ASLayoutElementGetCurrentContext();
|
||||
if (context == nil || _pendingTransitionID != context.transitionID) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
@ -546,8 +546,10 @@ ASPrimitiveTraitCollectionDeprecatedImplementation
|
||||
ASLayout *newLayout;
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
|
||||
ASLayoutElementSetCurrentContext(ASLayoutElementContextMake(transitionID));
|
||||
|
||||
ASLayoutElementContext *ctx = [[ASLayoutElementContext alloc] init];
|
||||
ctx.transitionID = transitionID;
|
||||
ASLayoutElementPushContext(ctx);
|
||||
|
||||
BOOL automaticallyManagesSubnodesDisabled = (self.automaticallyManagesSubnodes == NO);
|
||||
self.automaticallyManagesSubnodes = YES; // Temporary flag for 1.9.x
|
||||
@ -558,7 +560,7 @@ ASPrimitiveTraitCollectionDeprecatedImplementation
|
||||
self.automaticallyManagesSubnodes = NO; // Temporary flag for 1.9.x
|
||||
}
|
||||
|
||||
ASLayoutElementClearCurrentContext();
|
||||
ASLayoutElementPopContext();
|
||||
}
|
||||
|
||||
if (isCancelled()) {
|
||||
|
||||
@ -30,69 +30,62 @@
|
||||
|
||||
#pragma mark - ASLayoutElementContext
|
||||
|
||||
@implementation ASLayoutElementContext
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_transitionID = ASLayoutElementContextDefaultTransitionID;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
CGFloat const ASLayoutElementParentDimensionUndefined = NAN;
|
||||
CGSize const ASLayoutElementParentSizeUndefined = {ASLayoutElementParentDimensionUndefined, ASLayoutElementParentDimensionUndefined};
|
||||
|
||||
int32_t const ASLayoutElementContextInvalidTransitionID = 0;
|
||||
int32_t const ASLayoutElementContextDefaultTransitionID = ASLayoutElementContextInvalidTransitionID + 1;
|
||||
|
||||
static inline ASLayoutElementContext _ASLayoutElementContextMake(int32_t transitionID)
|
||||
{
|
||||
struct ASLayoutElementContext context;
|
||||
context.transitionID = transitionID;
|
||||
return context;
|
||||
}
|
||||
|
||||
static inline BOOL _IsValidTransitionID(int32_t transitionID)
|
||||
{
|
||||
return transitionID > ASLayoutElementContextInvalidTransitionID;
|
||||
}
|
||||
|
||||
struct ASLayoutElementContext const ASLayoutElementContextNull = _ASLayoutElementContextMake(ASLayoutElementContextInvalidTransitionID);
|
||||
|
||||
BOOL ASLayoutElementContextIsNull(struct ASLayoutElementContext context)
|
||||
{
|
||||
return !_IsValidTransitionID(context.transitionID);
|
||||
}
|
||||
|
||||
ASLayoutElementContext ASLayoutElementContextMake(int32_t transitionID)
|
||||
{
|
||||
NSCAssert(_IsValidTransitionID(transitionID), @"Invalid transition ID");
|
||||
return _ASLayoutElementContextMake(transitionID);
|
||||
}
|
||||
|
||||
pthread_key_t ASLayoutElementContextKey;
|
||||
|
||||
static void ASLayoutElementDestructor(void *p) {
|
||||
if (p != NULL) {
|
||||
ASDisplayNodeCFailAssert(@"Thread exited without clearing layout element context!");
|
||||
CFBridgingRelease(p);
|
||||
}
|
||||
};
|
||||
|
||||
// pthread_key_create must be called before the key can be used. This function does that.
|
||||
void ASLayoutElementContextEnsureKey()
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
pthread_key_create(&ASLayoutElementContextKey, free);
|
||||
pthread_key_create(&ASLayoutElementContextKey, ASLayoutElementDestructor);
|
||||
});
|
||||
}
|
||||
|
||||
void ASLayoutElementSetCurrentContext(struct ASLayoutElementContext context)
|
||||
void ASLayoutElementPushContext(ASLayoutElementContext *context)
|
||||
{
|
||||
ASLayoutElementContextEnsureKey();
|
||||
ASDisplayNodeCAssert(pthread_getspecific(ASLayoutElementContextKey) == NULL, @"Nested ASLayoutElementContexts aren't supported.");
|
||||
pthread_setspecific(ASLayoutElementContextKey, new ASLayoutElementContext(context));
|
||||
// NOTE: It would be easy to support nested contexts – just use an NSMutableArray here.
|
||||
ASDisplayNodeCAssertNil(ASLayoutElementGetCurrentContext(), @"Nested ASLayoutElementContexts aren't supported.");
|
||||
pthread_setspecific(ASLayoutElementContextKey, CFBridgingRetain(context));
|
||||
}
|
||||
|
||||
struct ASLayoutElementContext ASLayoutElementGetCurrentContext()
|
||||
ASLayoutElementContext *ASLayoutElementGetCurrentContext()
|
||||
{
|
||||
ASLayoutElementContextEnsureKey();
|
||||
auto heapCtx = (ASLayoutElementContext *)pthread_getspecific(ASLayoutElementContextKey);
|
||||
return (heapCtx ? *heapCtx : ASLayoutElementContextNull);
|
||||
// Don't retain here. Caller will retain if it wants to!
|
||||
return (__bridge __unsafe_unretained ASLayoutElementContext *)pthread_getspecific(ASLayoutElementContextKey);
|
||||
}
|
||||
|
||||
void ASLayoutElementClearCurrentContext()
|
||||
void ASLayoutElementPopContext()
|
||||
{
|
||||
ASLayoutElementContextEnsureKey();
|
||||
auto heapCtx = (ASLayoutElementContext *)pthread_getspecific(ASLayoutElementContextKey);
|
||||
if (heapCtx != NULL) {
|
||||
delete heapCtx;
|
||||
}
|
||||
ASDisplayNodeCAssertNotNil(ASLayoutElementGetCurrentContext(), @"Attempt to pop context when there wasn't a context!");
|
||||
CFBridgingRelease(pthread_getspecific(ASLayoutElementContextKey));
|
||||
pthread_setspecific(ASLayoutElementContextKey, NULL);
|
||||
}
|
||||
|
||||
|
||||
@ -23,26 +23,25 @@
|
||||
|
||||
#pragma mark - ASLayoutElementContext
|
||||
|
||||
struct ASLayoutElementContext {
|
||||
int32_t transitionID;
|
||||
};
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
AS_SUBCLASSING_RESTRICTED
|
||||
@interface ASLayoutElementContext : NSObject
|
||||
@property (nonatomic) int32_t transitionID;
|
||||
@end
|
||||
|
||||
extern int32_t const ASLayoutElementContextInvalidTransitionID;
|
||||
|
||||
extern int32_t const ASLayoutElementContextDefaultTransitionID;
|
||||
|
||||
extern struct ASLayoutElementContext const ASLayoutElementContextNull;
|
||||
// Does not currently support nesting – there must be no current context.
|
||||
extern void ASLayoutElementPushContext(ASLayoutElementContext * context);
|
||||
|
||||
extern BOOL ASLayoutElementContextIsNull(struct ASLayoutElementContext context);
|
||||
extern ASLayoutElementContext * _Nullable ASLayoutElementGetCurrentContext();
|
||||
|
||||
extern struct ASLayoutElementContext ASLayoutElementContextMake(int32_t transitionID);
|
||||
|
||||
extern void ASLayoutElementSetCurrentContext(struct ASLayoutElementContext context);
|
||||
|
||||
extern struct ASLayoutElementContext ASLayoutElementGetCurrentContext();
|
||||
|
||||
extern void ASLayoutElementClearCurrentContext();
|
||||
extern void ASLayoutElementPopContext();
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#pragma mark - ASLayoutElementLayoutDefaults
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user