mirror of
https://github.com/zhigang1992/react-native-reanimated.git
synced 2026-06-14 18:09:30 +08:00
When value gets detached from all component it can be still kept in memory and attached to some other component at later time. But because we don't know when JS reference is dropped we need to delete native counterpart of the value when it gets detached. This has led to a situation in which the value was reinstantiated on the native site. In that case if the value has changed we expect it to persist that changes when it gets attached again. This wasn't happening and each time the value was instantiated we'd always use the initial value. With this change we are solving that issue by querying the value right before we detach the native node and then we use that value to update config such that next time when it gets instantiated it uses updated value instead of the initial one.
168 lines
4.8 KiB
Objective-C
168 lines
4.8 KiB
Objective-C
#import "REAModule.h"
|
|
|
|
#import "REANodesManager.h"
|
|
|
|
typedef void (^AnimatedOperation)(REANodesManager *nodesManager);
|
|
|
|
@implementation REAModule
|
|
{
|
|
REANodesManager *_nodesManager;
|
|
NSMutableArray<AnimatedOperation> *_operations;
|
|
}
|
|
|
|
RCT_EXPORT_MODULE(ReanimatedModule);
|
|
|
|
- (void)invalidate
|
|
{
|
|
[_nodesManager invalidate];
|
|
[self.bridge.eventDispatcher removeDispatchObserver:self];
|
|
[self.bridge.uiManager.observerCoordinator removeObserver:self];
|
|
}
|
|
|
|
- (dispatch_queue_t)methodQueue
|
|
{
|
|
// This module needs to be on the same queue as the UIManager to avoid
|
|
// having to lock `_operations` and `_preOperations` since `uiManagerWillPerformMounting`
|
|
// will be called from that queue.
|
|
return RCTGetUIManagerQueue();
|
|
}
|
|
|
|
- (void)setBridge:(RCTBridge *)bridge
|
|
{
|
|
[super setBridge:bridge];
|
|
|
|
_nodesManager = [[REANodesManager alloc] initWithModule:self
|
|
uiManager:self.bridge.uiManager];
|
|
_operations = [NSMutableArray new];
|
|
|
|
[bridge.eventDispatcher addDispatchObserver:self];
|
|
[bridge.uiManager.observerCoordinator addObserver:self];
|
|
}
|
|
|
|
#pragma mark -- API
|
|
|
|
RCT_EXPORT_METHOD(createNode:(nonnull NSNumber *)nodeID
|
|
config:(NSDictionary<NSString *, id> *)config)
|
|
{
|
|
[self addOperationBlock:^(REANodesManager *nodesManager) {
|
|
[nodesManager createNode:nodeID config:config];
|
|
}];
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(dropNode:(nonnull NSNumber *)nodeID)
|
|
{
|
|
[self addOperationBlock:^(REANodesManager *nodesManager) {
|
|
[nodesManager dropNode:nodeID];
|
|
}];
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(getValue:(nonnull NSNumber *)nodeID
|
|
callback:(RCTResponseSenderBlock)callback) {
|
|
[self addOperationBlock:^(REANodesManager *nodesManager) {
|
|
[nodesManager getValue:nodeID callback:(RCTResponseSenderBlock)callback];
|
|
}];
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(connectNodes:(nonnull NSNumber *)parentID
|
|
childTag:(nonnull NSNumber *)childID)
|
|
{
|
|
[self addOperationBlock:^(REANodesManager *nodesManager) {
|
|
[nodesManager connectNodes:parentID childID:childID];
|
|
}];
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(disconnectNodes:(nonnull NSNumber *)parentID
|
|
childTag:(nonnull NSNumber *)childID)
|
|
{
|
|
[self addOperationBlock:^(REANodesManager *nodesManager) {
|
|
[nodesManager disconnectNodes:parentID childID:childID];
|
|
}];
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(connectNodeToView:(nonnull NSNumber *)nodeID
|
|
viewTag:(nonnull NSNumber *)viewTag)
|
|
{
|
|
NSString *viewName = [self.bridge.uiManager viewNameForReactTag:viewTag];
|
|
[self addOperationBlock:^(REANodesManager *nodesManager) {
|
|
[nodesManager connectNodeToView:nodeID viewTag:viewTag viewName:viewName];
|
|
}];
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(disconnectNodeFromView:(nonnull NSNumber *)nodeID
|
|
viewTag:(nonnull NSNumber *)viewTag)
|
|
{
|
|
[self addOperationBlock:^(REANodesManager *nodesManager) {
|
|
[nodesManager disconnectNodeFromView:nodeID viewTag:viewTag];
|
|
}];
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(attachEvent:(nonnull NSNumber *)viewTag
|
|
eventName:(nonnull NSString *)eventName
|
|
eventNodeID:(nonnull NSNumber *)eventNodeID)
|
|
{
|
|
[self addOperationBlock:^(REANodesManager *nodesManager) {
|
|
[nodesManager attachEvent:viewTag eventName:eventName eventNodeID:eventNodeID];
|
|
}];
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(detachEvent:(nonnull NSNumber *)viewTag
|
|
eventName:(nonnull NSString *)eventName
|
|
eventNodeID:(nonnull NSNumber *)eventNodeID)
|
|
{
|
|
[self addOperationBlock:^(REANodesManager *nodesManager) {
|
|
[nodesManager detachEvent:viewTag eventName:eventName eventNodeID:eventNodeID];
|
|
}];
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(configureProps:(nonnull NSArray<NSString *> *)nativeProps
|
|
uiProps:(nonnull NSArray<NSString *> *)uiProps)
|
|
{
|
|
[self addOperationBlock:^(REANodesManager *nodesManager) {
|
|
[nodesManager configureProps:[NSSet setWithArray:nativeProps] uiProps:[NSSet setWithArray:uiProps]];
|
|
}];
|
|
}
|
|
|
|
|
|
#pragma mark -- Batch handling
|
|
|
|
- (void)addOperationBlock:(AnimatedOperation)operation
|
|
{
|
|
[_operations addObject:operation];
|
|
}
|
|
|
|
#pragma mark - RCTUIManagerObserver
|
|
|
|
- (void)uiManagerWillPerformMounting:(RCTUIManager *)uiManager
|
|
{
|
|
if (_operations.count == 0) {
|
|
return;
|
|
}
|
|
|
|
NSArray<AnimatedOperation> *operations = _operations;
|
|
_operations = [NSMutableArray new];
|
|
|
|
REANodesManager *nodesManager = _nodesManager;
|
|
|
|
[uiManager addUIBlock:^(__unused RCTUIManager *manager, __unused NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
|
for (AnimatedOperation operation in operations) {
|
|
operation(nodesManager);
|
|
}
|
|
[nodesManager operationsBatchDidComplete];
|
|
}];
|
|
}
|
|
|
|
#pragma mark -- Events
|
|
|
|
- (NSArray<NSString *> *)supportedEvents
|
|
{
|
|
return @[@"onReanimatedCall", @"onReanimatedPropsChange"];
|
|
}
|
|
|
|
- (void)eventDispatcherWillDispatchEvent:(id<RCTEvent>)event
|
|
{
|
|
// Events can be dispatched from any queue
|
|
[_nodesManager dispatchEvent:event];
|
|
}
|
|
|
|
@end
|