POPAnimation.mm 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /**
  2. Copyright (c) 2014-present, Facebook, Inc.
  3. All rights reserved.
  4. This source code is licensed under the BSD-style license found in the
  5. LICENSE file in the root directory of this source tree. An additional grant
  6. of patent rights can be found in the PATENTS file in the same directory.
  7. */
  8. #import "POPAnimationExtras.h"
  9. #import "POPAnimationInternal.h"
  10. #import <objc/runtime.h>
  11. #import "POPAction.h"
  12. #import "POPAnimationRuntime.h"
  13. #import "POPAnimationTracerInternal.h"
  14. #import "POPAnimatorPrivate.h"
  15. using namespace POP;
  16. #pragma mark - POPAnimation
  17. @implementation POPAnimation
  18. @synthesize solver = _solver;
  19. @synthesize currentValue = _currentValue;
  20. @synthesize progressMarkers = _progressMarkers;
  21. #pragma mark - Lifecycle
  22. - (id)init
  23. {
  24. [NSException raise:NSStringFromClass([self class]) format:@"Attempting to instantiate an abstract class. Use a concrete subclass instead."];
  25. return nil;
  26. }
  27. - (id)_init
  28. {
  29. self = [super init];
  30. if (nil != self) {
  31. [self _initState];
  32. }
  33. return self;
  34. }
  35. - (void)_initState
  36. {
  37. _state = new POPAnimationState(self);
  38. }
  39. - (void)dealloc
  40. {
  41. if (_state) {
  42. delete _state;
  43. _state = NULL;
  44. };
  45. }
  46. #pragma mark - Properties
  47. - (id)delegate
  48. {
  49. return _state->delegate;
  50. }
  51. - (void)setDelegate:(id)delegate
  52. {
  53. _state->setDelegate(delegate);
  54. }
  55. - (BOOL)isPaused
  56. {
  57. return _state->paused;
  58. }
  59. - (void)setPaused:(BOOL)paused
  60. {
  61. _state->setPaused(paused ? true : false);
  62. }
  63. - (NSInteger)repeatCount
  64. {
  65. if (_state->autoreverses) {
  66. return _state->repeatCount / 2;
  67. } else {
  68. return _state->repeatCount;
  69. }
  70. }
  71. - (void)setRepeatCount:(NSInteger)repeatCount
  72. {
  73. if (repeatCount > 0) {
  74. if (repeatCount > NSIntegerMax / 2) {
  75. repeatCount = NSIntegerMax / 2;
  76. }
  77. if (_state->autoreverses) {
  78. _state->repeatCount = (repeatCount * 2);
  79. } else {
  80. _state->repeatCount = repeatCount;
  81. }
  82. }
  83. }
  84. - (BOOL)autoreverses
  85. {
  86. return _state->autoreverses;
  87. }
  88. - (void)setAutoreverses:(BOOL)autoreverses
  89. {
  90. _state->autoreverses = autoreverses;
  91. if (autoreverses) {
  92. if (_state->repeatCount == 0) {
  93. [self setRepeatCount:1];
  94. }
  95. }
  96. }
  97. FB_PROPERTY_GET(POPAnimationState, type, POPAnimationType);
  98. DEFINE_RW_PROPERTY_OBJ_COPY(POPAnimationState, animationDidStartBlock, setAnimationDidStartBlock:, POPAnimationDidStartBlock);
  99. DEFINE_RW_PROPERTY_OBJ_COPY(POPAnimationState, animationDidReachToValueBlock, setAnimationDidReachToValueBlock:, POPAnimationDidReachToValueBlock);
  100. DEFINE_RW_PROPERTY_OBJ_COPY(POPAnimationState, completionBlock, setCompletionBlock:, POPAnimationCompletionBlock);
  101. DEFINE_RW_PROPERTY_OBJ_COPY(POPAnimationState, animationDidApplyBlock, setAnimationDidApplyBlock:, POPAnimationDidApplyBlock);
  102. DEFINE_RW_PROPERTY_OBJ_COPY(POPAnimationState, name, setName:, NSString*);
  103. DEFINE_RW_PROPERTY(POPAnimationState, beginTime, setBeginTime:, CFTimeInterval);
  104. DEFINE_RW_FLAG(POPAnimationState, removedOnCompletion, removedOnCompletion, setRemovedOnCompletion:);
  105. DEFINE_RW_FLAG(POPAnimationState, repeatForever, repeatForever, setRepeatForever:);
  106. - (id)valueForUndefinedKey:(NSString *)key
  107. {
  108. return _state->dict[key];
  109. }
  110. - (void)setValue:(id)value forUndefinedKey:(NSString *)key
  111. {
  112. if (!value) {
  113. [_state->dict removeObjectForKey:key];
  114. } else {
  115. if (!_state->dict)
  116. _state->dict = [[NSMutableDictionary alloc] init];
  117. _state->dict[key] = value;
  118. }
  119. }
  120. - (POPAnimationTracer *)tracer
  121. {
  122. if (!_state->tracer) {
  123. _state->tracer = [[POPAnimationTracer alloc] initWithAnimation:self];
  124. }
  125. return _state->tracer;
  126. }
  127. - (NSString *)description
  128. {
  129. NSMutableString *s = [NSMutableString stringWithFormat:@"<%@:%p", NSStringFromClass([self class]), self];
  130. [self _appendDescription:s debug:NO];
  131. [s appendString:@">"];
  132. return s;
  133. }
  134. - (NSString *)debugDescription
  135. {
  136. NSMutableString *s = [NSMutableString stringWithFormat:@"<%@:%p", NSStringFromClass([self class]), self];
  137. [self _appendDescription:s debug:YES];
  138. [s appendString:@">"];
  139. return s;
  140. }
  141. #pragma mark - Utility
  142. POPAnimationState *POPAnimationGetState(POPAnimation *a)
  143. {
  144. return a->_state;
  145. }
  146. - (BOOL)_advance:(id)object currentTime:(CFTimeInterval)currentTime elapsedTime:(CFTimeInterval)elapsedTime
  147. {
  148. return YES;
  149. }
  150. - (void)_appendDescription:(NSMutableString *)s debug:(BOOL)debug
  151. {
  152. if (_state->name)
  153. [s appendFormat:@"; name = %@", _state->name];
  154. if (!self.removedOnCompletion)
  155. [s appendFormat:@"; removedOnCompletion = %@", POPStringFromBOOL(self.removedOnCompletion)];
  156. if (debug) {
  157. if (_state->active)
  158. [s appendFormat:@"; active = %@", POPStringFromBOOL(_state->active)];
  159. if (_state->paused)
  160. [s appendFormat:@"; paused = %@", POPStringFromBOOL(_state->paused)];
  161. }
  162. if (_state->beginTime) {
  163. [s appendFormat:@"; beginTime = %f", _state->beginTime];
  164. }
  165. for (NSString *key in _state->dict) {
  166. [s appendFormat:@"; %@ = %@", key, _state->dict[key]];
  167. }
  168. }
  169. @end
  170. #pragma mark - POPPropertyAnimation
  171. #pragma mark - POPBasicAnimation
  172. #pragma mark - POPDecayAnimation
  173. @implementation NSObject (POP)
  174. - (void)pop_addAnimation:(POPAnimation *)anim forKey:(NSString *)key
  175. {
  176. [[POPAnimator sharedAnimator] addAnimation:anim forObject:self key:key];
  177. }
  178. - (void)pop_removeAllAnimations
  179. {
  180. [[POPAnimator sharedAnimator] removeAllAnimationsForObject:self];
  181. }
  182. - (void)pop_removeAnimationForKey:(NSString *)key
  183. {
  184. [[POPAnimator sharedAnimator] removeAnimationForObject:self key:key];
  185. }
  186. - (NSArray *)pop_animationKeys
  187. {
  188. return [[POPAnimator sharedAnimator] animationKeysForObject:self];
  189. }
  190. - (id)pop_animationForKey:(NSString *)key
  191. {
  192. return [[POPAnimator sharedAnimator] animationForObject:self key:key];
  193. }
  194. @end
  195. @implementation NSProxy (POP)
  196. - (void)pop_addAnimation:(POPAnimation *)anim forKey:(NSString *)key
  197. {
  198. [[POPAnimator sharedAnimator] addAnimation:anim forObject:self key:key];
  199. }
  200. - (void)pop_removeAllAnimations
  201. {
  202. [[POPAnimator sharedAnimator] removeAllAnimationsForObject:self];
  203. }
  204. - (void)pop_removeAnimationForKey:(NSString *)key
  205. {
  206. [[POPAnimator sharedAnimator] removeAnimationForObject:self key:key];
  207. }
  208. - (NSArray *)pop_animationKeys
  209. {
  210. return [[POPAnimator sharedAnimator] animationKeysForObject:self];
  211. }
  212. - (id)pop_animationForKey:(NSString *)key
  213. {
  214. return [[POPAnimator sharedAnimator] animationForObject:self key:key];
  215. }
  216. @end
  217. @implementation POPAnimation (NSCopying)
  218. - (instancetype)copyWithZone:(NSZone *)zone
  219. {
  220. /*
  221. * Must use [self class] instead of POPAnimation so that subclasses can call this via super.
  222. * Even though POPAnimation and POPPropertyAnimation throw exceptions on init,
  223. * it's safe to call it since you can only copy objects that have been successfully created.
  224. */
  225. POPAnimation *copy = [[[self class] allocWithZone:zone] init];
  226. if (copy) {
  227. copy.name = self.name;
  228. copy.beginTime = self.beginTime;
  229. copy.delegate = self.delegate;
  230. copy.animationDidStartBlock = self.animationDidStartBlock;
  231. copy.animationDidReachToValueBlock = self.animationDidReachToValueBlock;
  232. copy.completionBlock = self.completionBlock;
  233. copy.animationDidApplyBlock = self.animationDidApplyBlock;
  234. copy.removedOnCompletion = self.removedOnCompletion;
  235. copy.autoreverses = self.autoreverses;
  236. copy.repeatCount = self.repeatCount;
  237. copy.repeatForever = self.repeatForever;
  238. }
  239. return copy;
  240. }
  241. @end