react-native-cesium 1.2.4 → 1.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/android/src/main/java/com/margelo/nitro/reactnativecesium/HybridCesiumView.kt +39 -0
  2. package/cpp/engine/EngineTunables.hpp +14 -2
  3. package/ios/HybridCesiumView.swift +43 -0
  4. package/lib/typescript/src/specs/cesium-view.nitro.d.ts +8 -0
  5. package/lib/typescript/src/specs/cesium-view.nitro.d.ts.map +1 -1
  6. package/nitrogen/generated/android/ReactNativeCesiumOnLoad.cpp +2 -0
  7. package/nitrogen/generated/android/c++/JFunc_void_CameraState.hpp +77 -0
  8. package/nitrogen/generated/android/c++/JHybridCesiumViewSpec.cpp +18 -0
  9. package/nitrogen/generated/android/c++/JHybridCesiumViewSpec.hpp +2 -0
  10. package/nitrogen/generated/android/c++/views/JHybridCesiumViewStateUpdater.cpp +4 -0
  11. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativecesium/Func_void_CameraState.kt +80 -0
  12. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativecesium/HybridCesiumViewSpec.kt +14 -0
  13. package/nitrogen/generated/ios/ReactNativeCesium-Swift-Cxx-Bridge.cpp +3 -3
  14. package/nitrogen/generated/ios/ReactNativeCesium-Swift-Cxx-Bridge.hpp +34 -19
  15. package/nitrogen/generated/ios/c++/HybridCesiumViewSpecSwift.hpp +7 -0
  16. package/nitrogen/generated/ios/c++/views/HybridCesiumViewComponent.mm +5 -0
  17. package/nitrogen/generated/ios/swift/Func_void_CameraState.swift +5 -5
  18. package/nitrogen/generated/ios/swift/HybridCesiumViewSpec.swift +1 -0
  19. package/nitrogen/generated/ios/swift/HybridCesiumViewSpec_cxx.swift +32 -0
  20. package/nitrogen/generated/shared/c++/HybridCesiumViewSpec.cpp +2 -0
  21. package/nitrogen/generated/shared/c++/HybridCesiumViewSpec.hpp +2 -0
  22. package/nitrogen/generated/shared/c++/views/HybridCesiumViewComponent.cpp +11 -0
  23. package/nitrogen/generated/shared/c++/views/HybridCesiumViewComponent.hpp +1 -0
  24. package/nitrogen/generated/shared/json/CesiumViewConfig.json +1 -0
  25. package/package.json +1 -1
  26. package/src/specs/cesium-view.nitro.ts +9 -0
@@ -152,6 +152,22 @@ class HybridCesiumView(private val appContext: Context) : HybridCesiumViewSpec()
152
152
 
153
153
  override var onMetrics: ((metrics: CesiumMetrics) -> Unit)? = null
154
154
 
155
+ override var onActualCamera: ((camera: CameraState) -> Unit)? = null
156
+ // Both accessed only on the render thread; no extra locking needed.
157
+ private var actualCameraLastEmitSec: Double = 0.0
158
+ private var actualCameraLastSent: CameraState? = null
159
+
160
+ // Returns true when the two snapshots differ enough to warrant a JS dispatch.
161
+ // Thresholds mirror EngineTunables.hpp kActualCameraCallbackInterval* constants.
162
+ private fun actualCameraChanged(a: CameraState, b: CameraState): Boolean =
163
+ Math.abs(a.latitude - b.latitude) > 1e-7 ||
164
+ Math.abs(a.longitude - b.longitude) > 1e-7 ||
165
+ Math.abs(a.altitude - b.altitude) > 0.05 ||
166
+ Math.abs(a.heading - b.heading) > 0.01 ||
167
+ Math.abs(a.pitch - b.pitch) > 0.01 ||
168
+ Math.abs(a.roll - b.roll) > 0.01 ||
169
+ Math.abs(a.verticalFovDeg - b.verticalFovDeg) > 0.01
170
+
155
171
  override val view: View get() = surfaceView
156
172
 
157
173
  private val frameCallback = Choreographer.FrameCallback {
@@ -217,6 +233,27 @@ class HybridCesiumView(private val appContext: Context) : HybridCesiumViewSpec()
217
233
  }
218
234
  }
219
235
 
236
+ // onActualCamera: poll at 5 Hz (kActualCameraCallbackIntervalSec = 0.2 s),
237
+ // but only dispatch when at least one field has moved beyond its epsilon.
238
+ val acCb = if (isShutdown) null else onActualCamera
239
+ if (acCb != null && (nowSeconds - actualCameraLastEmitSec) >= 0.2) {
240
+ actualCameraLastEmitSec = nowSeconds
241
+ val candidate = CameraState(
242
+ latitude = b.getActualLatitude(),
243
+ longitude = b.getActualLongitude(),
244
+ altitude = b.getActualAltitude(),
245
+ heading = b.getActualHeading(),
246
+ pitch = b.getActualPitch(),
247
+ roll = b.getActualRoll(),
248
+ verticalFovDeg = b.getActualVerticalFovDeg(),
249
+ )
250
+ val prev = actualCameraLastSent
251
+ if (prev == null || actualCameraChanged(candidate, prev)) {
252
+ actualCameraLastSent = candidate
253
+ acCb(candidate)
254
+ }
255
+ }
256
+
220
257
  renderInFlight.set(false)
