@onekeyfe/react-native-perf-stats 3.0.35 → 3.0.36
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.
- package/android/src/main/java/com/margelo/nitro/reactnativeperfstats/PerfStatsInitProvider.kt +11 -4
- package/android/src/main/java/com/margelo/nitro/reactnativeperfstats/ReactNativePerfStats.kt +333 -24
- package/ios/ReactNativePerfStats.swift +360 -15
- package/lib/module/index.js +77 -5
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/ReactNativePerfStats.nitro.d.ts +109 -1
- package/lib/typescript/src/ReactNativePerfStats.nitro.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +31 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/nitrogen/generated/android/c++/JFunc_void_MemoryWarningEvent.hpp +79 -0
- package/nitrogen/generated/android/c++/JHybridReactNativePerfStatsSpec.cpp +24 -0
- package/nitrogen/generated/android/c++/JHybridReactNativePerfStatsSpec.hpp +3 -0
- package/nitrogen/generated/android/c++/JMemoryWarningEvent.hpp +66 -0
- package/nitrogen/generated/android/c++/JMemoryWarningLevel.hpp +59 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativeperfstats/Func_void_MemoryWarningEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativeperfstats/HybridReactNativePerfStatsSpec.kt +17 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativeperfstats/MemoryWarningEvent.kt +44 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativeperfstats/MemoryWarningLevel.kt +21 -0
- package/nitrogen/generated/android/reactnativeperfstatsOnLoad.cpp +2 -0
- package/nitrogen/generated/ios/ReactNativePerfStats-Swift-Cxx-Bridge.cpp +8 -0
- package/nitrogen/generated/ios/ReactNativePerfStats-Swift-Cxx-Bridge.hpp +37 -0
- package/nitrogen/generated/ios/ReactNativePerfStats-Swift-Cxx-Umbrella.hpp +7 -0
- package/nitrogen/generated/ios/c++/HybridReactNativePerfStatsSpecSwift.hpp +27 -0
- package/nitrogen/generated/ios/swift/Func_void_MemoryWarningEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/HybridReactNativePerfStatsSpec.swift +3 -0
- package/nitrogen/generated/ios/swift/HybridReactNativePerfStatsSpec_cxx.swift +39 -0
- package/nitrogen/generated/ios/swift/MemoryWarningEvent.swift +58 -0
- package/nitrogen/generated/ios/swift/MemoryWarningLevel.swift +40 -0
- package/nitrogen/generated/shared/c++/HybridReactNativePerfStatsSpec.cpp +3 -0
- package/nitrogen/generated/shared/c++/HybridReactNativePerfStatsSpec.hpp +7 -0
- package/nitrogen/generated/shared/c++/MemoryWarningEvent.hpp +84 -0
- package/nitrogen/generated/shared/c++/MemoryWarningLevel.hpp +76 -0
- package/package.json +1 -1
- package/src/ReactNativePerfStats.nitro.ts +114 -1
- package/src/index.tsx +90 -5
|
@@ -12,18 +12,53 @@ export interface PerfSample {
|
|
|
12
12
|
/**
|
|
13
13
|
* UI thread frame rate, frames per second over the last 1 s window.
|
|
14
14
|
* Measured on the platform's main thread via Choreographer (Android)
|
|
15
|
-
* or CADisplayLink (iOS). `0` until at least one window has elapsed
|
|
15
|
+
* or CADisplayLink (iOS). `0` until at least one window has elapsed
|
|
16
|
+
* **and the sampler is running** — the underlying frame monitor only
|
|
17
|
+
* runs between `start()` and `stop()`, so one-shot `sample()` calls
|
|
18
|
+
* issued outside that window always report `0` here.
|
|
16
19
|
*/
|
|
17
20
|
uiFps: number;
|
|
18
21
|
/**
|
|
19
22
|
* JS thread frame rate, frames per second reported by the JS-side
|
|
20
23
|
* `requestAnimationFrame` ticker (see `startJsFpsTracker`). `0` if
|
|
21
24
|
* the tracker has not been started or no hint has been received yet.
|
|
25
|
+
* Same caveat as `uiFps`: one-shot `sample()` calls issued before
|
|
26
|
+
* `start()` (or after `stop()`) report `0` here.
|
|
22
27
|
*/
|
|
23
28
|
jsFps: number;
|
|
24
29
|
/** Wall-clock timestamp (ms since unix epoch) when the sample was taken. */
|
|
25
30
|
timestamp: number;
|
|
26
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Severity of a system-emitted memory pressure event, normalised across
|
|
34
|
+
* platforms.
|
|
35
|
+
*
|
|
36
|
+
* - `low`: Android `TRIM_MEMORY_RUNNING_MODERATE` /
|
|
37
|
+
* `TRIM_MEMORY_RUNNING_LOW`. iOS does not emit this level (iOS only
|
|
38
|
+
* fires the critical warning), so JS code should treat the absence of
|
|
39
|
+
* `low` events on iOS as expected, not a missing signal.
|
|
40
|
+
* - `critical`: iOS `UIApplicationDidReceiveMemoryWarningNotification`;
|
|
41
|
+
* Android `TRIM_MEMORY_RUNNING_CRITICAL` or `onLowMemory()`. Indicates
|
|
42
|
+
* the OS is about to start killing background apps (Android) or the
|
|
43
|
+
* app itself (iOS jetsam). Subscribers should drop everything that
|
|
44
|
+
* can be rebuilt on demand.
|
|
45
|
+
*/
|
|
46
|
+
export type MemoryWarningLevel = 'low' | 'critical';
|
|
47
|
+
export interface MemoryWarningEvent {
|
|
48
|
+
level: MemoryWarningLevel;
|
|
49
|
+
/**
|
|
50
|
+
* Process RSS in bytes at the moment the warning fired. `0` if the
|
|
51
|
+
* lookup failed.
|
|
52
|
+
*
|
|
53
|
+
* On iOS the primary source is `phys_footprint`; if that fails, the
|
|
54
|
+
* fallback path reads `resident_size`, which is semantically smaller
|
|
55
|
+
* and noisier. The two values are not directly comparable, so treat
|
|
56
|
+
* unexpected magnitude differences across reports cautiously.
|
|
57
|
+
*/
|
|
58
|
+
rss: number;
|
|
59
|
+
/** Wall-clock timestamp (ms since unix epoch). */
|
|
60
|
+
timestamp: number;
|
|
61
|
+
}
|
|
27
62
|
export interface ReactNativePerfStats extends HybridObject<{
|
|
28
63
|
ios: 'swift';
|
|
29
64
|
android: 'kotlin';
|
|
@@ -73,5 +108,78 @@ export interface ReactNativePerfStats extends HybridObject<{
|
|
|
73
108
|
* than calling this directly.
|
|
74
109
|
*/
|
|
75
110
|
setJsFpsHint(fps: number): void;
|
|
111
|
+
/**
|
|
112
|
+
* Subscribe to OS-emitted memory pressure events.
|
|
113
|
+
*
|
|
114
|
+
* - iOS: `UIApplicationDidReceiveMemoryWarningNotification`, mapped to
|
|
115
|
+
* `critical`. Fires on the main thread.
|
|
116
|
+
* - Android: `ComponentCallbacks2.onTrimMemory` filtered to
|
|
117
|
+
* `TRIM_MEMORY_RUNNING_*` (foreground process pressure), plus
|
|
118
|
+
* `onLowMemory()` as `critical`. Fires on the main thread.
|
|
119
|
+
*
|
|
120
|
+
* The native listener is registered process-wide on first call and
|
|
121
|
+
* survives `stop()` — memory pressure is independent of the perf
|
|
122
|
+
* sampler being active. Callbacks are invoked on the JS thread.
|
|
123
|
+
*
|
|
124
|
+
* **Always pair this with `removeMemoryWarningListener`** (e.g. in a
|
|
125
|
+
* React effect cleanup): the callback closure is retained for the life
|
|
126
|
+
* of the subscription, and forgetting to remove leaks every object the
|
|
127
|
+
* closure transitively captures — typically the React component instance
|
|
128
|
+
* that registered it. This matters in dev too: the native listener
|
|
129
|
+
* table is a process-wide singleton that **does not clear on RN
|
|
130
|
+
* reload**, so a Fast-Refresh / dev reload that drops the JS realm
|
|
131
|
+
* without first calling `removeMemoryWarningListener` will leave the
|
|
132
|
+
* pre-reload callback in the table, pointing at a dead JS context.
|
|
133
|
+
* The cleanest fix is the same effect-cleanup pattern.
|
|
134
|
+
*
|
|
135
|
+
* The relative order in which subscribed callbacks fire for a single
|
|
136
|
+
* event is **not guaranteed** — iOS iterates a hash dictionary, Android
|
|
137
|
+
* iterates a LinkedHashMap, and either may change. Don't take a
|
|
138
|
+
* cross-listener dependency.
|
|
139
|
+
*
|
|
140
|
+
* Dispatch: when a warning arrives, the native module walks all
|
|
141
|
+
* registered callbacks **serially on the main thread** before each
|
|
142
|
+
* one hops to the JS thread. Cost scales with the number of
|
|
143
|
+
* subscribers — keep N small (single-digit) and avoid registering one
|
|
144
|
+
* listener per render-tree branch.
|
|
145
|
+
*
|
|
146
|
+
* Side effects of the warning itself (before your callback fires):
|
|
147
|
+
* - **iOS** runs the same reclaim path as `cleanupNativeCaches`,
|
|
148
|
+
* which drops the process-wide `URLCache.shared`, the WK HTTP /
|
|
149
|
+
* AppCache / Service-Worker stores, and triggers a libmalloc
|
|
150
|
+
* pressure relief. If any code path in the app depends on
|
|
151
|
+
* URLCache for offline HTTP content, or on a Service Worker for
|
|
152
|
+
* offline WebView fallback, that state is dropped here — don't
|
|
153
|
+
* register this listener if either is load-bearing.
|
|
154
|
+
* - **Android** runs `Runtime.gc()` on every warning (LOW and
|
|
155
|
+
* CRITICAL). ART treats it as a hint.
|
|
156
|
+
*
|
|
157
|
+
* Returns an opaque id; pass it to `removeMemoryWarningListener` to
|
|
158
|
+
* unsubscribe.
|
|
159
|
+
*/
|
|
160
|
+
addMemoryWarningListener(callback: (event: MemoryWarningEvent) => void): number;
|
|
161
|
+
/** Unsubscribe a previously-registered memory warning listener. No-op for unknown ids. */
|
|
162
|
+
removeMemoryWarningListener(id: number): void;
|
|
163
|
+
/**
|
|
164
|
+
* Trigger the same native reclaim path the OS memory-warning observer
|
|
165
|
+
* runs, on demand. Use when the JS layer has reason to believe pressure
|
|
166
|
+
* is building before the OS posts a warning (e.g. backgrounding, a
|
|
167
|
+
* heavy route transition, jotai cache invalidation, post-import).
|
|
168
|
+
*
|
|
169
|
+
* - **iOS** clears `URLCache.shared` (process-wide HTTP response cache;
|
|
170
|
+
* any consumer that relies on URLCache for offline content loses
|
|
171
|
+
* it until the next request) and the WK HTTP / AppCache / Service-
|
|
172
|
+
* Worker stores (auth-related cookies / localStorage / IndexedDB
|
|
173
|
+
* are preserved). Then dispatches `malloc_zone_pressure_relief` on
|
|
174
|
+
* a background queue — the call returns to JS immediately, but the
|
|
175
|
+
* zone walk that actually frees pages can take 100-500 ms.
|
|
176
|
+
* - **Android** asks ART to GC via `Runtime.gc()` (hint only; the
|
|
177
|
+
* runtime decides whether to honour it). Returns quickly.
|
|
178
|
+
*
|
|
179
|
+
* Cheap on Android, cheap-to-return on iOS (heavy work runs async).
|
|
180
|
+
* Pair with `forceGarbageCollection()` if you also want the JS engine
|
|
181
|
+
* to participate.
|
|
182
|
+
*/
|
|
183
|
+
cleanupNativeCaches(): void;
|
|
76
184
|
}
|
|
77
185
|
//# sourceMappingURL=ReactNativePerfStats.nitro.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReactNativePerfStats.nitro.d.ts","sourceRoot":"","sources":["../../../src/ReactNativePerfStats.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE/D,MAAM,WAAW,UAAU;IACzB;;;;;OAKG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ,uEAAuE;IACvE,GAAG,EAAE,MAAM,CAAC;IACZ
|
|
1
|
+
{"version":3,"file":"ReactNativePerfStats.nitro.d.ts","sourceRoot":"","sources":["../../../src/ReactNativePerfStats.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE/D,MAAM,WAAW,UAAU;IACzB;;;;;OAKG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ,uEAAuE;IACvE,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;OAOG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,UAAU,CAAC;AAEpD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,kBAAkB,CAAC;IAC1B;;;;;;;;OAQG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ,kDAAkD;IAClD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBACf,SAAQ,YAAY,CAAC;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAA;CAAE,CAAC;IACzD;;;;;;;;OAQG;IACH,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAEhC,+EAA+E;IAC/E,IAAI,IAAI,IAAI,CAAC;IAEb;;;;;;;;;;;;;OAaG;IACH,WAAW,IAAI,IAAI,CAAC;IAEpB,gFAAgF;IAChF,WAAW,IAAI,IAAI,CAAC;IAEpB;;;;OAIG;IACH,MAAM,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IAE9B;;;;;;;;OAQG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAEhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgDG;IACH,wBAAwB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,GAAG,MAAM,CAAC;IAEhF,0FAA0F;IAC1F,2BAA2B,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAE9C;;;;;;;;;;;;;;;;;;;OAmBG;IACH,mBAAmB,IAAI,IAAI,CAAC;CAC7B"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { MemoryWarningEvent } from './ReactNativePerfStats.nitro';
|
|
1
2
|
export type * from './ReactNativePerfStats.nitro';
|
|
2
3
|
/**
|
|
3
4
|
* Start the JS-side FPS ticker. Normally invoked automatically by
|
|
@@ -19,5 +20,35 @@ export declare const ReactNativePerfStats: {
|
|
|
19
20
|
hideOverlay: () => void;
|
|
20
21
|
sample: () => Promise<import("./ReactNativePerfStats.nitro").PerfSample>;
|
|
21
22
|
setJsFpsHint: (fps: number) => void;
|
|
23
|
+
addMemoryWarningListener: (callback: (event: MemoryWarningEvent) => void) => number;
|
|
24
|
+
removeMemoryWarningListener: (id: number) => void;
|
|
25
|
+
/**
|
|
26
|
+
* Run the same native reclaim path the OS memory-warning observer
|
|
27
|
+
* triggers, on demand. Returns immediately (heavy work runs async
|
|
28
|
+
* on iOS). See the spec doc for what gets dropped on each platform.
|
|
29
|
+
*/
|
|
30
|
+
cleanupNativeCaches: () => void;
|
|
31
|
+
/**
|
|
32
|
+
* Best-effort hint to the JS engine that now is a good time to GC.
|
|
33
|
+
*
|
|
34
|
+
* Hermes does not expose a public `collectGarbage` binding in production
|
|
35
|
+
* builds; the only stable JS-level entry point is the (undocumented)
|
|
36
|
+
* `HermesInternal.gc` property, which is present in some builds and
|
|
37
|
+
* absent in others. We feature-detect it and fall back to a no-op so
|
|
38
|
+
* callers never have to branch.
|
|
39
|
+
*
|
|
40
|
+
* Returns `true` only if a GC binding was both found AND invoked
|
|
41
|
+
* without throwing. A `false` return therefore covers three cases —
|
|
42
|
+
* binding missing (production Hermes is the common case), binding
|
|
43
|
+
* present but threw, and any unexpected failure. The first miss is
|
|
44
|
+
* logged once via `console.warn` so the caller knows it landed in the
|
|
45
|
+
* "no binding" branch; throws are logged on every occurrence because
|
|
46
|
+
* those are real errors.
|
|
47
|
+
*
|
|
48
|
+
* Cost: when honoured, Hermes does a stop-the-world collection that
|
|
49
|
+
* can take 100–500 ms — never call this on the hot path. Memory-warning
|
|
50
|
+
* handlers are the intended use case.
|
|
51
|
+
*/
|
|
52
|
+
forceGarbageCollection(): boolean;
|
|
22
53
|
};
|
|
23
54
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,kBAAkB,EAEnB,MAAM,8BAA8B,CAAC;AAKtC,mBAAmB,8BAA8B,CAAC;AA6BlD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,gBAAgB,GAAE,MAAa,GAAG,IAAI,CAwBvE;AAED,+CAA+C;AAC/C,wBAAgB,gBAAgB,IAAI,IAAI,CAWvC;AAQD,eAAO,MAAM,oBAAoB;sBACb,MAAM,GAAG,IAAI;YAIvB,IAAI;uBAIK,IAAI;uBACJ,IAAI;;wBAED,MAAM,KAAG,IAAI;yCAIrB,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,KAC5C,MAAM;sCACyB,MAAM,KAAG,IAAI;IAE/C;;;;OAIG;+BACsB,IAAI;IAE7B;;;;;;;;;;;;;;;;;;;;OAoBG;8BACuB,OAAO;CAkClC,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// JFunc_void_MemoryWarningEvent.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © 2026 Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <fbjni/fbjni.h>
|
|
11
|
+
#include <functional>
|
|
12
|
+
|
|
13
|
+
#include "MemoryWarningEvent.hpp"
|
|
14
|
+
#include <functional>
|
|
15
|
+
#include <NitroModules/JNICallable.hpp>
|
|
16
|
+
#include "JMemoryWarningEvent.hpp"
|
|
17
|
+
#include "MemoryWarningLevel.hpp"
|
|
18
|
+
#include "JMemoryWarningLevel.hpp"
|
|
19
|
+
|
|
20
|
+
namespace margelo::nitro::reactnativeperfstats {
|
|
21
|
+
|
|
22
|
+
using namespace facebook;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Represents the Java/Kotlin callback `(event: MemoryWarningEvent) -> Unit`.
|
|
26
|
+
* This can be passed around between C++ and Java/Kotlin.
|
|
27
|
+
*/
|
|
28
|
+
struct JFunc_void_MemoryWarningEvent: public jni::JavaClass<JFunc_void_MemoryWarningEvent> {
|
|
29
|
+
public:
|
|
30
|
+
static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/reactnativeperfstats/Func_void_MemoryWarningEvent;";
|
|
31
|
+
|
|
32
|
+
public:
|
|
33
|
+
/**
|
|
34
|
+
* Invokes the function this `JFunc_void_MemoryWarningEvent` instance holds through JNI.
|
|
35
|
+
*/
|
|
36
|
+
void invoke(const MemoryWarningEvent& event) const {
|
|
37
|
+
static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<JMemoryWarningEvent> /* event */)>("invoke");
|
|
38
|
+
method(self(), JMemoryWarningEvent::fromCpp(event));
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* An implementation of Func_void_MemoryWarningEvent that is backed by a C++ implementation (using `std::function<...>`)
|
|
44
|
+
*/
|
|
45
|
+
class JFunc_void_MemoryWarningEvent_cxx final: public jni::HybridClass<JFunc_void_MemoryWarningEvent_cxx, JFunc_void_MemoryWarningEvent> {
|
|
46
|
+
public:
|
|
47
|
+
static jni::local_ref<JFunc_void_MemoryWarningEvent::javaobject> fromCpp(const std::function<void(const MemoryWarningEvent& /* event */)>& func) {
|
|
48
|
+
return JFunc_void_MemoryWarningEvent_cxx::newObjectCxxArgs(func);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
public:
|
|
52
|
+
/**
|
|
53
|
+
* Invokes the C++ `std::function<...>` this `JFunc_void_MemoryWarningEvent_cxx` instance holds.
|
|
54
|
+
*/
|
|
55
|
+
void invoke_cxx(jni::alias_ref<JMemoryWarningEvent> event) {
|
|
56
|
+
_func(event->toCpp());
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
public:
|
|
60
|
+
[[nodiscard]]
|
|
61
|
+
inline const std::function<void(const MemoryWarningEvent& /* event */)>& getFunction() const {
|
|
62
|
+
return _func;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
public:
|
|
66
|
+
static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/reactnativeperfstats/Func_void_MemoryWarningEvent_cxx;";
|
|
67
|
+
static void registerNatives() {
|
|
68
|
+
registerHybrid({makeNativeMethod("invoke_cxx", JFunc_void_MemoryWarningEvent_cxx::invoke_cxx)});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private:
|
|
72
|
+
explicit JFunc_void_MemoryWarningEvent_cxx(const std::function<void(const MemoryWarningEvent& /* event */)>& func): _func(func) { }
|
|
73
|
+
|
|
74
|
+
private:
|
|
75
|
+
friend HybridBase;
|
|
76
|
+
std::function<void(const MemoryWarningEvent& /* event */)> _func;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
} // namespace margelo::nitro::reactnativeperfstats
|
|
@@ -9,11 +9,22 @@
|
|
|
9
9
|
|
|
10
10
|
// Forward declaration of `PerfSample` to properly resolve imports.
|
|
11
11
|
namespace margelo::nitro::reactnativeperfstats { struct PerfSample; }
|
|
12
|
+
// Forward declaration of `MemoryWarningEvent` to properly resolve imports.
|
|
13
|
+
namespace margelo::nitro::reactnativeperfstats { struct MemoryWarningEvent; }
|
|
14
|
+
// Forward declaration of `MemoryWarningLevel` to properly resolve imports.
|
|
15
|
+
namespace margelo::nitro::reactnativeperfstats { enum class MemoryWarningLevel; }
|
|
12
16
|
|
|
13
17
|
#include "PerfSample.hpp"
|
|
14
18
|
#include <NitroModules/Promise.hpp>
|
|
15
19
|
#include <NitroModules/JPromise.hpp>
|
|
16
20
|
#include "JPerfSample.hpp"
|
|
21
|
+
#include "MemoryWarningEvent.hpp"
|
|
22
|
+
#include <functional>
|
|
23
|
+
#include "JFunc_void_MemoryWarningEvent.hpp"
|
|
24
|
+
#include <NitroModules/JNICallable.hpp>
|
|
25
|
+
#include "JMemoryWarningEvent.hpp"
|
|
26
|
+
#include "MemoryWarningLevel.hpp"
|
|
27
|
+
#include "JMemoryWarningLevel.hpp"
|
|
17
28
|
|
|
18
29
|
namespace margelo::nitro::reactnativeperfstats {
|
|
19
30
|
|
|
@@ -83,5 +94,18 @@ namespace margelo::nitro::reactnativeperfstats {
|
|
|
83
94
|
static const auto method = javaClassStatic()->getMethod<void(double /* fps */)>("setJsFpsHint");
|
|
84
95
|
method(_javaPart, fps);
|
|
85
96
|
}
|
|
97
|
+
double JHybridReactNativePerfStatsSpec::addMemoryWarningListener(const std::function<void(const MemoryWarningEvent& /* event */)>& callback) {
|
|
98
|
+
static const auto method = javaClassStatic()->getMethod<double(jni::alias_ref<JFunc_void_MemoryWarningEvent::javaobject> /* callback */)>("addMemoryWarningListener_cxx");
|
|
99
|
+
auto __result = method(_javaPart, JFunc_void_MemoryWarningEvent_cxx::fromCpp(callback));
|
|
100
|
+
return __result;
|
|
101
|
+
}
|
|
102
|
+
void JHybridReactNativePerfStatsSpec::removeMemoryWarningListener(double id) {
|
|
103
|
+
static const auto method = javaClassStatic()->getMethod<void(double /* id */)>("removeMemoryWarningListener");
|
|
104
|
+
method(_javaPart, id);
|
|
105
|
+
}
|
|
106
|
+
void JHybridReactNativePerfStatsSpec::cleanupNativeCaches() {
|
|
107
|
+
static const auto method = javaClassStatic()->getMethod<void()>("cleanupNativeCaches");
|
|
108
|
+
method(_javaPart);
|
|
109
|
+
}
|
|
86
110
|
|
|
87
111
|
} // namespace margelo::nitro::reactnativeperfstats
|
|
@@ -60,6 +60,9 @@ namespace margelo::nitro::reactnativeperfstats {
|
|
|
60
60
|
void hideOverlay() override;
|
|
61
61
|
std::shared_ptr<Promise<PerfSample>> sample() override;
|
|
62
62
|
void setJsFpsHint(double fps) override;
|
|
63
|
+
double addMemoryWarningListener(const std::function<void(const MemoryWarningEvent& /* event */)>& callback) override;
|
|
64
|
+
void removeMemoryWarningListener(double id) override;
|
|
65
|
+
void cleanupNativeCaches() override;
|
|
63
66
|
|
|
64
67
|
private:
|
|
65
68
|
friend HybridBase;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// JMemoryWarningEvent.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © 2026 Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <fbjni/fbjni.h>
|
|
11
|
+
#include "MemoryWarningEvent.hpp"
|
|
12
|
+
|
|
13
|
+
#include "JMemoryWarningLevel.hpp"
|
|
14
|
+
#include "MemoryWarningLevel.hpp"
|
|
15
|
+
|
|
16
|
+
namespace margelo::nitro::reactnativeperfstats {
|
|
17
|
+
|
|
18
|
+
using namespace facebook;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The C++ JNI bridge between the C++ struct "MemoryWarningEvent" and the the Kotlin data class "MemoryWarningEvent".
|
|
22
|
+
*/
|
|
23
|
+
struct JMemoryWarningEvent final: public jni::JavaClass<JMemoryWarningEvent> {
|
|
24
|
+
public:
|
|
25
|
+
static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/reactnativeperfstats/MemoryWarningEvent;";
|
|
26
|
+
|
|
27
|
+
public:
|
|
28
|
+
/**
|
|
29
|
+
* Convert this Java/Kotlin-based struct to the C++ struct MemoryWarningEvent by copying all values to C++.
|
|
30
|
+
*/
|
|
31
|
+
[[maybe_unused]]
|
|
32
|
+
[[nodiscard]]
|
|
33
|
+
MemoryWarningEvent toCpp() const {
|
|
34
|
+
static const auto clazz = javaClassStatic();
|
|
35
|
+
static const auto fieldLevel = clazz->getField<JMemoryWarningLevel>("level");
|
|
36
|
+
jni::local_ref<JMemoryWarningLevel> level = this->getFieldValue(fieldLevel);
|
|
37
|
+
static const auto fieldRss = clazz->getField<double>("rss");
|
|
38
|
+
double rss = this->getFieldValue(fieldRss);
|
|
39
|
+
static const auto fieldTimestamp = clazz->getField<double>("timestamp");
|
|
40
|
+
double timestamp = this->getFieldValue(fieldTimestamp);
|
|
41
|
+
return MemoryWarningEvent(
|
|
42
|
+
level->toCpp(),
|
|
43
|
+
rss,
|
|
44
|
+
timestamp
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public:
|
|
49
|
+
/**
|
|
50
|
+
* Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.
|
|
51
|
+
*/
|
|
52
|
+
[[maybe_unused]]
|
|
53
|
+
static jni::local_ref<JMemoryWarningEvent::javaobject> fromCpp(const MemoryWarningEvent& value) {
|
|
54
|
+
using JSignature = JMemoryWarningEvent(jni::alias_ref<JMemoryWarningLevel>, double, double);
|
|
55
|
+
static const auto clazz = javaClassStatic();
|
|
56
|
+
static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
|
|
57
|
+
return create(
|
|
58
|
+
clazz,
|
|
59
|
+
JMemoryWarningLevel::fromCpp(value.level),
|
|
60
|
+
value.rss,
|
|
61
|
+
value.timestamp
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
} // namespace margelo::nitro::reactnativeperfstats
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// JMemoryWarningLevel.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © 2026 Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <fbjni/fbjni.h>
|
|
11
|
+
#include "MemoryWarningLevel.hpp"
|
|
12
|
+
|
|
13
|
+
namespace margelo::nitro::reactnativeperfstats {
|
|
14
|
+
|
|
15
|
+
using namespace facebook;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The C++ JNI bridge between the C++ enum "MemoryWarningLevel" and the the Kotlin enum "MemoryWarningLevel".
|
|
19
|
+
*/
|
|
20
|
+
struct JMemoryWarningLevel final: public jni::JavaClass<JMemoryWarningLevel> {
|
|
21
|
+
public:
|
|
22
|
+
static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/reactnativeperfstats/MemoryWarningLevel;";
|
|
23
|
+
|
|
24
|
+
public:
|
|
25
|
+
/**
|
|
26
|
+
* Convert this Java/Kotlin-based enum to the C++ enum MemoryWarningLevel.
|
|
27
|
+
*/
|
|
28
|
+
[[maybe_unused]]
|
|
29
|
+
[[nodiscard]]
|
|
30
|
+
MemoryWarningLevel toCpp() const {
|
|
31
|
+
static const auto clazz = javaClassStatic();
|
|
32
|
+
static const auto fieldOrdinal = clazz->getField<int>("value");
|
|
33
|
+
int ordinal = this->getFieldValue(fieldOrdinal);
|
|
34
|
+
return static_cast<MemoryWarningLevel>(ordinal);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public:
|
|
38
|
+
/**
|
|
39
|
+
* Create a Java/Kotlin-based enum with the given C++ enum's value.
|
|
40
|
+
*/
|
|
41
|
+
[[maybe_unused]]
|
|
42
|
+
static jni::alias_ref<JMemoryWarningLevel> fromCpp(MemoryWarningLevel value) {
|
|
43
|
+
static const auto clazz = javaClassStatic();
|
|
44
|
+
static const auto fieldLOW = clazz->getStaticField<JMemoryWarningLevel>("LOW");
|
|
45
|
+
static const auto fieldCRITICAL = clazz->getStaticField<JMemoryWarningLevel>("CRITICAL");
|
|
46
|
+
|
|
47
|
+
switch (value) {
|
|
48
|
+
case MemoryWarningLevel::LOW:
|
|
49
|
+
return clazz->getStaticFieldValue(fieldLOW);
|
|
50
|
+
case MemoryWarningLevel::CRITICAL:
|
|
51
|
+
return clazz->getStaticFieldValue(fieldCRITICAL);
|
|
52
|
+
default:
|
|
53
|
+
std::string stringValue = std::to_string(static_cast<int>(value));
|
|
54
|
+
throw std::invalid_argument("Invalid enum value (" + stringValue + "!");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
} // namespace margelo::nitro::reactnativeperfstats
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// Func_void_MemoryWarningEvent.kt
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © 2026 Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
package com.margelo.nitro.reactnativeperfstats
|
|
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 `(event: 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_MemoryWarningEvent: (MemoryWarningEvent) -> 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(event: MemoryWarningEvent): Unit
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Represents the JavaScript callback `(event: 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_MemoryWarningEvent_cxx: Func_void_MemoryWarningEvent {
|
|
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(event: MemoryWarningEvent): Unit
|
|
60
|
+
= invoke_cxx(event)
|
|
61
|
+
|
|
62
|
+
@FastNative
|
|
63
|
+
private external fun invoke_cxx(event: MemoryWarningEvent): Unit
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Represents the JavaScript callback `(event: struct) => void`.
|
|
68
|
+
* This is implemented in Java/Kotlin, via a `(MemoryWarningEvent) -> Unit`.
|
|
69
|
+
* The callback is always coming from native.
|
|
70
|
+
*/
|
|
71
|
+
@DoNotStrip
|
|
72
|
+
@Keep
|
|
73
|
+
@Suppress("ClassName", "RedundantUnitReturnType", "unused")
|
|
74
|
+
class Func_void_MemoryWarningEvent_java(private val function: (MemoryWarningEvent) -> Unit): Func_void_MemoryWarningEvent {
|
|
75
|
+
@DoNotStrip
|
|
76
|
+
@Keep
|
|
77
|
+
override fun invoke(event: MemoryWarningEvent): Unit {
|
|
78
|
+
return this.function(event)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -69,6 +69,23 @@ abstract class HybridReactNativePerfStatsSpec: HybridObject() {
|
|
|
69
69
|
@DoNotStrip
|
|
70
70
|
@Keep
|
|
71
71
|
abstract fun setJsFpsHint(fps: Double): Unit
|
|
72
|
+
|
|
73
|
+
abstract fun addMemoryWarningListener(callback: (event: MemoryWarningEvent) -> Unit): Double
|
|
74
|
+
|
|
75
|
+
@DoNotStrip
|
|
76
|
+
@Keep
|
|
77
|
+
private fun addMemoryWarningListener_cxx(callback: Func_void_MemoryWarningEvent): Double {
|
|
78
|
+
val __result = addMemoryWarningListener(callback)
|
|
79
|
+
return __result
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@DoNotStrip
|
|
83
|
+
@Keep
|
|
84
|
+
abstract fun removeMemoryWarningListener(id: Double): Unit
|
|
85
|
+
|
|
86
|
+
@DoNotStrip
|
|
87
|
+
@Keep
|
|
88
|
+
abstract fun cleanupNativeCaches(): Unit
|
|
72
89
|
|
|
73
90
|
private external fun initHybrid(): HybridData
|
|
74
91
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// MemoryWarningEvent.kt
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © 2026 Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
package com.margelo.nitro.reactnativeperfstats
|
|
9
|
+
|
|
10
|
+
import androidx.annotation.Keep
|
|
11
|
+
import com.facebook.proguard.annotations.DoNotStrip
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Represents the JavaScript object/struct "MemoryWarningEvent".
|
|
16
|
+
*/
|
|
17
|
+
@DoNotStrip
|
|
18
|
+
@Keep
|
|
19
|
+
data class MemoryWarningEvent(
|
|
20
|
+
@DoNotStrip
|
|
21
|
+
@Keep
|
|
22
|
+
val level: MemoryWarningLevel,
|
|
23
|
+
@DoNotStrip
|
|
24
|
+
@Keep
|
|
25
|
+
val rss: Double,
|
|
26
|
+
@DoNotStrip
|
|
27
|
+
@Keep
|
|
28
|
+
val timestamp: Double
|
|
29
|
+
) {
|
|
30
|
+
/* primary constructor */
|
|
31
|
+
|
|
32
|
+
private companion object {
|
|
33
|
+
/**
|
|
34
|
+
* Constructor called from C++
|
|
35
|
+
*/
|
|
36
|
+
@DoNotStrip
|
|
37
|
+
@Keep
|
|
38
|
+
@Suppress("unused")
|
|
39
|
+
@JvmStatic
|
|
40
|
+
private fun fromCpp(level: MemoryWarningLevel, rss: Double, timestamp: Double): MemoryWarningEvent {
|
|
41
|
+
return MemoryWarningEvent(level, rss, timestamp)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// MemoryWarningLevel.kt
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © 2026 Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
package com.margelo.nitro.reactnativeperfstats
|
|
9
|
+
|
|
10
|
+
import androidx.annotation.Keep
|
|
11
|
+
import com.facebook.proguard.annotations.DoNotStrip
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Represents the JavaScript enum/union "MemoryWarningLevel".
|
|
15
|
+
*/
|
|
16
|
+
@DoNotStrip
|
|
17
|
+
@Keep
|
|
18
|
+
enum class MemoryWarningLevel(@DoNotStrip @Keep val value: Int) {
|
|
19
|
+
LOW(0),
|
|
20
|
+
CRITICAL(1);
|
|
21
|
+
}
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
#include <NitroModules/HybridObjectRegistry.hpp>
|
|
17
17
|
|
|
18
18
|
#include "JHybridReactNativePerfStatsSpec.hpp"
|
|
19
|
+
#include "JFunc_void_MemoryWarningEvent.hpp"
|
|
19
20
|
#include <NitroModules/DefaultConstructableObject.hpp>
|
|
20
21
|
|
|
21
22
|
namespace margelo::nitro::reactnativeperfstats {
|
|
@@ -28,6 +29,7 @@ int initialize(JavaVM* vm) {
|
|
|
28
29
|
return facebook::jni::initialize(vm, [] {
|
|
29
30
|
// Register native JNI methods
|
|
30
31
|
margelo::nitro::reactnativeperfstats::JHybridReactNativePerfStatsSpec::registerNatives();
|
|
32
|
+
margelo::nitro::reactnativeperfstats::JFunc_void_MemoryWarningEvent_cxx::registerNatives();
|
|
31
33
|
|
|
32
34
|
// Register Nitro Hybrid Objects
|
|
33
35
|
HybridObjectRegistry::registerHybridObjectConstructor(
|
|
@@ -30,6 +30,14 @@ namespace margelo::nitro::reactnativeperfstats::bridge::swift {
|
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
// pragma MARK: std::function<void(const MemoryWarningEvent& /* event */)>
|
|
34
|
+
Func_void_MemoryWarningEvent create_Func_void_MemoryWarningEvent(void* NON_NULL swiftClosureWrapper) noexcept {
|
|
35
|
+
auto swiftClosure = ReactNativePerfStats::Func_void_MemoryWarningEvent::fromUnsafe(swiftClosureWrapper);
|
|
36
|
+
return [swiftClosure = std::move(swiftClosure)](const MemoryWarningEvent& event) mutable -> void {
|
|
37
|
+
swiftClosure.call(event);
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
33
41
|
// pragma MARK: std::shared_ptr<HybridReactNativePerfStatsSpec>
|
|
34
42
|
std::shared_ptr<HybridReactNativePerfStatsSpec> create_std__shared_ptr_HybridReactNativePerfStatsSpec_(void* NON_NULL swiftUnsafePointer) noexcept {
|
|
35
43
|
ReactNativePerfStats::HybridReactNativePerfStatsSpec_cxx swiftPart = ReactNativePerfStats::HybridReactNativePerfStatsSpec_cxx::fromUnsafe(swiftUnsafePointer);
|