RenderCore/Utilities/CKInternalHelpers.mm (61 lines of code) (raw):
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#import "CKInternalHelpers.h"
#import <objc/runtime.h>
BOOL CKSubclassOverridesInstanceMethod(Class superclass, Class subclass, SEL selector) noexcept
{
if (![subclass isSubclassOfClass:superclass]) {
return NO;
}
Method superclassMethod = class_getInstanceMethod(superclass, selector);
Method subclassMethod = class_getInstanceMethod(subclass, selector);
IMP superclassIMP = superclassMethod ? method_getImplementation(superclassMethod) : NULL;
IMP subclassIMP = subclassMethod ? method_getImplementation(subclassMethod) : NULL;
if (superclassIMP == NULL) {
return NO;
}
return (superclassIMP != subclassIMP);
}
BOOL CKSubclassOverridesClassMethod(Class superclass, Class subclass, SEL selector) noexcept
{
if (![subclass isSubclassOfClass:superclass]) {
return NO;
}
Method superclassMethod = class_getClassMethod(superclass, selector);
Method subclassMethod = class_getClassMethod(subclass, selector);
IMP superclassIMP = superclassMethod ? method_getImplementation(superclassMethod) : NULL;
IMP subclassIMP = subclassMethod ? method_getImplementation(subclassMethod) : NULL;
if (superclassIMP == NULL) {
return NO;
}
return (superclassIMP != subclassIMP);
}
std::string CKStringFromPointer(const void *ptr) noexcept
{
char buf[64];
snprintf(buf, sizeof(buf), "%p", ptr);
return buf;
}
CGFloat CKScreenScale() noexcept
{
static CGFloat _scale;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_scale = [UIScreen mainScreen].scale;
});
return _scale;
}
CGFloat CKFloorPixelValue(CGFloat f) noexcept
{
return floor(f * CKScreenScale()) / CKScreenScale();
}
CGFloat CKCeilPixelValue(CGFloat f) noexcept
{
return ceil(f * CKScreenScale()) / CKScreenScale();
}
CGFloat CKRoundPixelValue(CGFloat f) noexcept
{
return round(f * CKScreenScale()) / CKScreenScale();
}
auto CKReturnIfResponds(id const obj, SEL const sel) -> id
{
return [obj respondsToSelector:sel] ? obj : nil;
}