221
258
 
222
259
  surfaceView.post { scheduleNextFrame(immediate = nextImmediate) }
@@ -292,6 +329,8 @@ class HybridCesiumView(private val appContext: Context) : HybridCesiumViewSpec()
292
329
  // into a dying JS runtime.
293
330
  isShutdown = true
294
331
  onMetrics = null
332
+ onActualCamera = null
333
+ actualCameraLastSent = null
295
334
 
296
335
  val rh = renderHandler
297
336
  val ht = renderThread
@@ -69,8 +69,8 @@ inline constexpr int32_t kDefaultLoadingDescendantLimit = 20;
69
69
  inline constexpr double kAlphaPos = 0.6; inline constexpr double kBetaPos = 0.05;
70
70
  inline constexpr double kAlphaAlt = 0.6; inline constexpr double kBetaAlt = 0.05;
71
71
  inline constexpr double kAlphaHdg = 0.55; inline constexpr double kBetaHdg = 0.05;
72
- inline constexpr double kAlphaPitch = 0.5; inline constexpr double kBetaPitch = 0.05;
73
- inline constexpr double kAlphaRoll = 0.5; inline constexpr double kBetaRoll = 0.05;
72
+ inline constexpr double kAlphaPitch = 0.75; inline constexpr double kBetaPitch = 0.05;
73
+ inline constexpr double kAlphaRoll = 0.75; inline constexpr double kBetaRoll = 0.05;
74
74
  inline constexpr double kAlphaVfov = 0.4; // no velocity term
75
75
  inline constexpr double kAlphaViewCorr = 0.5; // SLERP toward target
76
76
 
@@ -130,6 +130,18 @@ inline constexpr double kOutlierHeadingDeg = 0.0;
130
130
  // Metrics throttle: emit telemetry every N rendered frames.
131
131
  inline constexpr int kMetricsEmitEveryFrames = 20;
132
132
 
133
+ // Minimum interval between onActualCamera callback emissions (seconds).
134
+ // 0.2 s = 5 Hz — fast enough for HUD alignment, light on the JS bridge.
135
+ inline constexpr double kActualCameraCallbackIntervalSec = 0.2;
136
+
137
+ // Change-detection thresholds for onActualCamera.
138
+ // A new snapshot is only dispatched to JS when at least one field has moved
139
+ // by more than the corresponding epsilon since the last emission.
140
+ inline constexpr double kActualCameraDeltaLatLonDeg = 1e-7; // ~1 cm at equator
141
+ inline constexpr double kActualCameraDeltaAltMeters = 0.05; // 5 cm
142
+ inline constexpr double kActualCameraDeltaAngleDeg = 0.01; // heading / pitch / roll
143
+ inline constexpr double kActualCameraDeltaFovDeg = 0.01; // vertical FoV
144
+
133
145
  // Idle-probe interval (seconds): when the engine is idle, periodically tick
134
146
  // to catch late tile completions without redundant full draws.
135
147
  inline constexpr double kIdleProbeSeconds = 0.25;
