@aguacerowx/react-native 0.0.21 → 0.0.23
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/aguacerowx-react-native.podspec +5 -20
- package/android/build/.transforms/42e9b8fa82d77a1c205db5bf0d0ed519/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/.transforms/c8ab78b63f2cc835ac936d58e29a17ab/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/aguacerowx/reactnative/GridRenderLayer$VertexInfo.dex +0 -0
- package/android/build/.transforms/c8ab78b63f2cc835ac936d58e29a17ab/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/aguacerowx/reactnative/GridRenderLayer.dex +0 -0
- package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
- package/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/raw_fragment_shader.glsl.flat +0 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -1
- package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderLayer$VertexInfo.class +0 -0
- package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderLayer.class +0 -0
- package/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/fragment_shader.glsl +18 -8
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderLayer$VertexInfo.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderLayer.class +0 -0
- package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
- package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer$VertexInfo.class.uniqueId0 +0 -0
- package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer.class.uniqueId1 +0 -0
- package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
- package/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayer.java +8 -1
- package/android/src/main/res/raw/fragment_shader.glsl +18 -8
- package/ios/FragmentUniforms.swift +1 -0
- package/ios/GridRenderLayer.swift +117 -109
- package/ios/GridRenderLayerBridge.swift +11 -3
- package/ios/GridRenderLayerView.h +15 -1
- package/ios/GridRenderLayerView.m +65 -28
- package/ios/Shaders.metal +25 -13
- package/ios/compiled-shaders/Shaders-device.metallib +0 -0
- package/ios/compiled-shaders/Shaders-simulator.metallib +0 -0
- package/lib/commonjs/aguacerowx-react-native.podspec +5 -20
- package/lib/commonjs/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
- package/lib/commonjs/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/raw_fragment_shader.glsl.flat +0 -0
- package/lib/commonjs/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -1
- package/lib/commonjs/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderLayer$VertexInfo.class +0 -0
- package/lib/commonjs/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderLayer.class +0 -0
- package/lib/commonjs/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/fragment_shader.glsl +18 -8
- package/lib/commonjs/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderLayer$VertexInfo.class +0 -0
- package/lib/commonjs/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderLayer.class +0 -0
- package/lib/commonjs/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
- package/lib/commonjs/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer$VertexInfo.class.uniqueId0 +0 -0
- package/lib/commonjs/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer.class.uniqueId1 +0 -0
- package/lib/commonjs/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
- package/lib/commonjs/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayer.java +8 -1
- package/lib/commonjs/android/src/main/res/raw/fragment_shader.glsl +18 -8
- package/lib/commonjs/ios/FragmentUniforms.swift +1 -0
- package/lib/commonjs/ios/GridRenderLayer.swift +117 -109
- package/lib/commonjs/ios/GridRenderLayerBridge.swift +11 -3
- package/lib/commonjs/ios/GridRenderLayerView.h +15 -1
- package/lib/commonjs/ios/GridRenderLayerView.m +65 -28
- package/lib/commonjs/ios/Shaders.metal +25 -13
- package/lib/commonjs/ios/compiled-shaders/Shaders-device.metallib +0 -0
- package/lib/commonjs/ios/compiled-shaders/Shaders-simulator.metallib +0 -0
- package/lib/commonjs/package.json +2 -2
- package/lib/commonjs/scripts/compile-shaders.js.map +1 -1
- package/lib/commonjs/src/WeatherLayerManager.js +50 -5
- package/lib/commonjs/src/WeatherLayerManager.js.map +1 -1
- package/lib/module/aguacerowx-react-native.podspec +5 -20
- package/lib/module/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
- package/lib/module/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/raw_fragment_shader.glsl.flat +0 -0
- package/lib/module/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -1
- package/lib/module/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderLayer$VertexInfo.class +0 -0
- package/lib/module/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderLayer.class +0 -0
- package/lib/module/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/fragment_shader.glsl +18 -8
- package/lib/module/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderLayer$VertexInfo.class +0 -0
- package/lib/module/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderLayer.class +0 -0
- package/lib/module/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
- package/lib/module/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer$VertexInfo.class.uniqueId0 +0 -0
- package/lib/module/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer.class.uniqueId1 +0 -0
- package/lib/module/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
- package/lib/module/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayer.java +8 -1
- package/lib/module/android/src/main/res/raw/fragment_shader.glsl +18 -8
- package/lib/module/ios/FragmentUniforms.swift +1 -0
- package/lib/module/ios/GridRenderLayer.swift +117 -109
- package/lib/module/ios/GridRenderLayerBridge.swift +11 -3
- package/lib/module/ios/GridRenderLayerView.h +15 -1
- package/lib/module/ios/GridRenderLayerView.m +65 -28
- package/lib/module/ios/Shaders.metal +25 -13
- package/lib/module/ios/compiled-shaders/Shaders-device.metallib +0 -0
- package/lib/module/ios/compiled-shaders/Shaders-simulator.metallib +0 -0
- package/lib/module/lib/commonjs/aguacerowx-react-native.podspec +5 -20
- package/lib/module/lib/commonjs/ios/FragmentUniforms.swift +1 -0
- package/lib/module/lib/commonjs/ios/GridRenderLayer.swift +117 -109
- package/lib/module/lib/commonjs/ios/GridRenderLayerBridge.swift +11 -3
- package/lib/module/lib/commonjs/ios/GridRenderLayerView.h +15 -1
- package/lib/module/lib/commonjs/ios/GridRenderLayerView.m +65 -28
- package/lib/module/lib/commonjs/ios/Shaders.metal +25 -13
- package/lib/module/lib/commonjs/ios/compiled-shaders/Shaders-device.metallib +0 -0
- package/lib/module/lib/commonjs/ios/compiled-shaders/Shaders-simulator.metallib +0 -0
- package/lib/module/lib/commonjs/package.json +2 -2
- package/lib/module/lib/commonjs/scripts/compile-shaders.js.map +1 -1
- package/lib/module/lib/commonjs/src/WeatherLayerManager.js +50 -5
- package/lib/module/lib/commonjs/src/WeatherLayerManager.js.map +1 -1
- package/lib/module/package.json +2 -2
- package/lib/module/scripts/compile-shaders.js.map +1 -1
- package/lib/module/src/WeatherLayerManager.js +50 -5
- package/lib/module/src/WeatherLayerManager.js.map +1 -1
- package/lib/typescript/src/WeatherLayerManager.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/WeatherLayerManager.js +208 -165
- package/ios/compiled-shaders/Shaders.metallib +0 -0
- package/lib/commonjs/ios/compiled-shaders/Shaders.metallib +0 -0
- package/lib/module/ios/compiled-shaders/Shaders.metallib +0 -0
- package/lib/module/lib/commonjs/ios/compiled-shaders/Shaders.metallib +0 -0
|
@@ -24,26 +24,11 @@ Pod::Spec.new do |s|
|
|
|
24
24
|
'DEFINES_MODULE' => 'YES'
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
:script => 'echo "🔨 Copying Metal shaders..."
|
|
33
|
-
SHADER_DIR="${PODS_TARGET_SRCROOT}/ios/compiled-shaders"
|
|
34
|
-
METAL_SOURCE="${PODS_TARGET_SRCROOT}/ios/Shaders.metal"
|
|
35
|
-
|
|
36
|
-
if [ -f "$SHADER_DIR/Shaders.metallib" ]; then
|
|
37
|
-
cp -v "$SHADER_DIR/Shaders.metallib" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/" || true
|
|
38
|
-
echo "✅ Pre-compiled Metal shader copied"
|
|
39
|
-
elif [ -f "$METAL_SOURCE" ]; then
|
|
40
|
-
echo "⚠️ No pre-compiled shader found, will compile from source"
|
|
41
|
-
cp -v "$METAL_SOURCE" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/" || true
|
|
42
|
-
else
|
|
43
|
-
echo "❌ No Metal shaders found!"
|
|
44
|
-
fi',
|
|
45
|
-
:execution_position => :before_compile
|
|
46
|
-
}
|
|
27
|
+
# Include both pre-compiled shaders AND source as fallback
|
|
28
|
+
s.resources = [
|
|
29
|
+
'ios/compiled-shaders/Shaders-simulator.metallib',
|
|
30
|
+
'ios/compiled-shaders/Shaders-device.metallib',
|
|
31
|
+
'ios/Shaders.metal'
|
|
47
32
|
]
|
|
48
33
|
|
|
49
34
|
s.source_files = "ios/**/*.{h,m,mm,swift}", "ios/generated/**/*.{h,m,mm,cpp}"
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
#Tue Nov 18 11:28:28 EST 2025
|
|
2
2
|
com.aguacerowx.reactnative.aguacerowx-react-native-main-6\:/raw/fragment_shader.glsl=C\:\\Users\\my41m\\aguacero\\aguacero-sdks\\packages\\react-native\\android\\build\\intermediates\\packaged_res\\debug\\packageDebugResources\\raw\\fragment_shader.glsl
|
|
3
3
|
com.aguacerowx.reactnative.aguacerowx-react-native-main-6\:/raw/vertex_shader.glsl=C\:\\Users\\my41m\\aguacero\\aguacero-sdks\\packages\\react-native\\android\\build\\intermediates\\packaged_res\\debug\\packageDebugResources\\raw\\vertex_shader.glsl
|
|
4
4
|
com.aguacerowx.reactnative.aguacerowx-react-native-main-6\:/raw/debug_vertex_shader.glsl=C\:\\Users\\my41m\\aguacero\\aguacero-sdks\\packages\\react-native\\android\\build\\intermediates\\packaged_res\\debug\\packageDebugResources\\raw\\debug_vertex_shader.glsl
|
|
Binary file
|
|
Binary file
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// packages/react-native/android/src/main/res/raw/fragment_shader.glsl
|
|
2
|
-
|
|
3
1
|
precision highp float;
|
|
4
2
|
varying vec2 v_texCoord;
|
|
5
3
|
|
|
@@ -19,7 +17,8 @@ uniform vec2 u_data_range;
|
|
|
19
17
|
// Rendering parameters
|
|
20
18
|
uniform vec2 u_texture_size;
|
|
21
19
|
uniform int u_smoothing;
|
|
22
|
-
uniform int u_is_ptype; //
|
|
20
|
+
uniform int u_is_ptype; // Flag for ptype variables
|
|
21
|
+
uniform int u_is_mrms; // NEW: Flag for MRMS data
|
|
23
22
|
|
|
24
23
|
// --- HELPER FUNCTIONS ---
|
|
25
24
|
|
|
@@ -49,11 +48,22 @@ float get_value(vec2 coord) {
|
|
|
49
48
|
|
|
50
49
|
// Maps a physical value to a precipitation type category
|
|
51
50
|
float get_ptype_from_physical(float val) {
|
|
52
|
-
if (val < 0.0) return -1.0;
|
|
53
|
-
|
|
54
|
-
if (
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
if (val < 0.0) return -1.0;
|
|
52
|
+
|
|
53
|
+
if (u_is_mrms == 1) {
|
|
54
|
+
// MRMS: 0-100 rain, 100-200 snow, 200-300 freezing rain
|
|
55
|
+
if (val < 100.0) return 0.0;
|
|
56
|
+
if (val < 200.0) return 1.0;
|
|
57
|
+
if (val < 300.0) return 2.0;
|
|
58
|
+
return -1.0;
|
|
59
|
+
} else {
|
|
60
|
+
// Models: 0-100 rain, 100-200 snow, 200-300 freezing rain, 300-400 ice pellets
|
|
61
|
+
if (val < 100.0) return 0.0;
|
|
62
|
+
if (val < 200.0) return 1.0;
|
|
63
|
+
if (val < 300.0) return 2.0;
|
|
64
|
+
if (val < 400.0) return 3.0;
|
|
65
|
+
return -1.0;
|
|
66
|
+
}
|
|
57
67
|
}
|
|
58
68
|
|
|
59
69
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -68,7 +68,8 @@ public class GridRenderLayer implements CustomLayerHost {
|
|
|
68
68
|
private ByteBuffer pendingColormapBuffer = null;
|
|
69
69
|
private FloatBuffer pendingVertexBuffer = null;
|
|
70
70
|
private ShortBuffer pendingIndexBuffer = null;
|
|
71
|
-
|
|
71
|
+
private int uIsMRMS;
|
|
72
|
+
private boolean isMRMS = false;
|
|
72
73
|
|
|
73
74
|
public GridRenderLayer(Context context) {
|
|
74
75
|
this.context = context;
|
|
@@ -123,6 +124,7 @@ public class GridRenderLayer implements CustomLayerHost {
|
|
|
123
124
|
uSmoothing = GLES20.glGetUniformLocation(program, "u_smoothing");
|
|
124
125
|
uScaleType = GLES20.glGetUniformLocation(program, "u_scale_type");
|
|
125
126
|
uIsPtype = GLES20.glGetUniformLocation(program, "u_is_ptype");
|
|
127
|
+
uIsMRMS = GLES20.glGetUniformLocation(program, "u_is_mrms");
|
|
126
128
|
aPosition = GLES20.glGetAttribLocation(program, "a_position");
|
|
127
129
|
aTexCoord = GLES20.glGetAttribLocation(program, "a_texCoord");
|
|
128
130
|
}
|
|
@@ -138,6 +140,10 @@ public class GridRenderLayer implements CustomLayerHost {
|
|
|
138
140
|
Log.d(TAG, "setVariable called. Variable: '" + this.currentVariable + "', isPtype set to: " + this.isPtype);
|
|
139
141
|
}
|
|
140
142
|
|
|
143
|
+
public void setIsMRMS(boolean isMRMS) {
|
|
144
|
+
this.isMRMS = isMRMS;
|
|
145
|
+
Log.d(TAG, "setIsMRMS called with: " + isMRMS);
|
|
146
|
+
}
|
|
141
147
|
|
|
142
148
|
public void clearData() {
|
|
143
149
|
this.isVisible = false;
|
|
@@ -261,6 +267,7 @@ public class GridRenderLayer implements CustomLayerHost {
|
|
|
261
267
|
GLES20.glUniform1i(uSmoothing, smoothingEnabled ? 1 : 0);
|
|
262
268
|
GLES20.glUniform1i(uScaleType, this.scaleType);
|
|
263
269
|
GLES20.glUniform1i(uIsPtype, this.isPtype ? 1 : 0);
|
|
270
|
+
GLES20.glUniform1i(uIsMRMS, this.isMRMS ? 1 : 0);
|
|
264
271
|
|
|
265
272
|
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
|
|
266
273
|
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, dataTextureId);
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// packages/react-native/android/src/main/res/raw/fragment_shader.glsl
|
|
2
|
-
|
|
3
1
|
precision highp float;
|
|
4
2
|
varying vec2 v_texCoord;
|
|
5
3
|
|
|
@@ -19,7 +17,8 @@ uniform vec2 u_data_range;
|
|
|
19
17
|
// Rendering parameters
|
|
20
18
|
uniform vec2 u_texture_size;
|
|
21
19
|
uniform int u_smoothing;
|
|
22
|
-
uniform int u_is_ptype; //
|
|
20
|
+
uniform int u_is_ptype; // Flag for ptype variables
|
|
21
|
+
uniform int u_is_mrms; // NEW: Flag for MRMS data
|
|
23
22
|
|
|
24
23
|
// --- HELPER FUNCTIONS ---
|
|
25
24
|
|
|
@@ -49,11 +48,22 @@ float get_value(vec2 coord) {
|
|
|
49
48
|
|
|
50
49
|
// Maps a physical value to a precipitation type category
|
|
51
50
|
float get_ptype_from_physical(float val) {
|
|
52
|
-
if (val < 0.0) return -1.0;
|
|
53
|
-
|
|
54
|
-
if (
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
if (val < 0.0) return -1.0;
|
|
52
|
+
|
|
53
|
+
if (u_is_mrms == 1) {
|
|
54
|
+
// MRMS: 0-100 rain, 100-200 snow, 200-300 freezing rain
|
|
55
|
+
if (val < 100.0) return 0.0;
|
|
56
|
+
if (val < 200.0) return 1.0;
|
|
57
|
+
if (val < 300.0) return 2.0;
|
|
58
|
+
return -1.0;
|
|
59
|
+
} else {
|
|
60
|
+
// Models: 0-100 rain, 100-200 snow, 200-300 freezing rain, 300-400 ice pellets
|
|
61
|
+
if (val < 100.0) return 0.0;
|
|
62
|
+
if (val < 200.0) return 1.0;
|
|
63
|
+
if (val < 300.0) return 2.0;
|
|
64
|
+
if (val < 400.0) return 3.0;
|
|
65
|
+
return -1.0;
|
|
66
|
+
}
|
|
57
67
|
}
|
|
58
68
|
|
|
59
69
|
|
|
@@ -61,7 +61,8 @@ public class GridRenderLayer: NSObject {
|
|
|
61
61
|
textureSize: SIMD2<Float>(0.0, 0.0),
|
|
62
62
|
smoothing: 1,
|
|
63
63
|
scaleType: 0,
|
|
64
|
-
isPtype: 0
|
|
64
|
+
isPtype: 0,
|
|
65
|
+
isMRMS: 0
|
|
65
66
|
)
|
|
66
67
|
private var isVisible = false
|
|
67
68
|
private var pendingActiveFrameKey: String?
|
|
@@ -75,15 +76,13 @@ public class GridRenderLayer: NSObject {
|
|
|
75
76
|
let nx: Float
|
|
76
77
|
let ny: Float
|
|
77
78
|
let filePath: String
|
|
78
|
-
let originalScale: Float
|
|
79
|
-
let originalOffset: Float
|
|
79
|
+
let originalScale: Float
|
|
80
|
+
let originalOffset: Float
|
|
80
81
|
}
|
|
81
82
|
private var frameCache: [String: FrameMetadata] = [:]
|
|
82
|
-
private let
|
|
83
|
+
private let frameProcessingQueue = DispatchQueue(label: "com.aguacero.frame-processing", qos: .userInitiated, attributes: .concurrent)
|
|
84
|
+
private let semaphore = DispatchSemaphore(value: 8)
|
|
83
85
|
|
|
84
|
-
// The concurrent queue for background preloading all other frames.
|
|
85
|
-
private let backgroundTextureQueue = DispatchQueue(label: "com.aguacero.texture-processing-background", qos: .utility, attributes: .concurrent)
|
|
86
|
-
// MARK: - Initializer
|
|
87
86
|
private struct VertexInfo {
|
|
88
87
|
var mercX: Float
|
|
89
88
|
var mercY: Float
|
|
@@ -125,6 +124,13 @@ public class GridRenderLayer: NSObject {
|
|
|
125
124
|
// ADD THIS: Force the map to repaint to show the smoothing change immediately.
|
|
126
125
|
NotificationCenter.default.post(name: NSNotification.Name("TriggerMapRepaint"), object: nil)
|
|
127
126
|
}
|
|
127
|
+
|
|
128
|
+
@objc(setIsMRMSWithIsMRMS:)
|
|
129
|
+
public func setIsMRMS(isMRMS: Bool) {
|
|
130
|
+
self.uniforms.isMRMS = isMRMS ? 1 : 0
|
|
131
|
+
print("🟢 [GridRenderLayer] Set isMRMS: \(isMRMS)")
|
|
132
|
+
NotificationCenter.default.post(name: NSNotification.Name("TriggerMapRepaint"), object: nil)
|
|
133
|
+
}
|
|
128
134
|
|
|
129
135
|
// ADD THIS METHOD
|
|
130
136
|
@objc(setVariableWithVariable:)
|
|
@@ -182,11 +188,10 @@ public class GridRenderLayer: NSObject {
|
|
|
182
188
|
self.colormapTexture = texture
|
|
183
189
|
}
|
|
184
190
|
|
|
185
|
-
@objc(clearGpuCache)
|
|
191
|
+
@objc(clearGpuCache)
|
|
186
192
|
public func clearGpuCache() {
|
|
187
|
-
|
|
188
|
-
self
|
|
189
|
-
print("🟢 [GridRenderLayer] GPU frame cache cleared.")
|
|
193
|
+
frameProcessingQueue.async { [weak self] in
|
|
194
|
+
self?.frameCache.removeAll()
|
|
190
195
|
}
|
|
191
196
|
}
|
|
192
197
|
|
|
@@ -219,42 +224,39 @@ public class GridRenderLayer: NSObject {
|
|
|
219
224
|
}
|
|
220
225
|
|
|
221
226
|
private func updateInspectorCache(filePath: String, nx: Int, ny: Int, scale: Float, offset: Float, missing: Float, scaleType: Int) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
return
|
|
235
|
-
}
|
|
236
|
-
print("💡 [Inspector] 3. Successfully decompressed data.")
|
|
237
|
-
|
|
238
|
-
let reconstructedData = self.reconstructData(decompressedDeltas: decompressedDeltas)
|
|
239
|
-
print("💡 [Inspector] 4. Reconstructed data with \(reconstructedData.count) bytes.")
|
|
240
|
-
|
|
241
|
-
self.inspectorCache.update(
|
|
242
|
-
data: reconstructedData,
|
|
243
|
-
nx: nx,
|
|
244
|
-
ny: ny,
|
|
245
|
-
scale: scale,
|
|
246
|
-
offset: offset,
|
|
247
|
-
missing: missing,
|
|
248
|
-
scaleType: scaleType
|
|
249
|
-
)
|
|
250
|
-
|
|
251
|
-
print("💡 [Inspector] 5. ✅ Cache updated successfully with scaleType=\(scaleType)")
|
|
227
|
+
// This is now called from frameProcessingQueue, so we can do the work synchronously
|
|
228
|
+
guard let fileData = try? Data(contentsOf: URL(fileURLWithPath: filePath)) else {
|
|
229
|
+
print("❌ [Inspector] FATAL: Failed to read file data from path.")
|
|
230
|
+
self.inspectorCache.clear()
|
|
231
|
+
return
|
|
232
|
+
}
|
|
233
|
+
print("💡 [Inspector] 2. Successfully read \(fileData.count) bytes from file.")
|
|
234
|
+
|
|
235
|
+
guard let decompressedDeltas = self.decompressZstd(data: fileData) else {
|
|
236
|
+
print("❌ [Inspector] FATAL: Failed to decompress Zstd data.")
|
|
237
|
+
self.inspectorCache.clear()
|
|
238
|
+
return
|
|
252
239
|
}
|
|
240
|
+
print("💡 [Inspector] 3. Successfully decompressed data.")
|
|
241
|
+
|
|
242
|
+
let reconstructedData = self.reconstructData(decompressedDeltas: decompressedDeltas)
|
|
243
|
+
print("💡 [Inspector] 4. Reconstructed data with \(reconstructedData.count) bytes.")
|
|
244
|
+
|
|
245
|
+
self.inspectorCache.update(
|
|
246
|
+
data: reconstructedData,
|
|
247
|
+
nx: nx,
|
|
248
|
+
ny: ny,
|
|
249
|
+
scale: scale,
|
|
250
|
+
offset: offset,
|
|
251
|
+
missing: missing,
|
|
252
|
+
scaleType: scaleType
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
print("💡 [Inspector] 5. ✅ Cache updated successfully with scaleType=\(scaleType)")
|
|
253
256
|
}
|
|
254
257
|
|
|
255
258
|
@objc(setActiveFrameWithCacheKey:)
|
|
256
259
|
public func setActiveFrame(cacheKey: String) {
|
|
257
|
-
// First, check if the frame is already in the cache.
|
|
258
260
|
if let frame = frameCache[cacheKey] {
|
|
259
261
|
print("⚡️ [GridRenderLayer] Cache HIT for key: \(cacheKey). Swapping texture.")
|
|
260
262
|
|
|
@@ -266,42 +268,51 @@ public class GridRenderLayer: NSObject {
|
|
|
266
268
|
self.uniforms.scaleType = Int32(frame.scaleType)
|
|
267
269
|
|
|
268
270
|
self.isVisible = true
|
|
269
|
-
self.pendingActiveFrameKey = nil
|
|
271
|
+
self.pendingActiveFrameKey = nil
|
|
270
272
|
NotificationCenter.default.post(name: NSNotification.Name("TriggerMapRepaint"), object: nil)
|
|
271
273
|
|
|
272
|
-
//
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
274
|
+
// Update inspector cache on background thread since we already have the frame data
|
|
275
|
+
frameProcessingQueue.async { [weak self] in
|
|
276
|
+
self?.updateInspectorCache(
|
|
277
|
+
filePath: frame.filePath,
|
|
278
|
+
nx: Int(frame.nx),
|
|
279
|
+
ny: Int(frame.ny),
|
|
280
|
+
scale: frame.scale,
|
|
281
|
+
offset: frame.offset,
|
|
282
|
+
missing: frame.missing,
|
|
283
|
+
scaleType: frame.scaleType
|
|
284
|
+
)
|
|
285
|
+
}
|
|
283
286
|
|
|
284
287
|
} else {
|
|
285
|
-
// --- FIX: If it's a miss, store the key and wait for it to be primed. ---
|
|
286
288
|
print("⚠️ [GridRenderLayer] setActiveFrame cache MISS for key: \(cacheKey). Will apply when primed.")
|
|
287
289
|
self.pendingActiveFrameKey = cacheKey
|
|
288
|
-
self.isVisible = false
|
|
290
|
+
self.isVisible = false
|
|
289
291
|
}
|
|
290
292
|
}
|
|
291
|
-
|
|
292
293
|
@objc(primeGpuCacheWithFrameInfo:)
|
|
293
294
|
public func primeGpuCache(frameInfo: [String: [String: Any]]) {
|
|
294
295
|
let group = DispatchGroup()
|
|
295
296
|
|
|
296
297
|
if (frameInfo.count > 1) {
|
|
297
|
-
print("🟡 [GridRenderLayer] Starting to prime \(frameInfo.count) textures
|
|
298
|
+
print("🟡 [GridRenderLayer] Starting to prime \(frameInfo.count) textures with concurrent processing...")
|
|
298
299
|
}
|
|
299
300
|
|
|
300
301
|
for (cacheKey, info) in frameInfo {
|
|
301
302
|
group.enter()
|
|
302
303
|
|
|
303
|
-
|
|
304
|
-
|
|
304
|
+
frameProcessingQueue.async { [weak self] in
|
|
305
|
+
guard let self = self else {
|
|
306
|
+
group.leave()
|
|
307
|
+
return
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
self.semaphore.wait()
|
|
311
|
+
defer {
|
|
312
|
+
self.semaphore.signal()
|
|
313
|
+
group.leave()
|
|
314
|
+
}
|
|
315
|
+
|
|
305
316
|
if self.frameCache[cacheKey] != nil { return }
|
|
306
317
|
|
|
307
318
|
guard let filePath = info["filePath"] as? String,
|
|
@@ -311,16 +322,25 @@ public class GridRenderLayer: NSObject {
|
|
|
311
322
|
let offset = info["offset"] as? NSNumber,
|
|
312
323
|
let missing = info["missing"] as? NSNumber,
|
|
313
324
|
let scaleTypeStr = info["scaleType"] as? String,
|
|
314
|
-
let originalScale = info["originalScale"] as? NSNumber,
|
|
315
|
-
let originalOffset = info["originalOffset"] as? NSNumber
|
|
316
|
-
let fileData = try? Data(contentsOf: URL(fileURLWithPath: filePath)),
|
|
317
|
-
let finalTextureBytes = self.processRawData(fileData: fileData)
|
|
325
|
+
let originalScale = info["originalScale"] as? NSNumber,
|
|
326
|
+
let originalOffset = info["originalOffset"] as? NSNumber
|
|
318
327
|
else {
|
|
319
328
|
print("❌ [GridRenderLayer] Skipping prime for \(cacheKey), missing data.")
|
|
320
329
|
return
|
|
321
330
|
}
|
|
322
331
|
|
|
323
|
-
|
|
332
|
+
// Process data OFF the main thread
|
|
333
|
+
guard let fileData = try? Data(contentsOf: URL(fileURLWithPath: filePath)),
|
|
334
|
+
let finalTextureBytes = self.processRawData(fileData: fileData)
|
|
335
|
+
else {
|
|
336
|
+
print("❌ [GridRenderLayer] Failed to process data for \(cacheKey)")
|
|
337
|
+
return
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// Create texture on main thread
|
|
341
|
+
DispatchQueue.main.async { [weak self] in
|
|
342
|
+
guard let self = self else { return }
|
|
343
|
+
|
|
324
344
|
if let texture = self.createTextureFromBytes(bytes: finalTextureBytes, nx: nx.intValue, ny: ny.intValue) {
|
|
325
345
|
let metadata = FrameMetadata(
|
|
326
346
|
texture: texture,
|
|
@@ -331,11 +351,10 @@ public class GridRenderLayer: NSObject {
|
|
|
331
351
|
nx: nx.floatValue,
|
|
332
352
|
ny: ny.floatValue,
|
|
333
353
|
filePath: filePath,
|
|
334
|
-
originalScale: originalScale.floatValue,
|
|
335
|
-
originalOffset: originalOffset.floatValue
|
|
354
|
+
originalScale: originalScale.floatValue,
|
|
355
|
+
originalOffset: originalOffset.floatValue
|
|
336
356
|
)
|
|
337
357
|
self.frameCache[cacheKey] = metadata
|
|
338
|
-
print(" ✅ [GridRenderLayer] Primed and cached frame for key: \(cacheKey)")
|
|
339
358
|
|
|
340
359
|
if let pendingKey = self.pendingActiveFrameKey, pendingKey == cacheKey {
|
|
341
360
|
print("👍 [GridRenderLayer] The pending frame is now ready. Activating it.")
|
|
@@ -348,7 +367,7 @@ public class GridRenderLayer: NSObject {
|
|
|
348
367
|
|
|
349
368
|
group.notify(queue: .main) {
|
|
350
369
|
if (frameInfo.count > 1) {
|
|
351
|
-
print("🎉 [GridRenderLayer] All \(frameInfo.count) frames have been processed and cached
|
|
370
|
+
print("🎉 [GridRenderLayer] All \(frameInfo.count) frames have been processed and cached.")
|
|
352
371
|
}
|
|
353
372
|
}
|
|
354
373
|
}
|
|
@@ -356,19 +375,20 @@ public class GridRenderLayer: NSObject {
|
|
|
356
375
|
@objc public func updateDataTexture(data: String, nx: NSNumber, ny: NSNumber, scale: NSNumber, offset: NSNumber, missing: NSNumber, scaleType: String) {
|
|
357
376
|
print("🚀 [GridRenderLayer] FAST LANE: updateDataTexture called for initial frame...")
|
|
358
377
|
|
|
359
|
-
let filePath = data
|
|
378
|
+
let filePath = data
|
|
360
379
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
guard let fileData = try? Data(contentsOf: URL(fileURLWithPath: filePath)) else { return }
|
|
380
|
+
frameProcessingQueue.async { [weak self] in
|
|
381
|
+
guard let self = self else { return }
|
|
364
382
|
|
|
365
|
-
guard let
|
|
383
|
+
guard let fileData = try? Data(contentsOf: URL(fileURLWithPath: filePath)),
|
|
384
|
+
let finalTextureBytes = self.processRawData(fileData: fileData)
|
|
385
|
+
else {
|
|
366
386
|
print("❌ [GridRenderLayer] FAST LANE: Failed to process initial frame data.")
|
|
367
387
|
return
|
|
368
388
|
}
|
|
369
389
|
|
|
370
|
-
DispatchQueue.main.async {
|
|
371
|
-
guard let texture = self.createTextureFromBytes(bytes: finalTextureBytes, nx: nx.intValue, ny: ny.intValue) else {
|
|
390
|
+
DispatchQueue.main.async { [weak self] in
|
|
391
|
+
guard let self = self, let texture = self.createTextureFromBytes(bytes: finalTextureBytes, nx: nx.intValue, ny: ny.intValue) else {
|
|
372
392
|
return
|
|
373
393
|
}
|
|
374
394
|
|
|
@@ -383,8 +403,6 @@ public class GridRenderLayer: NSObject {
|
|
|
383
403
|
print("✅ [GridRenderLayer] FAST LANE: Initial frame processed and displayed.")
|
|
384
404
|
NotificationCenter.default.post(name: NSNotification.Name("TriggerMapRepaint"), object: nil)
|
|
385
405
|
|
|
386
|
-
// --- ADD THIS ---
|
|
387
|
-
// Update the inspector cache for the initial frame.
|
|
388
406
|
self.updateInspectorCache(
|
|
389
407
|
filePath: filePath,
|
|
390
408
|
nx: nx.intValue,
|
|
@@ -399,9 +417,6 @@ public class GridRenderLayer: NSObject {
|
|
|
399
417
|
}
|
|
400
418
|
|
|
401
419
|
@objc public func updateGeometry(corners: [String: Any], gridDef: [String: Any]) {
|
|
402
|
-
print("🟢 [GridRenderLayer] updateGeometry called")
|
|
403
|
-
print(" device: \(self.device != nil)")
|
|
404
|
-
|
|
405
420
|
guard self.device != nil else {
|
|
406
421
|
print("⚠️ [GridRenderLayer] Device not ready yet, storing geometry for later")
|
|
407
422
|
pendingGeometryUpdate = (corners: corners, gridDef: gridDef)
|
|
@@ -423,8 +438,6 @@ public class GridRenderLayer: NSObject {
|
|
|
423
438
|
return
|
|
424
439
|
}
|
|
425
440
|
|
|
426
|
-
print(" ✅ Generated \(vertices.count/4) vertices, \(indices.count/3) triangles")
|
|
427
|
-
|
|
428
441
|
self.indexCount = indices.count
|
|
429
442
|
|
|
430
443
|
DispatchQueue.main.async {
|
|
@@ -438,7 +451,6 @@ public class GridRenderLayer: NSObject {
|
|
|
438
451
|
print(" indexBuffer: \(self.indexBuffer != nil)")
|
|
439
452
|
print(" indexCount: \(self.indexCount)")
|
|
440
453
|
|
|
441
|
-
// TRIGGER A REPAINT - ADD THIS:
|
|
442
454
|
NotificationCenter.default.post(name: NSNotification.Name("TriggerMapRepaint"), object: nil)
|
|
443
455
|
}
|
|
444
456
|
}
|
|
@@ -610,11 +622,11 @@ public class GridRenderLayer: NSObject {
|
|
|
610
622
|
|
|
611
623
|
private func lccToLonLat(i: Double, j: Double, gridDef: [String: Any]) -> (lon: Double, lat: Double)? {
|
|
612
624
|
guard let projParams = gridDef["proj_params"] as? [String: Any],
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
625
|
+
let lat_0 = (projParams["lat_0"] as? NSNumber)?.doubleValue,
|
|
626
|
+
let lon_0 = (projParams["lon_0"] as? NSNumber)?.doubleValue,
|
|
627
|
+
let lat_1 = (projParams["lat_1"] as? NSNumber)?.doubleValue,
|
|
628
|
+
let lat_2 = (projParams["lat_2"] as? NSNumber)?.doubleValue,
|
|
629
|
+
let r_earth = (projParams["R"] as? NSNumber)?.doubleValue else {
|
|
618
630
|
print("❌ [LCC Geometry] Failed to extract LCC parameters.")
|
|
619
631
|
return nil
|
|
620
632
|
}
|
|
@@ -628,10 +640,9 @@ public class GridRenderLayer: NSObject {
|
|
|
628
640
|
let lat0_rad = lat_0 * toRad
|
|
629
641
|
let lon0_rad = lon_0 * toRad
|
|
630
642
|
|
|
631
|
-
// Calculate cone constant (n) using two standard parallels
|
|
632
643
|
let n: Double
|
|
633
644
|
if abs(lat_1 - lat_2) < 1e-10 {
|
|
634
|
-
n = sin(lat1_rad)
|
|
645
|
+
n = sin(lat1_rad)
|
|
635
646
|
} else {
|
|
636
647
|
n = log(cos(lat1_rad) / cos(lat2_rad)) / log(tan(π/4.0 + lat2_rad/2.0) / tan(π/4.0 + lat1_rad/2.0))
|
|
637
648
|
}
|
|
@@ -639,7 +650,6 @@ public class GridRenderLayer: NSObject {
|
|
|
639
650
|
let F = cos(lat1_rad) * pow(tan(π/4.0 + lat1_rad/2.0), n) / n
|
|
640
651
|
let rho_0 = r_earth * F * pow(tan(π/4.0 + lat0_rad/2.0), -n)
|
|
641
652
|
|
|
642
|
-
// i, j are the x, y projection coordinates
|
|
643
653
|
let x = i
|
|
644
654
|
let y = j
|
|
645
655
|
|
|
@@ -665,11 +675,16 @@ public class GridRenderLayer: NSObject {
|
|
|
665
675
|
|
|
666
676
|
private func generateGeometryData(gridDef: [String: Any], vertices: inout [Float], indices: inout [UInt16]) {
|
|
667
677
|
guard let gridParams = gridDef["grid_params"] as? [String: Any] else {
|
|
678
|
+
print("❌ [generateGeometryData] No grid_params found")
|
|
668
679
|
return
|
|
669
680
|
}
|
|
670
681
|
|
|
671
|
-
//
|
|
672
|
-
|
|
682
|
+
// Check grid type
|
|
683
|
+
let isGFS = isGFSType(gridParams: gridParams)
|
|
684
|
+
let isLCC = isLCCType(gridDef: gridDef)
|
|
685
|
+
|
|
686
|
+
if isGFS {
|
|
687
|
+
// GFS path remains unchanged
|
|
673
688
|
let subdivisions = 120
|
|
674
689
|
let verticesPerRow = (subdivisions * 3) + 1
|
|
675
690
|
let TILE_SIZE: Double = 512.0
|
|
@@ -701,12 +716,16 @@ public class GridRenderLayer: NSObject {
|
|
|
701
716
|
}
|
|
702
717
|
return
|
|
703
718
|
}
|
|
704
|
-
|
|
719
|
+
|
|
720
|
+
if isLCC {
|
|
721
|
+
print("🗺️ [generateGeometryData] Using LCC projection path")
|
|
705
722
|
generateLCCGeometry(gridDef: gridDef, vertices: &vertices, indices: &indices)
|
|
706
723
|
return
|
|
707
724
|
}
|
|
708
725
|
|
|
709
|
-
// Generic Grid Path (MRMS, etc.)
|
|
726
|
+
// Generic Grid Path (MRMS, regional models, etc.)
|
|
727
|
+
print("🗺️ [generateGeometryData] Using generic regional grid path")
|
|
728
|
+
|
|
710
729
|
let nx = gridParams["nx"] as? Int ?? 0
|
|
711
730
|
let ny = gridParams["ny"] as? Int ?? 0
|
|
712
731
|
let lon_first = gridParams["lon_first"] as? Double ?? 0.0
|
|
@@ -715,6 +734,7 @@ public class GridRenderLayer: NSObject {
|
|
|
715
734
|
let dy = gridParams["dy_degrees"] as? Double ?? 0.0
|
|
716
735
|
let lon_last = gridParams["lon_last"] as? Double ?? (lon_first + Double(nx - 1) * dx)
|
|
717
736
|
let lat_last = gridParams["lat_last"] as? Double ?? (lat_first + Double(ny - 1) * dy)
|
|
737
|
+
|
|
718
738
|
let lat_span = lat_last - lat_first
|
|
719
739
|
let isSouthToNorth = lat_span > 0
|
|
720
740
|
|
|
@@ -727,14 +747,12 @@ public class GridRenderLayer: NSObject {
|
|
|
727
747
|
let verticesPerRow = subdivisions_x + 1
|
|
728
748
|
let TILE_SIZE: Double = 512.0
|
|
729
749
|
|
|
730
|
-
|
|
731
|
-
let worldCopies = (data_lon_range > 300) ? [-1, 0, 1] : [0] // Only wrap if nearly global
|
|
750
|
+
let worldCopies = (data_lon_range > 300) ? [-1, 0, 1] : [0]
|
|
732
751
|
|
|
733
752
|
for world_copy in worldCopies {
|
|
734
753
|
let vertexStartIndex = UInt16(vertices.count / 4)
|
|
735
754
|
let lon_offset = Double(world_copy) * 360.0
|
|
736
755
|
|
|
737
|
-
// Generate vertices for this world copy
|
|
738
756
|
for row in 0...subdivisions_y {
|
|
739
757
|
for col in 0...subdivisions_x {
|
|
740
758
|
let v_interp = Float(row) / Float(subdivisions_y)
|
|
@@ -759,7 +777,6 @@ public class GridRenderLayer: NSObject {
|
|
|
759
777
|
}
|
|
760
778
|
}
|
|
761
779
|
|
|
762
|
-
// Generate indices (same as before)
|
|
763
780
|
for row in 0..<UInt16(subdivisions_y) {
|
|
764
781
|
for col in 0..<UInt16(subdivisions_x) {
|
|
765
782
|
let tl = vertexStartIndex + row * UInt16(verticesPerRow) + col
|
|
@@ -925,9 +942,6 @@ internal func internalRenderingWillStart(_ metalDevice: MTLDevice, colorPixelFor
|
|
|
925
942
|
return
|
|
926
943
|
}
|
|
927
944
|
|
|
928
|
-
print("✅ [GridRenderLayer] Past guards, about to render!")
|
|
929
|
-
print(" 🎨 About to draw \(indexCount) indices (\(indexCount/3) triangles)")
|
|
930
|
-
|
|
931
945
|
let needsLinear = (uniforms.smoothing != 0)
|
|
932
946
|
if isDataSamplerLinear != needsLinear {
|
|
933
947
|
let samplerDesc = MTLSamplerDescriptor()
|
|
@@ -956,9 +970,6 @@ internal func internalRenderingWillStart(_ metalDevice: MTLDevice, colorPixelFor
|
|
|
956
970
|
SIMD4<Float>(floatArray[12], floatArray[13], floatArray[14], floatArray[15])
|
|
957
971
|
)
|
|
958
972
|
|
|
959
|
-
print(" 📐 MVP matrix after scaling: \(mvp)")
|
|
960
|
-
print(" 📍 Zoom: \(zoom), Scale factor: \(scale)")
|
|
961
|
-
|
|
962
973
|
// Add depth state
|
|
963
974
|
let depthStencilDescriptor = MTLDepthStencilDescriptor()
|
|
964
975
|
depthStencilDescriptor.depthCompareFunction = .always
|
|
@@ -977,12 +988,9 @@ internal func internalRenderingWillStart(_ metalDevice: MTLDevice, colorPixelFor
|
|
|
977
988
|
encoder.setFragmentSamplerState(dataSamplerState, index: 0)
|
|
978
989
|
encoder.setFragmentSamplerState(colormapSamplerState, index: 1)
|
|
979
990
|
|
|
980
|
-
print(" 🎨 Drawing indexed primitives now...")
|
|
981
991
|
encoder.drawIndexedPrimitives(type: .triangle, indexCount: indexCount, indexType: .uint16, indexBuffer: indices, indexBufferOffset: 0)
|
|
982
|
-
print(" ✅ Draw call completed")
|
|
983
992
|
|
|
984
993
|
encoder.endEncoding()
|
|
985
|
-
print(" ✅ Encoder ended")
|
|
986
994
|
}
|
|
987
995
|
|
|
988
996
|
internal func internalRenderingWillEnd() {
|