react-native-smooth-clip-view 0.2.8 → 0.3.0
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/README.md +86 -21
- package/android/CMakeLists.txt +7 -0
- package/android/build.gradle +14 -2
- package/android/proguard-rules.pro +3 -3
- package/android/src/main/cpp/SmoothClipAndroid.h +10 -0
- package/android/src/main/cpp/SmoothClipBindings.cpp +896 -6
- package/android/src/main/cpp/SmoothClipRegistry.cpp +1067 -46
- package/android/src/main/cpp/SmoothClipTrace.h +25 -0
- package/android/src/main/java/com/smoothclipview/ClipGeometryNormalizer.kt +265 -0
- package/android/src/main/java/com/smoothclipview/SmoothClipBindings.kt +21 -0
- package/android/src/main/java/com/smoothclipview/SmoothClipModule.kt +283 -0
- package/android/src/main/java/com/smoothclipview/SmoothClipView.kt +385 -24
- package/android/src/main/java/com/smoothclipview/SmoothClipViewManager.kt +138 -24
- package/cpp/SmoothClipAnimationCurve.h +151 -122
- package/cpp/SmoothClipRegistry.h +102 -4
- package/cpp/SmoothClipSharedGeometry.h +146 -7
- package/cpp/SmoothClipVelocityTracker.h +13 -9
- package/ios/SmoothClipGeometry.h +184 -6
- package/ios/SmoothClipRegistry.mm +1033 -25
- package/ios/SmoothClipRegistrySnapshot.h +13 -0
- package/ios/SmoothClipTurboModule.cpp +857 -2
- package/ios/SmoothClipTurboModule.h +310 -0
- package/ios/SmoothClipView.mm +714 -183
- package/ios/SmoothClipViewRegistry.h +1 -0
- package/ios/reactnativesmoothclipview.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- package/ios/reactnativesmoothclipview.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/lib/module/NativeSmoothClipModule.js.map +1 -1
- package/lib/module/SmoothClipView.ios.js +22 -6
- package/lib/module/SmoothClipView.ios.js.map +1 -1
- package/lib/module/SmoothClipView.js +1 -46
- package/lib/module/SmoothClipView.js.map +1 -1
- package/lib/module/SmoothClipViewNativeComponent.ts +27 -1
- package/lib/module/capabilities.js +4 -0
- package/lib/module/capabilities.js.map +1 -0
- package/lib/module/capabilities.native.js +36 -0
- package/lib/module/capabilities.native.js.map +1 -0
- package/lib/module/capabilityTypes.js +11 -0
- package/lib/module/capabilityTypes.js.map +1 -0
- package/lib/module/driverState.js +0 -28
- package/lib/module/driverState.js.map +1 -1
- package/lib/module/drivers.js +1 -281
- package/lib/module/drivers.js.map +1 -1
- package/lib/module/drivers.native.js +340 -75
- package/lib/module/drivers.native.js.map +1 -1
- package/lib/module/geometry.js +147 -17
- package/lib/module/geometry.js.map +1 -1
- package/lib/module/groupDriverTypes.js +4 -0
- package/lib/module/groupDriverTypes.js.map +1 -0
- package/lib/module/groupDrivers.android.js +4 -0
- package/lib/module/groupDrivers.android.js.map +1 -0
- package/lib/module/groupDrivers.ios.js +4 -0
- package/lib/module/groupDrivers.ios.js.map +1 -0
- package/lib/module/groupDrivers.js +4 -0
- package/lib/module/groupDrivers.js.map +1 -0
- package/lib/module/groupDrivers.native.js +799 -0
- package/lib/module/groupDrivers.native.js.map +1 -0
- package/lib/module/index.js +3 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/presentationProtocol.js +15 -0
- package/lib/module/presentationProtocol.js.map +1 -0
- package/lib/typescript/src/NativeSmoothClipModule.d.ts +25 -0
- package/lib/typescript/src/NativeSmoothClipModule.d.ts.map +1 -1
- package/lib/typescript/src/SmoothClipView.d.ts +2 -10
- package/lib/typescript/src/SmoothClipView.d.ts.map +1 -1
- package/lib/typescript/src/SmoothClipView.ios.d.ts +133 -2
- package/lib/typescript/src/SmoothClipView.ios.d.ts.map +1 -1
- package/lib/typescript/src/SmoothClipViewNativeComponent.d.ts +8 -0
- package/lib/typescript/src/SmoothClipViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/capabilities.d.ts +3 -0
- package/lib/typescript/src/capabilities.d.ts.map +1 -0
- package/lib/typescript/src/capabilities.native.d.ts +3 -0
- package/lib/typescript/src/capabilities.native.d.ts.map +1 -0
- package/lib/typescript/src/capabilityTypes.d.ts +10 -0
- package/lib/typescript/src/capabilityTypes.d.ts.map +1 -0
- package/lib/typescript/src/driverState.d.ts +1 -6
- package/lib/typescript/src/driverState.d.ts.map +1 -1
- package/lib/typescript/src/driverTypes.d.ts +39 -11
- package/lib/typescript/src/driverTypes.d.ts.map +1 -1
- package/lib/typescript/src/drivers.d.ts +2 -4
- package/lib/typescript/src/drivers.d.ts.map +1 -1
- package/lib/typescript/src/drivers.native.d.ts.map +1 -1
- package/lib/typescript/src/geometry.d.ts +36 -2
- package/lib/typescript/src/geometry.d.ts.map +1 -1
- package/lib/typescript/src/groupDriverTypes.d.ts +66 -0
- package/lib/typescript/src/groupDriverTypes.d.ts.map +1 -0
- package/lib/typescript/src/groupDrivers.android.d.ts +2 -0
- package/lib/typescript/src/groupDrivers.android.d.ts.map +1 -0
- package/lib/typescript/src/groupDrivers.d.ts +2 -0
- package/lib/typescript/src/groupDrivers.d.ts.map +1 -0
- package/lib/typescript/src/groupDrivers.ios.d.ts +2 -0
- package/lib/typescript/src/groupDrivers.ios.d.ts.map +1 -0
- package/lib/typescript/src/groupDrivers.native.d.ts +4 -0
- package/lib/typescript/src/groupDrivers.native.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +6 -3
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/presentationProtocol.d.ts +4 -0
- package/lib/typescript/src/presentationProtocol.d.ts.map +1 -0
- package/package.json +10 -11
- package/src/NativeSmoothClipModule.ts +275 -0
- package/src/SmoothClipView.ios.tsx +30 -11
- package/src/SmoothClipView.tsx +2 -76
- package/src/SmoothClipViewNativeComponent.ts +27 -1
- package/src/capabilities.native.ts +69 -0
- package/src/capabilities.ts +2 -0
- package/src/capabilityTypes.ts +17 -0
- package/src/driverState.ts +1 -41
- package/src/driverTypes.ts +56 -11
- package/src/drivers.native.ts +921 -151
- package/src/drivers.ts +2 -423
- package/src/geometry.ts +231 -27
- package/src/groupDriverTypes.ts +117 -0
- package/src/groupDrivers.android.ts +1 -0
- package/src/groupDrivers.ios.ts +1 -0
- package/src/groupDrivers.native.ts +1189 -0
- package/src/groupDrivers.ts +1 -0
- package/src/index.ts +30 -2
- package/src/presentationProtocol.ts +28 -0
- package/lib/module/SmoothClipView.web.js +0 -54
- package/lib/module/SmoothClipView.web.js.map +0 -1
- package/lib/module/index.web.js +0 -8
- package/lib/module/index.web.js.map +0 -1
- package/lib/module/webClipPath.js +0 -25
- package/lib/module/webClipPath.js.map +0 -1
- package/lib/typescript/src/SmoothClipView.web.d.ts +0 -10
- package/lib/typescript/src/SmoothClipView.web.d.ts.map +0 -1
- package/lib/typescript/src/index.web.d.ts +0 -9
- package/lib/typescript/src/index.web.d.ts.map +0 -1
- package/lib/typescript/src/webClipPath.d.ts +0 -7
- package/lib/typescript/src/webClipPath.d.ts.map +0 -1
- package/src/SmoothClipView.web.tsx +0 -66
- package/src/index.web.ts +0 -23
- package/src/webClipPath.ts +0 -30
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
#include <fbjni/fbjni.h>
|
|
6
6
|
#include <jsi/jsi.h>
|
|
7
7
|
|
|
8
|
+
#include <algorithm>
|
|
8
9
|
#include <cmath>
|
|
9
10
|
#include <limits>
|
|
10
11
|
#include <memory>
|
|
@@ -32,14 +33,40 @@ bool validDriverId(double value) {
|
|
|
32
33
|
value <= kMaxSafeJavaScriptInteger && std::floor(value) == value;
|
|
33
34
|
}
|
|
34
35
|
|
|
36
|
+
bool validCurve(double value) {
|
|
37
|
+
return std::isfinite(value) && std::floor(value) == value &&
|
|
38
|
+
(value == static_cast<double>(ClipCurve::Circular) ||
|
|
39
|
+
value == static_cast<double>(ClipCurve::Continuous));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
bool validRadiusOverride(double value) {
|
|
43
|
+
return std::isfinite(value) || std::isnan(value);
|
|
44
|
+
}
|
|
45
|
+
|
|
35
46
|
bool finitePresentation(const Presentation &presentation) {
|
|
36
47
|
return std::isfinite(presentation.clip.x) &&
|
|
37
48
|
std::isfinite(presentation.clip.y) &&
|
|
38
49
|
std::isfinite(presentation.clip.width) &&
|
|
39
50
|
std::isfinite(presentation.clip.height) &&
|
|
40
51
|
std::isfinite(presentation.clip.radius) &&
|
|
52
|
+
validRadiusOverride(presentation.clip.topLeftRadius) &&
|
|
53
|
+
validRadiusOverride(presentation.clip.topRightRadius) &&
|
|
54
|
+
validRadiusOverride(presentation.clip.bottomRightRadius) &&
|
|
55
|
+
validRadiusOverride(presentation.clip.bottomLeftRadius) &&
|
|
56
|
+
(presentation.clip.curve == ClipCurve::Circular ||
|
|
57
|
+
presentation.clip.curve == ClipCurve::Continuous) &&
|
|
41
58
|
std::isfinite(presentation.contentTranslateX) &&
|
|
42
|
-
std::isfinite(presentation.contentTranslateY)
|
|
59
|
+
std::isfinite(presentation.contentTranslateY) &&
|
|
60
|
+
std::isfinite(presentation.contentScale) &&
|
|
61
|
+
presentation.contentScale > 0;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
bool finiteV2Presentation(const Presentation &presentation) {
|
|
65
|
+
return finitePresentation(presentation) &&
|
|
66
|
+
std::isfinite(presentation.clip.topLeftRadius) &&
|
|
67
|
+
std::isfinite(presentation.clip.topRightRadius) &&
|
|
68
|
+
std::isfinite(presentation.clip.bottomRightRadius) &&
|
|
69
|
+
std::isfinite(presentation.clip.bottomLeftRadius);
|
|
43
70
|
}
|
|
44
71
|
|
|
45
72
|
bool boolArg(const Value *args, size_t count, size_t index) {
|
|
@@ -69,6 +96,72 @@ Presentation presentationFromArgs(const Value *args, size_t offset) {
|
|
|
69
96
|
args[offset + 6].asNumber()};
|
|
70
97
|
}
|
|
71
98
|
|
|
99
|
+
Presentation presentationV2FromArgs(const Value *args, size_t offset) {
|
|
100
|
+
Geometry geometry{
|
|
101
|
+
args[offset].asNumber(),
|
|
102
|
+
args[offset + 1].asNumber(),
|
|
103
|
+
args[offset + 2].asNumber(),
|
|
104
|
+
args[offset + 3].asNumber(),
|
|
105
|
+
0.0};
|
|
106
|
+
geometry.topLeftRadius = args[offset + 4].asNumber();
|
|
107
|
+
geometry.topRightRadius = args[offset + 5].asNumber();
|
|
108
|
+
geometry.bottomRightRadius = args[offset + 6].asNumber();
|
|
109
|
+
geometry.bottomLeftRadius = args[offset + 7].asNumber();
|
|
110
|
+
const double curveCode = args[offset + 8].asNumber();
|
|
111
|
+
geometry.curve = curveCode == static_cast<double>(ClipCurve::Continuous)
|
|
112
|
+
? ClipCurve::Continuous
|
|
113
|
+
: curveCode == static_cast<double>(ClipCurve::Circular)
|
|
114
|
+
? ClipCurve::Circular
|
|
115
|
+
: static_cast<ClipCurve>(-1);
|
|
116
|
+
if (geometry.topLeftRadius == geometry.topRightRadius &&
|
|
117
|
+
geometry.topLeftRadius == geometry.bottomRightRadius &&
|
|
118
|
+
geometry.topLeftRadius == geometry.bottomLeftRadius) {
|
|
119
|
+
geometry.radius = geometry.topLeftRadius;
|
|
120
|
+
}
|
|
121
|
+
return Presentation{
|
|
122
|
+
geometry,
|
|
123
|
+
args[offset + 9].asNumber(),
|
|
124
|
+
args[offset + 10].asNumber(),
|
|
125
|
+
args[offset + 11].asNumber()};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
Presentation presentationV2FromArray(
|
|
129
|
+
Runtime &runtime,
|
|
130
|
+
const Array &values,
|
|
131
|
+
size_t offset) {
|
|
132
|
+
Geometry geometry{
|
|
133
|
+
values.getValueAtIndex(runtime, offset).asNumber(),
|
|
134
|
+
values.getValueAtIndex(runtime, offset + 1).asNumber(),
|
|
135
|
+
values.getValueAtIndex(runtime, offset + 2).asNumber(),
|
|
136
|
+
values.getValueAtIndex(runtime, offset + 3).asNumber(),
|
|
137
|
+
0.0};
|
|
138
|
+
geometry.topLeftRadius =
|
|
139
|
+
values.getValueAtIndex(runtime, offset + 4).asNumber();
|
|
140
|
+
geometry.topRightRadius =
|
|
141
|
+
values.getValueAtIndex(runtime, offset + 5).asNumber();
|
|
142
|
+
geometry.bottomRightRadius =
|
|
143
|
+
values.getValueAtIndex(runtime, offset + 6).asNumber();
|
|
144
|
+
geometry.bottomLeftRadius =
|
|
145
|
+
values.getValueAtIndex(runtime, offset + 7).asNumber();
|
|
146
|
+
const double curveCode =
|
|
147
|
+
values.getValueAtIndex(runtime, offset + 8).asNumber();
|
|
148
|
+
geometry.curve = curveCode == static_cast<double>(ClipCurve::Continuous)
|
|
149
|
+
? ClipCurve::Continuous
|
|
150
|
+
: curveCode == static_cast<double>(ClipCurve::Circular)
|
|
151
|
+
? ClipCurve::Circular
|
|
152
|
+
: static_cast<ClipCurve>(-1);
|
|
153
|
+
if (geometry.topLeftRadius == geometry.topRightRadius &&
|
|
154
|
+
geometry.topLeftRadius == geometry.bottomRightRadius &&
|
|
155
|
+
geometry.topLeftRadius == geometry.bottomLeftRadius) {
|
|
156
|
+
geometry.radius = geometry.topLeftRadius;
|
|
157
|
+
}
|
|
158
|
+
return Presentation{
|
|
159
|
+
geometry,
|
|
160
|
+
values.getValueAtIndex(runtime, offset + 9).asNumber(),
|
|
161
|
+
values.getValueAtIndex(runtime, offset + 10).asNumber(),
|
|
162
|
+
values.getValueAtIndex(runtime, offset + 11).asNumber()};
|
|
163
|
+
}
|
|
164
|
+
|
|
72
165
|
Array presentationArray(Runtime &runtime, const Presentation &presentation) {
|
|
73
166
|
Array result(runtime, 7);
|
|
74
167
|
result.setValueAtIndex(runtime, 0, presentation.clip.x);
|
|
@@ -81,6 +174,40 @@ Array presentationArray(Runtime &runtime, const Presentation &presentation) {
|
|
|
81
174
|
return result;
|
|
82
175
|
}
|
|
83
176
|
|
|
177
|
+
Array presentationArrayV2(Runtime &runtime, const Presentation &presentation) {
|
|
178
|
+
Array result(runtime, 12);
|
|
179
|
+
result.setValueAtIndex(runtime, 0, presentation.clip.x);
|
|
180
|
+
result.setValueAtIndex(runtime, 1, presentation.clip.y);
|
|
181
|
+
result.setValueAtIndex(runtime, 2, presentation.clip.width);
|
|
182
|
+
result.setValueAtIndex(runtime, 3, presentation.clip.height);
|
|
183
|
+
result.setValueAtIndex(
|
|
184
|
+
runtime,
|
|
185
|
+
4,
|
|
186
|
+
SmoothClipResolvedRadius(
|
|
187
|
+
presentation.clip.topLeftRadius, presentation.clip.radius));
|
|
188
|
+
result.setValueAtIndex(
|
|
189
|
+
runtime,
|
|
190
|
+
5,
|
|
191
|
+
SmoothClipResolvedRadius(
|
|
192
|
+
presentation.clip.topRightRadius, presentation.clip.radius));
|
|
193
|
+
result.setValueAtIndex(
|
|
194
|
+
runtime,
|
|
195
|
+
6,
|
|
196
|
+
SmoothClipResolvedRadius(
|
|
197
|
+
presentation.clip.bottomRightRadius, presentation.clip.radius));
|
|
198
|
+
result.setValueAtIndex(
|
|
199
|
+
runtime,
|
|
200
|
+
7,
|
|
201
|
+
SmoothClipResolvedRadius(
|
|
202
|
+
presentation.clip.bottomLeftRadius, presentation.clip.radius));
|
|
203
|
+
result.setValueAtIndex(
|
|
204
|
+
runtime, 8, static_cast<double>(presentation.clip.curve));
|
|
205
|
+
result.setValueAtIndex(runtime, 9, presentation.contentTranslateX);
|
|
206
|
+
result.setValueAtIndex(runtime, 10, presentation.contentTranslateY);
|
|
207
|
+
result.setValueAtIndex(runtime, 11, presentation.contentScale);
|
|
208
|
+
return result;
|
|
209
|
+
}
|
|
210
|
+
|
|
84
211
|
Array cancelResultArray(
|
|
85
212
|
Runtime &runtime,
|
|
86
213
|
bool handled,
|
|
@@ -98,10 +225,206 @@ Array cancelResultArray(
|
|
|
98
225
|
return result;
|
|
99
226
|
}
|
|
100
227
|
|
|
228
|
+
Array cancelResultArrayV2(
|
|
229
|
+
Runtime &runtime,
|
|
230
|
+
bool handled,
|
|
231
|
+
const Presentation &presentation) {
|
|
232
|
+
Array result(runtime, 13);
|
|
233
|
+
result.setValueAtIndex(runtime, 0, handled ? 1.0 : 0.0);
|
|
234
|
+
result.setValueAtIndex(runtime, 1, presentation.clip.x);
|
|
235
|
+
result.setValueAtIndex(runtime, 2, presentation.clip.y);
|
|
236
|
+
result.setValueAtIndex(runtime, 3, presentation.clip.width);
|
|
237
|
+
result.setValueAtIndex(runtime, 4, presentation.clip.height);
|
|
238
|
+
result.setValueAtIndex(
|
|
239
|
+
runtime,
|
|
240
|
+
5,
|
|
241
|
+
SmoothClipResolvedRadius(
|
|
242
|
+
presentation.clip.topLeftRadius, presentation.clip.radius));
|
|
243
|
+
result.setValueAtIndex(
|
|
244
|
+
runtime,
|
|
245
|
+
6,
|
|
246
|
+
SmoothClipResolvedRadius(
|
|
247
|
+
presentation.clip.topRightRadius, presentation.clip.radius));
|
|
248
|
+
result.setValueAtIndex(
|
|
249
|
+
runtime,
|
|
250
|
+
7,
|
|
251
|
+
SmoothClipResolvedRadius(
|
|
252
|
+
presentation.clip.bottomRightRadius, presentation.clip.radius));
|
|
253
|
+
result.setValueAtIndex(
|
|
254
|
+
runtime,
|
|
255
|
+
8,
|
|
256
|
+
SmoothClipResolvedRadius(
|
|
257
|
+
presentation.clip.bottomLeftRadius, presentation.clip.radius));
|
|
258
|
+
result.setValueAtIndex(
|
|
259
|
+
runtime, 9, static_cast<double>(presentation.clip.curve));
|
|
260
|
+
result.setValueAtIndex(runtime, 10, presentation.contentTranslateX);
|
|
261
|
+
result.setValueAtIndex(runtime, 11, presentation.contentTranslateY);
|
|
262
|
+
result.setValueAtIndex(runtime, 12, presentation.contentScale);
|
|
263
|
+
return result;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
Array snapshotsArrayV2(
|
|
267
|
+
Runtime &runtime,
|
|
268
|
+
const std::vector<DriverSnapshot> &snapshots) {
|
|
269
|
+
Array result(runtime, snapshots.size() * 13);
|
|
270
|
+
size_t offset = 0;
|
|
271
|
+
for (const DriverSnapshot &snapshot : snapshots) {
|
|
272
|
+
result.setValueAtIndex(runtime, offset++, snapshot.ready ? 1.0 : 0.0);
|
|
273
|
+
const Presentation &presentation = snapshot.presentation;
|
|
274
|
+
result.setValueAtIndex(runtime, offset++, presentation.clip.x);
|
|
275
|
+
result.setValueAtIndex(runtime, offset++, presentation.clip.y);
|
|
276
|
+
result.setValueAtIndex(runtime, offset++, presentation.clip.width);
|
|
277
|
+
result.setValueAtIndex(runtime, offset++, presentation.clip.height);
|
|
278
|
+
result.setValueAtIndex(
|
|
279
|
+
runtime,
|
|
280
|
+
offset++,
|
|
281
|
+
SmoothClipResolvedRadius(
|
|
282
|
+
presentation.clip.topLeftRadius, presentation.clip.radius));
|
|
283
|
+
result.setValueAtIndex(
|
|
284
|
+
runtime,
|
|
285
|
+
offset++,
|
|
286
|
+
SmoothClipResolvedRadius(
|
|
287
|
+
presentation.clip.topRightRadius, presentation.clip.radius));
|
|
288
|
+
result.setValueAtIndex(
|
|
289
|
+
runtime,
|
|
290
|
+
offset++,
|
|
291
|
+
SmoothClipResolvedRadius(
|
|
292
|
+
presentation.clip.bottomRightRadius, presentation.clip.radius));
|
|
293
|
+
result.setValueAtIndex(
|
|
294
|
+
runtime,
|
|
295
|
+
offset++,
|
|
296
|
+
SmoothClipResolvedRadius(
|
|
297
|
+
presentation.clip.bottomLeftRadius, presentation.clip.radius));
|
|
298
|
+
result.setValueAtIndex(
|
|
299
|
+
runtime, offset++, static_cast<double>(presentation.clip.curve));
|
|
300
|
+
result.setValueAtIndex(runtime, offset++, presentation.contentTranslateX);
|
|
301
|
+
result.setValueAtIndex(runtime, offset++, presentation.contentTranslateY);
|
|
302
|
+
result.setValueAtIndex(runtime, offset++, presentation.contentScale);
|
|
303
|
+
}
|
|
304
|
+
return result;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
bool validSuspensionPolicy(double value) {
|
|
308
|
+
return value == static_cast<double>(GroupSuspensionPolicy::Pause) ||
|
|
309
|
+
value == static_cast<double>(GroupSuspensionPolicy::Finish);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
std::vector<uint64_t> driverIdsFromArray(Runtime &runtime, const Array &values) {
|
|
313
|
+
std::vector<uint64_t> driverIds;
|
|
314
|
+
const size_t length = values.size(runtime);
|
|
315
|
+
driverIds.reserve(length);
|
|
316
|
+
for (size_t index = 0; index < length; index += 1) {
|
|
317
|
+
const double value = values.getValueAtIndex(runtime, index).asNumber();
|
|
318
|
+
if (!validDriverId(value) ||
|
|
319
|
+
std::find(driverIds.begin(), driverIds.end(),
|
|
320
|
+
static_cast<uint64_t>(value)) != driverIds.end()) {
|
|
321
|
+
return {};
|
|
322
|
+
}
|
|
323
|
+
driverIds.push_back(static_cast<uint64_t>(value));
|
|
324
|
+
}
|
|
325
|
+
return driverIds;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
bool parseGroupMotionEntries(
|
|
329
|
+
Runtime &runtime,
|
|
330
|
+
const Array &values,
|
|
331
|
+
std::vector<GroupMotionEntry> &entries) {
|
|
332
|
+
const size_t length = values.size(runtime);
|
|
333
|
+
if (length < 26 || length % 26 != 0) return false;
|
|
334
|
+
entries.reserve(length / 26);
|
|
335
|
+
for (size_t index = 0; index < length; index += 26) {
|
|
336
|
+
const double driverId = values.getValueAtIndex(runtime, index).asNumber();
|
|
337
|
+
const double hasFromValue =
|
|
338
|
+
values.getValueAtIndex(runtime, index + 1).asNumber();
|
|
339
|
+
const double fromCurve =
|
|
340
|
+
values.getValueAtIndex(runtime, index + 10).asNumber();
|
|
341
|
+
const double targetCurve =
|
|
342
|
+
values.getValueAtIndex(runtime, index + 22).asNumber();
|
|
343
|
+
const Presentation from =
|
|
344
|
+
presentationV2FromArray(runtime, values, index + 2);
|
|
345
|
+
const Presentation target =
|
|
346
|
+
presentationV2FromArray(runtime, values, index + 14);
|
|
347
|
+
if (!validDriverId(driverId) ||
|
|
348
|
+
(hasFromValue != 0.0 && hasFromValue != 1.0) ||
|
|
349
|
+
!validCurve(fromCurve) || !validCurve(targetCurve) ||
|
|
350
|
+
!finiteV2Presentation(from) || !finiteV2Presentation(target)) {
|
|
351
|
+
entries.clear();
|
|
352
|
+
return false;
|
|
353
|
+
}
|
|
354
|
+
entries.push_back(
|
|
355
|
+
{static_cast<uint64_t>(driverId), hasFromValue == 1.0, from, target, {}});
|
|
356
|
+
}
|
|
357
|
+
return true;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
bool parseGroupKeyframeEntries(
|
|
361
|
+
Runtime &runtime,
|
|
362
|
+
const Array &values,
|
|
363
|
+
std::vector<GroupMotionEntry> &entries) {
|
|
364
|
+
const size_t length = values.size(runtime);
|
|
365
|
+
size_t index = 0;
|
|
366
|
+
while (index < length) {
|
|
367
|
+
if (length - index < 27) return false;
|
|
368
|
+
const double driverId = values.getValueAtIndex(runtime, index).asNumber();
|
|
369
|
+
const double hasFromValue =
|
|
370
|
+
values.getValueAtIndex(runtime, index + 1).asNumber();
|
|
371
|
+
const double fromCurve =
|
|
372
|
+
values.getValueAtIndex(runtime, index + 10).asNumber();
|
|
373
|
+
const double targetCurve =
|
|
374
|
+
values.getValueAtIndex(runtime, index + 22).asNumber();
|
|
375
|
+
const double frameCountValue =
|
|
376
|
+
values.getValueAtIndex(runtime, index + 26).asNumber();
|
|
377
|
+
const Presentation from =
|
|
378
|
+
presentationV2FromArray(runtime, values, index + 2);
|
|
379
|
+
const Presentation target =
|
|
380
|
+
presentationV2FromArray(runtime, values, index + 14);
|
|
381
|
+
if (!validDriverId(driverId) ||
|
|
382
|
+
(hasFromValue != 0.0 && hasFromValue != 1.0) ||
|
|
383
|
+
!validCurve(fromCurve) || !validCurve(targetCurve) ||
|
|
384
|
+
!finiteV2Presentation(from) || !finiteV2Presentation(target) ||
|
|
385
|
+
!std::isfinite(frameCountValue) || frameCountValue < 2 ||
|
|
386
|
+
std::floor(frameCountValue) != frameCountValue) {
|
|
387
|
+
return false;
|
|
388
|
+
}
|
|
389
|
+
const size_t frameCount = static_cast<size_t>(frameCountValue);
|
|
390
|
+
index += 27;
|
|
391
|
+
if (frameCount > (length - index) / 13) return false;
|
|
392
|
+
std::vector<Keyframe> keyframes;
|
|
393
|
+
keyframes.reserve(frameCount);
|
|
394
|
+
double previousOffset = -1;
|
|
395
|
+
for (size_t frameIndex = 0; frameIndex < frameCount; frameIndex += 1) {
|
|
396
|
+
const double offset = values.getValueAtIndex(runtime, index).asNumber();
|
|
397
|
+
const double curve =
|
|
398
|
+
values.getValueAtIndex(runtime, index + 9).asNumber();
|
|
399
|
+
const Presentation presentation =
|
|
400
|
+
presentationV2FromArray(runtime, values, index + 1);
|
|
401
|
+
if (!std::isfinite(offset) || offset < 0 || offset > 1 ||
|
|
402
|
+
offset <= previousOffset || !validCurve(curve) ||
|
|
403
|
+
!finiteV2Presentation(presentation)) {
|
|
404
|
+
return false;
|
|
405
|
+
}
|
|
406
|
+
previousOffset = offset;
|
|
407
|
+
keyframes.push_back({offset, presentation});
|
|
408
|
+
index += 13;
|
|
409
|
+
}
|
|
410
|
+
if (keyframes.front().offset != 0 || keyframes.back().offset != 1) {
|
|
411
|
+
return false;
|
|
412
|
+
}
|
|
413
|
+
entries.push_back({
|
|
414
|
+
static_cast<uint64_t>(driverId),
|
|
415
|
+
hasFromValue == 1.0,
|
|
416
|
+
from,
|
|
417
|
+
target,
|
|
418
|
+
std::move(keyframes)});
|
|
419
|
+
}
|
|
420
|
+
return !entries.empty();
|
|
421
|
+
}
|
|
422
|
+
|
|
101
423
|
struct BindingsState {
|
|
102
424
|
Runtime *runtime = nullptr;
|
|
103
425
|
std::shared_ptr<CallInvoker> callInvoker;
|
|
104
426
|
std::unordered_map<int32_t, std::shared_ptr<Function>> listeners;
|
|
427
|
+
std::unordered_map<int32_t, std::shared_ptr<Function>> groupListeners;
|
|
105
428
|
int32_t nextListenerId = 0;
|
|
106
429
|
};
|
|
107
430
|
|
|
@@ -137,6 +460,7 @@ void installBindings(
|
|
|
137
460
|
// against — the new one; the TurboModule invalidate hook releases them
|
|
138
461
|
// while their runtime is still alive, and this is the safety net.
|
|
139
462
|
state->listeners.clear();
|
|
463
|
+
state->groupListeners.clear();
|
|
140
464
|
state->runtime = &runtime;
|
|
141
465
|
state->callInvoker = callInvoker;
|
|
142
466
|
|
|
@@ -163,20 +487,268 @@ void installBindings(
|
|
|
163
487
|
});
|
|
164
488
|
});
|
|
165
489
|
|
|
490
|
+
setGroupCompletionCallback(
|
|
491
|
+
state.get(),
|
|
492
|
+
[state](
|
|
493
|
+
uint64_t controllerId,
|
|
494
|
+
int32_t groupId,
|
|
495
|
+
bool finished,
|
|
496
|
+
std::vector<uint64_t> driverIds) {
|
|
497
|
+
auto invoker = state->callInvoker;
|
|
498
|
+
if (!invoker) return;
|
|
499
|
+
invoker->invokeAsync(
|
|
500
|
+
[state, controllerId, groupId, finished,
|
|
501
|
+
driverIds = std::move(driverIds)]() {
|
|
502
|
+
if (state->runtime == nullptr) return;
|
|
503
|
+
Runtime &rt = *state->runtime;
|
|
504
|
+
std::vector<std::shared_ptr<Function>> snapshot;
|
|
505
|
+
snapshot.reserve(state->groupListeners.size());
|
|
506
|
+
for (const auto &entry : state->groupListeners) {
|
|
507
|
+
snapshot.push_back(entry.second);
|
|
508
|
+
}
|
|
509
|
+
for (const auto &listener : snapshot) {
|
|
510
|
+
Object result(rt);
|
|
511
|
+
result.setProperty(
|
|
512
|
+
rt, "controllerId", static_cast<double>(controllerId));
|
|
513
|
+
result.setProperty(rt, "groupId", groupId);
|
|
514
|
+
result.setProperty(rt, "finished", finished);
|
|
515
|
+
Array ids(rt, driverIds.size());
|
|
516
|
+
for (size_t index = 0; index < driverIds.size(); index += 1) {
|
|
517
|
+
ids.setValueAtIndex(
|
|
518
|
+
rt, index, static_cast<double>(driverIds[index]));
|
|
519
|
+
}
|
|
520
|
+
result.setProperty(rt, "driverIds", std::move(ids));
|
|
521
|
+
listener->call(rt, std::move(result));
|
|
522
|
+
}
|
|
523
|
+
});
|
|
524
|
+
});
|
|
525
|
+
|
|
166
526
|
Object bindings(runtime);
|
|
167
527
|
|
|
168
528
|
setHostFunction(
|
|
169
|
-
runtime, bindings, "
|
|
529
|
+
runtime, bindings, "getPresentationProtocolVersion", 0,
|
|
530
|
+
[](Runtime &, const Value &, const Value *, size_t) -> Value {
|
|
531
|
+
return Value(2);
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
setHostFunction(
|
|
535
|
+
runtime, bindings, "supportsAutonomousComplexPathAnimation", 0,
|
|
536
|
+
[](Runtime &, const Value &, const Value *, size_t) -> Value {
|
|
537
|
+
// Static complex clipping is available. Autonomous complex-path
|
|
538
|
+
// animation is deliberately gated off until physical-device sampling
|
|
539
|
+
// proves the release tolerance and frame-time requirements.
|
|
540
|
+
return Value(false);
|
|
541
|
+
});
|
|
542
|
+
|
|
543
|
+
setHostFunction(
|
|
544
|
+
runtime, bindings, "beginGroupInteractionV2", 1,
|
|
545
|
+
[](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
|
|
546
|
+
if (count < 1 || !args[0].isObject() ||
|
|
547
|
+
!args[0].getObject(rt).isArray(rt)) {
|
|
548
|
+
return Array(rt, 0);
|
|
549
|
+
}
|
|
550
|
+
Array values = args[0].getObject(rt).getArray(rt);
|
|
551
|
+
const std::vector<uint64_t> driverIds = driverIdsFromArray(rt, values);
|
|
552
|
+
if (driverIds.empty()) return Array(rt, 0);
|
|
553
|
+
return snapshotsArrayV2(rt, beginGroupInteraction(driverIds));
|
|
554
|
+
});
|
|
555
|
+
|
|
556
|
+
setHostFunction(
|
|
557
|
+
runtime, bindings, "snapshotGroupV2", 1,
|
|
558
|
+
[](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
|
|
559
|
+
if (count < 1 || !args[0].isObject() ||
|
|
560
|
+
!args[0].getObject(rt).isArray(rt)) {
|
|
561
|
+
return Array(rt, 0);
|
|
562
|
+
}
|
|
563
|
+
Array values = args[0].getObject(rt).getArray(rt);
|
|
564
|
+
const std::vector<uint64_t> driverIds = driverIdsFromArray(rt, values);
|
|
565
|
+
if (driverIds.empty()) return Array(rt, 0);
|
|
566
|
+
return snapshotsArrayV2(rt, snapshotGroup(driverIds));
|
|
567
|
+
});
|
|
568
|
+
|
|
569
|
+
setHostFunction(
|
|
570
|
+
runtime, bindings, "setClipPresentationBatchV2", 1,
|
|
571
|
+
[](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
|
|
572
|
+
if (count < 1 || !args[0].isObject() ||
|
|
573
|
+
!args[0].getObject(rt).isArray(rt)) {
|
|
574
|
+
return Value(false);
|
|
575
|
+
}
|
|
576
|
+
Array values = args[0].getObject(rt).getArray(rt);
|
|
577
|
+
const size_t length = values.size(rt);
|
|
578
|
+
if (length < 13 || length % 13 != 0) return Value(false);
|
|
579
|
+
std::vector<BatchEntry> entries;
|
|
580
|
+
entries.reserve(length / 13);
|
|
581
|
+
for (size_t index = 0; index < length; index += 13) {
|
|
582
|
+
const double driverId =
|
|
583
|
+
values.getValueAtIndex(rt, index).asNumber();
|
|
584
|
+
const double curve =
|
|
585
|
+
values.getValueAtIndex(rt, index + 9).asNumber();
|
|
586
|
+
const Presentation presentation =
|
|
587
|
+
presentationV2FromArray(rt, values, index + 1);
|
|
588
|
+
if (!validDriverId(driverId) || !validCurve(curve) ||
|
|
589
|
+
!finiteV2Presentation(presentation)) {
|
|
590
|
+
return Value(false);
|
|
591
|
+
}
|
|
592
|
+
entries.push_back(
|
|
593
|
+
{static_cast<uint64_t>(driverId), presentation});
|
|
594
|
+
}
|
|
595
|
+
return Value(setPresentationBatch(entries));
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
setHostFunction(
|
|
599
|
+
runtime, bindings, "animateTimingGroupV2", 10,
|
|
600
|
+
[](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
|
|
601
|
+
if (count < 9 || !args[1].isObject() ||
|
|
602
|
+
!args[1].getObject(rt).isArray(rt)) {
|
|
603
|
+
return Value(0);
|
|
604
|
+
}
|
|
605
|
+
const double controllerId = args[0].asNumber();
|
|
606
|
+
Array values = args[1].getObject(rt).getArray(rt);
|
|
607
|
+
std::vector<GroupMotionEntry> entries;
|
|
608
|
+
const TimingAnimation animation{
|
|
609
|
+
args[2].asNumber(), args[3].asNumber(), args[4].asNumber(),
|
|
610
|
+
args[5].asNumber(), args[6].asNumber(),
|
|
611
|
+
static_cast<int32_t>(args[7].asNumber())};
|
|
612
|
+
const double suspension = args[8].asNumber();
|
|
613
|
+
if (!validDriverId(controllerId) ||
|
|
614
|
+
!parseGroupMotionEntries(rt, values, entries) ||
|
|
615
|
+
!std::isfinite(animation.durationMs) ||
|
|
616
|
+
!std::isfinite(animation.controlPoint1X) ||
|
|
617
|
+
!std::isfinite(animation.controlPoint1Y) ||
|
|
618
|
+
!std::isfinite(animation.controlPoint2X) ||
|
|
619
|
+
!std::isfinite(animation.controlPoint2Y) ||
|
|
620
|
+
!validSuspensionPolicy(suspension)) {
|
|
621
|
+
return Value(0);
|
|
622
|
+
}
|
|
623
|
+
return Value(animateTimingGroup(
|
|
624
|
+
static_cast<uint64_t>(controllerId),
|
|
625
|
+
std::move(entries),
|
|
626
|
+
animation,
|
|
627
|
+
static_cast<GroupSuspensionPolicy>(
|
|
628
|
+
static_cast<int32_t>(suspension)),
|
|
629
|
+
startStampArg(args, count, 9)));
|
|
630
|
+
});
|
|
631
|
+
|
|
632
|
+
setHostFunction(
|
|
633
|
+
runtime, bindings, "animateSpringGroupV2", 10,
|
|
634
|
+
[](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
|
|
635
|
+
if (count < 9 || !args[1].isObject() ||
|
|
636
|
+
!args[1].getObject(rt).isArray(rt)) {
|
|
637
|
+
return Value(0);
|
|
638
|
+
}
|
|
639
|
+
const double controllerId = args[0].asNumber();
|
|
640
|
+
Array values = args[1].getObject(rt).getArray(rt);
|
|
641
|
+
std::vector<GroupMotionEntry> entries;
|
|
642
|
+
const SpringAnimation animation{
|
|
643
|
+
args[2].asNumber(), args[3].asNumber(), args[4].asNumber(),
|
|
644
|
+
args[5].asNumber(), boolArg(args, count, 6),
|
|
645
|
+
static_cast<int32_t>(args[7].asNumber())};
|
|
646
|
+
const double suspension = args[8].asNumber();
|
|
647
|
+
if (!validDriverId(controllerId) ||
|
|
648
|
+
!parseGroupMotionEntries(rt, values, entries) ||
|
|
649
|
+
!std::isfinite(animation.mass) ||
|
|
650
|
+
!std::isfinite(animation.stiffness) ||
|
|
651
|
+
!std::isfinite(animation.damping) ||
|
|
652
|
+
!std::isfinite(animation.initialVelocity) || animation.mass <= 0 ||
|
|
653
|
+
animation.stiffness <= 0 || animation.damping < 0 ||
|
|
654
|
+
!validSuspensionPolicy(suspension)) {
|
|
655
|
+
return Value(0);
|
|
656
|
+
}
|
|
657
|
+
return Value(animateSpringGroup(
|
|
658
|
+
static_cast<uint64_t>(controllerId),
|
|
659
|
+
std::move(entries),
|
|
660
|
+
animation,
|
|
661
|
+
static_cast<GroupSuspensionPolicy>(
|
|
662
|
+
static_cast<int32_t>(suspension)),
|
|
663
|
+
startStampArg(args, count, 9)));
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
setHostFunction(
|
|
667
|
+
runtime, bindings, "animateKeyframesGroupV2", 6,
|
|
668
|
+
[](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
|
|
669
|
+
if (count < 5 || !args[1].isObject() ||
|
|
670
|
+
!args[1].getObject(rt).isArray(rt)) {
|
|
671
|
+
return Value(0);
|
|
672
|
+
}
|
|
673
|
+
const double controllerId = args[0].asNumber();
|
|
674
|
+
Array values = args[1].getObject(rt).getArray(rt);
|
|
675
|
+
std::vector<GroupMotionEntry> entries;
|
|
676
|
+
const double durationMs = args[2].asNumber();
|
|
677
|
+
const int32_t reduceMotion = static_cast<int32_t>(args[3].asNumber());
|
|
678
|
+
const double suspension = args[4].asNumber();
|
|
679
|
+
if (!validDriverId(controllerId) ||
|
|
680
|
+
!parseGroupKeyframeEntries(rt, values, entries) ||
|
|
681
|
+
!std::isfinite(durationMs) ||
|
|
682
|
+
!validSuspensionPolicy(suspension)) {
|
|
683
|
+
return Value(0);
|
|
684
|
+
}
|
|
685
|
+
return Value(animateKeyframesGroup(
|
|
686
|
+
static_cast<uint64_t>(controllerId),
|
|
687
|
+
std::move(entries),
|
|
688
|
+
durationMs,
|
|
689
|
+
reduceMotion,
|
|
690
|
+
static_cast<GroupSuspensionPolicy>(
|
|
691
|
+
static_cast<int32_t>(suspension)),
|
|
692
|
+
startStampArg(args, count, 5)));
|
|
693
|
+
});
|
|
694
|
+
|
|
695
|
+
setHostFunction(
|
|
696
|
+
runtime, bindings, "cancelAnimationGroupV2", 2,
|
|
697
|
+
[](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
|
|
698
|
+
if (count < 2 || !args[0].isNumber() || !args[1].isNumber()) {
|
|
699
|
+
return Array(rt, 0);
|
|
700
|
+
}
|
|
701
|
+
const double groupId = args[0].asNumber();
|
|
702
|
+
const double behavior = args[1].asNumber();
|
|
703
|
+
if (!std::isfinite(groupId) || groupId <= 0 ||
|
|
704
|
+
std::floor(groupId) != groupId ||
|
|
705
|
+
(behavior != static_cast<double>(GroupCancelBehavior::Freeze) &&
|
|
706
|
+
behavior != static_cast<double>(GroupCancelBehavior::Finish))) {
|
|
707
|
+
return Array(rt, 0);
|
|
708
|
+
}
|
|
709
|
+
return snapshotsArrayV2(
|
|
710
|
+
rt,
|
|
711
|
+
cancelAnimationGroup(
|
|
712
|
+
static_cast<int32_t>(groupId),
|
|
713
|
+
static_cast<GroupCancelBehavior>(
|
|
714
|
+
static_cast<int32_t>(behavior))));
|
|
715
|
+
});
|
|
716
|
+
|
|
717
|
+
setHostFunction(
|
|
718
|
+
runtime, bindings, "setClipPresentation", 11,
|
|
170
719
|
[](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
|
|
171
720
|
if (count < 9) return Value::undefined();
|
|
172
721
|
const double driverId = args[0].asNumber();
|
|
173
722
|
const Presentation presentation = presentationFromArgs(args, 1);
|
|
174
723
|
const bool takeOwnership = boolArg(args, count, 8);
|
|
175
724
|
const bool overridePendingAnimation = boolArg(args, count, 9);
|
|
725
|
+
// Optional trailing flag; absent means record (the pre-flag
|
|
726
|
+
// behavior), so only an explicit false skips the velocity sample.
|
|
727
|
+
const bool recordVelocity =
|
|
728
|
+
!(count > 10 && args[10].isBool() && !args[10].getBool());
|
|
176
729
|
if (validDriverId(driverId) && finitePresentation(presentation)) {
|
|
177
730
|
setPresentation(
|
|
178
731
|
static_cast<uint64_t>(driverId), presentation, takeOwnership,
|
|
179
|
-
overridePendingAnimation);
|
|
732
|
+
overridePendingAnimation, recordVelocity);
|
|
733
|
+
}
|
|
734
|
+
return Value::undefined();
|
|
735
|
+
});
|
|
736
|
+
|
|
737
|
+
setHostFunction(
|
|
738
|
+
runtime, bindings, "setClipPresentationV2", 16,
|
|
739
|
+
[](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
|
|
740
|
+
if (count < 14) return Value::undefined();
|
|
741
|
+
const double driverId = args[0].asNumber();
|
|
742
|
+
const Presentation presentation = presentationV2FromArgs(args, 1);
|
|
743
|
+
const bool takeOwnership = boolArg(args, count, 13);
|
|
744
|
+
const bool overridePendingAnimation = boolArg(args, count, 14);
|
|
745
|
+
const bool recordVelocity =
|
|
746
|
+
!(count > 15 && args[15].isBool() && !args[15].getBool());
|
|
747
|
+
if (validDriverId(driverId) && validCurve(args[9].asNumber()) &&
|
|
748
|
+
finiteV2Presentation(presentation)) {
|
|
749
|
+
setPresentation(
|
|
750
|
+
static_cast<uint64_t>(driverId), presentation, takeOwnership,
|
|
751
|
+
overridePendingAnimation, recordVelocity);
|
|
180
752
|
}
|
|
181
753
|
return Value::undefined();
|
|
182
754
|
});
|
|
@@ -191,6 +763,28 @@ void installBindings(
|
|
|
191
763
|
rt, beginInteraction(static_cast<uint64_t>(args[0].asNumber())));
|
|
192
764
|
});
|
|
193
765
|
|
|
766
|
+
setHostFunction(
|
|
767
|
+
runtime, bindings, "beginInteractionV2", 1,
|
|
768
|
+
[](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
|
|
769
|
+
if (count < 1 || !validDriverId(args[0].asNumber())) {
|
|
770
|
+
return presentationArrayV2(rt, {{0, 0, 0, 0, 0}, 0, 0});
|
|
771
|
+
}
|
|
772
|
+
return presentationArrayV2(
|
|
773
|
+
rt, beginInteraction(static_cast<uint64_t>(args[0].asNumber())));
|
|
774
|
+
});
|
|
775
|
+
|
|
776
|
+
setHostFunction(
|
|
777
|
+
runtime, bindings, "snapshotCurrentV2", 1,
|
|
778
|
+
[](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
|
|
779
|
+
if (count < 1 || !validDriverId(args[0].asNumber())) {
|
|
780
|
+
return presentationArrayV2(rt, {{0, 0, 0, 0, 0}, 0, 0});
|
|
781
|
+
}
|
|
782
|
+
return presentationArrayV2(
|
|
783
|
+
rt,
|
|
784
|
+
snapshotCurrentAndroid(
|
|
785
|
+
static_cast<uint64_t>(args[0].asNumber())));
|
|
786
|
+
});
|
|
787
|
+
|
|
194
788
|
setHostFunction(
|
|
195
789
|
runtime, bindings, "animateTiming", 23,
|
|
196
790
|
[](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
|
|
@@ -211,6 +805,31 @@ void installBindings(
|
|
|
211
805
|
static_cast<uint64_t>(driverId),
|
|
212
806
|
{boolArg(args, count, 1), start, startStampArg(args, count, 22)},
|
|
213
807
|
target,
|
|
808
|
+
animation,
|
|
809
|
+
AnimationValidationMode::LegacyV1));
|
|
810
|
+
});
|
|
811
|
+
|
|
812
|
+
setHostFunction(
|
|
813
|
+
runtime, bindings, "animateTimingV2", 33,
|
|
814
|
+
[](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
|
|
815
|
+
if (count < 32) return Value(0);
|
|
816
|
+
const double driverId = args[0].asNumber();
|
|
817
|
+
const Presentation start = presentationV2FromArgs(args, 2);
|
|
818
|
+
const Presentation target = presentationV2FromArgs(args, 14);
|
|
819
|
+
const TimingAnimation animation{
|
|
820
|
+
args[26].asNumber(), args[27].asNumber(), args[28].asNumber(),
|
|
821
|
+
args[29].asNumber(), args[30].asNumber(),
|
|
822
|
+
static_cast<int32_t>(args[31].asNumber())};
|
|
823
|
+
if (!validDriverId(driverId) || !validCurve(args[10].asNumber()) ||
|
|
824
|
+
!validCurve(args[22].asNumber()) ||
|
|
825
|
+
!finiteV2Presentation(start) || !finiteV2Presentation(target) ||
|
|
826
|
+
!std::isfinite(animation.durationMs)) {
|
|
827
|
+
return Value(0);
|
|
828
|
+
}
|
|
829
|
+
return Value(animateTiming(
|
|
830
|
+
static_cast<uint64_t>(driverId),
|
|
831
|
+
{boolArg(args, count, 1), start, startStampArg(args, count, 32)},
|
|
832
|
+
target,
|
|
214
833
|
animation));
|
|
215
834
|
});
|
|
216
835
|
|
|
@@ -229,15 +848,42 @@ void installBindings(
|
|
|
229
848
|
!finitePresentation(target) || !std::isfinite(animation.mass) ||
|
|
230
849
|
!std::isfinite(animation.stiffness) ||
|
|
231
850
|
!std::isfinite(animation.damping) ||
|
|
232
|
-
!std::isfinite(animation.initialVelocity)
|
|
233
|
-
animation.mass <= 0 || animation.stiffness <= 0 ||
|
|
234
|
-
animation.damping < 0) {
|
|
851
|
+
!std::isfinite(animation.initialVelocity)) {
|
|
235
852
|
return Value(0);
|
|
236
853
|
}
|
|
237
854
|
return Value(animateSpring(
|
|
238
855
|
static_cast<uint64_t>(driverId),
|
|
239
856
|
{boolArg(args, count, 1), start, startStampArg(args, count, 22)},
|
|
240
857
|
target,
|
|
858
|
+
animation,
|
|
859
|
+
AnimationValidationMode::LegacyV1));
|
|
860
|
+
});
|
|
861
|
+
|
|
862
|
+
setHostFunction(
|
|
863
|
+
runtime, bindings, "animateSpringV2", 33,
|
|
864
|
+
[](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
|
|
865
|
+
if (count < 32) return Value(0);
|
|
866
|
+
const double driverId = args[0].asNumber();
|
|
867
|
+
const Presentation start = presentationV2FromArgs(args, 2);
|
|
868
|
+
const Presentation target = presentationV2FromArgs(args, 14);
|
|
869
|
+
const SpringAnimation animation{
|
|
870
|
+
args[26].asNumber(), args[27].asNumber(), args[28].asNumber(),
|
|
871
|
+
args[29].asNumber(), boolArg(args, count, 30),
|
|
872
|
+
static_cast<int32_t>(args[31].asNumber())};
|
|
873
|
+
if (!validDriverId(driverId) || !validCurve(args[10].asNumber()) ||
|
|
874
|
+
!validCurve(args[22].asNumber()) ||
|
|
875
|
+
!finiteV2Presentation(start) || !finiteV2Presentation(target) ||
|
|
876
|
+
!std::isfinite(animation.mass) ||
|
|
877
|
+
!std::isfinite(animation.stiffness) ||
|
|
878
|
+
!std::isfinite(animation.damping) ||
|
|
879
|
+
!std::isfinite(animation.initialVelocity) || animation.mass <= 0 ||
|
|
880
|
+
animation.stiffness <= 0 || animation.damping < 0) {
|
|
881
|
+
return Value(0);
|
|
882
|
+
}
|
|
883
|
+
return Value(animateSpring(
|
|
884
|
+
static_cast<uint64_t>(driverId),
|
|
885
|
+
{boolArg(args, count, 1), start, startStampArg(args, count, 32)},
|
|
886
|
+
target,
|
|
241
887
|
animation));
|
|
242
888
|
});
|
|
243
889
|
|
|
@@ -289,6 +935,157 @@ void installBindings(
|
|
|
289
935
|
target,
|
|
290
936
|
durationMs,
|
|
291
937
|
std::move(keyframes),
|
|
938
|
+
reduceMotion,
|
|
939
|
+
AnimationValidationMode::LegacyV1));
|
|
940
|
+
});
|
|
941
|
+
|
|
942
|
+
setHostFunction(
|
|
943
|
+
runtime, bindings, "animateKeyframesV2", 30,
|
|
944
|
+
[](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
|
|
945
|
+
if (count < 29 || !args[27].isObject() ||
|
|
946
|
+
!args[27].getObject(rt).isArray(rt)) {
|
|
947
|
+
return Value(0);
|
|
948
|
+
}
|
|
949
|
+
const double driverId = args[0].asNumber();
|
|
950
|
+
const Presentation start = presentationV2FromArgs(args, 2);
|
|
951
|
+
const Presentation target = presentationV2FromArgs(args, 14);
|
|
952
|
+
const double durationMs = args[26].asNumber();
|
|
953
|
+
const int32_t reduceMotion = static_cast<int32_t>(args[28].asNumber());
|
|
954
|
+
Array frames = args[27].getObject(rt).getArray(rt);
|
|
955
|
+
const size_t length = frames.size(rt);
|
|
956
|
+
if (!validDriverId(driverId) || !validCurve(args[10].asNumber()) ||
|
|
957
|
+
!validCurve(args[22].asNumber()) ||
|
|
958
|
+
!finiteV2Presentation(start) || !finiteV2Presentation(target) ||
|
|
959
|
+
!std::isfinite(durationMs) || length < 26 || length % 13 != 0) {
|
|
960
|
+
return Value(0);
|
|
961
|
+
}
|
|
962
|
+
std::vector<Keyframe> keyframes;
|
|
963
|
+
keyframes.reserve(length / 13);
|
|
964
|
+
double previousOffset = -1;
|
|
965
|
+
for (size_t index = 0; index < length; index += 13) {
|
|
966
|
+
const double offset = frames.getValueAtIndex(rt, index).asNumber();
|
|
967
|
+
const double curveCode =
|
|
968
|
+
frames.getValueAtIndex(rt, index + 9).asNumber();
|
|
969
|
+
const Presentation frame =
|
|
970
|
+
presentationV2FromArray(rt, frames, index + 1);
|
|
971
|
+
if (!std::isfinite(offset) || offset < 0 || offset > 1 ||
|
|
972
|
+
offset <= previousOffset || !validCurve(curveCode) ||
|
|
973
|
+
!finiteV2Presentation(frame)) {
|
|
974
|
+
return Value(0);
|
|
975
|
+
}
|
|
976
|
+
previousOffset = offset;
|
|
977
|
+
keyframes.push_back({offset, frame});
|
|
978
|
+
}
|
|
979
|
+
if (keyframes.front().offset != 0 || keyframes.back().offset != 1) {
|
|
980
|
+
return Value(0);
|
|
981
|
+
}
|
|
982
|
+
return Value(animateKeyframes(
|
|
983
|
+
static_cast<uint64_t>(driverId),
|
|
984
|
+
{boolArg(args, count, 1), start, startStampArg(args, count, 29)},
|
|
985
|
+
target,
|
|
986
|
+
durationMs,
|
|
987
|
+
std::move(keyframes),
|
|
988
|
+
reduceMotion));
|
|
989
|
+
});
|
|
990
|
+
|
|
991
|
+
setHostFunction(
|
|
992
|
+
runtime, bindings, "animateTimingFromV2", 32,
|
|
993
|
+
[](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
|
|
994
|
+
if (count < 31) return Value(0);
|
|
995
|
+
const double driverId = args[0].asNumber();
|
|
996
|
+
const Presentation start = presentationV2FromArgs(args, 1);
|
|
997
|
+
const Presentation target = presentationV2FromArgs(args, 13);
|
|
998
|
+
const TimingAnimation animation{
|
|
999
|
+
args[25].asNumber(), args[26].asNumber(), args[27].asNumber(),
|
|
1000
|
+
args[28].asNumber(), args[29].asNumber(),
|
|
1001
|
+
static_cast<int32_t>(args[30].asNumber())};
|
|
1002
|
+
if (!validDriverId(driverId) || !validCurve(args[9].asNumber()) ||
|
|
1003
|
+
!validCurve(args[21].asNumber()) ||
|
|
1004
|
+
!finiteV2Presentation(start) || !finiteV2Presentation(target) ||
|
|
1005
|
+
!std::isfinite(animation.durationMs)) {
|
|
1006
|
+
return Value(0);
|
|
1007
|
+
}
|
|
1008
|
+
return Value(animateTiming(
|
|
1009
|
+
static_cast<uint64_t>(driverId),
|
|
1010
|
+
{true, start, startStampArg(args, count, 31)},
|
|
1011
|
+
target,
|
|
1012
|
+
animation));
|
|
1013
|
+
});
|
|
1014
|
+
|
|
1015
|
+
setHostFunction(
|
|
1016
|
+
runtime, bindings, "animateSpringFromV2", 32,
|
|
1017
|
+
[](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
|
|
1018
|
+
if (count < 31) return Value(0);
|
|
1019
|
+
const double driverId = args[0].asNumber();
|
|
1020
|
+
const Presentation start = presentationV2FromArgs(args, 1);
|
|
1021
|
+
const Presentation target = presentationV2FromArgs(args, 13);
|
|
1022
|
+
const SpringAnimation animation{
|
|
1023
|
+
args[25].asNumber(), args[26].asNumber(), args[27].asNumber(),
|
|
1024
|
+
args[28].asNumber(), boolArg(args, count, 29),
|
|
1025
|
+
static_cast<int32_t>(args[30].asNumber())};
|
|
1026
|
+
if (!validDriverId(driverId) || !validCurve(args[9].asNumber()) ||
|
|
1027
|
+
!validCurve(args[21].asNumber()) ||
|
|
1028
|
+
!finiteV2Presentation(start) || !finiteV2Presentation(target) ||
|
|
1029
|
+
!std::isfinite(animation.mass) ||
|
|
1030
|
+
!std::isfinite(animation.stiffness) ||
|
|
1031
|
+
!std::isfinite(animation.damping) ||
|
|
1032
|
+
!std::isfinite(animation.initialVelocity) || animation.mass <= 0 ||
|
|
1033
|
+
animation.stiffness <= 0 || animation.damping < 0) {
|
|
1034
|
+
return Value(0);
|
|
1035
|
+
}
|
|
1036
|
+
return Value(animateSpring(
|
|
1037
|
+
static_cast<uint64_t>(driverId),
|
|
1038
|
+
{true, start, startStampArg(args, count, 31)},
|
|
1039
|
+
target,
|
|
1040
|
+
animation));
|
|
1041
|
+
});
|
|
1042
|
+
|
|
1043
|
+
setHostFunction(
|
|
1044
|
+
runtime, bindings, "animateKeyframesFromV2", 29,
|
|
1045
|
+
[](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
|
|
1046
|
+
if (count < 28 || !args[26].isObject() ||
|
|
1047
|
+
!args[26].getObject(rt).isArray(rt)) {
|
|
1048
|
+
return Value(0);
|
|
1049
|
+
}
|
|
1050
|
+
const double driverId = args[0].asNumber();
|
|
1051
|
+
const Presentation start = presentationV2FromArgs(args, 1);
|
|
1052
|
+
const Presentation target = presentationV2FromArgs(args, 13);
|
|
1053
|
+
const double durationMs = args[25].asNumber();
|
|
1054
|
+
const int32_t reduceMotion = static_cast<int32_t>(args[27].asNumber());
|
|
1055
|
+
Array frames = args[26].getObject(rt).getArray(rt);
|
|
1056
|
+
const size_t length = frames.size(rt);
|
|
1057
|
+
if (!validDriverId(driverId) || !validCurve(args[9].asNumber()) ||
|
|
1058
|
+
!validCurve(args[21].asNumber()) ||
|
|
1059
|
+
!finiteV2Presentation(start) || !finiteV2Presentation(target) ||
|
|
1060
|
+
!std::isfinite(durationMs) || length < 26 || length % 13 != 0) {
|
|
1061
|
+
return Value(0);
|
|
1062
|
+
}
|
|
1063
|
+
std::vector<Keyframe> keyframes;
|
|
1064
|
+
keyframes.reserve(length / 13);
|
|
1065
|
+
double previousOffset = -1;
|
|
1066
|
+
for (size_t index = 0; index < length; index += 13) {
|
|
1067
|
+
const double offset = frames.getValueAtIndex(rt, index).asNumber();
|
|
1068
|
+
const double frameCurve =
|
|
1069
|
+
frames.getValueAtIndex(rt, index + 9).asNumber();
|
|
1070
|
+
const Presentation frame =
|
|
1071
|
+
presentationV2FromArray(rt, frames, index + 1);
|
|
1072
|
+
if (!std::isfinite(offset) || offset < 0 || offset > 1 ||
|
|
1073
|
+
offset <= previousOffset || !validCurve(frameCurve) ||
|
|
1074
|
+
!finiteV2Presentation(frame)) {
|
|
1075
|
+
return Value(0);
|
|
1076
|
+
}
|
|
1077
|
+
previousOffset = offset;
|
|
1078
|
+
keyframes.push_back({offset, frame});
|
|
1079
|
+
}
|
|
1080
|
+
if (keyframes.front().offset != 0 || keyframes.back().offset != 1) {
|
|
1081
|
+
return Value(0);
|
|
1082
|
+
}
|
|
1083
|
+
return Value(animateKeyframes(
|
|
1084
|
+
static_cast<uint64_t>(driverId),
|
|
1085
|
+
{true, start, startStampArg(args, count, 28)},
|
|
1086
|
+
target,
|
|
1087
|
+
durationMs,
|
|
1088
|
+
std::move(keyframes),
|
|
292
1089
|
reduceMotion));
|
|
293
1090
|
});
|
|
294
1091
|
|
|
@@ -313,6 +1110,21 @@ void installBindings(
|
|
|
313
1110
|
return cancelResultArray(rt, result.handled, result.presentation);
|
|
314
1111
|
});
|
|
315
1112
|
|
|
1113
|
+
setHostFunction(
|
|
1114
|
+
runtime, bindings, "cancelAnimationV2", 3,
|
|
1115
|
+
[](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
|
|
1116
|
+
if (count < 3 || !validDriverId(args[0].asNumber())) {
|
|
1117
|
+
return cancelResultArrayV2(
|
|
1118
|
+
rt, false, {{0, 0, 0, 0, 0}, 0, 0});
|
|
1119
|
+
}
|
|
1120
|
+
const CancelResult result = cancelAnimation(
|
|
1121
|
+
static_cast<uint64_t>(args[0].asNumber()),
|
|
1122
|
+
static_cast<int32_t>(args[1].asNumber()),
|
|
1123
|
+
static_cast<int32_t>(args[2].asNumber()) == 1);
|
|
1124
|
+
return cancelResultArrayV2(
|
|
1125
|
+
rt, result.handled, result.presentation);
|
|
1126
|
+
});
|
|
1127
|
+
|
|
316
1128
|
setHostFunction(
|
|
317
1129
|
runtime, bindings, "destroyDriver", 1,
|
|
318
1130
|
[](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
|
|
@@ -345,6 +1157,29 @@ void installBindings(
|
|
|
345
1157
|
return subscription;
|
|
346
1158
|
});
|
|
347
1159
|
|
|
1160
|
+
setHostFunction(
|
|
1161
|
+
runtime, bindings, "onClipGroupAnimationComplete", 1,
|
|
1162
|
+
[state](Runtime &rt, const Value &, const Value *args, size_t count)
|
|
1163
|
+
-> Value {
|
|
1164
|
+
if (count < 1 || !args[0].isObject() ||
|
|
1165
|
+
!args[0].getObject(rt).isFunction(rt)) {
|
|
1166
|
+
return Value::undefined();
|
|
1167
|
+
}
|
|
1168
|
+
auto listener = std::make_shared<Function>(
|
|
1169
|
+
args[0].getObject(rt).getFunction(rt));
|
|
1170
|
+
const int32_t listenerId = ++state->nextListenerId;
|
|
1171
|
+
state->groupListeners.emplace(listenerId, std::move(listener));
|
|
1172
|
+
Object subscription(rt);
|
|
1173
|
+
setHostFunction(
|
|
1174
|
+
rt, subscription, "remove", 0,
|
|
1175
|
+
[state, listenerId](
|
|
1176
|
+
Runtime &, const Value &, const Value *, size_t) -> Value {
|
|
1177
|
+
state->groupListeners.erase(listenerId);
|
|
1178
|
+
return Value::undefined();
|
|
1179
|
+
});
|
|
1180
|
+
return subscription;
|
|
1181
|
+
});
|
|
1182
|
+
|
|
348
1183
|
runtime.global().setProperty(runtime, "__SmoothClipView", bindings);
|
|
349
1184
|
}
|
|
350
1185
|
|
|
@@ -355,7 +1190,9 @@ void invalidateBindings() {
|
|
|
355
1190
|
// own runtime.
|
|
356
1191
|
auto state = bindingsState();
|
|
357
1192
|
clearCompletionCallback(state.get());
|
|
1193
|
+
clearGroupCompletionCallback(state.get());
|
|
358
1194
|
state->listeners.clear();
|
|
1195
|
+
state->groupListeners.clear();
|
|
359
1196
|
state->runtime = nullptr;
|
|
360
1197
|
state->callInvoker = nullptr;
|
|
361
1198
|
}
|
|
@@ -403,6 +1240,58 @@ void nativeRegisterView(
|
|
|
403
1240
|
lifecycleVisible != 0);
|
|
404
1241
|
}
|
|
405
1242
|
|
|
1243
|
+
void nativeRegisterViewV2(
|
|
1244
|
+
jni::alias_ref<jni::JObject>,
|
|
1245
|
+
jdouble driverId,
|
|
1246
|
+
jni::alias_ref<smoothclip::JSmoothClipView> view,
|
|
1247
|
+
jdouble x,
|
|
1248
|
+
jdouble y,
|
|
1249
|
+
jdouble width,
|
|
1250
|
+
jdouble height,
|
|
1251
|
+
jdouble topLeftRadius,
|
|
1252
|
+
jdouble topRightRadius,
|
|
1253
|
+
jdouble bottomRightRadius,
|
|
1254
|
+
jdouble bottomLeftRadius,
|
|
1255
|
+
jint curveCode,
|
|
1256
|
+
jdouble contentTranslateX,
|
|
1257
|
+
jdouble contentTranslateY,
|
|
1258
|
+
jdouble contentScale,
|
|
1259
|
+
jdouble density,
|
|
1260
|
+
jdouble widthPx,
|
|
1261
|
+
jdouble heightPx,
|
|
1262
|
+
jboolean lifecycleVisible) {
|
|
1263
|
+
if (driverId <= 0 || !std::isfinite(driverId) || !std::isfinite(x) ||
|
|
1264
|
+
!std::isfinite(y) || !std::isfinite(width) || !std::isfinite(height) ||
|
|
1265
|
+
!std::isfinite(topLeftRadius) || !std::isfinite(topRightRadius) ||
|
|
1266
|
+
!std::isfinite(bottomRightRadius) || !std::isfinite(bottomLeftRadius) ||
|
|
1267
|
+
!std::isfinite(contentTranslateX) ||
|
|
1268
|
+
!std::isfinite(contentTranslateY) || !std::isfinite(contentScale) ||
|
|
1269
|
+
contentScale <= 0 ||
|
|
1270
|
+
(curveCode != static_cast<jint>(smoothclip::ClipCurve::Circular) &&
|
|
1271
|
+
curveCode != static_cast<jint>(smoothclip::ClipCurve::Continuous))) {
|
|
1272
|
+
return;
|
|
1273
|
+
}
|
|
1274
|
+
smoothclip::Geometry geometry{x, y, width, height, 0.0};
|
|
1275
|
+
geometry.topLeftRadius = topLeftRadius;
|
|
1276
|
+
geometry.topRightRadius = topRightRadius;
|
|
1277
|
+
geometry.bottomRightRadius = bottomRightRadius;
|
|
1278
|
+
geometry.bottomLeftRadius = bottomLeftRadius;
|
|
1279
|
+
geometry.curve = static_cast<smoothclip::ClipCurve>(curveCode);
|
|
1280
|
+
if (topLeftRadius == topRightRadius && topLeftRadius == bottomRightRadius &&
|
|
1281
|
+
topLeftRadius == bottomLeftRadius) {
|
|
1282
|
+
geometry.radius = topLeftRadius;
|
|
1283
|
+
}
|
|
1284
|
+
smoothclip::registerViewAndroid(
|
|
1285
|
+
static_cast<uint64_t>(driverId),
|
|
1286
|
+
view,
|
|
1287
|
+
smoothclip::Presentation{
|
|
1288
|
+
geometry, contentTranslateX, contentTranslateY, contentScale},
|
|
1289
|
+
density,
|
|
1290
|
+
widthPx,
|
|
1291
|
+
heightPx,
|
|
1292
|
+
lifecycleVisible != 0);
|
|
1293
|
+
}
|
|
1294
|
+
|
|
406
1295
|
void nativeSetViewHostGeometry(
|
|
407
1296
|
jni::alias_ref<jni::JObject>,
|
|
408
1297
|
jdouble driverId,
|
|
@@ -450,6 +1339,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
|
|
450
1339
|
{
|
|
451
1340
|
makeNativeMethod("getBindingsInstaller", getBindingsInstaller),
|
|
452
1341
|
makeNativeMethod("nativeRegisterView", nativeRegisterView),
|
|
1342
|
+
makeNativeMethod("nativeRegisterViewV2", nativeRegisterViewV2),
|
|
453
1343
|
makeNativeMethod(
|
|
454
1344
|
"nativeSetViewHostGeometry", nativeSetViewHostGeometry),
|
|
455
1345
|
makeNativeMethod("nativeUnregisterView", nativeUnregisterView),
|