@@ -145,6 +145,23 @@ class HybridCesiumView: HybridCesiumViewSpec {
145
145
 
146
146
  var onMetrics: ((CesiumMetrics) -> Void)?
147
147
 
148
+ var onActualCamera: ((CameraState) -> Void)?
149
+ // Both accessed only on the render queue; no extra locking needed.
150
+ private var actualCameraLastEmitTime: CFTimeInterval = 0
151
+ private var actualCameraLastSent: CameraState? = nil
152
+
153
+ // Returns true when the two snapshots differ enough to warrant a JS dispatch.
154
+ // Thresholds mirror EngineTunables.hpp kActualCameraCallbackInterval* constants.
155
+ private func actualCameraChanged(_ a: CameraState, from b: CameraState) -> Bool {
156
+ abs(a.latitude - b.latitude) > 1e-7 ||
157
+ abs(a.longitude - b.longitude) > 1e-7 ||
158
+ abs(a.altitude - b.altitude) > 0.05 ||
159
+ abs(a.heading - b.heading) > 0.01 ||
160
+ abs(a.pitch - b.pitch) > 0.01 ||
161
+ abs(a.roll - b.roll) > 0.01 ||
162
+ abs(a.verticalFovDeg - b.verticalFovDeg) > 0.01
163
+ }
164
+
148
165
  // MARK: - Methods
149
166
 
150
167
  func getActualCamera() throws -> Promise<CameraState> {
@@ -544,12 +561,36 @@ class HybridCesiumView: HybridCesiumViewSpec {
544
561
  ) : nil
545
562
  if shouldEmitMetrics { self.metricsFrameCounter = 0 }
546
563
 
564
+ // onActualCamera: poll at 5 Hz (kActualCameraCallbackIntervalSec = 0.2 s),
565
+ // but only dispatch when at least one field has moved beyond its epsilon.
566
+ var actualCameraSnapshot: CameraState? = nil
567
+ if self.onActualCamera != nil && !self.isShutdown &&
568
+ (nowSeconds - self.actualCameraLastEmitTime) >= 0.2 {
569
+ self.actualCameraLastEmitTime = nowSeconds
570
+ let candidate = CameraState(
571
+ latitude: bridge.readActualLatitude(),
572
+ longitude: bridge.readActualLongitude(),
573
+ altitude: bridge.readActualAltitude(),
574
+ heading: bridge.readActualHeading(),
575
+ pitch: bridge.readActualPitch(),
576
+ roll: bridge.readActualRoll(),
577
+ verticalFovDeg: bridge.readActualVerticalFovDeg()
578
+ )
579
+ if self.actualCameraLastSent.map({ self.actualCameraChanged(candidate, from: $0) }) ?? true {
580
+ actualCameraSnapshot = candidate
581
+ self.actualCameraLastSent = candidate
582
+ }
583
+ }
584
+
547
585
  DispatchQueue.main.async { [weak self] in
548
586
  guard let self = self, !self.isShutdown else { return }
549
587
  self.setDisplayLinkFrameRate(idle: nextIsIdle)
550
588
  if let m = metricsSnapshot, let cb = self.onMetrics {
551
589
  cb(m)
552
590
  }
591
+ if let cam = actualCameraSnapshot, let cb = self.onActualCamera {
592
+ cb(cam)
593
+ }
553
594
  }
554
595
  // renderInFlight is cleared by the defer at the top of this closure.
555
596
  }
@@ -562,6 +603,8 @@ class HybridCesiumView: HybridCesiumViewSpec {
562
603
  // JS dispatcher that may already be gone.
563
604
  isShutdown = true
564
605
  onMetrics = nil
606
+ onActualCamera = nil
607
+ actualCameraLastSent = nil
565
608
 
566
609
  layoutPollTimer?.invalidate()
567
610
  layoutPollTimer = nil
@@ -93,6 +93,14 @@ export interface CesiumViewProps extends HybridViewProps {
93
93
  /** Maximum horizontal ground speed (metres per second). 0 = uncapped. */
94
94
  maxGroundSpeedMps?: number;
95
95
  onMetrics?: (metrics: CesiumMetrics) => void;
96
+ /**
97
+ * Called at ~5 Hz with the post-integration actual camera — the same state
98
+ * returned by `getActualCamera()`. Only fires when at least one field has
99
+ * changed beyond its epsilon threshold since the last emission, so a
100
+ * stationary camera produces no bridge traffic. Use this to keep HUD overlay
101
+ * symbology aligned with the rendered view without polling from JS.
102
+ */
103
+ onActualCamera?: (camera: CameraState) => void;
96
104
  }
97
105
  /**
98
106
  * Per-DoF camera control. Every setter records the measurement with the
@@ -1 +1 @@
1
- {"version":3,"file":"cesium-view.nitro.d.ts","sourceRoot":"","sources":["../../../../src/specs/cesium-view.nitro.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cesium-view.nitro.d.ts","sourceRoot":"","sources":["../../../../src/specs/cesium-view.nitro.ts"],"names":[],"mappings":"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"}
@@ -17,6 +17,7 @@
17
17
 
18
18
  #include "JHybridCesiumViewSpec.hpp"
19
19
  #include "JFunc_void_CesiumMetrics.hpp"
20
+ #include "JFunc_void_CameraState.hpp"
20
21
  #include "views/JHybridCesiumViewStateUpdater.hpp"
21
22
  #include <NitroModules/DefaultConstructableObject.hpp>
22
23
 
@@ -44,6 +45,7 @@ void registerAllNatives() {
44
45
  // Register native JNI methods
45
46
  margelo::nitro::reactnativecesium::JHybridCesiumViewSpec::CxxPart::registerNatives();
46
47
  margelo::nitro::reactnativecesium::JFunc_void_CesiumMetrics_cxx::registerNatives();
48
+ margelo::nitro::reactnativecesium::JFunc_void_CameraState_cxx::registerNatives();
47
49
  margelo::nitro::reactnativecesium::views::JHybridCesiumViewStateUpdater::registerNatives();
48
50
 
49
51
  // Register Nitro Hybrid Objects
@@ -0,0 +1,77 @@
1
+ ///
2
+ /// JFunc_void_CameraState.hpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #pragma once
9
+
10
+ #include <fbjni/fbjni.h>
11
+ #include <functional>
12
+
13
+ #include "CameraState.hpp"
14
+ #include <functional>
15
+ #include <NitroModules/JNICallable.hpp>
16
+ #include "JCameraState.hpp"
17
+
18
+ namespace margelo::nitro::reactnativecesium {
19
+
20
+ using namespace facebook;
21
+
22
+ /**
23
+ * Represents the Java/Kotlin callback `(camera: CameraState) -> Unit`.
24
+ * This can be passed around between C++ and Java/Kotlin.
25
+ */
26
+ struct JFunc_void_CameraState: public jni::JavaClass<JFunc_void_CameraState> {
27
+ public:
28
+ static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/reactnativecesium/Func_void_CameraState;";
29
+
30
+ public:
31
+ /**
32
+ * Invokes the function this `JFunc_void_CameraState` instance holds through JNI.
33
+ */
34
+ void invoke(const CameraState& camera) const {
35
+ static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<JCameraState> /* camera */)>("invoke");
36
+ method(self(), JCameraState::fromCpp(camera));
37
+ }
38
+ };
39
+
40
+ /**
41
+ * An implementation of Func_void_CameraState that is backed by a C++ implementation (using `std::function<...>`)
42
+ */
43
+ class JFunc_void_CameraState_cxx final: public jni::HybridClass<JFunc_void_CameraState_cxx, JFunc_void_CameraState> {
44
+ public:
45
+ static jni::local_ref<JFunc_void_CameraState::javaobject> fromCpp(const std::function<void(const CameraState& /* camera */)>& func) {
46
+ return JFunc_void_CameraState_cxx::newObjectCxxArgs(func);
47
+ }
48
+
49
+ public:
50
+ /**
51
+ * Invokes the C++ `std::function<...>` this `JFunc_void_CameraState_cxx` instance holds.
52
+ */
53
+ void invoke_cxx(jni::alias_ref<JCameraState> camera) {
54
+ _func(camera->toCpp());
55
+ }
56
+
57
+ public:
58
+ [[nodiscard]]
59
+ inline const std::function<void(const CameraState& /* camera */)>& getFunction() const {
60
+ return _func;
61
+ }
62
+
63
+ public:
64
+ static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/reactnativecesium/Func_void_CameraState_cxx;";
65
+ static void registerNatives() {
66
+ registerHybrid({makeNativeMethod("invoke_cxx", JFunc_void_CameraState_cxx::invoke_cxx)});
67
+ }
68
+
69
+ private:
70
+ explicit JFunc_void_CameraState_cxx(const std::function<void(const CameraState& /* camera */)>& func): _func(func) { }
71
+
72
+ private:
73
+ friend HybridBase;
74
+ std::function<void(const CameraState& /* camera */)> _func;
75
+ };
76
+
77
+ } // namespace margelo::nitro::reactnativecesium
@@ -23,6 +23,7 @@ namespace margelo::nitro::reactnativecesium { struct Quaternion; }
23
23
  #include "JFunc_void_CesiumMetrics.hpp"
