react-native-smooth-clip-view 0.2.9 → 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 +60 -21
- package/android/build.gradle +6 -2
- package/android/proguard-rules.pro +3 -3
- package/android/src/main/cpp/SmoothClipAndroid.h +10 -0
- package/android/src/main/cpp/SmoothClipBindings.cpp +890 -4
- package/android/src/main/cpp/SmoothClipRegistry.cpp +1056 -44
- 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 +371 -18
- package/android/src/main/java/com/smoothclipview/SmoothClipViewManager.kt +138 -24
- package/cpp/SmoothClipAnimationCurve.h +151 -122
- package/cpp/SmoothClipRegistry.h +95 -3
- package/cpp/SmoothClipSharedGeometry.h +146 -7
- package/cpp/SmoothClipVelocityTracker.h +13 -9
- package/ios/SmoothClipGeometry.h +184 -6
- package/ios/SmoothClipRegistry.mm +1028 -22
- 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 +263 -63
- 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 +25 -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 +42 -11
- package/src/drivers.native.ts +824 -124
- 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,8 +487,233 @@ 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
|
|
|
528
|
+
setHostFunction(
|
|
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
|
+
|
|
168
717
|
setHostFunction(
|
|
169
718
|
runtime, bindings, "setClipPresentation", 11,
|
|
170
719
|
[](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
|
|
@@ -185,6 +734,25 @@ void installBindings(
|
|
|
185
734
|
return Value::undefined();
|
|
186
735
|
});
|
|
187
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);
|
|
752
|
+
}
|
|
753
|
+
return Value::undefined();
|
|
754
|
+
});
|
|
755
|
+
|
|
188
756
|
setHostFunction(
|
|
189
757
|
runtime, bindings, "beginInteraction", 1,
|
|
190
758
|
[](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
|
|
@@ -195,6 +763,28 @@ void installBindings(
|
|
|
195
763
|
rt, beginInteraction(static_cast<uint64_t>(args[0].asNumber())));
|
|
196
764
|
});
|
|
197
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
|
+
|
|
198
788
|
setHostFunction(
|
|
199
789
|
runtime, bindings, "animateTiming", 23,
|
|
200
790
|
[](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
|
|
@@ -215,6 +805,31 @@ void installBindings(
|
|
|
215
805
|
static_cast<uint64_t>(driverId),
|
|
216
806
|
{boolArg(args, count, 1), start, startStampArg(args, count, 22)},
|
|
217
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,
|
|
218
833
|
animation));
|
|
219
834
|
});
|
|
220
835
|
|
|
@@ -233,15 +848,42 @@ void installBindings(
|
|
|
233
848
|
!finitePresentation(target) || !std::isfinite(animation.mass) ||
|
|
234
849
|
!std::isfinite(animation.stiffness) ||
|
|
235
850
|
!std::isfinite(animation.damping) ||
|
|
236
|
-
!std::isfinite(animation.initialVelocity)
|
|
237
|
-
animation.mass <= 0 || animation.stiffness <= 0 ||
|
|
238
|
-
animation.damping < 0) {
|
|
851
|
+
!std::isfinite(animation.initialVelocity)) {
|
|
239
852
|
return Value(0);
|
|
240
853
|
}
|
|
241
854
|
return Value(animateSpring(
|
|
242
855
|
static_cast<uint64_t>(driverId),
|
|
243
856
|
{boolArg(args, count, 1), start, startStampArg(args, count, 22)},
|
|
244
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,
|
|
245
887
|
animation));
|
|
246
888
|
});
|
|
247
889
|
|
|
@@ -293,6 +935,157 @@ void installBindings(
|
|
|
293
935
|
target,
|
|
294
936
|
durationMs,
|
|
295
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),
|
|
296
1089
|
reduceMotion));
|
|
297
1090
|
});
|
|
298
1091
|
|
|
@@ -317,6 +1110,21 @@ void installBindings(
|
|
|
317
1110
|
return cancelResultArray(rt, result.handled, result.presentation);
|
|
318
1111
|
});
|
|
319
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
|
+
|
|
320
1128
|
setHostFunction(
|
|
321
1129
|
runtime, bindings, "destroyDriver", 1,
|
|
322
1130
|
[](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
|
|
@@ -349,6 +1157,29 @@ void installBindings(
|
|
|
349
1157
|
return subscription;
|
|
350
1158
|
});
|
|
351
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
|
+
|
|
352
1183
|
runtime.global().setProperty(runtime, "__SmoothClipView", bindings);
|
|
353
1184
|
}
|
|
354
1185
|
|
|
@@ -359,7 +1190,9 @@ void invalidateBindings() {
|
|
|
359
1190
|
// own runtime.
|
|
360
1191
|
auto state = bindingsState();
|
|
361
1192
|
clearCompletionCallback(state.get());
|
|
1193
|
+
clearGroupCompletionCallback(state.get());
|
|
362
1194
|
state->listeners.clear();
|
|
1195
|
+
state->groupListeners.clear();
|
|
363
1196
|
state->runtime = nullptr;
|
|
364
1197
|
state->callInvoker = nullptr;
|
|
365
1198
|
}
|
|
@@ -407,6 +1240,58 @@ void nativeRegisterView(
|
|
|
407
1240
|
lifecycleVisible != 0);
|
|
408
1241
|
}
|
|
409
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
|
+
|
|
410
1295
|
void nativeSetViewHostGeometry(
|
|
411
1296
|
jni::alias_ref<jni::JObject>,
|
|
412
1297
|
jdouble driverId,
|
|
@@ -454,6 +1339,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
|
|
454
1339
|
{
|
|
455
1340
|
makeNativeMethod("getBindingsInstaller", getBindingsInstaller),
|
|
456
1341
|
makeNativeMethod("nativeRegisterView", nativeRegisterView),
|
|
1342
|
+
makeNativeMethod("nativeRegisterViewV2", nativeRegisterViewV2),
|
|
457
1343
|
makeNativeMethod(
|
|
458
1344
|
"nativeSetViewHostGeometry", nativeSetViewHostGeometry),
|
|
459
1345
|
makeNativeMethod("nativeUnregisterView", nativeUnregisterView),
|