155 lines
3.7 KiB
Plaintext
155 lines
3.7 KiB
Plaintext
#import <reanimated/apple/REAAssertJavaScriptQueue.h>
|
|
#import <reanimated/apple/REAAssertTurboModuleManagerQueue.h>
|
|
#import <reanimated/apple/REANodesManager.h>
|
|
|
|
#import <React/RCTUtils.h>
|
|
|
|
@implementation REANodesManager {
|
|
READisplayLink *_displayLink;
|
|
NSMutableArray<REAOnAnimationCallback> *_onAnimationCallbacks;
|
|
REAEventHandler _eventHandler;
|
|
REAPerformOperations _performOperations;
|
|
}
|
|
|
|
- (READisplayLink *)getDisplayLink
|
|
{
|
|
RCTAssertMainQueue();
|
|
|
|
if (!_displayLink) {
|
|
_displayLink = [READisplayLink displayLinkWithTarget:self selector:@selector(onAnimationFrame:)];
|
|
#if !TARGET_OS_OSX
|
|
_displayLink.preferredFramesPerSecond = 120; // will fallback to 60 fps for devices without Pro Motion display
|
|
#endif // TARGET_OS_OSX
|
|
[_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
|
|
}
|
|
return _displayLink;
|
|
}
|
|
|
|
- (void)useDisplayLinkOnMainQueue:(CADisplayLinkOperation)displayLinkOperation
|
|
{
|
|
// This method is called on the JavaScript queue during initialization or on the ShadowQueue during invalidation.
|
|
react_native_assert(REAIsJavaScriptQueue() || REAIsTurboModuleManagerQueue());
|
|
|
|
__weak __typeof__(self) weakSelf = self;
|
|
RCTExecuteOnMainQueue(^{
|
|
__typeof__(self) strongSelf = weakSelf;
|
|
if (strongSelf == nil) {
|
|
return;
|
|
}
|
|
displayLinkOperation([strongSelf getDisplayLink]);
|
|
});
|
|
}
|
|
|
|
- (nonnull instancetype)init
|
|
{
|
|
REAAssertJavaScriptQueue();
|
|
|
|
if ((self = [super init])) {
|
|
_onAnimationCallbacks = [NSMutableArray new];
|
|
_eventHandler = ^(id<RCTEvent> event) {
|
|
// no-op
|
|
};
|
|
}
|
|
[self useDisplayLinkOnMainQueue:^(READisplayLink *displayLink) {
|
|
[displayLink setPaused:YES];
|
|
}];
|
|
|
|
return self;
|
|
}
|
|
|
|
- (void)invalidate
|
|
{
|
|
REAAssertTurboModuleManagerQueue();
|
|
|
|
_eventHandler = nil;
|
|
[self useDisplayLinkOnMainQueue:^(READisplayLink *displayLink) {
|
|
[displayLink invalidate];
|
|
}];
|
|
}
|
|
|
|
- (void)postOnAnimation:(REAOnAnimationCallback)clb
|
|
{
|
|
RCTAssertMainQueue();
|
|
[_onAnimationCallbacks addObject:clb];
|
|
[self startUpdatingOnAnimationFrame];
|
|
}
|
|
|
|
- (void)registerEventHandler:(REAEventHandler)eventHandler
|
|
{
|
|
REAAssertJavaScriptQueue();
|
|
_eventHandler = eventHandler;
|
|
}
|
|
|
|
- (void)registerPerformOperations:(REAPerformOperations)performOperations
|
|
{
|
|
REAAssertJavaScriptQueue();
|
|
_performOperations = performOperations;
|
|
}
|
|
|
|
- (void)startUpdatingOnAnimationFrame
|
|
{
|
|
RCTAssertMainQueue();
|
|
[[self getDisplayLink] setPaused:NO];
|
|
}
|
|
|
|
- (void)stopUpdatingOnAnimationFrame
|
|
{
|
|
RCTAssertMainQueue();
|
|
[[self getDisplayLink] setPaused:YES];
|
|
}
|
|
|
|
- (void)onAnimationFrame:(READisplayLink *)displayLink
|
|
{
|
|
RCTAssertMainQueue();
|
|
|
|
NSArray<REAOnAnimationCallback> *callbacks = _onAnimationCallbacks;
|
|
_onAnimationCallbacks = [NSMutableArray new];
|
|
|
|
// When one of the callbacks would postOnAnimation callback we don't want
|
|
// to process it until the next frame. This is why we cpy the array before
|
|
// we iterate over it
|
|
for (REAOnAnimationCallback block in callbacks) {
|
|
block(displayLink);
|
|
}
|
|
|
|
[self performOperations];
|
|
|
|
if (_onAnimationCallbacks.count == 0) {
|
|
[self stopUpdatingOnAnimationFrame];
|
|
}
|
|
}
|
|
|
|
- (void)performOperations
|
|
{
|
|
RCTAssertMainQueue();
|
|
_performOperations(); // calls ReanimatedModuleProxy::performOperations
|
|
}
|
|
|
|
- (void)dispatchEvent:(id<RCTEvent>)event
|
|
{
|
|
RCTAssertMainQueue();
|
|
__weak REAEventHandler eventHandler = _eventHandler;
|
|
__weak __typeof__(self) weakSelf = self;
|
|
RCTExecuteOnMainQueue(^void() {
|
|
__typeof__(self) strongSelf = weakSelf;
|
|
if (strongSelf == nil) {
|
|
return;
|
|
}
|
|
if (eventHandler == nil) {
|
|
return;
|
|
}
|
|
eventHandler(event);
|
|
[strongSelf performOperations];
|
|
});
|
|
}
|
|
|
|
- (void)maybeFlushUIUpdatesQueue
|
|
{
|
|
RCTAssertMainQueue();
|
|
if ([[self getDisplayLink] isPaused]) {
|
|
[self performOperations];
|
|
}
|
|
}
|
|
|
|
@end
|