Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,71 @@ - (dispatch_queue_t)methodQueue {
return RCTGetUIManagerQueue();
}

RCT_EXPORT_METHOD(create:(nonnull NSNumber*)tag lineString: (nonnull NSArray*)coordinates startOffset: (nonnull NSNumber*)startOffset endOffset: (nonnull NSNumber*)endOffset resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
resolve([[ChangeLineOffsetsShapeAnimator createWithTag:tag coordinates:coordinates startOffset:startOffset endOffset:endOffset] getTag]);
// Must match NativeRNMBXChangeLineOffsetsShapeAnimatorModuleSpec exactly (codegen uses NSInteger/double).
- (void)generate:(NSInteger)tag
coordinates:(NSArray *)coordinates
startOffset:(double)startOffset
endOffset:(double)endOffset
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject
{
ChangeLineOffsetsShapeAnimator *animator =
[ChangeLineOffsetsShapeAnimator createWithTag:@(tag)
coordinates:coordinates
startOffset:@(startOffset)
endOffset:@(endOffset)];
if (animator == nil) {
reject(@"RNMBXChangeLineOffsetsShapeAnimatorModule", @"Failed to generate animator", nil);
return;
}
resolve([animator getTag]);
}

RCT_EXPORT_METHOD(setLineString:(nonnull NSNumber*)tag coordinates: (nonnull NSArray*)coordinates startOffset: (nonnull NSNumber*)startOffset endOffset: (nonnull NSNumber*)endOffset resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
[ChangeLineOffsetsShapeAnimator setLineStringWithTag:tag coordinates:coordinates startOffset:startOffset endOffset:endOffset resolve:resolve reject:reject];
- (void)setLineString:(NSInteger)tag
coordinates:(NSArray *)coordinates
startOffset:(double)startOffset
endOffset:(double)endOffset
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject
{
[ChangeLineOffsetsShapeAnimator setLineStringWithTag:@(tag)
coordinates:coordinates
startOffset:@(startOffset)
endOffset:@(endOffset)
resolve:resolve
reject:reject];
}

RCT_EXPORT_METHOD(setStartOffset:(nonnull NSNumber*)tag offset: (nonnull NSNumber*)offset durationMs: (nonnull NSNumber*)durationMs resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
[ChangeLineOffsetsShapeAnimator setStartOffsetWithTag:tag offset:offset durationMs:durationMs resolve:resolve reject:reject];
- (void)setStartOffset:(NSInteger)tag
offset:(double)offset
duration:(double)duration
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject
{
[ChangeLineOffsetsShapeAnimator setStartOffsetWithTag:@(tag)
offset:@(offset)
durationMs:@(duration)
resolve:resolve
reject:reject];
}

RCT_EXPORT_METHOD(setEndOffset:(nonnull NSNumber*)tag offset: (nonnull NSNumber*)offset durationMs: (nonnull NSNumber*)durationMs resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
[ChangeLineOffsetsShapeAnimator setEndOffsetWithTag:tag offset:offset durationMs:durationMs resolve:resolve reject:reject];
- (void)setEndOffset:(NSInteger)tag
offset:(double)offset
duration:(double)duration
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject
{
[ChangeLineOffsetsShapeAnimator setEndOffsetWithTag:@(tag)
offset:@(offset)
durationMs:@(duration)
resolve:resolve
reject:reject];
}

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
(const facebook::react::ObjCTurboModule::InitParams &)params
{
return std::make_shared<facebook::react::NativeRNMBXShapeSourceModuleSpecJSI>(params);
return std::make_shared<facebook::react::NativeRNMBXChangeLineOffsetsShapeAnimatorModuleSpecJSI>(params);
}

@end
30 changes: 25 additions & 5 deletions ios/RNMBX/ShapeAnimators/RNMBXMovePointShapeAnimatorModule.mm
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,38 @@ - (dispatch_queue_t)methodQueue {
return RCTGetUIManagerQueue();
}

RCT_EXPORT_METHOD(generate:(nonnull NSNumber*)tag startCoordinate: (nonnull NSArray*)startCoordinate resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
resolve([[MovePointShapeAnimator generateWithTag:tag startCoordinate:startCoordinate] getTag]);
// Must match NativeRNMBXMovePointShapeAnimatorModuleSpec exactly (codegen uses NSInteger/double).
- (void)generate:(NSInteger)tag
coordinate:(NSArray *)coordinate
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject
{
MovePointShapeAnimator *animator =
[MovePointShapeAnimator generateWithTag:@(tag) startCoordinate:coordinate];
if (animator == nil) {
reject(@"RNMBXMovePointShapeAnimatorModule", @"Failed to generate animator", nil);
return;
}
resolve([animator getTag]);
}

RCT_EXPORT_METHOD(moveTo:(nonnull NSNumber*)tag coordinate: (nonnull NSArray*)coordinate durationMs: (nonnull NSNumber*)durationMs resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
[MovePointShapeAnimator moveToTag:tag coordinate:coordinate durationMs:durationMs resolve:resolve reject:reject];
- (void)moveTo:(NSInteger)tag
coordinate:(NSArray *)coordinate
duration:(double)duration
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject
{
[MovePointShapeAnimator moveToTag:@(tag)
coordinate:coordinate
durationMs:@(duration)
resolve:resolve
reject:reject];
}

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
(const facebook::react::ObjCTurboModule::InitParams &)params
{
return std::make_shared<facebook::react::NativeRNMBXPointAnnotationModuleSpecJSI>(params);
return std::make_shared<facebook::react::NativeRNMBXMovePointShapeAnimatorModuleSpecJSI>(params);
}

@end
37 changes: 21 additions & 16 deletions ios/RNMBX/ShapeAnimators/RNMBXMovePointShapeAnimatorModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,23 +93,28 @@ extension MovePointShapeAnimator {
}

@objc
public static func moveTo(tag: NSNumber, coordinate: NSArray, durationMs: NSNumber, resolve: RCTPromiseResolveBlock, reject: @escaping (_ code: String, _ message: String, _ error: NSError) -> Void) {
guard let lng = coordinate[0] as? Double, let lat = coordinate[1] as? Double else {
reject("\(LOG_TAG): moveTo", "Unable to find animator with tag \(tag)", NSError())
return
}
public static func moveTo(tag: NSNumber, coordinate: NSArray, durationMs: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping (_ code: String, _ message: String, _ error: NSError) -> Void) {
DispatchQueue.main.async {
// RN arrays often bridge as NSNumber; `as? Double` fails for NSNumber.
let lngValue = (coordinate[0] as? NSNumber)?.doubleValue ?? (coordinate[0] as? Double)
let latValue = (coordinate[1] as? NSNumber)?.doubleValue ?? (coordinate[1] as? Double)
guard let lng = lngValue, let lat = latValue else {
reject("\(LOG_TAG): moveTo", "Invalid coordinate for tag \(tag)", NSError())
return
}

guard let animator = getAnimator(tag: tag) else {
reject("\(LOG_TAG): moveTo", "Unable to find animator with tag \(tag)", NSError())
return
}

let targetCoord = LocationCoordinate2D(
latitude: lat,
longitude: lng
)

guard let animator = getAnimator(tag: tag) else {
reject("\(LOG_TAG): moveTo", "Unable to find animator with tag \(tag)", NSError())
return
animator.moveTo(coordinate: targetCoord, durationSec: durationMs.doubleValue / 1000)
resolve(tag)
}

let targetCoord = LocationCoordinate2D(
latitude: lat,
longitude: lng
)

animator.moveTo(coordinate: targetCoord, durationSec: durationMs.doubleValue / 1000)
resolve(tag)
}
}
5 changes: 5 additions & 0 deletions ios/RNMBX/ShapeAnimators/ShapeAnimatorCommon.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ public class ShapeAnimatorCommon: NSObject, ShapeAnimator {
// - MARK: Lifecycle

@objc func refresh() {
guard Thread.isMainThread else {
DispatchQueue.main.async { [weak self] in self?.refresh() }
return
}

if startedAt == nil {
startedAt = displayLink?.targetTimestamp.magnitude ?? 0
}
Expand Down
15 changes: 13 additions & 2 deletions ios/RNMBX/ShapeAnimators/ShapeAnimatorManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,24 @@ class ShapeAnimatorManager {

typealias Tag = Int

private let lock = NSLock()
var animatorByTags: [Tag: ShapeAnimator] = [:]

func getShapeAnimatorByTag(tag: Tag) -> ShapeAnimator? {
return animatorByTags[tag]
return get(tag: tag)
}

// Keep registration synchronous: ShapeSource.shape looks up by tag in didSet.
// Hopping to main.async races that lookup and can leave the source unbound.
// Lock instead so generate (UIManager queue) and get (main) stay consistent.
func register(tag: Tag, animator: ShapeAnimator) {
lock.lock()
animatorByTags[tag] = animator
lock.unlock()
}

func withAnimator(tag: NSNumber, callback: (ShapeAnimator) -> Void) {
if let animator = animatorByTags[tag.intValue] {
if let animator = get(tag: tag.intValue) {
callback(animator)
}
}
Expand All @@ -26,6 +32,8 @@ class ShapeAnimatorManager {
}

func get(tag: Tag) -> ShapeAnimator? {
lock.lock()
defer { lock.unlock() }
return animatorByTags[tag]
}

Expand All @@ -37,6 +45,9 @@ class ShapeAnimatorManager {
if let tag = json["__nativeTag"] as? Int {
return get(tag: tag)
}
if let tagNumber = json["__nativeTag"] as? NSNumber {
return get(tag: tagNumber.intValue)
}
}
} catch {
Logger.log(level: .error, tag: LOG_TAG, message: "Unable to get animator tag from \(shape): \(error)")
Expand Down