Skip to content

Commit 6ba5397

Browse files
authored
Remove custom JSCRuntime (#66)
- Remove JSC references from build.gradle and CMakeLists.txt files. - Remove our custom JSCRuntime.h/JSCRuntime.cpp. - In the interop layer (both Android and iOS), use jsi::Runtime directly (don't try to extract the JSC global context and wrap it in our custom JSCRuntime). - Add a direct dependency on base-64. - Use base-64 very early in initialization to provide an atob polyfill.
1 parent e20aead commit 6ba5397

File tree

11 files changed

+80
-1598
lines changed

11 files changed

+80
-1598
lines changed

Apps/Playground/package-lock.json

+26-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Apps/Playground/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
},
1212
"dependencies": {
1313
"@babylonjs/core": "4.2.0-alpha.30",
14+
"@babylonjs/loaders": "4.2.0-alpha.30",
1415
"@babylonjs/react-native": "file:../../Modules/@babylonjs/react-native",
1516
"@react-native-community/slider": "^2.0.9",
1617
"logkitty": "^0.7.1",

Modules/@babylonjs/react-native/EngineHook.ts

+42-36
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ import { PERMISSIONS, check, request } from 'react-native-permissions';
44
import { Engine, NativeEngine, WebXRSessionManager } from '@babylonjs/core';
55
import { BabylonModule } from './BabylonModule';
66
import { DisposeEngine } from './EngineHelpers';
7-
8-
declare const window: any;
7+
import * as base64 from 'base-64';
98

109
// These are errors that are normally thrown by WebXR's requestSession, so we should throw the same errors under similar circumstances so app code can be written the same for browser or native.
1110
// https://developer.mozilla.org/en-US/docs/Web/API/XRSystem/requestSession
@@ -22,6 +21,47 @@ class DOMException {
2221
get name(): string { return DOMError[this.error]; }
2322
}
2423

24+
// Override the WebXRSessionManager.initializeSessionAsync to insert a camera permissions request. It would be cleaner to do this directly in the native XR implementation, but there are a couple problems with that:
25+
// 1. React Native does not provide a way to hook into the permissions request result (at least on Android).
26+
// 2. If it is done on the native side, then we need one implementation per platform.
27+
{
28+
const originalInitializeSessionAsync: (...args: any[]) => Promise<any> = WebXRSessionManager.prototype.initializeSessionAsync;
29+
WebXRSessionManager.prototype.initializeSessionAsync = async function (...args: any[]): Promise<any> {
30+
const cameraPermission = Platform.select({
31+
android: PERMISSIONS.ANDROID.CAMERA,
32+
ios: PERMISSIONS.IOS.CAMERA,
33+
});
34+
35+
// Only Android and iOS are supported.
36+
if (cameraPermission === undefined) {
37+
throw new DOMException(DOMError.NotSupportedError);
38+
}
39+
40+
// If the permission has not been granted yet, but also not been blocked, then request permission.
41+
let permissionStatus = await check(cameraPermission);
42+
if (permissionStatus == "denied")
43+
{
44+
permissionStatus = await request(cameraPermission);
45+
}
46+
47+
// If the permission has still not been granted, then throw an appropriate exception, otherwise continue with the actual XR session initialization.
48+
switch(permissionStatus) {
49+
case "unavailable":
50+
throw new DOMException(DOMError.NotSupportedError);
51+
case "denied":
52+
case "blocked":
53+
throw new DOMException(DOMError.SecurityError);
54+
case "granted":
55+
return originalInitializeSessionAsync.apply(this, args);
56+
}
57+
}
58+
}
59+
60+
// Babylon Native includes a native atob polyfill, but it relies JSI to deal with the strings, and JSI has a bug where it assumes strings are null terminated, and a base 64 string can contain one of these.
61+
// So for now, provide a JavaScript based atob polyfill.
62+
declare const global: any;
63+
global.atob = base64.decode;
64+
2565
export function useEngine(): Engine | undefined {
2666
const [engine, setEngine] = useState<Engine>();
2767

@@ -32,40 +72,6 @@ export function useEngine(): Engine | undefined {
3272
(async () => {
3373
if (await BabylonModule.initialize() && !disposed)
3474
{
35-
// Override the WebXRSessionManager.initializeSessionAsync to insert a camera permissions request. It would be cleaner to do this directly in the native XR implementation, but there are a couple problems with that:
36-
// 1. React Native does not provide a way to hook into the permissions request result (at least on Android).
37-
// 2. If it is done on the native side, then we need one implementation per platform.
38-
const originalInitializeSessionAsync: (...args: any[]) => Promise<any> = WebXRSessionManager.prototype.initializeSessionAsync;
39-
WebXRSessionManager.prototype.initializeSessionAsync = async function (...args: any[]): Promise<any> {
40-
const cameraPermission = Platform.select({
41-
android: PERMISSIONS.ANDROID.CAMERA,
42-
ios: PERMISSIONS.IOS.CAMERA,
43-
});
44-
45-
// Only Android and iOS are supported.
46-
if (cameraPermission === undefined) {
47-
throw new DOMException(DOMError.NotSupportedError);
48-
}
49-
50-
// If the permission has not been granted yet, but also not been blocked, then request permission.
51-
let permissionStatus = await check(cameraPermission);
52-
if (permissionStatus == "denied")
53-
{
54-
permissionStatus = await request(cameraPermission);
55-
}
56-
57-
// If the permission has still not been granted, then throw an appropriate exception, otherwise continue with the actual XR session initialization.
58-
switch(permissionStatus) {
59-
case "unavailable":
60-
throw new DOMException(DOMError.NotSupportedError);
61-
case "denied":
62-
case "blocked":
63-
throw new DOMException(DOMError.SecurityError);
64-
case "granted":
65-
return originalInitializeSessionAsync.apply(this, args);
66-
}
67-
}
68-
6975
engine = new NativeEngine();
7076

7177
// NOTE: This is a workaround for https://github.com/BabylonJS/BabylonReactNative/issues/60

0 commit comments

Comments
 (0)