Commit 063244d
authored
"Embedding" (simple) API layer (#1701)
## Summary
Introduces a new **`Babylon::Embedding`** layer that gives host apps a
small, opinionated `Runtime` + `View` API for embedding Babylon Native,
and migrates every Playground host (Android, iOS, visionOS, macOS, UWP,
Win32, X11) onto it. The goal is to make platform integration a job that
takes tens — not hundreds — of lines of code, and to do that without
leaking `AppRuntime`, `Graphics::Device`, plugin headers, polyfill
plumbing, or threading rules into the host.
Two layers ship together:
1. **Core C++ API**
(`Embedding/Include/Shared/Babylon/Embedding/{Runtime,View,RuntimeOptions,LogLevel}.h`)
— cross-platform, single source of truth for the lifecycle, threading,
suspend/resume, input forwarding, and XR window management.
2. **Per-platform language facades** that wrap the core API in idiomatic
types for the host language:
- **Android**: JNI shared library (`BabylonNativeEmbedding.cpp`) + a
host-authored Java facade (`BabylonNative.java`)
- **Apple**: `BNRuntime` / `BNView` Obj‑C classes (Swift-friendly via
the bridging header)
## What's new
### `Embedding` core (`Embedding/Source`, `Embedding/Include/Shared`)
Two value types with explicit ownership and a documented contract:
```cpp
Babylon::Embedding::RuntimeOptions options{};
options.enableDebugger = true;
options.log = [](LogLevel level, std::string_view msg) { /* … */ };
Babylon::Embedding::Runtime runtime{options};
runtime.LoadScript("app:///Scripts/babylon.max.js");
runtime.LoadScript("app:///Scripts/scene.js");
Babylon::Embedding::View view{runtime, nativeWindowHandle};
view.Resize(width, height, CoordinateUnits::Physical);
// driven from the host's draw callback:
view.RenderFrame();
```
What the layer takes care of for you:
- **Runtime construction**: spins up `AppRuntime`, `JsRuntime`,
polyfills (Console, Window, XMLHttpRequest, WebSocket, URL, Canvas,
TextDecoder, Performance, Scheduling), and non‑GPU plugins.
- **GPU deferral**: `Graphics::Device`, `NativeEngine`, `NativeInput`,
`NativeCanvas`, `TestUtils`, and (optionally) `NativeXr` / `ShaderCache`
are constructed lazily on the **first** `View::Resize`. Subsequent View
attaches just rebind the Device.
- **Script queuing**: `LoadScript` / `Eval` / `RunOnJsThread` are safe
to call before the first `View` attach; queued and flushed when the
engine comes up.
- **Suspend / Resume**: reference-counted, closes the in-flight frame,
pauses JS timers, optionally persists the shader cache.
- **Input**: `OnPointer*` / `OnMouse*` accept either `Physical` or
`Logical` pixel units; the View handles DPR conversion.
- **XR window**: `Runtime::SetXrWindow` hands off a secondary surface
for NativeXr.
- **Logging**: single `RuntimeOptions::log` sink for
`console.{log,warn,error}`, `Babylon::DebugTrace`, and uncaught JS
exceptions.
### Android facade
`Embedding/Android/` builds the JNI shared library
`libBabylonNativeEmbedding.so` (replacing the old
`BabylonNativeJNI.cpp`). It ships the **native side only** — each host
authors its own Java declarations that match the JNI ABI. The
Playground's facade
(`Apps/Playground/Android/BabylonNative/…/com/babylonjs/embedding/BabylonNative.java`,
replacing the old `Wrapper.java`) is a thin `static`-method mirror of
the C++ API:
- **Process lifecycle**: `setContext`, `setCurrentActivity`, `pause`,
`resume`, `requestPermissionsResult`
- **Runtime**: `runtimeCreate` (optionally with a nested
`RuntimeOptions`), `runtimeDestroy`, `runtimeLoadScript`, `runtimeEval`,
`runtimeSetXrSurface`, `runtimeIsXrActive`
- **View**: `viewAttach`, `viewDetach`, `viewRenderFrame`, `viewResize`,
`viewPointerDown` / `viewPointerMove` / `viewPointerUp`
A separate `com.library.babylonnative.BabylonView` helper wires
`SurfaceHolder.Callback` and touch events to those calls.
### Apple facade
`Embedding/Apple/` — Obj‑C wrappers (`BNRuntime`, `BNView`,
`BNViewDelegate`) usable from Obj‑C and from Swift via the bridging
header. Used by Playground iOS, macOS, and visionOS. `BNRuntimeNative.h`
exposes the underlying `Babylon::Embedding::Runtime*` for callers that
need the C++ API.
## Host app migrations
Every Playground host now runs on top of the Embedding layer:
| Host | Before | After |
|---|---|---|
| Android | `BabylonNativeJNI.cpp` + `Wrapper.java` | `BabylonNative`
Java facade over the JNI layer |
| iOS | `LibNativeBridge.{h,mm}` + ad-hoc Swift glue | `BNRuntime` /
`BNView`, ~75-line `ViewController.swift` |
| macOS | `ViewController.mm` doing its own AppContext plumbing | Same
`BNRuntime` / `BNView` types as iOS |
| visionOS | `LibNativeBridge.{h,mm}` + custom App.swift threading |
`BNRuntime` / `BNView` + bridging header |
| Win32 | `AppContext` + manual `UpdateSize` / mouse plumbing |
`Runtime` + `View` with `WM_POINTER` → `View::On*` |
| UWP | C++/WinRT `AppContext` + manual swap-chain plumbing | `Runtime`
+ `View` from `IInspectable` |
| X11 | `AppContext` + X11 event handlers | `Runtime` + `View` with
`View::OnMouse*` |
The shared `AppContext.{h,cpp}` is gone — each host now constructs a
`Runtime` + `View` directly.
## Lifecycle contract
- **First View attach is the heavy step.** Hosts MUST call `Resize` at
least once with the surface's pixel dimensions before the first
`RenderFrame` — the Device is built on the first Resize.
- **One View per Runtime at a time.** `View` constructor throws
`std::runtime_error` on double-attach.
- **Destroy Views before their Runtime.** `~View` clears the
back-reference, so LIFO destruction works; `~Runtime` asserts (debug
builds) if a View is still attached.
- **Frame thread**: `RenderFrame`, `Resize`, `Suspend`, `Resume`,
`LoadScript`, `Eval`, `RunOnJsThread`, View construction/destruction.
- **Any thread**: `OnPointer*` / `OnMouse*` / `IsSuspended` /
`IsXrActive` / `SetXrWindow`.
## File scope
```
Embedding/
Include/Shared/Babylon/Embedding/{Runtime,View,RuntimeOptions,LogLevel}.h
Source/{Runtime,View}.cpp + RuntimeImpl.h
Android/ — JNI shared library (Java facade lives per-host; see Playground)
Apple/ — BNRuntime / BNView / BNViewDelegate
Apps/Playground/
Win32/ UWP/ X11/ macOS/ iOS/ visionOS/ Android/ (all migrated)
```
## Closed open items
- [x] AI-generated comment cleanup
- [x] Naming (renamed to "Embedding")
- [x] All Playground hosts migrated (Android, iOS, visionOS, macOS, UWP,
Win32, X11)
- [x] `RunOnJsThread` now has an `afterScriptLoad` parameter
- [x] `Runtime` / `View` are regular movable value types
- [x] Removed the planning `.md` from the repo root
- [ ] Real fix for DeviceImpl.cpp issue1 parent b320866 commit 063244d
70 files changed
Lines changed: 4365 additions & 1537 deletions
File tree
- .github/instructions
- Apps/Playground
- Android
- BabylonNative
- src/main
- cpp
- java/com
- babylonjs/embedding
- library/babylonnative
- app/src/main/java/com/android/babylonnative/playground
- UWP
- Win32
- X11
- iOS
- macOS
- visionOS
- Core/Graphics
- InternalInclude/Babylon/Graphics
- Source
- Dependencies
- Embedding
- Android
- src/main/cpp
- Apple
- Source
- Include
- Platform
- Android/Babylon/Embedding/Android
- Apple/Babylon/Embedding/Apple
- Source
- Install
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 9 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
27 | | - | |
| 27 | + | |
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
| |||
80 | 80 | | |
81 | 81 | | |
82 | 82 | | |
83 | | - | |
| 83 | + | |
84 | 84 | | |
85 | | - | |
86 | | - | |
87 | | - | |
88 | | - | |
89 | | - | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
90 | 92 | | |
91 | 93 | | |
92 | 94 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
11 | 18 | | |
12 | 19 | | |
13 | | - | |
14 | | - | |
15 | | - | |
16 | | - | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
17 | 31 | | |
18 | | - | |
| 32 | + | |
19 | 33 | | |
20 | 34 | | |
21 | | - | |
22 | | - | |
23 | | - | |
| 35 | + | |
24 | 36 | | |
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 | | - | |
| 37 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
Lines changed: 0 additions & 194 deletions
This file was deleted.
Lines changed: 39 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 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 | + | |
0 commit comments