Summary: Similar to D21040429, we need to add data sent to Flipper desktop so that we can use to retrieve necessary data. ~~The implementation is different; storing **all** component data is needed because the plugin refers to it when asked for information. This might cause an issue because we need to store more data. However, due to the sparseness of data at a single touch, this shouldn't cause any OOM.~~ Implementation Detail: - `FlipperKitLayoutPlugin.mm` - When the process finishes the tree returned is trie from root node to every node that is touched - `SKTouch.m` - `_nodeStack` keeps track of path from root to current component - `_treeStack` keeps track of current prefix tree (trie) - `continueWithChildIndex` takes care of logic for `_nodeStack` and `_treeStack` Reviewed By: Andrey-Mishanin Differential Revision: D21335956 fbshipit-source-id: 84c0cabd7399abe50cf2deaff2b01149a1a792d5
83 lines
2.3 KiB
Objective-C
83 lines
2.3 KiB
Objective-C
/*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
#if FB_SONARKIT_ENABLED
|
|
|
|
#import "SKTouch.h"
|
|
#import "SKNodeDescriptor.h"
|
|
|
|
@implementation SKTouch {
|
|
SKTouchFinishDelegate _onFinish;
|
|
|
|
CGPoint _currentTouchPoint;
|
|
|
|
SKDescriptorMapper* _descriptorMapper;
|
|
|
|
NSMutableArray<id<NSObject>>* _nodeStack;
|
|
NSMutableArray<NSMutableDictionary*>* _treeStack;
|
|
}
|
|
|
|
- (instancetype)initWithTouchPoint:(CGPoint)touchPoint
|
|
withRootNode:(id<NSObject>)node
|
|
withDescriptorMapper:(SKDescriptorMapper*)mapper
|
|
finishWithBlock:(SKTouchFinishDelegate)finishBlock {
|
|
if (self = [super init]) {
|
|
_onFinish = finishBlock;
|
|
_currentTouchPoint = touchPoint;
|
|
_descriptorMapper = mapper;
|
|
_nodeStack = [NSMutableArray new];
|
|
[_nodeStack addObject:node];
|
|
_treeStack = [NSMutableArray new];
|
|
[_treeStack addObject:[[NSMutableDictionary alloc] init]];
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
- (void)continueWithChildIndex:(NSUInteger)childIndex
|
|
withOffset:(CGPoint)offset {
|
|
_currentTouchPoint.x -= offset.x;
|
|
_currentTouchPoint.y -= offset.y;
|
|
|
|
id<NSObject> currentNode = _nodeStack.lastObject;
|
|
SKNodeDescriptor* descriptor =
|
|
[_descriptorMapper descriptorForClass:[currentNode class]];
|
|
id<NSObject> nextNode = [descriptor childForNode:currentNode
|
|
atIndex:childIndex];
|
|
[_nodeStack addObject:nextNode];
|
|
[_treeStack addObject:[[NSMutableDictionary alloc] init]];
|
|
|
|
descriptor = [_descriptorMapper descriptorForClass:[nextNode class]];
|
|
NSString* currentId = [descriptor identifierForNode:nextNode];
|
|
[descriptor hitTest:self forNode:nextNode];
|
|
|
|
// After finish this component
|
|
_currentTouchPoint.x += offset.x;
|
|
_currentTouchPoint.y += offset.y;
|
|
[_nodeStack removeLastObject];
|
|
NSDictionary* currentDict = _treeStack.lastObject;
|
|
[_treeStack removeLastObject];
|
|
[_treeStack.lastObject setObject:currentDict forKey:currentId];
|
|
}
|
|
|
|
- (void)finish {
|
|
_onFinish(_nodeStack.lastObject);
|
|
}
|
|
|
|
- (void)retrieveSelectTree:(SKProcessFinishDelegate)callback {
|
|
callback(_treeStack.lastObject);
|
|
[_treeStack removeAllObjects];
|
|
}
|
|
|
|
- (BOOL)containedIn:(CGRect)bounds {
|
|
return CGRectContainsPoint(bounds, _currentTouchPoint);
|
|
}
|
|
|
|
@end
|
|
|
|
#endif
|