24
24
  #include <NitroModules/JNICallable.hpp>
25
25
  #include "JCesiumMetrics.hpp"
26
+ #include "JFunc_void_CameraState.hpp"
26
27
  #include <NitroModules/Promise.hpp>
27
28
  #include <NitroModules/JPromise.hpp>
28
29
  #include "Quaternion.hpp"
@@ -318,6 +319,23 @@ namespace margelo::nitro::reactnativecesium {
318
319
  static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<JFunc_void_CesiumMetrics::javaobject> /* onMetrics */)>("setOnMetrics_cxx");
319
320
  method(_javaPart, onMetrics.has_value() ? JFunc_void_CesiumMetrics_cxx::fromCpp(onMetrics.value()) : nullptr);
320
321
  }
322
+ std::optional<std::function<void(const CameraState& /* camera */)>> JHybridCesiumViewSpec::getOnActualCamera() {
323
+ static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JFunc_void_CameraState::javaobject>()>("getOnActualCamera_cxx");
324
+ auto __result = method(_javaPart);
325
+ return __result != nullptr ? std::make_optional([&]() -> std::function<void(const CameraState& /* camera */)> {
326
+ if (__result->isInstanceOf(JFunc_void_CameraState_cxx::javaClassStatic())) [[likely]] {
327
+ auto downcast = jni::static_ref_cast<JFunc_void_CameraState_cxx::javaobject>(__result);
328
+ return downcast->cthis()->getFunction();
329
+ } else {
330
+ auto __resultRef = jni::make_global(__result);
331
+ return JNICallable<JFunc_void_CameraState, void(CameraState)>(std::move(__resultRef));
332
+ }
333
+ }()) : std::nullopt;
334
+ }
335
+ void JHybridCesiumViewSpec::setOnActualCamera(const std::optional<std::function<void(const CameraState& /* camera */)>>& onActualCamera) {
336
+ static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<JFunc_void_CameraState::javaobject> /* onActualCamera */)>("setOnActualCamera_cxx");
337
+ method(_javaPart, onActualCamera.has_value() ? JFunc_void_CameraState_cxx::fromCpp(onActualCamera.value()) : nullptr);
338
+ }
321
339
 
322
340
  // Methods
