diff --git a/Modules/@babylonjs/react-native/BabylonModule.ts b/Modules/@babylonjs/react-native/BabylonModule.ts index 1803f11c1..9c03716d0 100644 --- a/Modules/@babylonjs/react-native/BabylonModule.ts +++ b/Modules/@babylonjs/react-native/BabylonModule.ts @@ -3,25 +3,27 @@ import { NativeEngine } from '@babylonjs/core'; // This global object is part of Babylon Native. declare const _native: { - graphicsInitializationPromise: Promise; + whenGraphicsReady: () => Promise; engineInstance: NativeEngine; } const NativeBabylonModule: { initialize(): Promise; whenInitialized(): Promise; + reset(): Promise; } = NativeModules.BabylonModule; export const BabylonModule = { initialize: async () => { const initialized = await NativeBabylonModule.initialize(); if (initialized) { - await _native.graphicsInitializationPromise; + await _native.whenGraphicsReady(); } return initialized; }, whenInitialized: NativeBabylonModule.whenInitialized, + reset: NativeBabylonModule.reset, createEngine: () => { const engine = new NativeEngine(); diff --git a/Modules/@babylonjs/react-native/EngineHook.ts b/Modules/@babylonjs/react-native/EngineHook.ts index 3491e3849..4ba0536eb 100644 --- a/Modules/@babylonjs/react-native/EngineHook.ts +++ b/Modules/@babylonjs/react-native/EngineHook.ts @@ -83,6 +83,7 @@ export function useEngine(): Engine | undefined { if (engine) { DisposeEngine(engine); } + BabylonModule.reset(); setEngine(undefined); }; }, []); diff --git a/Modules/@babylonjs/react-native/android/src/main/cpp/BabylonNativeInterop.cpp b/Modules/@babylonjs/react-native/android/src/main/cpp/BabylonNativeInterop.cpp index ec36efc46..a69bd1b82 100644 --- a/Modules/@babylonjs/react-native/android/src/main/cpp/BabylonNativeInterop.cpp +++ b/Modules/@babylonjs/react-native/android/src/main/cpp/BabylonNativeInterop.cpp @@ -85,6 +85,12 @@ namespace Babylon auto height = static_cast(ANativeWindow_getHeight(windowPtr)); m_graphics->UpdateWindow(windowPtr); m_graphics->UpdateSize(width, height); + m_graphics->EnableRendering(); + } + + void Reset() + { + m_graphics->DisableRendering(); } void SetPointerButtonState(uint32_t pointerId, uint32_t buttonId, bool isDown, uint32_t x, uint32_t y) @@ -166,6 +172,12 @@ extern "C" JNIEXPORT void JNICALL Java_com_babylonreactnative_BabylonNativeInter native->SetPointerPosition(static_cast(pointerId), static_cast(x), static_cast(y)); } +extern "C" JNIEXPORT void JNICALL Java_com_babylonreactnative_BabylonNativeInterop_reset(JNIEnv* env, jclass obj, jlong instanceRef) +{ + auto native = reinterpret_cast(instanceRef); + native->Reset(); +} + extern "C" JNIEXPORT void JNICALL Java_com_babylonreactnative_BabylonNativeInterop_destroy(JNIEnv* env, jclass obj, jlong instanceRef) { auto native = reinterpret_cast(instanceRef); diff --git a/Modules/@babylonjs/react-native/android/src/main/java/com/babylonreactnative/BabylonModule.java b/Modules/@babylonjs/react-native/android/src/main/java/com/babylonreactnative/BabylonModule.java index 1fb1fcbcc..573bc0e76 100644 --- a/Modules/@babylonjs/react-native/android/src/main/java/com/babylonreactnative/BabylonModule.java +++ b/Modules/@babylonjs/react-native/android/src/main/java/com/babylonreactnative/BabylonModule.java @@ -39,4 +39,12 @@ public void initialize(Promise promise) { public void whenInitialized(Promise promise) { BabylonNativeInterop.whenInitialized(this.getReactApplicationContext()).thenAccept(instanceRef -> promise.resolve(instanceRef != 0)); } + + @ReactMethod + public void reset(Promise promise) { + this.getReactApplicationContext().runOnJSQueueThread(() -> { + BabylonNativeInterop.reset(this.getReactApplicationContext()); + promise.resolve(null); + }); + } } diff --git a/Modules/@babylonjs/react-native/android/src/main/java/com/babylonreactnative/BabylonNativeInterop.java b/Modules/@babylonjs/react-native/android/src/main/java/com/babylonreactnative/BabylonNativeInterop.java index ee0ff9d6e..fa4d8231f 100644 --- a/Modules/@babylonjs/react-native/android/src/main/java/com/babylonreactnative/BabylonNativeInterop.java +++ b/Modules/@babylonjs/react-native/android/src/main/java/com/babylonreactnative/BabylonNativeInterop.java @@ -35,6 +35,7 @@ final class BabylonNativeInterop { private static native void refresh(long instanceRef, Surface surface); private static native void setPointerButtonState(long instanceRef, int pointerId, int buttonId, boolean isDown, int x, int y); private static native void setPointerPosition(long instanceRef, int pointerId, int x, int y); + private static native void reset(long instanceRef); private static native void destroy(long instanceRef); // Must be called from the Android UI thread @@ -137,6 +138,17 @@ static void deinitialize() { BabylonNativeInterop.destroyOldNativeInstances(null); } + static void reset(ReactContext reactContext) { + JavaScriptContextHolder jsContext = reactContext.getJavaScriptContextHolder(); + CompletableFuture instanceRefFuture = BabylonNativeInterop.nativeInstances.get(jsContext); + if (instanceRefFuture != null) { + Long instanceRef = instanceRefFuture.getNow(null); + if (instanceRef != null) { + BabylonNativeInterop.reset(instanceRef); + } + } + } + private static CompletableFuture getOrCreateFuture(ReactContext reactContext) { JavaScriptContextHolder jsContext = reactContext.getJavaScriptContextHolder(); CompletableFuture instanceRefFuture = BabylonNativeInterop.nativeInstances.get(jsContext); diff --git a/Modules/@babylonjs/react-native/ios/BabylonModule.mm b/Modules/@babylonjs/react-native/ios/BabylonModule.mm index 71f8b1669..05af48afc 100644 --- a/Modules/@babylonjs/react-native/ios/BabylonModule.mm +++ b/Modules/@babylonjs/react-native/ios/BabylonModule.mm @@ -1,9 +1,14 @@ #import "BabylonNativeInterop.h" #import +#import #import +@interface RCTBridge (RCTTurboModule) +- (std::shared_ptr)jsCallInvoker; +@end + @interface BabylonModule : NSObject @end @@ -21,4 +26,11 @@ @implementation BabylonModule [BabylonNativeInterop whenInitialized:self.bridge resolve:resolve]; } +RCT_EXPORT_METHOD(reset:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { + self.bridge.jsCallInvoker->invokeAsync([resolve]() { + [BabylonNativeInterop reset]; + resolve([NSNull null]); + }); +} + @end diff --git a/Modules/@babylonjs/react-native/ios/BabylonNative.cpp b/Modules/@babylonjs/react-native/ios/BabylonNative.cpp index 01cd49d06..541c63d6c 100644 --- a/Modules/@babylonjs/react-native/ios/BabylonNative.cpp +++ b/Modules/@babylonjs/react-native/ios/BabylonNative.cpp @@ -87,6 +87,7 @@ namespace Babylon { m_impl->graphics->UpdateWindow(windowPtr); m_impl->graphics->UpdateSize(width, height); + m_impl->graphics->EnableRendering(); } void Native::Resize(size_t width, size_t height) @@ -94,6 +95,11 @@ namespace Babylon m_impl->graphics->UpdateSize(width, height); } + void Native::Reset() + { + m_impl->graphics->DisableRendering(); + } + void Native::SetPointerButtonState(uint32_t pointerId, uint32_t buttonId, bool isDown, uint32_t x, uint32_t y) { if (isDown) diff --git a/Modules/@babylonjs/react-native/ios/BabylonNative.h b/Modules/@babylonjs/react-native/ios/BabylonNative.h index f021f7246..d7ce8fa97 100644 --- a/Modules/@babylonjs/react-native/ios/BabylonNative.h +++ b/Modules/@babylonjs/react-native/ios/BabylonNative.h @@ -13,6 +13,7 @@ namespace Babylon ~Native(); void Refresh(void* windowPtr, size_t width, size_t height); void Resize(size_t width, size_t height); + void Reset(); void SetPointerButtonState(uint32_t pointerId, uint32_t buttonId, bool isDown, uint32_t x, uint32_t y); void SetPointerPosition(uint32_t pointerId, uint32_t x, uint32_t y); diff --git a/Modules/@babylonjs/react-native/ios/BabylonNativeInterop.h b/Modules/@babylonjs/react-native/ios/BabylonNativeInterop.h index e829ec41b..2ecca3399 100644 --- a/Modules/@babylonjs/react-native/ios/BabylonNativeInterop.h +++ b/Modules/@babylonjs/react-native/ios/BabylonNativeInterop.h @@ -7,4 +7,5 @@ + (void)setView:(RCTBridge*)bridge jsRunLoop:(NSRunLoop*)jsRunLoop mktView:(MTKView*)mtkView; + (void)reportTouchEvent:(NSSet*)touches withEvent:(UIEvent*)event; + (void)whenInitialized:(RCTBridge*)bridge resolve:(RCTPromiseResolveBlock)resolve; ++ (void)reset; @end diff --git a/Modules/@babylonjs/react-native/ios/BabylonNativeInterop.mm b/Modules/@babylonjs/react-native/ios/BabylonNativeInterop.mm index a7e3d8793..857b45ee1 100644 --- a/Modules/@babylonjs/react-native/ios/BabylonNativeInterop.mm +++ b/Modules/@babylonjs/react-native/ios/BabylonNativeInterop.mm @@ -115,6 +115,12 @@ + (void)whenInitialized:(RCTBridge*)bridge resolve:(RCTPromiseResolveBlock)resol } } ++ (void)reset { + if (currentNativeInstance) { + currentNativeInstance->Reset(); + } +} + + (void)setCurrentView:(MTKView*)mtkView { currentView = mtkView; activeTouches = [NSMutableArray new]; diff --git a/Modules/@babylonjs/react-native/submodules/BabylonNative b/Modules/@babylonjs/react-native/submodules/BabylonNative index d9042b8ff..26c4b2d0a 160000 --- a/Modules/@babylonjs/react-native/submodules/BabylonNative +++ b/Modules/@babylonjs/react-native/submodules/BabylonNative @@ -1 +1 @@ -Subproject commit d9042b8ff52fad2c9bcbc27f4999ba944c68d57d +Subproject commit 26c4b2d0a573c61e46695ff449b05c24ec40aa6f