浏览代码

Initial equalTo() autoboxing implementation

Nikolay Tymchenko 11 年之前
父节点
当前提交
ccf371921b
共有 5 个文件被更改,包括 111 次插入44 次删除
  1. 3 21
      Masonry/MASCompositeConstraint.m
  2. 11 1
      Masonry/MASConstraint.h
  3. 9 5
      Masonry/MASConstraint.m
  4. 65 0
      Masonry/MASUtilities.h
  5. 23 17
      Masonry/MASViewConstraint.m

+ 3 - 21
Masonry/MASCompositeConstraint.m

@@ -121,28 +121,10 @@
 
 #pragma mark - NSLayoutRelation proxies
 
-- (MASConstraint * (^)(id))equalTo {
-    return ^id(id attr) {
+- (MASConstraint * (^)(id, NSLayoutRelation))_equalToWithRelation {
+    return ^id(id attr, NSLayoutRelation relation) {
         for (MASConstraint *constraint in self.childConstraints.copy) {
-            constraint.equalTo(attr);
-        }
-        return self;
-    };
-}
-
-- (MASConstraint * (^)(id))greaterThanOrEqualTo {
-    return ^id(id attr) {
-        for (MASConstraint *constraint in self.childConstraints.copy) {
-            constraint.greaterThanOrEqualTo(attr);
-        }
-        return self;
-    };
-}
-
-- (MASConstraint * (^)(id))lessThanOrEqualTo {
-    return ^id(id attr) {
-        for (MASConstraint *constraint in self.childConstraints.copy) {
-            constraint.lessThanOrEqualTo(attr);
+            constraint._equalToWithRelation(attr, relation);
         }
         return self;
     };

+ 11 - 1
Masonry/MASConstraint.h

@@ -99,6 +99,16 @@
  */
 - (MASConstraint * (^)(id attr))lessThanOrEqualTo;
 
+// TODO: description
+// TODO: update docs for the methods above
+- (MASConstraint * (^)(id attr, NSLayoutRelation relation))_equalToWithRelation;
+
+#define equalTo(...)                 _equalToWithRelation(MASBoxValue((__VA_ARGS__)), NSLayoutRelationEqual)
+
+#define greaterThanOrEqualTo(...)    _equalToWithRelation(MASBoxValue((__VA_ARGS__)), NSLayoutRelationGreaterThanOrEqual)
+
+#define lessThanOrEqualTo(...)       _equalToWithRelation(MASBoxValue((__VA_ARGS__)), NSLayoutRelationLessThanOrEqual)
+
 /**
  *	optional semantic property which has no effect but improves the readability of constraint
  */
@@ -179,4 +189,4 @@
  */
 - (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint;
 
-@end
+@end

+ 9 - 5
Masonry/MASConstraint.m

@@ -21,6 +21,14 @@
 	return [super init];
 }
 
+#pragma mark - Dummies
+
+- (MASConstraint * (^)(id))equalTo { return nil; }
+
+- (MASConstraint * (^)(id))greaterThanOrEqualTo { return nil; }
+
+- (MASConstraint * (^)(id))lessThanOrEqualTo { return nil; }
+
 #pragma mark - Abstract
 
 - (MASConstraint * (^)(MASEdgeInsets insets))insets { methodNotImplemented(); }
@@ -43,11 +51,7 @@
 
 - (MASConstraint * (^)())priorityHigh { methodNotImplemented(); }
 
-- (MASConstraint * (^)(id attr))equalTo { methodNotImplemented(); }
-
-- (MASConstraint * (^)(id attr))greaterThanOrEqualTo { methodNotImplemented(); }
-
-- (MASConstraint * (^)(id attr))lessThanOrEqualTo { methodNotImplemented(); }
+- (MASConstraint * (^)(id, NSLayoutRelation))_equalToWithRelation { methodNotImplemented(); }
 
 - (MASConstraint *)with { methodNotImplemented(); }
 

+ 65 - 0
Masonry/MASUtilities.h

@@ -67,3 +67,68 @@
  */
 #define MAS_NSUINT_BIT (CHAR_BIT * sizeof(NSUInteger))
 #define MAS_NSUINTROTATE(val, howmuch) ((((NSUInteger)val) << howmuch) | (((NSUInteger)val) >> (MAS_NSUINT_BIT - howmuch)))
+
+// TODO: description
+
+static inline id _MASBoxValue(const char *type, ...) {
+    va_list v;
+    va_start(v, type);
+    id obj = nil;
+    if (strcmp(type, @encode(id)) == 0) {
+        id actual = va_arg(v, id);
+        obj = actual;
+    } else if (strcmp(type, @encode(CGPoint)) == 0) {
+        CGPoint actual = (CGPoint)va_arg(v, CGPoint);
+        obj = [NSValue value:&actual withObjCType:type];
+    } else if (strcmp(type, @encode(CGSize)) == 0) {
+        CGSize actual = (CGSize)va_arg(v, CGSize);
+        obj = [NSValue value:&actual withObjCType:type];
+    } else if (strcmp(type, @encode(MASEdgeInsets)) == 0) {
+        MASEdgeInsets actual = (MASEdgeInsets)va_arg(v, MASEdgeInsets);
+        obj = [NSValue value:&actual withObjCType:type];
+    } else if (strcmp(type, @encode(char)) == 0) {
+        char actual = (char)va_arg(v, int);
+        obj = [NSNumber numberWithChar:actual];
+    } else if(strcmp(type, @encode(_Bool)) == 0) {
+        _Static_assert(sizeof(_Bool) <= sizeof(int), "Expected _Bool to be subject to vararg type promotion");
+        _Bool actual = (_Bool)va_arg(v, int);
+        obj = [NSNumber numberWithBool:actual];
+    } else if (strcmp(type, @encode(double)) == 0) {
+        double actual = (double)va_arg(v, double);
+        obj = [NSNumber numberWithDouble:actual];
+    } else if (strcmp(type, @encode(float)) == 0) {
+        float actual = (float)va_arg(v, double);
+        obj = [NSNumber numberWithFloat:actual];
+    } else if (strcmp(type, @encode(int)) == 0) {
+        int actual = (int)va_arg(v, int);
+        obj = [NSNumber numberWithInt:actual];
+    } else if (strcmp(type, @encode(long)) == 0) {
+        long actual = (long)va_arg(v, long);
+        obj = [NSNumber numberWithLong:actual];
+    } else if (strcmp(type, @encode(long long)) == 0) {
+        long long actual = (long long)va_arg(v, long long);
+        obj = [NSNumber numberWithLongLong:actual];
+    } else if (strcmp(type, @encode(short)) == 0) {
+        short actual = (short)va_arg(v, int);
+        obj = [NSNumber numberWithShort:actual];
+    } else if (strcmp(type, @encode(unsigned char)) == 0) {
+        unsigned char actual = (unsigned char)va_arg(v, unsigned int);
+        obj = [NSNumber numberWithUnsignedChar:actual];
+    } else if (strcmp(type, @encode(unsigned int)) == 0) {
+        unsigned int actual = (int)va_arg(v, unsigned int);
+        obj = [NSNumber numberWithUnsignedInt:actual];
+    } else if (strcmp(type, @encode(unsigned long)) == 0) {
+        unsigned long actual = (unsigned long)va_arg(v, unsigned long);
+        obj = [NSNumber numberWithUnsignedLong:actual];
+    } else if (strcmp(type, @encode(unsigned long long)) == 0) {
+        unsigned long long actual = (unsigned long long)va_arg(v, unsigned long long);
+        obj = [NSNumber numberWithUnsignedLongLong:actual];
+    } else if (strcmp(type, @encode(unsigned short)) == 0) {
+        unsigned short actual = (unsigned short)va_arg(v, unsigned int);
+        obj = [NSNumber numberWithUnsignedShort:actual];
+    }
+    va_end(v);
+    return obj;
+}
+
+#define MASBoxValue(value) _MASBoxValue(@encode(__typeof__((value))), (value))

+ 23 - 17
Masonry/MASViewConstraint.m

@@ -79,7 +79,25 @@
 - (void)setSecondViewAttribute:(id)secondViewAttribute {
     if ([secondViewAttribute isKindOfClass:NSNumber.class]) {
         self.layoutConstant = [secondViewAttribute doubleValue];
-    }  else if ([secondViewAttribute isKindOfClass:MAS_VIEW.class]) {
+    } else if ([secondViewAttribute isKindOfClass:NSValue.class]) {
+        NSValue *value = (NSValue *)secondViewAttribute;
+        if (strcmp(value.objCType, @encode(CGPoint)) == 0) {
+            CGPoint point;
+            [value getValue:&point];
+            self.centerOffset = point;
+        } else if (strcmp(value.objCType, @encode(CGSize)) == 0) {
+            CGSize size;
+            [value getValue:&size];
+            self.sizeOffset = size;
+        } else if (strcmp(value.objCType, @encode(MASEdgeInsets)) == 0) {
+            MASEdgeInsets insets;
+            [value getValue:&insets];
+            self.insets = insets;
+        } else {
+            // TODO: avoid duplication
+            NSAssert(NO, @"attempting to add unsupported attribute: %@", secondViewAttribute);
+        }
+    } else if ([secondViewAttribute isKindOfClass:MAS_VIEW.class]) {
         _secondViewAttribute = [[MASViewAttribute alloc] initWithView:secondViewAttribute layoutAttribute:self.firstViewAttribute.layoutAttribute];
     } else if ([secondViewAttribute isKindOfClass:MASViewAttribute.class]) {
         _secondViewAttribute = secondViewAttribute;
@@ -174,10 +192,10 @@
     };
 }
 
-#pragma mark - NSLayoutRelation proxies
+#pragma mark - NSLayoutRelation proxy
 
-- (MASConstraint * (^)(id))equalityWithRelation:(NSLayoutRelation)relation {
-    return ^id(id attribute) {
+- (MASConstraint * (^)(id, NSLayoutRelation))_equalToWithRelation {
+    return ^id(id attribute, NSLayoutRelation relation) {
         if ([attribute isKindOfClass:NSArray.class]) {
             NSAssert(!self.hasLayoutRelation, @"Redefinition of constraint relation");
             NSMutableArray *children = NSMutableArray.new;
@@ -191,7 +209,7 @@
             [self.delegate constraint:self shouldBeReplacedWithConstraint:compositeConstraint];
             return compositeConstraint;
         } else {
-            NSAssert(!self.hasLayoutRelation || self.layoutRelation == relation && [attribute isKindOfClass:NSNumber.class], @"Redefinition of constraint relation");
+            NSAssert(!self.hasLayoutRelation || self.layoutRelation == relation && [attribute isKindOfClass:NSValue.class], @"Redefinition of constraint relation");
             self.layoutRelation = relation;
             self.secondViewAttribute = attribute;
             return self;
@@ -199,18 +217,6 @@
     };
 }
 
-- (MASConstraint * (^)(id))equalTo {
-    return [self equalityWithRelation:NSLayoutRelationEqual];
-}
-
-- (MASConstraint * (^)(id))greaterThanOrEqualTo {
-    return [self equalityWithRelation:NSLayoutRelationGreaterThanOrEqual];
-}
-
-- (MASConstraint * (^)(id))lessThanOrEqualTo {
-    return [self equalityWithRelation:NSLayoutRelationLessThanOrEqual];
-}
-
 #pragma mark - Semantic properties
 
 - (MASConstraint *)with {