323
341
  void JHybridCesiumViewSpec::setPosition(double latitude, double longitude) {
@@ -106,6 +106,8 @@ namespace margelo::nitro::reactnativecesium {
106
106
  void setMaxGroundSpeedMps(std::optional<double> maxGroundSpeedMps) override;
107
107
  std::optional<std::function<void(const CesiumMetrics& /* metrics */)>> getOnMetrics() override;
108
108
  void setOnMetrics(const std::optional<std::function<void(const CesiumMetrics& /* metrics */)>>& onMetrics) override;
109
+ std::optional<std::function<void(const CameraState& /* camera */)>> getOnActualCamera() override;
110
+ void setOnActualCamera(const std::optional<std::function<void(const CameraState& /* camera */)>>& onActualCamera) override;
109
111
 
110
112
  public:
111
113
  // Methods
@@ -149,6 +149,10 @@ void JHybridCesiumViewStateUpdater::updateViewProps(jni::alias_ref<jni::JClass>
149
149
  hybridView->setOnMetrics(props->onMetrics.value);
150
150
  props->onMetrics.isDirty = false;
151
151
  }
152
+ if (props->onActualCamera.isDirty) {
153
+ hybridView->setOnActualCamera(props->onActualCamera.value);
154
+ props->onActualCamera.isDirty = false;
155
+ }
152
156
 
153
157
  // Update hybridRef if it changed
154
158
  if (props->hybridRef.isDirty) {
@@ -0,0 +1,80 @@
1
+ ///
2
+ /// Func_void_CameraState.kt
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ package com.margelo.nitro.reactnativecesium
9
+
10
+ import androidx.annotation.Keep
11
+ import com.facebook.jni.HybridData
12
+ import com.facebook.proguard.annotations.DoNotStrip
13
+ import dalvik.annotation.optimization.FastNative
14
+
15
+
16
+ /**
17
+ * Represents the JavaScript callback `(camera: struct) => void`.
18
+ * This can be either implemented in C++ (in which case it might be a callback coming from JS),
19
+ * or in Kotlin/Java (in which case it is a native callback).
20
+ */
21
+ @DoNotStrip
22
+ @Keep
23
+ @Suppress("ClassName", "RedundantUnitReturnType")
24
+ fun interface Func_void_CameraState: (CameraState) -> Unit {
25
+ /**
26
+ * Call the given JS callback.
27
+ * @throws Throwable if the JS function itself throws an error, or if the JS function/runtime has already been deleted.
28
+ */
29
+ @DoNotStrip
30
+ @Keep
31
+ override fun invoke(camera: CameraState): Unit
32
+ }
33
+
34
+ /**
35
+ * Represents the JavaScript callback `(camera: struct) => void`.
36
+ * This is implemented in C++, via a `std::function<...>`.
37
+ * The callback might be coming from JS.
38
+ */
39
+ @DoNotStrip
40
+ @Keep
41
+ @Suppress(
42
+ "KotlinJniMissingFunction", "unused",
43
+ "RedundantSuppression", "RedundantUnitReturnType", "FunctionName",
44
+ "ConvertSecondaryConstructorToPrimary", "ClassName", "LocalVariableName",
45
+ )
46
+ class Func_void_CameraState_cxx: Func_void_CameraState {
47
+ @DoNotStrip
48
+ @Keep
49
+ private val mHybridData: HybridData
50
+
51
+ @DoNotStrip
52
+ @Keep
53
+ private constructor(hybridData: HybridData) {
54
+ mHybridData = hybridData
55
+ }
56
+
57
+ @DoNotStrip
58
+ @Keep
59
+ override fun invoke(camera: CameraState): Unit
60
+ = invoke_cxx(camera)
61
+
62
+ @FastNative
63
+ private external fun invoke_cxx(camera: CameraState): Unit
64
+ }
65
+
66
+ /**
67
+ * Represents the JavaScript callback `(camera: struct) => void`.
68
+ * This is implemented in Java/Kotlin, via a `(CameraState) -> Unit`.
69
+ * The callback is always coming from native.
70
+ */
71
+ @DoNotStrip
72
+ @Keep
73
+ @Suppress("ClassName", "RedundantUnitReturnType", "unused")
74
+ class Func_void_CameraState_java(private val function: (CameraState) -> Unit): Func_void_CameraState {
75
+ @DoNotStrip
76
+ @Keep
77
+ override fun invoke(camera: CameraState): Unit {
78
+ return this.function(camera)
79
+ }
80
+ }
@@ -202,6 +202,20 @@ abstract class HybridCesiumViewSpec: HybridView() {
202
202
  set(value) {
203
203
  onMetrics = value?.let { it }
204
204
  }
205
+
206
+ abstract var onActualCamera: ((camera: CameraState) -> Unit)?
207
+
208
+ private var onActualCamera_cxx: Func_void_CameraState?
209
+ @Keep
210
+ @DoNotStrip
211
+ get() {
212
+ return onActualCamera?.let { Func_void_CameraState_java(it) }
213
+ }
214
+ @Keep
215
+ @DoNotStrip
216
+ set(value) {
217
+ onActualCamera = value?.let { it }
218
+ }
205
219
 
206
220
  // Methods
207
221
  @DoNotStrip
@@ -22,11 +22,11 @@ namespace margelo::nitro::reactnativecesium::bridge::swift {
22
22
  };
23
23
  }
24
24
 
25
- // pragma MARK: std::function<void(const CameraState& /* result */)>
25
+ // pragma MARK: std::function<void(const CameraState& /* camera */)>
26
26
  Func_void_CameraState create_Func_void_CameraState(void* NON_NULL swiftClosureWrapper) noexcept {
27
27
  auto swiftClosure = ReactNativeCesium::Func_void_CameraState::fromUnsafe(swiftClosureWrapper);
28
- return [swiftClosure = std::move(swiftClosure)](const CameraState& result) mutable -> void {
29
- swiftClosure.call(result);
28
+ return [swiftClosure = std::move(swiftClosure)](const CameraState& camera) mutable -> void {
29
+ swiftClosure.call(camera);
30
30
  };
31
31
  }
32
32
 
@@ -108,40 +108,55 @@ namespace margelo::nitro::reactnativecesium::bridge::swift {
108
108
  return optional.value();
109
109
  }
110
110
 
111
- // pragma MARK: std::shared_ptr<Promise<CameraState>>
112
- /**
113
- * Specialized version of `std::shared_ptr<Promise<CameraState>>`.
114
- */
115
- using std__shared_ptr_Promise_CameraState__ = std::shared_ptr<Promise<CameraState>>;
116
- inline std::shared_ptr<Promise<CameraState>> create_std__shared_ptr_Promise_CameraState__() noexcept {
117
- return Promise<CameraState>::create();
118
- }
119
- inline PromiseHolder<CameraState> wrap_std__shared_ptr_Promise_CameraState__(std::shared_ptr<Promise<CameraState>> promise) noexcept {
120
- return PromiseHolder<CameraState>(std::move(promise));
121
- }
122
-
123
- // pragma MARK: std::function<void(const CameraState& /* result */)>
111
+ // pragma MARK: std::function<void(const CameraState& /* camera */)>
124
112
  /**
125
113
  * Specialized version of `std::function<void(const CameraState&)>`.
126
114
  */
127
- using Func_void_CameraState = std::function<void(const CameraState& /* result */)>;
115
+ using Func_void_CameraState = std::function<void(const CameraState& /* camera */)>;
128
116
  /**
129
- * Wrapper class for a `std::function<void(const CameraState& / * result * /)>`, this can be used from Swift.
117
+ * Wrapper class for a `std::function<void(const CameraState& / * camera * /)>`, this can be used from Swift.
130
118
  */
131
119
  class Func_void_CameraState_Wrapper final {
132
120
  public:
133
- explicit Func_void_CameraState_Wrapper(std::function<void(const CameraState& /* result */)>&& func): _function(std::make_unique<std::function<void(const CameraState& /* result */)>>(std::move(func))) {}
134
- inline void call(CameraState result) const noexcept {
135
- _function->operator()(result);
121
+ explicit Func_void_CameraState_Wrapper(std::function<void(const CameraState& /* camera */)>&& func): _function(std::make_unique<std::function<void(const CameraState& /* camera */)>>(std::move(func))) {}
122
+ inline void call(CameraState camera) const noexcept {
123
+ _function->operator()(camera);
136
124
  }
137
125
  private:
138
- std::unique_ptr<std::function<void(const CameraState& /* result */)>> _function;
126
+ std::unique_ptr<std::function<void(const CameraState& /* camera */)>> _function;
139
127
  } SWIFT_NONCOPYABLE;
140
128
  Func_void_CameraState create_Func_void_CameraState(void* NON_NULL swiftClosureWrapper) noexcept;
141
129
  inline Func_void_CameraState_Wrapper wrap_Func_void_CameraState(Func_void_CameraState value) noexcept {
142
130
  return Func_void_CameraState_Wrapper(std::move(value));
143
131
  }
144
132
 
133
+ // pragma MARK: std::optional<std::function<void(const CameraState& /* camera */)>>
134
+ /**
135
+ * Specialized version of `std::optional<std::function<void(const CameraState& / * camera * /)>>`.
136
+ */
137
+ using std__optional_std__function_void_const_CameraState_____camera______ = std::optional<std::function<void(const CameraState& /* camera */)>>;
138
+ inline std::optional<std::function<void(const CameraState& /* camera */)>> create_std__optional_std__function_void_const_CameraState_____camera______(const std::function<void(const CameraState& /* camera */)>& value) noexcept {
139
+ return std::optional<std::function<void(const CameraState& /* camera */)>>(value);
140
+ }
141
+ inline bool has_value_std__optional_std__function_void_const_CameraState_____camera______(const std::optional<std::function<void(const CameraState& /* camera */)>>& optional) noexcept {
142
+ return optional.has_value();
143
+ }
144
+ inline std::function<void(const CameraState& /* camera */)> get_std__optional_std__function_void_const_CameraState_____camera______(const std::optional<std::function<void(const CameraState& /* camera */)>>& optional) noexcept {
145
+ return optional.value();
146
+ }
147
+
148
+ // pragma MARK: std::shared_ptr<Promise<CameraState>>
149
+ /**
150
+ * Specialized version of `std::shared_ptr<Promise<CameraState>>`.
151
+ */
152
+ using std__shared_ptr_Promise_CameraState__ = std::shared_ptr<Promise<CameraState>>;
153
+ inline std::shared_ptr<Promise<CameraState>> create_std__shared_ptr_Promise_CameraState__() noexcept {
154
+ return Promise<CameraState>::create();
155
+ }
156
+ inline PromiseHolder<CameraState> wrap_std__shared_ptr_Promise_CameraState__(std::shared_ptr<Promise<CameraState>> promise) noexcept {
157
+ return PromiseHolder<CameraState>(std::move(promise));
158
+ }
159
+
145
160
  // pragma MARK: std::function<void(const std::exception_ptr& /* error */)>
146
161
  /**
147
162
  * Specialized version of `std::function<void(const std::exception_ptr&)>`.
@@ -261,6 +261,13 @@ namespace margelo::nitro::reactnativecesium {
261
261
  inline void setOnMetrics(const std::optional<std::function<void(const CesiumMetrics& /* metrics */)>>& onMetrics) noexcept override {
262
262
  _swiftPart.setOnMetrics(onMetrics);
263
263
  }
264
+ inline std::optional<std::function<void(const CameraState& /* camera */)>> getOnActualCamera() noexcept override {
265
+ auto __result = _swiftPart.getOnActualCamera();
266
+ return __result;
267
+ }
268
+ inline void setOnActualCamera(const std::optional<std::function<void(const CameraState& /* camera */)>>& onActualCamera) noexcept override {
269
+ _swiftPart.setOnActualCamera(onActualCamera);
270
+ }
264
271
 
265
272
  public:
266
273
  // Methods
@@ -219,6 +219,11 @@ using namespace margelo::nitro::reactnativecesium::views;
219
219
  swiftPart.setOnMetrics(newViewProps.onMetrics.value);
220
220
  newViewProps.onMetrics.isDirty = false;
221
221
  }
222
+ // onActualCamera: optional
223
+ if (newViewProps.onActualCamera.isDirty) {
224
+ swiftPart.setOnActualCamera(newViewProps.onActualCamera.value);
225
+ newViewProps.onActualCamera.isDirty = false;
226
+ }
222
227
 
223
228
  swiftPart.afterUpdate();
224
229
 
@@ -8,21 +8,21 @@
8
8
  import NitroModules
9
9
 
10
10
  /**
11
- * Wraps a Swift `(_ value: CameraState) -> Void` as a class.
11
+ * Wraps a Swift `(_ camera: CameraState) -> Void` as a class.
12
12
  * This class can be used from C++, e.g. to wrap the Swift closure as a `std::function`.
13
13
  */
14
14
  public final class Func_void_CameraState {
15
15
  public typealias bridge = margelo.nitro.reactnativecesium.bridge.swift
16
16
 
17
- private let closure: (_ value: CameraState) -> Void
17
+ private let closure: (_ camera: CameraState) -> Void
18
18
 
19
- public init(_ closure: @escaping (_ value: CameraState) -> Void) {
19
+ public init(_ closure: @escaping (_ camera: CameraState) -> Void) {
20
20
  self.closure = closure
21
21
  }
22
22
 
23
23
  @inline(__always)
24
- public func call(value: CameraState) -> Void {
25
- self.closure(value)
24
+ public func call(camera: CameraState) -> Void {
25
+ self.closure(camera)
26
26
  }
27
27
 
28
28
  /**
@@ -38,6 +38,7 @@ public protocol HybridCesiumViewSpec_protocol: HybridObject, HybridView {
38
38
  var maxClimbRateMps: Double? { get set }
39
39
  var maxGroundSpeedMps: Double? { get set }
40
40
  var onMetrics: ((_ metrics: CesiumMetrics) -> Void)? { get set }
41
+ var onActualCamera: ((_ camera: CameraState) -> Void)? { get set }
41
42
 
42
43
  // Methods
43
44
  func setPosition(latitude: Double, longitude: Double) throws -> Void
@@ -683,6 +683,38 @@ open class HybridCesiumViewSpec_cxx {
683
683
  }()
684
684
  }
685
685
  }
686
+
687
+ public final var onActualCamera: bridge.std__optional_std__function_void_const_CameraState_____camera______ {
688
+ @inline(__always)
689
+ get {
690
+ return { () -> bridge.std__optional_std__function_void_const_CameraState_____camera______ in
691
+ if let __unwrappedValue = self.__implementation.onActualCamera {
692
+ return bridge.create_std__optional_std__function_void_const_CameraState_____camera______({ () -> bridge.Func_void_CameraState in
693
+ let __closureWrapper = Func_void_CameraState(__unwrappedValue)
694
+ return bridge.create_Func_void_CameraState(__closureWrapper.toUnsafe())
695
+ }())
696
+ } else {
697
+ return .init()
698
+ }
699
+ }()
700
+ }
701
+ @inline(__always)
702
+ set {
703
+ self.__implementation.onActualCamera = { () -> ((_ camera: CameraState) -> Void)? in
704
+ if bridge.has_value_std__optional_std__function_void_const_CameraState_____camera______(newValue) {
705
+ let __unwrapped = bridge.get_std__optional_std__function_void_const_CameraState_____camera______(newValue)
706
+ return { () -> (CameraState) -> Void in
707
+ let __wrappedFunction = bridge.wrap_Func_void_CameraState(__unwrapped)
708
+ return { (__camera: CameraState) -> Void in
709
+ __wrappedFunction.call(__camera)
710
+ }
711
+ }()
712
+ } else {
713
+ return nil
714
+ }
715
+ }()
716
+ }
717
+ }
686
718
 
687
719
  // Methods
688
720
  @inline(__always)
@@ -70,6 +70,8 @@ namespace margelo::nitro::reactnativecesium {
70
70
  prototype.registerHybridSetter("maxGroundSpeedMps", &HybridCesiumViewSpec::setMaxGroundSpeedMps);
71
71
  prototype.registerHybridGetter("onMetrics", &HybridCesiumViewSpec::getOnMetrics);
72
72
  prototype.registerHybridSetter("onMetrics", &HybridCesiumViewSpec::setOnMetrics);
73
+ prototype.registerHybridGetter("onActualCamera", &HybridCesiumViewSpec::getOnActualCamera);
74
+ prototype.registerHybridSetter("onActualCamera", &HybridCesiumViewSpec::setOnActualCamera);
73
75
  prototype.registerHybridMethod("setPosition", &HybridCesiumViewSpec::setPosition);
74
76
  prototype.registerHybridMethod("setAltitude", &HybridCesiumViewSpec::setAltitude);
75
77
  prototype.registerHybridMethod("setHeading", &HybridCesiumViewSpec::setHeading);
@@ -111,6 +111,8 @@ namespace margelo::nitro::reactnativecesium {
111
111
  virtual void setMaxGroundSpeedMps(std::optional<double> maxGroundSpeedMps) = 0;
112
112
  virtual std::optional<std::function<void(const CesiumMetrics& /* metrics */)>> getOnMetrics() = 0;
113
113
  virtual void setOnMetrics(const std::optional<std::function<void(const CesiumMetrics& /* metrics */)>>& onMetrics) = 0;
114
+ virtual std::optional<std::function<void(const CameraState& /* camera */)>> getOnActualCamera() = 0;
115
+ virtual void setOnActualCamera(const std::optional<std::function<void(const CameraState& /* camera */)>>& onActualCamera) = 0;
114
116
 
115
117
  public:
116
118
  // Methods
@@ -306,6 +306,16 @@ namespace margelo::nitro::reactnativecesium::views {
306
306
  throw std::runtime_error(std::string("CesiumView.onMetrics: ") + exc.what());
307
307
  }
308
308
  }()),
309
+ onActualCamera([&]() -> CachedProp<std::optional<std::function<void(const CameraState& /* camera */)>>> {
310
+ try {
311
+ const react::RawValue* rawValue = rawProps.at("onActualCamera", nullptr, nullptr);
312
+ if (rawValue == nullptr) return sourceProps.onActualCamera;
313
+ const auto& [runtime, value] = (std::pair<jsi::Runtime*, jsi::Value>)*rawValue;
314
+ return CachedProp<std::optional<std::function<void(const CameraState& /* camera */)>>>::fromRawValue(*runtime, value.asObject(*runtime).getProperty(*runtime, PropNameIDCache::get(*runtime, "f")), sourceProps.onActualCamera);
315
+ } catch (const std::exception& exc) {
316
+ throw std::runtime_error(std::string("CesiumView.onActualCamera: ") + exc.what());
317
+ }
318
+ }()),
309
319
  hybridRef([&]() -> CachedProp<std::optional<std::function<void(const std::shared_ptr<HybridCesiumViewSpec>& /* ref */)>>> {
310
320
  try {
311
321
  const react::RawValue* rawValue = rawProps.at("hybridRef", nullptr, nullptr);
@@ -347,6 +357,7 @@ namespace margelo::nitro::reactnativecesium::views {
347
357
  case hashString("maxClimbRateMps"): return true;
348
358
  case hashString("maxGroundSpeedMps"): return true;
349
359
  case hashString("onMetrics"): return true;
360
+ case hashString("onActualCamera"): return true;
350
361
  case hashString("hybridRef"): return true;
351
362
  default: return false;
352
363
  }
@@ -72,6 +72,7 @@ namespace margelo::nitro::reactnativecesium::views {
72
72
  CachedProp<std::optional<double>> maxClimbRateMps;
73
73
  CachedProp<std::optional<double>> maxGroundSpeedMps;
74
74
  CachedProp<std::optional<std::function<void(const CesiumMetrics& /* metrics */)>>> onMetrics;
75
+ CachedProp<std::optional<std::function<void(const CameraState& /* camera */)>>> onActualCamera;
75
76
  CachedProp<std::optional<std::function<void(const std::shared_ptr<HybridCesiumViewSpec>& /* ref */)>>> hybridRef;
76
77
 
77
78
  private:
@@ -32,6 +32,7 @@
32
32
  "maxClimbRateMps": true,
33
33
  "maxGroundSpeedMps": true,
34
34
  "onMetrics": true,
35
+ "onActualCamera": true,
35
36
  "hybridRef": true
36
37
  }
37
38
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-cesium",
3
- "version": "1.2.4",
3
+ "version": "1.2.6",
4
4
  "description": "Experimental Cesium rendering for React Native via Nitro (iOS/Metal today; Android planned)",
5
5
  "main": "./lib/commonjs/index.js",
6
6
  "module": "./lib/module/index.js",
@@ -110,6 +110,15 @@ export interface CesiumViewProps extends HybridViewProps {
110
110
  maxGroundSpeedMps?: number
111
111
 
112
112
  onMetrics?: (metrics: CesiumMetrics) => void
113
+
114
+ /**
115
+ * Called at ~5 Hz with the post-integration actual camera — the same state
116
+ * returned by `getActualCamera()`. Only fires when at least one field has
117
+ * changed beyond its epsilon threshold since the last emission, so a
118
+ * stationary camera produces no bridge traffic. Use this to keep HUD overlay
119
+ * symbology aligned with the rendered view without polling from JS.
120
+ */
121
+ onActualCamera?: (camera: CameraState) => void
113
122
  }
114
123
 
115
124
  /**