LookinMsgAttribute.m 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. //
  2. // LookinMsgAttribute.m
  3. // Lookin
  4. //
  5. // Created by Li Kai on 2019/8/19.
  6. // https://lookin.work
  7. //
  8. #import "LookinMsgAttribute.h"
  9. #import "LookinMsgTargetAction.h"
  10. @implementation LookinMsgActionParams
  11. - (double)doubleValue {
  12. if (![self.value isKindOfClass:[NSNumber class]]) {
  13. NSAssert(NO, @"");
  14. return 0;
  15. }
  16. return ((NSNumber *)self.value).doubleValue;
  17. }
  18. - (NSInteger)integerValue {
  19. if (![self.value isKindOfClass:[NSNumber class]]) {
  20. NSAssert(NO, @"");
  21. return 0;
  22. }
  23. return ((NSNumber *)self.value).integerValue;
  24. }
  25. - (BOOL)boolValue {
  26. if (![self.value isKindOfClass:[NSNumber class]]) {
  27. NSAssert(NO, @"");
  28. return 0;
  29. }
  30. return ((NSNumber *)self.value).boolValue;
  31. }
  32. @end
  33. @interface LookinMsgAttribute ()
  34. @property(nonatomic, strong, readwrite) id currentValue;
  35. @property(nonatomic, strong) NSMutableArray<LookinMsgTargetAction *> *subscribers;
  36. @end
  37. @implementation LookinMsgAttribute
  38. + (instancetype)attributeWithValue:(id)value {
  39. LookinMsgAttribute *attr = [LookinMsgAttribute new];
  40. attr.currentValue = value;
  41. return attr;
  42. }
  43. - (instancetype)init {
  44. if (self = [super init]) {
  45. self.subscribers = [NSMutableArray array];
  46. }
  47. return self;
  48. }
  49. - (void)setValue:(id)value ignoreSubscriber:(id)ignoreSubscriber userInfo:(id)userInfo {
  50. if ([self.currentValue isEqual:value]) {
  51. // value 相等的话直接拒绝
  52. return;
  53. }
  54. self.currentValue = value;
  55. __block NSMutableIndexSet *invalidIdxs = nil;
  56. [self.subscribers enumerateObjectsUsingBlock:^(LookinMsgTargetAction * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  57. id subscriberTarget = obj.target;
  58. SEL subscriberAction = obj.action;
  59. if (!subscriberTarget) {
  60. // target 已被释放,删掉这组 target-action 吧
  61. if (!invalidIdxs) {
  62. invalidIdxs = [NSMutableIndexSet indexSet];
  63. }
  64. [invalidIdxs addIndex:idx];
  65. return;
  66. }
  67. if (subscriberTarget == ignoreSubscriber) {
  68. // 不要通知 ignoreSubscriber
  69. return;
  70. }
  71. LookinMsgActionParams *params = [LookinMsgActionParams new];
  72. params.userInfo = userInfo;
  73. params.value = value;
  74. params.relatedObject = obj.relatedObject;
  75. #if TARGET_OS_IPHONE
  76. [[UIApplication sharedApplication] sendAction:subscriberAction to:subscriberTarget from:params forEvent:nil];
  77. #elif TARGET_OS_MAC
  78. [NSApp sendAction:subscriberAction to:subscriberTarget from:params];
  79. #endif
  80. }];
  81. if (invalidIdxs.count) {
  82. [self.subscribers removeObjectsAtIndexes:invalidIdxs];
  83. }
  84. }
  85. - (void)subscribe:(id)target action:(SEL)action relatedObject:(id)relatedObject {
  86. [self subscribe:target action:action relatedObject:relatedObject sendAtOnce:NO];
  87. }
  88. - (void)subscribe:(id)target action:(SEL)action relatedObject:(id)relatedObject sendAtOnce:(BOOL)sendAtOnce {
  89. if (!target || !action) {
  90. return;
  91. }
  92. LookinMsgTargetAction *newOne = [LookinMsgTargetAction new];
  93. newOne.target = target;
  94. newOne.action = action;
  95. newOne.relatedObject = relatedObject;
  96. if ([self.subscribers containsObject:newOne]) {
  97. return;
  98. }
  99. [self.subscribers addObject:newOne];
  100. if (sendAtOnce) {
  101. LookinMsgActionParams *params = [LookinMsgActionParams new];
  102. params.value = self.currentValue;
  103. params.relatedObject = relatedObject;
  104. #if TARGET_OS_IPHONE
  105. [[UIApplication sharedApplication] sendAction:action to:target from:params forEvent:nil];
  106. #elif TARGET_OS_MAC
  107. [NSApp sendAction:action to:target from:params];
  108. #endif
  109. }
  110. }
  111. @end
  112. @implementation LookinDoubleMsgAttribute
  113. + (instancetype)attributeWithDouble:(double)value {
  114. LookinDoubleMsgAttribute *attr = [LookinDoubleMsgAttribute new];
  115. attr.currentValue = @(value);
  116. return attr;
  117. }
  118. - (void)setDoubleValue:(double)doubleValue ignoreSubscriber:(id)ignoreSubscriber {
  119. [self setValue:@(doubleValue) ignoreSubscriber:ignoreSubscriber userInfo:nil];
  120. }
  121. - (double)currentDoubleValue {
  122. return ((NSNumber *)self.currentValue).doubleValue;
  123. }
  124. @end
  125. @implementation LookinIntegerMsgAttribute
  126. + (instancetype)attributeWithInteger:(NSInteger)value {
  127. LookinIntegerMsgAttribute *attr = [LookinIntegerMsgAttribute new];
  128. attr.currentValue = @(value);
  129. return attr;
  130. }
  131. - (void)setIntegerValue:(NSInteger)integerValue ignoreSubscriber:(id)ignoreSubscriber {
  132. [self setValue:@(integerValue) ignoreSubscriber:ignoreSubscriber userInfo:nil];
  133. }
  134. - (NSInteger)currentIntegerValue {
  135. return ((NSNumber *)self.currentValue).integerValue;
  136. }
  137. @end
  138. @implementation LookinBOOLMsgAttribute
  139. + (instancetype)attributeWithBOOL:(BOOL)value {
  140. LookinBOOLMsgAttribute *attr = [LookinBOOLMsgAttribute new];
  141. attr.currentValue = @(value);
  142. return attr;
  143. }
  144. - (void)setBOOLValue:(BOOL)BOOLValue ignoreSubscriber:(id)ignoreSubscriber {
  145. [self setValue:@(BOOLValue) ignoreSubscriber:ignoreSubscriber userInfo:nil];
  146. }
  147. - (BOOL)currentBOOLValue {
  148. return ((NSNumber *)self.currentValue).boolValue;
  149. }
  150. @end