react-native-smooth-clip-view 0.3.0 → 0.4.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.
Files changed (199) hide show
  1. package/README.md +132 -388
  2. package/android/build.gradle +3 -3
  3. package/android/proguard-rules.pro +2 -2
  4. package/android/src/main/cpp/SmoothClipAndroid.h +9 -12
  5. package/android/src/main/cpp/SmoothClipBindings.cpp +300 -704
  6. package/android/src/main/cpp/SmoothClipRegistry.cpp +348 -594
  7. package/android/src/main/java/com/smoothclipview/ClipGeometryNormalizer.kt +36 -227
  8. package/android/src/main/java/com/smoothclipview/SmoothClipBindings.kt +16 -19
  9. package/android/src/main/java/com/smoothclipview/SmoothClipModule.kt +36 -294
  10. package/android/src/main/java/com/smoothclipview/SmoothClipView.kt +344 -488
  11. package/android/src/main/java/com/smoothclipview/SmoothClipViewManager.kt +75 -77
  12. package/cpp/SmoothClipAnimationCurve.h +237 -346
  13. package/cpp/SmoothClipRegistry.h +24 -52
  14. package/cpp/SmoothClipSharedGeometry.h +64 -94
  15. package/cpp/SmoothClipVelocityTracker.h +5 -5
  16. package/ios/SmoothClipGeometry.h +23 -34
  17. package/ios/SmoothClipRegistry.mm +206 -711
  18. package/ios/SmoothClipTurboModule.cpp +217 -715
  19. package/ios/SmoothClipTurboModule.h +54 -297
  20. package/ios/SmoothClipView.mm +599 -505
  21. package/ios/SmoothClipViewRegistry.h +2 -7
  22. package/lib/module/NativeSmoothClipModule.js.map +1 -1
  23. package/lib/module/SmoothClipView.ios.js +84 -17
  24. package/lib/module/SmoothClipView.ios.js.map +1 -1
  25. package/lib/module/SmoothClipView.js +1 -1
  26. package/lib/module/SmoothClipView.js.map +1 -1
  27. package/lib/module/SmoothClipViewNativeComponent.ts +20 -26
  28. package/lib/module/capabilities.native.js +1 -19
  29. package/lib/module/capabilities.native.js.map +1 -1
  30. package/lib/module/capabilityTypes.js +0 -9
  31. package/lib/module/capabilityTypes.js.map +1 -1
  32. package/lib/module/controllerInternals.js +28 -0
  33. package/lib/module/controllerInternals.js.map +1 -0
  34. package/lib/module/controllerLifecycle.js +9 -0
  35. package/lib/module/controllerLifecycle.js.map +1 -0
  36. package/lib/module/controllerTypes.js +4 -0
  37. package/lib/module/controllerTypes.js.map +1 -0
  38. package/lib/module/controllers.android.js +4 -0
  39. package/lib/module/controllers.android.js.map +1 -0
  40. package/lib/module/controllers.ios.js +4 -0
  41. package/lib/module/controllers.ios.js.map +1 -0
  42. package/lib/module/controllers.js +4 -0
  43. package/lib/module/controllers.js.map +1 -0
  44. package/lib/module/controllers.native.js +89 -0
  45. package/lib/module/controllers.native.js.map +1 -0
  46. package/lib/module/geometry.js +71 -51
  47. package/lib/module/geometry.js.map +1 -1
  48. package/lib/module/groupTypes.js +4 -0
  49. package/lib/module/{groupDriverTypes.js.map → groupTypes.js.map} +1 -1
  50. package/lib/module/groups.android.js +4 -0
  51. package/lib/module/groups.android.js.map +1 -0
  52. package/lib/module/groups.ios.js +4 -0
  53. package/lib/module/groups.ios.js.map +1 -0
  54. package/lib/module/groups.js +4 -0
  55. package/lib/module/groups.js.map +1 -0
  56. package/lib/module/groups.native.js +399 -0
  57. package/lib/module/groups.native.js.map +1 -0
  58. package/lib/module/ids.js +8 -0
  59. package/lib/module/ids.js.map +1 -0
  60. package/lib/module/index.js +3 -3
  61. package/lib/module/index.js.map +1 -1
  62. package/lib/module/nativeCompletion.js +37 -16
  63. package/lib/module/nativeCompletion.js.map +1 -1
  64. package/lib/module/presentationCodec.js +81 -0
  65. package/lib/module/presentationCodec.js.map +1 -0
  66. package/lib/typescript/src/NativeSmoothClipModule.d.ts +14 -23
  67. package/lib/typescript/src/NativeSmoothClipModule.d.ts.map +1 -1
  68. package/lib/typescript/src/SmoothClipView.d.ts +1 -1
  69. package/lib/typescript/src/SmoothClipView.d.ts.map +1 -1
  70. package/lib/typescript/src/SmoothClipView.ios.d.ts +18 -14
  71. package/lib/typescript/src/SmoothClipView.ios.d.ts.map +1 -1
  72. package/lib/typescript/src/SmoothClipViewNativeComponent.d.ts +10 -5
  73. package/lib/typescript/src/SmoothClipViewNativeComponent.d.ts.map +1 -1
  74. package/lib/typescript/src/capabilities.native.d.ts +1 -1
  75. package/lib/typescript/src/capabilities.native.d.ts.map +1 -1
  76. package/lib/typescript/src/capabilityTypes.d.ts +0 -6
  77. package/lib/typescript/src/capabilityTypes.d.ts.map +1 -1
  78. package/lib/typescript/src/controllerInternals.d.ts +14 -0
  79. package/lib/typescript/src/controllerInternals.d.ts.map +1 -0
  80. package/lib/typescript/src/controllerLifecycle.d.ts +3 -0
  81. package/lib/typescript/src/controllerLifecycle.d.ts.map +1 -0
  82. package/lib/typescript/src/controllerTypes.d.ts +62 -0
  83. package/lib/typescript/src/controllerTypes.d.ts.map +1 -0
  84. package/lib/typescript/src/controllers.android.d.ts +2 -0
  85. package/lib/typescript/src/controllers.android.d.ts.map +1 -0
  86. package/lib/typescript/src/controllers.d.ts +2 -0
  87. package/lib/typescript/src/controllers.d.ts.map +1 -0
  88. package/lib/typescript/src/controllers.ios.d.ts +2 -0
  89. package/lib/typescript/src/controllers.ios.d.ts.map +1 -0
  90. package/lib/typescript/src/controllers.native.d.ts +3 -0
  91. package/lib/typescript/src/controllers.native.d.ts.map +1 -0
  92. package/lib/typescript/src/geometry.d.ts +22 -12
  93. package/lib/typescript/src/geometry.d.ts.map +1 -1
  94. package/lib/typescript/src/groupTypes.d.ts +31 -0
  95. package/lib/typescript/src/groupTypes.d.ts.map +1 -0
  96. package/lib/typescript/src/groups.android.d.ts +2 -0
  97. package/lib/typescript/src/groups.android.d.ts.map +1 -0
  98. package/lib/typescript/src/groups.d.ts +2 -0
  99. package/lib/typescript/src/groups.d.ts.map +1 -0
  100. package/lib/typescript/src/groups.ios.d.ts +2 -0
  101. package/lib/typescript/src/groups.ios.d.ts.map +1 -0
  102. package/lib/typescript/src/groups.native.d.ts +3 -0
  103. package/lib/typescript/src/groups.native.d.ts.map +1 -0
  104. package/lib/typescript/src/ids.d.ts +2 -0
  105. package/lib/typescript/src/ids.d.ts.map +1 -0
  106. package/lib/typescript/src/index.d.ts +6 -6
  107. package/lib/typescript/src/index.d.ts.map +1 -1
  108. package/lib/typescript/src/nativeCompletion.d.ts +16 -6
  109. package/lib/typescript/src/nativeCompletion.d.ts.map +1 -1
  110. package/lib/typescript/src/presentationCodec.d.ts +10 -0
  111. package/lib/typescript/src/presentationCodec.d.ts.map +1 -0
  112. package/package.json +8 -3
  113. package/src/NativeSmoothClipModule.ts +41 -292
  114. package/src/SmoothClipView.ios.tsx +130 -23
  115. package/src/SmoothClipView.tsx +5 -1
  116. package/src/SmoothClipViewNativeComponent.ts +20 -26
  117. package/src/capabilities.native.ts +2 -52
  118. package/src/capabilityTypes.ts +0 -14
  119. package/src/controllerInternals.ts +52 -0
  120. package/src/controllerLifecycle.ts +6 -0
  121. package/src/controllerTypes.ts +87 -0
  122. package/src/controllers.android.ts +1 -0
  123. package/src/controllers.ios.ts +1 -0
  124. package/src/controllers.native.ts +104 -0
  125. package/src/controllers.ts +1 -0
  126. package/src/geometry.ts +118 -74
  127. package/src/groupTypes.ts +53 -0
  128. package/src/groups.android.ts +1 -0
  129. package/src/groups.ios.ts +1 -0
  130. package/src/groups.native.ts +604 -0
  131. package/src/groups.ts +1 -0
  132. package/src/ids.ts +6 -0
  133. package/src/index.ts +20 -28
  134. package/src/nativeCompletion.ts +67 -32
  135. package/src/presentationCodec.ts +134 -0
  136. package/lib/module/driverState.js +0 -82
  137. package/lib/module/driverState.js.map +0 -1
  138. package/lib/module/driverTypes.js +0 -4
  139. package/lib/module/driverTypes.js.map +0 -1
  140. package/lib/module/drivers.android.js +0 -6
  141. package/lib/module/drivers.android.js.map +0 -1
  142. package/lib/module/drivers.ios.js +0 -6
  143. package/lib/module/drivers.ios.js.map +0 -1
  144. package/lib/module/drivers.js +0 -4
  145. package/lib/module/drivers.js.map +0 -1
  146. package/lib/module/drivers.native.js +0 -756
  147. package/lib/module/drivers.native.js.map +0 -1
  148. package/lib/module/groupDriverTypes.js +0 -4
  149. package/lib/module/groupDrivers.android.js +0 -4
  150. package/lib/module/groupDrivers.android.js.map +0 -1
  151. package/lib/module/groupDrivers.ios.js +0 -4
  152. package/lib/module/groupDrivers.ios.js.map +0 -1
  153. package/lib/module/groupDrivers.js +0 -4
  154. package/lib/module/groupDrivers.js.map +0 -1
  155. package/lib/module/groupDrivers.native.js +0 -799
  156. package/lib/module/groupDrivers.native.js.map +0 -1
  157. package/lib/module/presentationProtocol.js +0 -15
  158. package/lib/module/presentationProtocol.js.map +0 -1
  159. package/lib/module/reactRequests.js +0 -56
  160. package/lib/module/reactRequests.js.map +0 -1
  161. package/lib/typescript/src/driverState.d.ts +0 -26
  162. package/lib/typescript/src/driverState.d.ts.map +0 -1
  163. package/lib/typescript/src/driverTypes.d.ts +0 -121
  164. package/lib/typescript/src/driverTypes.d.ts.map +0 -1
  165. package/lib/typescript/src/drivers.android.d.ts +0 -3
  166. package/lib/typescript/src/drivers.android.d.ts.map +0 -1
  167. package/lib/typescript/src/drivers.d.ts +0 -3
  168. package/lib/typescript/src/drivers.d.ts.map +0 -1
  169. package/lib/typescript/src/drivers.ios.d.ts +0 -3
  170. package/lib/typescript/src/drivers.ios.d.ts.map +0 -1
  171. package/lib/typescript/src/drivers.native.d.ts +0 -5
  172. package/lib/typescript/src/drivers.native.d.ts.map +0 -1
  173. package/lib/typescript/src/groupDriverTypes.d.ts +0 -66
  174. package/lib/typescript/src/groupDriverTypes.d.ts.map +0 -1
  175. package/lib/typescript/src/groupDrivers.android.d.ts +0 -2
  176. package/lib/typescript/src/groupDrivers.android.d.ts.map +0 -1
  177. package/lib/typescript/src/groupDrivers.d.ts +0 -2
  178. package/lib/typescript/src/groupDrivers.d.ts.map +0 -1
  179. package/lib/typescript/src/groupDrivers.ios.d.ts +0 -2
  180. package/lib/typescript/src/groupDrivers.ios.d.ts.map +0 -1
  181. package/lib/typescript/src/groupDrivers.native.d.ts +0 -4
  182. package/lib/typescript/src/groupDrivers.native.d.ts.map +0 -1
  183. package/lib/typescript/src/presentationProtocol.d.ts +0 -4
  184. package/lib/typescript/src/presentationProtocol.d.ts.map +0 -1
  185. package/lib/typescript/src/reactRequests.d.ts +0 -9
  186. package/lib/typescript/src/reactRequests.d.ts.map +0 -1
  187. package/src/driverState.ts +0 -118
  188. package/src/driverTypes.ts +0 -171
  189. package/src/drivers.android.ts +0 -8
  190. package/src/drivers.ios.ts +0 -8
  191. package/src/drivers.native.ts +0 -1599
  192. package/src/drivers.ts +0 -6
  193. package/src/groupDriverTypes.ts +0 -117
  194. package/src/groupDrivers.android.ts +0 -1
  195. package/src/groupDrivers.ios.ts +0 -1
  196. package/src/groupDrivers.native.ts +0 -1189
  197. package/src/groupDrivers.ts +0 -1
  198. package/src/presentationProtocol.ts +0 -28
  199. package/src/reactRequests.ts +0 -76
