-
Notifications
You must be signed in to change notification settings - Fork 69
Expand file tree
/
Copy pathBabylonNativeInterop.mm
More file actions
134 lines (109 loc) · 4.5 KB
/
BabylonNativeInterop.mm
File metadata and controls
134 lines (109 loc) · 4.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#import "BabylonNativeInterop.h"
#import "BabylonNative.h"
#import <React/RCTBridge+Private.h>
#import <jsi/jsi.h>
#include <ReactCommon/CallInvoker.h>
#import <Foundation/Foundation.h>
#import <memory>
using namespace facebook;
@interface RCTBridge (RCTTurboModule)
- (std::shared_ptr<facebook::react::CallInvoker>)jsCallInvoker;
@end
namespace {
jsi::Runtime* GetJSIRuntime(RCTBridge* bridge) {
RCTCxxBridge* cxxBridge = reinterpret_cast<RCTCxxBridge*>(bridge);
return reinterpret_cast<jsi::Runtime*>(cxxBridge.runtime);
}
}
@implementation BabylonNativeInterop
static NSMutableArray* activeTouches = [NSMutableArray new];
+ (void)initialize:(RCTBridge*)bridge {
auto jsCallInvoker{ bridge.jsCallInvoker };
auto jsDispatcher{ [jsCallInvoker{ std::move(jsCallInvoker) }](std::function<void()> func)
{
jsCallInvoker->invokeAsync([func{ std::move(func) }]
{
func();
});
} };
BabylonNative::Initialize(*GetJSIRuntime(bridge), std::move(jsDispatcher));
[[NSNotificationCenter defaultCenter] removeObserver:self
name:RCTBridgeWillInvalidateModulesNotification
object:bridge.parentBridge];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(onBridgeWillInvalidate:)
name:RCTBridgeWillInvalidateModulesNotification
object:bridge.parentBridge];
}
// NOTE: This happens during dev mode reload, when the JS engine is being shutdown and restarted.
+ (void)onBridgeWillInvalidate:(NSNotification*)notification
{
BabylonNative::Deinitialize();
}
+ (void)updateView:(MTKView*)mtkView {
const CGFloat scale = mtkView.contentScaleFactor;
const int width = static_cast<int>(mtkView.bounds.size.width * scale);
const int height = static_cast<int>(mtkView.bounds.size.height * scale);
if (width != 0 && height != 0) {
BabylonNative::UpdateView(mtkView.layer, width, height);
}
}
+ (void)updateMSAA:(NSNumber*)value {
BabylonNative::UpdateMSAA([value unsignedCharValue]);
}
+ (void)renderView {
BabylonNative::RenderView();
}
+ (void)resetView {
BabylonNative::ResetView();
}
+ (void)updateXRView:(MTKView*)mtkView {
BabylonNative::UpdateXRView(mtkView);
}
+ (bool)isXRActive {
return BabylonNative::IsXRActive();
}
+ (void)reportTouchEvent:(MTKView*)mtkView touches:(NSSet<UITouch*>*)touches event:(UIEvent*)event {
for (UITouch* touch in touches) {
if (touch.view == mtkView) {
const CGFloat scale = mtkView.contentScaleFactor;
const CGPoint pointerPosition = [touch locationInView:mtkView];
const uint32_t x = static_cast<uint32_t>(pointerPosition.x * scale);
const uint32_t y = static_cast<uint32_t>(pointerPosition.y * scale);
switch (touch.phase) {
case UITouchPhaseBegan: {
// The activeTouches array only grows, it does not shrink (to keep indices constant since they are used as pointer ids),
// so look for an unused (null) array element and reuse it if found. Otherwise, add a new entry to the array.
NSUInteger pointerId = [activeTouches indexOfObject:[NSNull null]];
if (pointerId != NSNotFound) {
[activeTouches replaceObjectAtIndex:pointerId withObject:touch];
} else {
pointerId = [activeTouches count];
[activeTouches addObject:touch];
}
BabylonNative::SetTouchButtonState(static_cast<uint32_t>(pointerId), true, x, y);
break;
}
case UITouchPhaseMoved: {
NSUInteger pointerId = [activeTouches indexOfObject:touch];
if (pointerId != NSNotFound) {
BabylonNative::SetTouchPosition(static_cast<uint32_t>(pointerId), x, y);
}
break;
}
case UITouchPhaseEnded:
case UITouchPhaseCancelled: {
NSUInteger pointerId = [activeTouches indexOfObject:touch];
if (pointerId != NSNotFound) {
[activeTouches replaceObjectAtIndex:pointerId withObject:[NSNull null]];
BabylonNative::SetTouchButtonState(static_cast<uint32_t>(pointerId), false, x, y);
}
break;
}
default:
break;
}
}
}
}
@end