Skip to content
Merged
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
2 changes: 1 addition & 1 deletion Modules/@babylonjs/react-native/EngineHook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Platform } from 'react-native';
import { PERMISSIONS, check, request } from 'react-native-permissions';
import { Engine, WebXRSessionManager, WebXRExperienceHelper, Color4, Tools } from '@babylonjs/core';
import { ReactNativeEngine } from './ReactNativeEngine';
import './VersionValidation';

import * as base64 from 'base-64';

// 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.
Expand Down
65 changes: 13 additions & 52 deletions Modules/@babylonjs/react-native/EngineView.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,9 @@
import React, { Component, FunctionComponent, SyntheticEvent, useCallback, useEffect, useState, useRef } from 'react';
import { requireNativeComponent, ViewProps, AppState, AppStateStatus, View, Text, findNodeHandle, UIManager } from 'react-native';
import React, { Component, FunctionComponent, SyntheticEvent, useCallback, useEffect, useState, useRef, useMemo } from 'react';
import { ViewProps, View, Text, findNodeHandle, UIManager } from 'react-native';
import { Camera, SceneInstrumentation } from '@babylonjs/core';
import { ensureInitialized } from './BabylonModule';
import { ReactNativeEngine } from './ReactNativeEngine';

declare const global: any;

interface NativeEngineViewProps extends ViewProps {
isTransparent: boolean;
onSnapshotDataReturned: (event: SyntheticEvent) => void;
}

const NativeEngineView: {
prototype: Component<NativeEngineViewProps>;
new(props: Readonly<NativeEngineViewProps>): Component<NativeEngineViewProps>;
} = global['EngineView'] || (global['EngineView'] = requireNativeComponent('EngineView'));
import { useModuleInitializer, useRenderLoop } from './NativeEngineHook';
import { NativeEngineViewProps, NativeEngineView } from './NativeEngineView';

export interface EngineViewProps extends ViewProps {
camera?: Camera;
Expand All @@ -33,53 +22,25 @@ interface SceneStats {
}

export const EngineView: FunctionComponent<EngineViewProps> = (props: EngineViewProps) => {
const [initialized, setInitialized] = useState<boolean>();
const [appState, setAppState] = useState(AppState.currentState);
//const [fps, setFps] = useState<number>();
const [sceneStats, setSceneStats] = useState<SceneStats>();
const engineViewRef = useRef<Component<NativeEngineViewProps>>(null);
const snapshotPromise = useRef<{ promise: Promise<string>, resolve: (data: string) => void }>();
const isTransparent = props.isTransparent || false

useEffect(() => {
(async () => {
setInitialized(await ensureInitialized());
})();
}, []);
const initialized = useModuleInitializer();

useEffect(() => {
const onAppStateChanged = (appState: AppStateStatus) => {
setAppState(appState);
};

AppState.addEventListener("change", onAppStateChanged);
const engine = useMemo(() => {
return props.camera?.getScene().getEngine() as ReactNativeEngine;
}, [props.camera]);

return () => {
AppState.removeEventListener("change", onAppStateChanged);
const renderLoop = useCallback(() => {
for (let scene of engine.scenes) {
scene.render();
}
}, []);

useEffect(() => {
if (props.camera && appState === "active") {
const engine = props.camera.getScene().getEngine() as ReactNativeEngine;
}, [engine]);

if (!engine.isDisposed) {
engine.runRenderLoop(() => {
for (let scene of engine.scenes) {
scene.render();
}
});

return () => {
if (!engine.isDisposed) {
engine.stopRenderLoop();
}
};
}
}

return undefined;
}, [props.camera, appState]);
useRenderLoop(engine, renderLoop);

useEffect(() => {
if (props.camera && (props.displayFrameRate ?? __DEV__)) {
Expand Down
56 changes: 56 additions & 0 deletions Modules/@babylonjs/react-native/NativeEngineHook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { useEffect, useState } from 'react';
import { AppState, AppStateStatus } from 'react-native';
import { ensureInitialized } from './BabylonModule';
import { ReactNativeEngine } from './ReactNativeEngine';

import './VersionValidation';

export function useModuleInitializer(): boolean | undefined {
const [initialized, setInitialized] = useState<boolean>();

useEffect(() => {
(async () => {
setInitialized(await ensureInitialized());
})();
}, []);

return initialized;
}

function useAppState(): string {
const [appState, setAppState] = useState(AppState.currentState);

useEffect(() => {
const onAppStateChanged = (appState: AppStateStatus) => {
setAppState(appState);
};

AppState.addEventListener("change", onAppStateChanged);

return () => {
AppState.removeEventListener("change", onAppStateChanged);
}
}, []);

return appState;
}

export function useRenderLoop(engine: ReactNativeEngine | undefined, renderCallback: () => void): void {
const appState = useAppState();

useEffect(() => {
if (engine && appState === "active") {
if (!engine.isDisposed) {
engine.runRenderLoop(renderCallback);

return () => {
if (!engine.isDisposed) {
engine.stopRenderLoop();
}
};
}
}

return undefined;
}, [appState, engine]);
}
14 changes: 14 additions & 0 deletions Modules/@babylonjs/react-native/NativeEngineView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Component, SyntheticEvent } from 'react';
import { requireNativeComponent, ViewProps } from 'react-native';

declare const global: any;

export interface NativeEngineViewProps extends ViewProps {
isTransparent: boolean;
onSnapshotDataReturned?: (event: SyntheticEvent) => void;
}

export const NativeEngineView: {
prototype: Component<NativeEngineViewProps>;
new(props: Readonly<NativeEngineViewProps>): Component<NativeEngineViewProps>;
} = global['EngineView'] || (global['EngineView'] = requireNativeComponent('EngineView'));
6 changes: 6 additions & 0 deletions Package/gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,12 @@ const validate = async () => {
'Assembled/NativeCapture.d.ts',
'Assembled/NativeCapture.js',
'Assembled/NativeCapture.js.map',
'Assembled/NativeEngineHook.d.ts',
'Assembled/NativeEngineHook.js',
'Assembled/NativeEngineHook.js.map',
'Assembled/NativeEngineView.d.ts',
'Assembled/NativeEngineView.js',
'Assembled/NativeEngineView.js.map',
'Assembled/FontFace.d.ts',
'Assembled/FontFace.js',
'Assembled/FontFace.js.map',
Expand Down