@@ -27,6 +27,9 @@ namespace smoothclip {
27
27
  namespace {
28
28
 
29
29
  constexpr double kMaxSafeJavaScriptInteger = 9007199254740991.0;
30
+ constexpr size_t kPresentationStride = 21;
31
+ constexpr size_t kSnapshotStride = kPresentationStride + 1;
32
+ constexpr size_t kMotionEntryStride = kPresentationStride * 2 + 2;
30
33
 
31
34
  bool validDriverId(double value) {
32
35
  return std::isfinite(value) && value > 0 &&
@@ -43,7 +46,7 @@ bool validRadiusOverride(double value) {
43
46
  return std::isfinite(value) || std::isnan(value);
44
47
  }
45
48
 
46
- bool finitePresentation(const Presentation &presentation) {
49
+ bool finiteBasePresentation(const Presentation &presentation) {
47
50
  return std::isfinite(presentation.clip.x) &&
48
51
  std::isfinite(presentation.clip.y) &&
49
52
  std::isfinite(presentation.clip.width) &&
@@ -61,18 +64,43 @@ bool finitePresentation(const Presentation &presentation) {
61
64
  presentation.contentScale > 0;
62
65
  }
63
66
 
64
- bool finiteV2Presentation(const Presentation &presentation) {
65
- return finitePresentation(presentation) &&
67
+ bool finitePresentation(const Presentation &presentation) {
68
+ return finiteBasePresentation(presentation) &&
66
69
  std::isfinite(presentation.clip.topLeftRadius) &&
67
70
  std::isfinite(presentation.clip.topRightRadius) &&
68
71
  std::isfinite(presentation.clip.bottomRightRadius) &&
69
- std::isfinite(presentation.clip.bottomLeftRadius);
72
+ std::isfinite(presentation.clip.bottomLeftRadius) &&
73
+ std::isfinite(presentation.shadow.red) &&
74
+ std::isfinite(presentation.shadow.green) &&
75
+ std::isfinite(presentation.shadow.blue) &&
76
+ std::isfinite(presentation.shadow.alpha) &&
77
+ std::isfinite(presentation.shadow.offsetX) &&
78
+ std::isfinite(presentation.shadow.offsetY) &&
79
+ std::isfinite(presentation.shadow.blurRadius) &&
80
+ std::isfinite(presentation.shadow.spreadDistance) &&
81
+ presentation.shadow.red >= 0 && presentation.shadow.red <= 1 &&
82
+ presentation.shadow.green >= 0 && presentation.shadow.green <= 1 &&
83
+ presentation.shadow.blue >= 0 && presentation.shadow.blue <= 1 &&
84
+ presentation.shadow.alpha >= 0 && presentation.shadow.alpha <= 1 &&
85
+ presentation.shadow.blurRadius >= 0;
70
86
  }
71
87
 
72
88
  bool boolArg(const Value *args, size_t count, size_t index) {
73
89
  return index < count && args[index].isBool() && args[index].getBool();
74
90
  }
75
91
 
92
+ bool numberAt(
93
+ Runtime &runtime,
94
+ const Array &values,
95
+ size_t index,
96
+ double &result) {
97
+ if (index >= values.size(runtime)) return false;
98
+ const Value value = values.getValueAtIndex(runtime, index);
99
+ if (!value.isNumber()) return false;
100
+ result = value.asNumber();
101
+ return std::isfinite(result);
102
+ }
103
+
76
104
  // Optional trailing start stamp (Reanimated-rule milliseconds captured in the
77
105
  // issuing worklet), converted to the registry's CLOCK_MONOTONIC seconds. A
78
106
  // missing or non-numeric argument — and the JS side's deliberate NaN fallback
@@ -85,237 +113,123 @@ double startStampArg(const Value *args, size_t count, size_t index) {
85
113
  : std::numeric_limits<double>::quiet_NaN();
86
114
  }
87
115
 
88
- Presentation presentationFromArgs(const Value *args, size_t offset) {
89
- return Presentation{
90
- {args[offset].asNumber(),
91
- args[offset + 1].asNumber(),
92
- args[offset + 2].asNumber(),
93
- args[offset + 3].asNumber(),
94
- args[offset + 4].asNumber()},
95
- args[offset + 5].asNumber(),
96
- args[offset + 6].asNumber()};
97
- }
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(
116
+ bool presentationAt(
129
117
  Runtime &runtime,
130
118
  const Array &values,
131
- size_t offset) {
119
+ size_t offset,
120
+ Presentation &result) {
121
+ const size_t length = values.size(runtime);
122
+ if (offset > length || length - offset < kPresentationStride) {
123
+ return false;
124
+ }
125
+ double packet[kPresentationStride];
126
+ for (size_t index = 0; index < kPresentationStride; index += 1) {
127
+ const Value value = values.getValueAtIndex(runtime, offset + index);
128
+ if (!value.isNumber()) return false;
129
+ packet[index] = value.asNumber();
130
+ }
131
+ const double curveCode = packet[8];
132
+ if (!validCurve(curveCode) ||
133
+ (packet[12] != 0.0 && packet[12] != 1.0)) {
134
+ return false;
135
+ }
132
136
  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
+ packet[0], packet[1], packet[2], packet[3],
137
138
  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();
139
+ geometry.topLeftRadius = packet[4];
140
+ geometry.topRightRadius = packet[5];
141
+ geometry.bottomRightRadius = packet[6];
142
+ geometry.bottomLeftRadius = packet[7];
148
143
  geometry.curve = curveCode == static_cast<double>(ClipCurve::Continuous)
149
144
  ? ClipCurve::Continuous
150
- : curveCode == static_cast<double>(ClipCurve::Circular)
151
- ? ClipCurve::Circular
152
- : static_cast<ClipCurve>(-1);
145
+ : ClipCurve::Circular;
153
146
  if (geometry.topLeftRadius == geometry.topRightRadius &&
154
147
  geometry.topLeftRadius == geometry.bottomRightRadius &&
155
148
  geometry.topLeftRadius == geometry.bottomLeftRadius) {
156
149
  geometry.radius = geometry.topLeftRadius;
157
150
  }
158
- return Presentation{
151
+ result = Presentation{
159
152
  geometry,
160
- values.getValueAtIndex(runtime, offset + 9).asNumber(),
161
- values.getValueAtIndex(runtime, offset + 10).asNumber(),
162
- values.getValueAtIndex(runtime, offset + 11).asNumber()};
153
+ packet[9], packet[10], packet[11],
154
+ Shadow{
155
+ packet[12] == 1.0,
156
+ packet[13], packet[14], packet[15], packet[16],
157
+ packet[17], packet[18], packet[19], packet[20]}};
158
+ return finitePresentation(result);
163
159
  }
164
160
 
165
- Array presentationArray(Runtime &runtime, const Presentation &presentation) {
166
- Array result(runtime, 7);
167
- result.setValueAtIndex(runtime, 0, presentation.clip.x);
168
- result.setValueAtIndex(runtime, 1, presentation.clip.y);
169
- result.setValueAtIndex(runtime, 2, presentation.clip.width);
170
- result.setValueAtIndex(runtime, 3, presentation.clip.height);
171
- result.setValueAtIndex(runtime, 4, presentation.clip.radius);
172
- result.setValueAtIndex(runtime, 5, presentation.contentTranslateX);
173
- result.setValueAtIndex(runtime, 6, presentation.contentTranslateY);
174
- return result;
175
- }
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));
161
+ void appendPresentation(
162
+ Runtime &runtime,
163
+ Array &result,
164
+ size_t &offset,
165
+ const Presentation &presentation) {
166
+ result.setValueAtIndex(runtime, offset++, presentation.clip.x);
167
+ result.setValueAtIndex(runtime, offset++, presentation.clip.y);
168
+ result.setValueAtIndex(runtime, offset++, presentation.clip.width);
169
+ result.setValueAtIndex(runtime, offset++, presentation.clip.height);
170
+ result.setValueAtIndex(runtime, offset++, SmoothClipResolvedRadius(
171
+ presentation.clip.topLeftRadius, presentation.clip.radius));
172
+ result.setValueAtIndex(runtime, offset++, SmoothClipResolvedRadius(
173
+ presentation.clip.topRightRadius, presentation.clip.radius));
174
+ result.setValueAtIndex(runtime, offset++, SmoothClipResolvedRadius(
175
+ presentation.clip.bottomRightRadius, presentation.clip.radius));
176
+ result.setValueAtIndex(runtime, offset++, SmoothClipResolvedRadius(
177
+ presentation.clip.bottomLeftRadius, presentation.clip.radius));
198
178
  result.setValueAtIndex(
199
- runtime,
200
- 7,
201
- SmoothClipResolvedRadius(
202
- presentation.clip.bottomLeftRadius, presentation.clip.radius));
179
+ runtime, offset++, static_cast<double>(presentation.clip.curve));
180
+ result.setValueAtIndex(runtime, offset++, presentation.contentTranslateX);
181
+ result.setValueAtIndex(runtime, offset++, presentation.contentTranslateY);
182
+ result.setValueAtIndex(runtime, offset++, presentation.contentScale);
203
183
  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;
184
+ runtime, offset++, presentation.shadow.enabled ? 1.0 : 0.0);
185
+ result.setValueAtIndex(runtime, offset++, presentation.shadow.red);
186
+ result.setValueAtIndex(runtime, offset++, presentation.shadow.green);
187
+ result.setValueAtIndex(runtime, offset++, presentation.shadow.blue);
188
+ result.setValueAtIndex(runtime, offset++, presentation.shadow.alpha);
189
+ result.setValueAtIndex(runtime, offset++, presentation.shadow.offsetX);
190
+ result.setValueAtIndex(runtime, offset++, presentation.shadow.offsetY);
191
+ result.setValueAtIndex(runtime, offset++, presentation.shadow.blurRadius);
192
+ result.setValueAtIndex(runtime, offset++, presentation.shadow.spreadDistance);
209
193
  }
210
194
 
211
- Array cancelResultArray(
212
- Runtime &runtime,
213
- bool handled,
214
- const Presentation &presentation) {
215
- Array result(runtime, 8);
216
- // JS checks `values[0] !== 1`, so the handled flag must be a number.
217
- result.setValueAtIndex(runtime, 0, handled ? 1.0 : 0.0);
218
- result.setValueAtIndex(runtime, 1, presentation.clip.x);
219
- result.setValueAtIndex(runtime, 2, presentation.clip.y);
220
- result.setValueAtIndex(runtime, 3, presentation.clip.width);
221
- result.setValueAtIndex(runtime, 4, presentation.clip.height);
222
- result.setValueAtIndex(runtime, 5, presentation.clip.radius);
223
- result.setValueAtIndex(runtime, 6, presentation.contentTranslateX);
224
- result.setValueAtIndex(runtime, 7, presentation.contentTranslateY);
195
+ Array presentationArray(Runtime &runtime, const Presentation &presentation) {
196
+ Array result(runtime, kPresentationStride);
197
+ size_t offset = 0;
198
+ appendPresentation(runtime, result, offset, presentation);
225
199
  return result;
226
200
  }
227
201
 
228
- Array cancelResultArrayV2(
202
+ Array cancelResultArray(
229
203
  Runtime &runtime,
230
204
  bool handled,
231
205
  const Presentation &presentation) {
232
- Array result(runtime, 13);
206
+ Array result(runtime, kSnapshotStride);
233
207
  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);
208
+ size_t offset = 1;
209
+ appendPresentation(runtime, result, offset, presentation);
263
210
  return result;
264
211
  }
265
212
 
266
- Array snapshotsArrayV2(
213
+ Array snapshotsArray(
267
214
  Runtime &runtime,
268
215
  const std::vector<DriverSnapshot> &snapshots) {
269
- Array result(runtime, snapshots.size() * 13);
216
+ Array result(runtime, snapshots.size() * kSnapshotStride);
270
217
  size_t offset = 0;
271
218
  for (const DriverSnapshot &snapshot : snapshots) {
272
219
  result.setValueAtIndex(runtime, offset++, snapshot.ready ? 1.0 : 0.0);
273
220
  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);
221
+ appendPresentation(runtime, result, offset, presentation);
303
222
  }
304
223
  return result;
305
224
  }
306
225
 
307
- bool validSuspensionPolicy(double value) {
308
- return value == static_cast<double>(GroupSuspensionPolicy::Pause) ||
309
- value == static_cast<double>(GroupSuspensionPolicy::Finish);
310
- }
311
-
312
226
  std::vector<uint64_t> driverIdsFromArray(Runtime &runtime, const Array &values) {
313
227
  std::vector<uint64_t> driverIds;
314
228
  const size_t length = values.size(runtime);
315
229
  driverIds.reserve(length);
316
230
  for (size_t index = 0; index < length; index += 1) {
317
- const double value = values.getValueAtIndex(runtime, index).asNumber();
318
- if (!validDriverId(value) ||
231
+ double value;
232
+ if (!numberAt(runtime, values, index, value) || !validDriverId(value) ||
319
233
  std::find(driverIds.begin(), driverIds.end(),
320
234
  static_cast<uint64_t>(value)) != driverIds.end()) {
321
235
  return {};
@@ -330,96 +244,32 @@ bool parseGroupMotionEntries(
330
244
  const Array &values,
331
245
  std::vector<GroupMotionEntry> &entries) {
332
246
  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) ||
247
+ if (length < kMotionEntryStride || length % kMotionEntryStride != 0) {
248
+ return false;
249
+ }
250
+ entries.reserve(length / kMotionEntryStride);
251
+ for (size_t index = 0; index < length; index += kMotionEntryStride) {
252
+ double driverId;
253
+ double hasFromValue;
254
+ Presentation from;
255
+ Presentation target;
256
+ if (!numberAt(runtime, values, index, driverId) ||
257
+ !numberAt(runtime, values, index + 1, hasFromValue) ||
258
+ !presentationAt(runtime, values, index + 2, from) ||
259
+ !presentationAt(
260
+ runtime, values, index + 2 + kPresentationStride, target) ||
261
+ !validDriverId(driverId) ||
348
262
  (hasFromValue != 0.0 && hasFromValue != 1.0) ||
349
- !validCurve(fromCurve) || !validCurve(targetCurve) ||
350
- !finiteV2Presentation(from) || !finiteV2Presentation(target)) {
263
+ !finitePresentation(from) || !finitePresentation(target)) {
351
264
  entries.clear();
352
265
  return false;
353
266
  }
354
267
  entries.push_back(
355
- {static_cast<uint64_t>(driverId), hasFromValue == 1.0, from, target, {}});
268
+ {static_cast<uint64_t>(driverId), hasFromValue == 1.0, from, target});
356
269
  }
357
270
  return true;
358
271
  }
359
272
 
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
-
423
273
  struct BindingsState {
424
274
  Runtime *runtime = nullptr;
425
275
  std::shared_ptr<CallInvoker> callInvoker;
@@ -466,10 +316,15 @@ void installBindings(
466
316
 
467
317
  setCompletionCallback(
468
318
  state.get(),
469
- [state](uint64_t driverId, int32_t animationId, bool finished) {
319
+ [state](
320
+ uint64_t driverId,
321
+ int32_t animationId,
322
+ int32_t completionTag,
323
+ bool finished) {
470
324
  auto invoker = state->callInvoker;
471
325
  if (!invoker) return;
472
- invoker->invokeAsync([state, driverId, animationId, finished]() {
326
+ invoker->invokeAsync(
327
+ [state, driverId, animationId, completionTag, finished]() {
473
328
  if (state->runtime == nullptr) return;
474
329
  Runtime &rt = *state->runtime;
475
330
  std::vector<std::shared_ptr<Function>> snapshot;
@@ -481,6 +336,7 @@ void installBindings(
481
336
  Object result(rt);
482
337
  result.setProperty(rt, "driverId", static_cast<double>(driverId));
483
338
  result.setProperty(rt, "animationId", animationId);
339
+ result.setProperty(rt, "completionTag", completionTag);
484
340
  result.setProperty(rt, "finished", finished);
485
341
  listener->call(rt, std::move(result));
486
342
  }
@@ -492,13 +348,14 @@ void installBindings(
492
348
  [state](
493
349
  uint64_t controllerId,
494
350
  int32_t groupId,
351
+ int32_t completionTag,
495
352
  bool finished,
496
- std::vector<uint64_t> driverIds) {
353
+ std::vector<DriverSnapshot> snapshots) {
497
354
  auto invoker = state->callInvoker;
498
355
  if (!invoker) return;
499
356
  invoker->invokeAsync(
500
- [state, controllerId, groupId, finished,
501
- driverIds = std::move(driverIds)]() {
357
+ [state, controllerId, groupId, completionTag, finished,
358
+ snapshots = std::move(snapshots)]() {
502
359
  if (state->runtime == nullptr) return;
503
360
  Runtime &rt = *state->runtime;
504
361
  std::vector<std::shared_ptr<Function>> snapshot;
@@ -511,13 +368,10 @@ void installBindings(
511
368
  result.setProperty(
512
369
  rt, "controllerId", static_cast<double>(controllerId));
513
370
  result.setProperty(rt, "groupId", groupId);
371
+ result.setProperty(rt, "completionTag", completionTag);
514
372
  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));
373
+ result.setProperty(
374
+ rt, "snapshots", snapshotsArray(rt, snapshots));
521
375
  listener->call(rt, std::move(result));
522
376
  }
523
377
  });
@@ -525,12 +379,6 @@ void installBindings(
525
379
 
526
380
  Object bindings(runtime);
527
381
 
528
- setHostFunction(
529
- runtime, bindings, "getPresentationProtocolVersion", 0,
530
- [](Runtime &, const Value &, const Value *, size_t) -> Value {
531
- return Value(2);
532
- });
533
-
534
382
  setHostFunction(
535
383
  runtime, bindings, "supportsAutonomousComplexPathAnimation", 0,
536
384
  [](Runtime &, const Value &, const Value *, size_t) -> Value {
@@ -541,7 +389,7 @@ void installBindings(
541
389
  });
542
390
 
543
391
  setHostFunction(
544
- runtime, bindings, "beginGroupInteractionV2", 1,
392
+ runtime, bindings, "beginGroupInteraction", 1,
545
393
  [](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
546
394
  if (count < 1 || !args[0].isObject() ||
547
395
  !args[0].getObject(rt).isArray(rt)) {
@@ -550,11 +398,11 @@ void installBindings(
550
398
  Array values = args[0].getObject(rt).getArray(rt);
551
399
  const std::vector<uint64_t> driverIds = driverIdsFromArray(rt, values);
552
400
  if (driverIds.empty()) return Array(rt, 0);
553
- return snapshotsArrayV2(rt, beginGroupInteraction(driverIds));
401
+ return snapshotsArray(rt, beginGroupInteraction(driverIds));
554
402
  });
555
403
 
556
404
  setHostFunction(
557
- runtime, bindings, "snapshotGroupV2", 1,
405
+ runtime, bindings, "snapshotGroup", 1,
558
406
  [](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
559
407
  if (count < 1 || !args[0].isObject() ||
560
408
  !args[0].getObject(rt).isArray(rt)) {
@@ -563,11 +411,11 @@ void installBindings(
563
411
  Array values = args[0].getObject(rt).getArray(rt);
564
412
  const std::vector<uint64_t> driverIds = driverIdsFromArray(rt, values);
565
413
  if (driverIds.empty()) return Array(rt, 0);
566
- return snapshotsArrayV2(rt, snapshotGroup(driverIds));
414
+ return snapshotsArray(rt, snapshotGroup(driverIds));
567
415
  });
568
416
 
569
417
  setHostFunction(
570
- runtime, bindings, "setClipPresentationBatchV2", 1,
418
+ runtime, bindings, "setClipPresentationBatch", 1,
571
419
  [](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
572
420
  if (count < 1 || !args[0].isObject() ||
573
421
  !args[0].getObject(rt).isArray(rt)) {
@@ -575,18 +423,17 @@ void installBindings(
575
423
  }
576
424
  Array values = args[0].getObject(rt).getArray(rt);
577
425
  const size_t length = values.size(rt);
578
- if (length < 13 || length % 13 != 0) return Value(false);
426
+ if (length < kSnapshotStride || length % kSnapshotStride != 0) {
427
+ return Value(false);
428
+ }
579
429
  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)) {
430
+ entries.reserve(length / kSnapshotStride);
431
+ for (size_t index = 0; index < length; index += kSnapshotStride) {
432
+ double driverId;
433
+ Presentation presentation;
434
+ if (!numberAt(rt, values, index, driverId) ||
435
+ !presentationAt(rt, values, index + 1, presentation) ||
436
+ !validDriverId(driverId) || !finitePresentation(presentation)) {
590
437
  return Value(false);
591
438
  }
592
439
  entries.push_back(
@@ -596,9 +443,9 @@ void installBindings(
596
443
  });
597
444
 
598
445
  setHostFunction(
599
- runtime, bindings, "animateTimingGroupV2", 10,
446
+ runtime, bindings, "animateTimingGroup", 10,
600
447
  [](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
601
- if (count < 9 || !args[1].isObject() ||
448
+ if (count < 10 || !args[1].isObject() ||
602
449
  !args[1].getObject(rt).isArray(rt)) {
603
450
  return Value(0);
604
451
  }
@@ -609,7 +456,6 @@ void installBindings(
609
456
  args[2].asNumber(), args[3].asNumber(), args[4].asNumber(),
610
457
  args[5].asNumber(), args[6].asNumber(),
611
458
  static_cast<int32_t>(args[7].asNumber())};
612
- const double suspension = args[8].asNumber();
613
459
  if (!validDriverId(controllerId) ||
614
460
  !parseGroupMotionEntries(rt, values, entries) ||
615
461
  !std::isfinite(animation.durationMs) ||
@@ -617,22 +463,21 @@ void installBindings(
617
463
  !std::isfinite(animation.controlPoint1Y) ||
618
464
  !std::isfinite(animation.controlPoint2X) ||
619
465
  !std::isfinite(animation.controlPoint2Y) ||
620
- !validSuspensionPolicy(suspension)) {
466
+ !std::isfinite(args[8].asNumber())) {
621
467
  return Value(0);
622
468
  }
623
469
  return Value(animateTimingGroup(
624
470
  static_cast<uint64_t>(controllerId),
625
471
  std::move(entries),
626
472
  animation,
627
- static_cast<GroupSuspensionPolicy>(
628
- static_cast<int32_t>(suspension)),
473
+ static_cast<int32_t>(args[8].asNumber()),
629
474
  startStampArg(args, count, 9)));
630
475
  });
631
476
 
632
477
  setHostFunction(
633
- runtime, bindings, "animateSpringGroupV2", 10,
478
+ runtime, bindings, "animateSpringGroup", 10,
634
479
  [](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
635
- if (count < 9 || !args[1].isObject() ||
480
+ if (count < 10 || !args[1].isObject() ||
636
481
  !args[1].getObject(rt).isArray(rt)) {
637
482
  return Value(0);
638
483
  }
@@ -641,59 +486,30 @@ void installBindings(
641
486
  std::vector<GroupMotionEntry> entries;
642
487
  const SpringAnimation animation{
643
488
  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();
489
+ args[5].asNumber(), false,
490
+ static_cast<int32_t>(args[7].asNumber()),
491
+ args[6].asNumber()};
647
492
  if (!validDriverId(controllerId) ||
648
493
  !parseGroupMotionEntries(rt, values, entries) ||
649
494
  !std::isfinite(animation.mass) ||
650
495
  !std::isfinite(animation.stiffness) ||
651
496
  !std::isfinite(animation.damping) ||
652
497
  !std::isfinite(animation.initialVelocity) || animation.mass <= 0 ||
653
- animation.stiffness <= 0 || animation.damping < 0 ||
654
- !validSuspensionPolicy(suspension)) {
498
+ !std::isfinite(animation.energyThreshold) ||
499
+ !std::isfinite(args[8].asNumber()) || animation.stiffness <= 0 ||
500
+ animation.damping < 0 || animation.energyThreshold <= 0) {
655
501
  return Value(0);
656
502
  }
657
503
  return Value(animateSpringGroup(
658
504
  static_cast<uint64_t>(controllerId),
659
505
  std::move(entries),
660
506
  animation,
661
- static_cast<GroupSuspensionPolicy>(
662
- static_cast<int32_t>(suspension)),
507
+ static_cast<int32_t>(args[8].asNumber()),
663
508
  startStampArg(args, count, 9)));
664
509
  });
665
510
 
666
511
  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,
512
+ runtime, bindings, "cancelAnimationGroup", 2,
697
513
  [](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
698
514
  if (count < 2 || !args[0].isNumber() || !args[1].isNumber()) {
699
515
  return Array(rt, 0);
@@ -706,7 +522,7 @@ void installBindings(
706
522
  behavior != static_cast<double>(GroupCancelBehavior::Finish))) {
707
523
  return Array(rt, 0);
708
524
  }
709
- return snapshotsArrayV2(
525
+ return snapshotsArray(
710
526
  rt,
711
527
  cancelAnimationGroup(
712
528
  static_cast<int32_t>(groupId),
@@ -715,40 +531,65 @@ void installBindings(
715
531
  });
716
532
 
717
533
  setHostFunction(
718
- runtime, bindings, "setClipPresentation", 11,
534
+ runtime, bindings, "setClipPresentation", 4,
719
535
  [](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
720
- if (count < 9) return Value::undefined();
536
+ if (count < 4 || !args[0].isNumber() || !args[1].isObject() ||
537
+ !args[1].getObject(rt).isArray(rt)) {
538
+ return Value::undefined();
539
+ }
721
540
  const double driverId = args[0].asNumber();
722
- const Presentation presentation = presentationFromArgs(args, 1);
723
- const bool takeOwnership = boolArg(args, count, 8);
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());
729
- if (validDriverId(driverId) && finitePresentation(presentation)) {
541
+ const Array values = args[1].getObject(rt).getArray(rt);
542
+ Presentation presentation;
543
+ if (values.size(rt) == kPresentationStride &&
544
+ validDriverId(driverId) &&
545
+ presentationAt(rt, values, 0, presentation)) {
730
546
  setPresentation(
731
- static_cast<uint64_t>(driverId), presentation, takeOwnership,
732
- overridePendingAnimation, recordVelocity);
547
+ static_cast<uint64_t>(driverId), presentation,
548
+ boolArg(args, count, 2), boolArg(args, count, 3), true);
733
549
  }
734
550
  return Value::undefined();
735
551
  });
736
552
 
737
553
  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();
554
+ runtime, bindings, "setClipFrameScalars", 22,
555
+ [](Runtime &, const Value &, const Value *args, size_t count) -> Value {
556
+ if (count < 22) return Value::undefined();
741
557
  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());
558
+ Geometry geometry{
559
+ args[1].asNumber(), args[2].asNumber(), args[3].asNumber(),
560
+ args[4].asNumber(), 0};
561
+ geometry.topLeftRadius = args[5].asNumber();
562
+ geometry.topRightRadius = args[6].asNumber();
563
+ geometry.bottomRightRadius = args[7].asNumber();
564
+ geometry.bottomLeftRadius = args[8].asNumber();
565
+ geometry.curve = static_cast<ClipCurve>(
566
+ static_cast<int32_t>(args[9].asNumber()));
567
+ if (geometry.topLeftRadius == geometry.topRightRadius &&
568
+ geometry.topLeftRadius == geometry.bottomRightRadius &&
569
+ geometry.topLeftRadius == geometry.bottomLeftRadius) {
570
+ geometry.radius = geometry.topLeftRadius;
571
+ }
572
+ const Presentation presentation{
573
+ geometry,
574
+ args[10].asNumber(),
575
+ args[11].asNumber(),
576
+ args[12].asNumber(),
577
+ {
578
+ boolArg(args, count, 13),
579
+ args[14].asNumber(),
580
+ args[15].asNumber(),
581
+ args[16].asNumber(),
582
+ args[17].asNumber(),
583
+ args[18].asNumber(),
584
+ args[19].asNumber(),
585
+ args[20].asNumber(),
586
+ args[21].asNumber(),
587
+ }};
747
588
  if (validDriverId(driverId) && validCurve(args[9].asNumber()) &&
748
- finiteV2Presentation(presentation)) {
589
+ finitePresentation(presentation)) {
749
590
  setPresentation(
750
- static_cast<uint64_t>(driverId), presentation, takeOwnership,
751
- overridePendingAnimation, recordVelocity);
591
+ static_cast<uint64_t>(driverId), presentation,
592
+ true, false, true);
752
593
  }
753
594
  return Value::undefined();
754
595
  });
@@ -764,268 +605,78 @@ void installBindings(
764
605
  });
765
606
 
766
607
  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,
608
+ runtime, bindings, "snapshotCurrent", 1,
778
609
  [](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
779
610
  if (count < 1 || !validDriverId(args[0].asNumber())) {
780
- return presentationArrayV2(rt, {{0, 0, 0, 0, 0}, 0, 0});
611
+ return presentationArray(rt, {{0, 0, 0, 0, 0}, 0, 0});
781
612
  }
782
- return presentationArrayV2(
613
+ return presentationArray(
783
614
  rt,
784
615
  snapshotCurrentAndroid(
785
616
  static_cast<uint64_t>(args[0].asNumber())));
786
617
  });
787
618
 
788
619
  setHostFunction(
789
- runtime, bindings, "animateTiming", 23,
620
+ runtime, bindings, "animateTiming", 11,
790
621
  [](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
791
- if (count < 22) return Value(0);
792
- const double driverId = args[0].asNumber();
793
- const Presentation start = presentationFromArgs(args, 2);
794
- const Presentation target = presentationFromArgs(args, 9);
795
- const TimingAnimation animation{
796
- args[16].asNumber(), args[17].asNumber(), args[18].asNumber(),
797
- args[19].asNumber(), args[20].asNumber(),
798
- static_cast<int32_t>(args[21].asNumber())};
799
- if (!validDriverId(driverId) || !finitePresentation(start) ||
800
- !finitePresentation(target) ||
801
- !std::isfinite(animation.durationMs)) {
622
+ if (count < 10 || !args[0].isNumber() || !args[1].isObject() ||
623
+ !args[1].getObject(rt).isArray(rt) || !args[2].isObject() ||
624
+ !args[2].getObject(rt).isArray(rt) || !args[9].isNumber() ||
625
+ !std::isfinite(args[9].asNumber())) {
802
626
  return Value(0);
803
627
  }
804
- return Value(animateTiming(
805
- static_cast<uint64_t>(driverId),
806
- {boolArg(args, count, 1), start, startStampArg(args, count, 22)},
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
628
  const double driverId = args[0].asNumber();
817
- const Presentation start = presentationV2FromArgs(args, 2);
818
- const Presentation target = presentationV2FromArgs(args, 14);
629
+ const Array startValues = args[1].getObject(rt).getArray(rt);
630
+ const Array targetValues = args[2].getObject(rt).getArray(rt);
631
+ const bool hasInteractiveStart = startValues.size(rt) != 0;
632
+ Presentation start{};
633
+ Presentation target;
819
634
  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) ||
635
+ args[3].asNumber(), args[4].asNumber(), args[5].asNumber(),
636
+ args[6].asNumber(), args[7].asNumber(),
637
+ static_cast<int32_t>(args[8].asNumber())};
638
+ if (!validDriverId(driverId) ||
639
+ (hasInteractiveStart &&
640
+ (startValues.size(rt) != kPresentationStride ||
641
+ !presentationAt(rt, startValues, 0, start))) ||
642
+ targetValues.size(rt) != kPresentationStride ||
643
+ !presentationAt(rt, targetValues, 0, target) ||
826
644
  !std::isfinite(animation.durationMs)) {
827
645
  return Value(0);
828
646
  }
829
647
  return Value(animateTiming(
830
648
  static_cast<uint64_t>(driverId),
831
- {boolArg(args, count, 1), start, startStampArg(args, count, 32)},
832
- target,
833
- animation));
834
- });
835
-
836
- setHostFunction(
837
- runtime, bindings, "animateSpring", 23,
838
- [](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
839
- if (count < 22) return Value(0);
840
- const double driverId = args[0].asNumber();
841
- const Presentation start = presentationFromArgs(args, 2);
842
- const Presentation target = presentationFromArgs(args, 9);
843
- const SpringAnimation animation{
844
- args[16].asNumber(), args[17].asNumber(), args[18].asNumber(),
845
- args[19].asNumber(), boolArg(args, count, 20),
846
- static_cast<int32_t>(args[21].asNumber())};
847
- if (!validDriverId(driverId) || !finitePresentation(start) ||
848
- !finitePresentation(target) || !std::isfinite(animation.mass) ||
849
- !std::isfinite(animation.stiffness) ||
850
- !std::isfinite(animation.damping) ||
851
- !std::isfinite(animation.initialVelocity)) {
852
- return Value(0);
853
- }
854
- return Value(animateSpring(
855
- static_cast<uint64_t>(driverId),
856
- {boolArg(args, count, 1), start, startStampArg(args, count, 22)},
649
+ {hasInteractiveStart, start, startStampArg(args, count, 10)},
857
650
  target,
858
651
  animation,
859
- AnimationValidationMode::LegacyV1));
652
+ static_cast<int32_t>(args[9].asNumber())));
860
653
  });
861
654
 
862
655
  setHostFunction(
863
- runtime, bindings, "animateSpringV2", 33,
656
+ runtime, bindings, "animateSpring", 11,
864
657
  [](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,
887
- animation));
888
- });
889
-
890
- setHostFunction(
891
- runtime, bindings, "animateKeyframes", 20,
892
- [](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
893
- if (count < 19 || !args[17].isObject() ||
894
- !args[17].getObject(rt).isArray(rt)) {
658
+ if (count < 10 || !args[0].isNumber() || !args[1].isObject() ||
659
+ !args[1].getObject(rt).isArray(rt) || !args[2].isObject() ||
660
+ !args[2].getObject(rt).isArray(rt) || !args[9].isNumber() ||
661
+ !std::isfinite(args[9].asNumber())) {
895
662
  return Value(0);
896
663
  }
897
664
  const double driverId = args[0].asNumber();
898
- const Presentation start = presentationFromArgs(args, 2);
899
- const Presentation target = presentationFromArgs(args, 9);
900
- const double durationMs = args[16].asNumber();
901
- const int32_t reduceMotion = static_cast<int32_t>(args[18].asNumber());
902
- Array frames = args[17].getObject(rt).getArray(rt);
903
- const size_t length = frames.size(rt);
904
- if (!validDriverId(driverId) || !finitePresentation(start) ||
905
- !finitePresentation(target) || !std::isfinite(durationMs) ||
906
- length < 16 || length % 8 != 0) {
907
- return Value(0);
908
- }
909
- std::vector<Keyframe> keyframes;
910
- keyframes.reserve(length / 8);
911
- double previousOffset = -1;
912
- for (size_t index = 0; index < length; index += 8) {
913
- const double offset = frames.getValueAtIndex(rt, index).asNumber();
914
- const Presentation frame{
915
- {frames.getValueAtIndex(rt, index + 1).asNumber(),
916
- frames.getValueAtIndex(rt, index + 2).asNumber(),
917
- frames.getValueAtIndex(rt, index + 3).asNumber(),
918
- frames.getValueAtIndex(rt, index + 4).asNumber(),
919
- frames.getValueAtIndex(rt, index + 5).asNumber()},
920
- frames.getValueAtIndex(rt, index + 6).asNumber(),
921
- frames.getValueAtIndex(rt, index + 7).asNumber()};
922
- if (!std::isfinite(offset) || offset < 0 || offset > 1 ||
923
- offset <= previousOffset || !finitePresentation(frame)) {
924
- return Value(0);
925
- }
926
- previousOffset = offset;
927
- keyframes.push_back({offset, frame});
928
- }
929
- if (keyframes.front().offset != 0 || keyframes.back().offset != 1) {
930
- return Value(0);
931
- }
932
- return Value(animateKeyframes(
933
- static_cast<uint64_t>(driverId),
934
- {boolArg(args, count, 1), start, startStampArg(args, count, 19)},
935
- target,
936
- durationMs,
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);
665
+ const Array startValues = args[1].getObject(rt).getArray(rt);
666
+ const Array targetValues = args[2].getObject(rt).getArray(rt);
667
+ const bool hasInteractiveStart = startValues.size(rt) != 0;
668
+ Presentation start{};
669
+ Presentation target;
1022
670
  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) ||
671
+ args[3].asNumber(), args[4].asNumber(), args[5].asNumber(),
672
+ args[6].asNumber(), boolArg(args, count, 7),
673
+ static_cast<int32_t>(args[8].asNumber())};
674
+ if (!validDriverId(driverId) ||
675
+ (hasInteractiveStart &&
676
+ (startValues.size(rt) != kPresentationStride ||
677
+ !presentationAt(rt, startValues, 0, start))) ||
678
+ targetValues.size(rt) != kPresentationStride ||
679
+ !presentationAt(rt, targetValues, 0, target) ||
1029
680
  !std::isfinite(animation.mass) ||
1030
681
  !std::isfinite(animation.stiffness) ||
1031
682
  !std::isfinite(animation.damping) ||
@@ -1035,58 +686,10 @@ void installBindings(
1035
686
  }
1036
687
  return Value(animateSpring(
1037
688
  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)},
689
+ {hasInteractiveStart, start, startStampArg(args, count, 10)},
1086
690
  target,
1087
- durationMs,
1088
- std::move(keyframes),
1089
- reduceMotion));
691
+ animation,
692
+ static_cast<int32_t>(args[9].asNumber())));
1090
693
  });
1091
694
 
1092
695
  setHostFunction(
@@ -1101,27 +704,14 @@ void installBindings(
1101
704
  runtime, bindings, "cancelAnimation", 3,
1102
705
  [](Runtime &rt, const Value &, const Value *args, size_t count) -> Value {
1103
706
  if (count < 3 || !validDriverId(args[0].asNumber())) {
1104
- return cancelResultArray(rt, false, {{0, 0, 0, 0, 0}, 0, 0});
1105
- }
1106
- const CancelResult result = cancelAnimation(
1107
- static_cast<uint64_t>(args[0].asNumber()),
1108
- static_cast<int32_t>(args[1].asNumber()),
1109
- static_cast<int32_t>(args[2].asNumber()) == 1);
1110
- return cancelResultArray(rt, result.handled, result.presentation);
1111
- });
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(
707
+ return cancelResultArray(
1118
708
  rt, false, {{0, 0, 0, 0, 0}, 0, 0});
1119
709
  }
1120
710
  const CancelResult result = cancelAnimation(
1121
711
  static_cast<uint64_t>(args[0].asNumber()),
1122
712
  static_cast<int32_t>(args[1].asNumber()),
1123
713
  static_cast<int32_t>(args[2].asNumber()) == 1);
1124
- return cancelResultArrayV2(
714
+ return cancelResultArray(
1125
715
  rt, result.handled, result.presentation);
1126
716
  });
1127
717
 
@@ -1214,33 +804,6 @@ jni::local_ref<BindingsInstallerHolder::javaobject> getBindingsInstaller(
1214
804
  }
1215
805
 
1216
806
  void nativeRegisterView(
1217
- jni::alias_ref<jni::JObject>,
1218
- jdouble driverId,
1219
- jni::alias_ref<smoothclip::JSmoothClipView> view,
1220
- jdouble x,
1221
- jdouble y,
1222
- jdouble width,
1223
- jdouble height,
1224
- jdouble radius,
1225
- jdouble contentTranslateX,
1226
- jdouble contentTranslateY,
1227
- jdouble density,
1228
- jdouble widthPx,
1229
- jdouble heightPx,
1230
- jboolean lifecycleVisible) {
1231
- if (driverId <= 0 || !std::isfinite(driverId)) return;
1232
- smoothclip::registerViewAndroid(
1233
- static_cast<uint64_t>(driverId),
1234
- view,
1235
- smoothclip::Presentation{
1236
- {x, y, width, height, radius}, contentTranslateX, contentTranslateY},
1237
- density,
1238
- widthPx,
1239
- heightPx,
1240
- lifecycleVisible != 0);
1241
- }
1242
-
1243
- void nativeRegisterViewV2(
1244
807
  jni::alias_ref<jni::JObject>,
1245
808
  jdouble driverId,
1246
809
  jni::alias_ref<smoothclip::JSmoothClipView> view,
@@ -1256,6 +819,15 @@ void nativeRegisterViewV2(
1256
819
  jdouble contentTranslateX,
1257
820
  jdouble contentTranslateY,
1258
821
  jdouble contentScale,
822
+ jboolean shadowEnabled,
823
+ jdouble shadowRed,
824
+ jdouble shadowGreen,
825
+ jdouble shadowBlue,
826
+ jdouble shadowAlpha,
827
+ jdouble shadowOffsetX,
828
+ jdouble shadowOffsetY,
829
+ jdouble shadowBlurRadius,
830
+ jdouble shadowSpreadDistance,
1259
831
  jdouble density,
1260
832
  jdouble widthPx,
1261
833
  jdouble heightPx,
@@ -1266,7 +838,14 @@ void nativeRegisterViewV2(
1266
838
  !std::isfinite(bottomRightRadius) || !std::isfinite(bottomLeftRadius) ||
1267
839
  !std::isfinite(contentTranslateX) ||
1268
840
  !std::isfinite(contentTranslateY) || !std::isfinite(contentScale) ||
1269
- contentScale <= 0 ||
841
+ !std::isfinite(shadowRed) || !std::isfinite(shadowGreen) ||
842
+ !std::isfinite(shadowBlue) || !std::isfinite(shadowAlpha) ||
843
+ !std::isfinite(shadowOffsetX) ||
844
+ !std::isfinite(shadowOffsetY) || !std::isfinite(shadowBlurRadius) ||
845
+ !std::isfinite(shadowSpreadDistance) || contentScale <= 0 ||
846
+ shadowRed < 0 || shadowRed > 1 || shadowGreen < 0 || shadowGreen > 1 ||
847
+ shadowBlue < 0 || shadowBlue > 1 || shadowAlpha < 0 || shadowAlpha > 1 ||
848
+ shadowBlurRadius < 0 ||
1270
849
  (curveCode != static_cast<jint>(smoothclip::ClipCurve::Circular) &&
1271
850
  curveCode != static_cast<jint>(smoothclip::ClipCurve::Continuous))) {
1272
851
  return;
@@ -1281,11 +860,21 @@ void nativeRegisterViewV2(
1281
860
  topLeftRadius == bottomLeftRadius) {
1282
861
  geometry.radius = topLeftRadius;
1283
862
  }
863
+ smoothclip::Shadow shadow{
864
+ shadowEnabled != 0,
865
+ shadowRed,
866
+ shadowGreen,
867
+ shadowBlue,
868
+ shadowAlpha,
869
+ shadowOffsetX,
870
+ shadowOffsetY,
871
+ shadowBlurRadius,
872
+ shadowSpreadDistance};
1284
873
  smoothclip::registerViewAndroid(
1285
874
  static_cast<uint64_t>(driverId),
1286
875
  view,
1287
876
  smoothclip::Presentation{
1288
- geometry, contentTranslateX, contentTranslateY, contentScale},
877
+ geometry, contentTranslateX, contentTranslateY, contentScale, shadow},
1289
878
  density,
1290
879
  widthPx,
1291
880
  heightPx,
@@ -1312,6 +901,13 @@ void nativeUnregisterView(
1312
901
  smoothclip::unregisterViewAndroid(static_cast<uint64_t>(driverId), view);
1313
902
  }
1314
903
 
904
+ void nativeDestroyDriver(
905
+ jni::alias_ref<jni::JObject>,
906
+ jdouble driverId) {
907
+ if (driverId <= 0 || !std::isfinite(driverId)) return;
908
+ smoothclip::destroyDriver(static_cast<uint64_t>(driverId));
909
+ }
910
+
1315
911
  void nativeSetViewLifecycleVisibility(
1316
912
  jni::alias_ref<jni::JObject>,
1317
913
  jdouble driverId,
@@ -1339,10 +935,10 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
1339
935
  {
1340
936
  makeNativeMethod("getBindingsInstaller", getBindingsInstaller),
1341
937
  makeNativeMethod("nativeRegisterView", nativeRegisterView),
1342
- makeNativeMethod("nativeRegisterViewV2", nativeRegisterViewV2),
1343
938
  makeNativeMethod(
1344
939
  "nativeSetViewHostGeometry", nativeSetViewHostGeometry),
1345
940
  makeNativeMethod("nativeUnregisterView", nativeUnregisterView),
941
+ makeNativeMethod("nativeDestroyDriver", nativeDestroyDriver),
1346
942
  makeNativeMethod(
1347
943
  "nativeSetViewLifecycleVisibility",
1348
944
  nativeSetViewLifecycleVisibility),