• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <algorithm>
16 #include <bitset>
17 #include <limits>
18 #include <numeric>
19 
20 #include <gmock/gmock-matchers.h>
21 #include <gtest/gtest.h>
22 
23 #include <meta/api/animation.h>
24 #include <meta/api/util.h>
25 #include <meta/interface/intf_containable.h>
26 
27 #include "TestRunner.h"
28 #include "helpers/animation_test_base.h"
29 #include "helpers/serialisation_utils.h"
30 #include "helpers/test_utils.h"
31 #include "helpers/testing_objects.h"
32 #include "helpers/util.h"
33 
34 using META_NS::CreateInstance;
35 using namespace testing;
36 using namespace testing::ext;
37 
38 META_BEGIN_NAMESPACE()
39 
40 class StaggeredAnimationTest : public AnimationTestBase {
41 protected:
SetUpTestSuite()42     static void SetUpTestSuite()
43     {
44         SetTest();
45     }
TearDownTestSuite()46     static void TearDownTestSuite()
47     {
48         TearDownTest();
49     }
SetUp()50     void SetUp() override
51     {
52         AnimationTestBase::SetUp();
53 
54         t1_ = META_NS::GetObjectRegistry().Create<ITestType>(ClassId::TestType);
55         r1_ = META_NS::GetObjectRegistry().Create<ITestType>(ClassId::TestType);
56 
57         ASSERT_NE(t1_, nullptr);
58     }
59 
60     template<class A, class T>
SetProperties(A & target,const IProperty::Ptr & property,T from,T to,TimeSpan duration)61     void SetProperties(A& target, const IProperty::Ptr& property, T from, T to, TimeSpan duration)
62     {
63         target.SetProperty(property);
64         target.SetFrom(from);
65         target.SetTo(to);
66         target.SetDuration(duration);
67     }
68 
69     ITestType::Ptr t1_;
70     ITestType::Ptr r1_;
71 };
72 
73 /**
74  * @tc.name: CreateParallel
75  * @tc.desc: test CreateParallel
76  * @tc.type: FUNC
77  */
78 HWTEST_F(StaggeredAnimationTest, CreateParallel, TestSize.Level1)
79 {
80     auto anim = CreateObjectInstance<IParallelAnimation>();
81 
82     ASSERT_TRUE(anim);
83     EXPECT_TRUE(anim.GetInterface(META_NS::InterfaceId::IObject.Id().ToUid()));
84     EXPECT_TRUE(anim.GetInterface(META_NS::InterfaceId::IAnimation.Id().ToUid()));
85     EXPECT_TRUE(anim.GetInterface(META_NS::InterfaceId::IStaggeredAnimation.Id().ToUid()));
86     EXPECT_TRUE(anim.GetInterface(META_NS::InterfaceId::IParallelAnimation.Id().ToUid()));
87     EXPECT_TRUE(anim.GetInterface(META_NS::InterfaceId::IStartableAnimation.Id().ToUid()));
88 }
89 
90 /**
91  * @tc.name: CreateSequential
92  * @tc.desc: test CreateSequential
93  * @tc.type: FUNC
94  */
95 HWTEST_F(StaggeredAnimationTest, CreateSequential, TestSize.Level1)
96 {
97     auto anim = CreateObjectInstance<ISequentialAnimation>();
98 
99     ASSERT_TRUE(anim);
100     EXPECT_TRUE(anim.GetInterface(META_NS::InterfaceId::IObject.Id().ToUid()));
101     EXPECT_TRUE(anim.GetInterface(META_NS::InterfaceId::IAnimation.Id().ToUid()));
102     EXPECT_TRUE(anim.GetInterface(META_NS::InterfaceId::IStaggeredAnimation.Id().ToUid()));
103     EXPECT_TRUE(anim.GetInterface(META_NS::InterfaceId::ISequentialAnimation.Id().ToUid()));
104     EXPECT_TRUE(anim.GetInterface(META_NS::InterfaceId::IStartableAnimation.Id().ToUid()));
105 }
106 
107 /**
108  * @tc.name: ParallelSingleChild
109  * @tc.desc: test ParallelSingleChild
110  * @tc.type: FUNC
111  */
112 HWTEST_F(StaggeredAnimationTest, ParallelSingleChild, TestSize.Level1)
113 {
114     auto staggered = CreateObjectInstance<IParallelAnimation>();
115     auto anim1 = CreateObjectInstance<IKeyframeAnimation, BASE_NS::Math::Vec3>();
116 
117     BASE_NS::Math::Vec3 from { 0, 0, 0 };
118     BASE_NS::Math::Vec3 to { 100, 50, 0 };
119 
120     SetProperties(anim1, t1_->Vec3Property1(), from, to, TimeSpan::Milliseconds(100));
121 
122     Container(staggered).Add(Object(anim1));
123     staggered.Start();
124     staggered.Step(GetTestClock());
125 
126     EXPECT_TRUE(staggered.GetRunning());
127     EXPECT_TRUE(anim1.GetRunning());
128     EXPECT_EQ(staggered.GetTotalDuration(), TimeSpan::Milliseconds(100));
129 
130     BASE_NS::Math::Vec3 previous = from;
131     float previousProgress = 0.f;
132 
__anon5e1217880102(uint32_t frame) 133     StepAnimations({ staggered }, 10, 10, [&](uint32_t frame) {
134         auto progress = staggered.GetProgress();
135         // Check that progress of ParallelAnimation moves forward
136         EXPECT_GT(progress, previousProgress);
137         previousProgress = progress;
138 
139         bool running = anim1.GetRunning();
140         EXPECT_EQ(running, frame < 10) << "Frame: " << frame;
141 
142         // Check animations that are still running are proceeding
143         auto pos = GetValue(t1_->Vec3Property1());
144         EXPECT_GT(pos, previous) << "Frame: " << frame;
145         previous = pos;
146     });
147 
148     EXPECT_FALSE(staggered.GetRunning());
149     EXPECT_EQ(staggered.GetProgress(), 1.f);
150     EXPECT_EQ(anim1.GetProgress(), 1.f);
151     EXPECT_EQ(GetValue(t1_->Vec3Property1()), to);
152 }
153 
154 /**
155  * @tc.name: Parallel
156  * @tc.desc: test Parallel
157  * @tc.type: FUNC
158  */
159 HWTEST_F(StaggeredAnimationTest, Parallel, TestSize.Level1)
160 {
161     auto staggered = CreateObjectInstance<IParallelAnimation>();
162     auto anim1 = CreateObjectInstance<IKeyframeAnimation, BASE_NS::Math::Vec3>();
163     auto anim2 = CreateObjectInstance<IKeyframeAnimation, BASE_NS::Math::Vec3>();
164     auto anim3 = CreateObjectInstance<IKeyframeAnimation, BASE_NS::Math::Vec3>();
165 
166     BASE_NS::Math::Vec3 from { 0, 0, 0 };
167     BASE_NS::Math::Vec3 to[3] = { { 100, 50, 0 }, { 20, 20, 100 }, { 200, 200, 0 } };
168 
169     SetProperties(anim1, t1_->Vec3Property1(), from, to[0], TimeSpan::Milliseconds(100));
170     SetProperties(anim2, t1_->Vec3Property2(), from, to[1], TimeSpan::Milliseconds(50));
171     SetProperties(anim3, t1_->Vec3Property3(), from, to[2], TimeSpan::Milliseconds(100));
172 
173     auto c = Container(staggered);
174     c.Add(anim1);
175     c.Add(anim2);
176     c.Add(anim3);
177     staggered.Start();
178     staggered.Step(GetTestClock());
179 
180     EXPECT_TRUE(staggered.GetRunning());
181     EXPECT_TRUE(anim1.GetRunning());
182     EXPECT_TRUE(anim2.GetRunning());
183     EXPECT_TRUE(anim3.GetRunning());
184     EXPECT_EQ(staggered.GetTotalDuration(), TimeSpan::Milliseconds(100));
185 
186     BASE_NS::Math::Vec3 previous[3] = { from, from, from };
187     float previousProgress = 0.f;
188 
__anon5e1217880202(uint32_t frame) 189     StepAnimations({ staggered }, 10, 10, [&](uint32_t frame) {
190         auto progress = staggered.GetProgress();
191         // Check that progress of ParallelAnimation moves forward
192         EXPECT_GT(progress, previousProgress);
193         previousProgress = progress;
194 
195         std::bitset<3> currentAnimsRunning;
196         currentAnimsRunning[0] = anim1.GetRunning();
197         currentAnimsRunning[1] = anim2.GetRunning();
198         currentAnimsRunning[2] = anim3.GetRunning();
199         // First animation finishes at 50ms, the rest at 100ms
200         size_t expectedRunning = frame > 4 ? frame > 9 ? 0 : 2 : 3;
201         EXPECT_EQ(currentAnimsRunning.count(), expectedRunning) << "Frame: " << frame;
202 
203         // Check animations that are still running are proceeding
204         if (currentAnimsRunning[0]) {
205             auto pos = GetValue(t1_->Vec3Property1());
206             EXPECT_GT(pos, previous[0]) << "Frame: " << frame;
207             previous[0] = pos;
208         }
209         if (currentAnimsRunning[1]) {
210             auto rot = GetValue(t1_->Vec3Property2());
211             EXPECT_GT(rot, previous[1]) << "Frame: " << frame;
212             previous[1] = rot;
213         }
214         if (currentAnimsRunning[2]) {
215             auto sca = GetValue(t1_->Vec3Property3());
216             EXPECT_GT(sca, previous[2]) << "Frame: " << frame;
217             previous[2] = sca;
218         }
219     });
220 
221     EXPECT_FALSE(staggered.GetRunning());
222     EXPECT_EQ(staggered.GetProgress(), 1.f);
223     EXPECT_EQ(anim1.GetProgress(), 1.f);
224     EXPECT_EQ(anim2.GetProgress(), 1.f);
225     EXPECT_EQ(anim3.GetProgress(), 1.f);
226     EXPECT_EQ(GetValue(t1_->Vec3Property1()), to[0]);
227     EXPECT_EQ(GetValue(t1_->Vec3Property2()), to[1]);
228     EXPECT_EQ(GetValue(t1_->Vec3Property3()), to[2]);
229 }
230 
231 /**
232  * @tc.name: ParallelStopsItsChildrenWhenNotRunning
233  * @tc.desc: test ParallelStopsItsChildrenWhenNotRunning
234  * @tc.type: FUNC
235  */
236 HWTEST_F(StaggeredAnimationTest, ParallelStopsItsChildrenWhenNotRunning, TestSize.Level1)
237 {
238     auto staggered = META_NS::ParallelAnimation(CreateInstance(ClassId::ParallelAnimation));
239     auto childAnim = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
240 
241     SetProperties(childAnim, t1_->Vec3Property1(), BASE_NS::Math::Vec3 { 0, 0, 0 }, BASE_NS::Math::Vec3 { 100, 50, 0 },
242         TimeSpan::Milliseconds(100));
243 
244     Container(staggered).Add(childAnim);
245     staggered.Start();
__anon5e1217880302(uint32_t ) 246     StepAnimations({ staggered }, 10, 10, [](uint32_t /*frame*/) {});
247     staggered.Stop();
248 
249     EXPECT_FALSE(staggered.GetRunning());
250     EXPECT_FALSE(childAnim.GetRunning());
251 }
252 
253 /**
254  * @tc.name: ParallelSerialization
255  * @tc.desc: test ParallelSerialization
256  * @tc.type: FUNC
257  */
258 HWTEST_F(StaggeredAnimationTest, ParallelSerialization, TestSize.Level1)
259 {
260     TestSerialiser ser;
261     BASE_NS::Math::Vec3 from { 0, 0, 0 };
262     BASE_NS::Math::Vec3 to[3] = { { 100, 50, 0 }, { 20, 20, 100 }, { 200, 200, 0 } };
263     {
264         auto staggered = META_NS::ParallelAnimation(CreateInstance(ClassId::ParallelAnimation));
265         auto anim1 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
266         auto anim2 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
267         auto anim3 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
268 
269         SetProperties(anim1, t1_->Vec3Property1(), from, to[0], TimeSpan::Milliseconds(100));
270         SetProperties(anim2, t1_->Vec3Property2(), from, to[1], TimeSpan::Milliseconds(50));
271         SetProperties(anim3, t1_->Vec3Property3(), from, to[2], TimeSpan::Milliseconds(100));
272 
273         auto c = Container(staggered);
274 
275         c.Add(anim1);
276         c.Add(anim2);
277         c.Add(anim3);
278 
279         Metadata obj(CreateInstance(ClassId::Object));
280         obj.AddProperty(t1_->Vec3Property1());
281         obj.AddProperty(t1_->Vec3Property2());
282         obj.AddProperty(t1_->Vec3Property3());
283         AttachmentContainer(obj).Attach(staggered);
284         ASSERT_TRUE(ser.Export(Object(obj)));
285         ser.Dump("app://test.json");
286     }
287 
288     auto obj = ser.Import<IMetadata>();
289     ASSERT_TRUE(obj);
290 
291     auto att = interface_cast<IAttach>(obj);
292     ASSERT_TRUE(att);
293     auto attvec = att->GetAttachments<IAnimation>();
294     ASSERT_EQ(attvec.size(), 1);
295     ParallelAnimation staggered(attvec.front());
296     ASSERT_TRUE(staggered);
297 
298     auto anims = staggered.GetAnimations();
299     ASSERT_EQ(anims.size(), 3);
300     KeyframeAnimation<BASE_NS::Math::Vec3> anim1(anims[0]);
301     ASSERT_TRUE(anim1);
302     KeyframeAnimation<BASE_NS::Math::Vec3> anim2(anims[1]);
303     ASSERT_TRUE(anim2);
304     KeyframeAnimation<BASE_NS::Math::Vec3> anim3(anims[2]);
305     ASSERT_TRUE(anim3);
306     Property<BASE_NS::Math::Vec3> prop1(anim1.GetProperty().lock());
307     ASSERT_TRUE(prop1);
308     Property<BASE_NS::Math::Vec3> prop2(anim2.GetProperty().lock());
309     ASSERT_TRUE(prop2);
310     Property<BASE_NS::Math::Vec3> prop3(anim3.GetProperty().lock());
311     ASSERT_TRUE(prop3);
312 
313     staggered.Start();
314     staggered.Step(GetTestClock());
315 
316     BASE_NS::Math::Vec3 previous[3] = { from, from, from };
317     float previousProgress = 0.f;
318 
__anon5e1217880402(uint32_t frame) 319     StepAnimations({ staggered }, 10, 10, [&](uint32_t frame) {
320         auto progress = staggered.GetProgress();
321         // Check that progress of ParallelAnimation moves forward
322         EXPECT_GT(progress, previousProgress);
323         previousProgress = progress;
324 
325         std::bitset<3> currentAnimsRunning;
326         currentAnimsRunning[0] = anim1.GetRunning();
327         currentAnimsRunning[1] = anim2.GetRunning();
328         currentAnimsRunning[2] = anim3.GetRunning();
329         // First animation finishes at 50ms, the rest at 100ms
330         size_t expectedRunning = frame > 4 ? frame > 9 ? 0 : 2 : 3;
331         EXPECT_EQ(currentAnimsRunning.count(), expectedRunning) << "Frame: " << frame;
332 
333         // Check animations that are still running are proceeding
334         if (currentAnimsRunning[0]) {
335             auto pos = prop1->GetValue();
336             EXPECT_GT(pos, previous[0]) << "Frame: " << frame;
337             previous[0] = pos;
338         }
339         if (currentAnimsRunning[1]) {
340             auto rot = prop2->GetValue();
341             EXPECT_GT(rot, previous[1]) << "Frame: " << frame;
342             previous[1] = rot;
343         }
344         if (currentAnimsRunning[0]) {
345             auto sca = prop3->GetValue();
346             EXPECT_GT(sca, previous[2]) << "Frame: " << frame;
347             previous[2] = sca;
348         }
349     });
350 
351     EXPECT_FALSE(staggered.GetRunning());
352     EXPECT_EQ(staggered.GetProgress(), 1.f);
353     EXPECT_EQ(anim1.GetProgress(), 1.f);
354     EXPECT_EQ(anim2.GetProgress(), 1.f);
355     EXPECT_EQ(anim3.GetProgress(), 1.f);
356     EXPECT_EQ(GetValue(prop1), to[0]);
357     EXPECT_EQ(GetValue(prop2), to[1]);
358     EXPECT_EQ(GetValue(prop3), to[2]);
359 }
360 
361 /**
362  * @tc.name: ParallelLoop
363  * @tc.desc: test ParallelLoop
364  * @tc.type: FUNC
365  */
366 HWTEST_F(StaggeredAnimationTest, ParallelLoop, TestSize.Level1)
367 {
368     auto staggered = META_NS::ParallelAnimation(CreateInstance(ClassId::ParallelAnimation));
369     auto anim1 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
370     auto anim2 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
371     auto anim3 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
372     const int loopCount = 3;
373     auto loop =
374         META_NS::AnimationModifiers::Loop(CreateInstance(ClassId::LoopAnimationModifier)).SetLoopCount(loopCount);
375 
376     AttachmentContainer(staggered).Attach(loop);
377 
378     BASE_NS::Math::Vec3 from { 0, 0, 0 };
379     BASE_NS::Math::Vec3 to[3] = { { 100, 50, 0 }, { 20, 20, 100 }, { 200, 200, 0 } };
380 
381     SetProperties(anim1, t1_->Vec3Property1(), from, to[0], TimeSpan::Milliseconds(100));
382     SetProperties(anim2, t1_->Vec3Property2(), from, to[1], TimeSpan::Milliseconds(50));
383     SetProperties(anim3, t1_->Vec3Property3(), from, to[2], TimeSpan::Milliseconds(100));
384 
385     Container c(staggered);
386     c.Add(anim1);
387     c.Add(anim2);
388     c.Add(anim3);
389     staggered.Start();
390     staggered.Step(GetTestClock());
391 
392     EXPECT_TRUE(staggered.GetRunning());
393     EXPECT_TRUE(anim1.GetRunning());
394     EXPECT_TRUE(anim2.GetRunning());
395     EXPECT_TRUE(anim3.GetRunning());
396     EXPECT_EQ(staggered.GetTotalDuration(), TimeSpan::Milliseconds(100) * loopCount);
397 
398     for (int i = 0; i < loopCount; ++i) {
399         float previousProgress = -1.f;
400         auto initFrom = from - BASE_NS::Math::Vec3(1, 1, 1);
401         BASE_NS::Math::Vec3 previous[3] = { initFrom, initFrom, initFrom };
402         auto loop = i + 1;
403 
__anon5e1217880502(uint32_t frame) 404         StepAnimations({ staggered }, 10, 10, [&](uint32_t frame) {
405             auto progress = staggered.GetProgress();
406             // Check that progress of ParallelAnimation moves forward
407             EXPECT_GT(progress, previousProgress) << "Frame " << frame << ", Loop: " << loop;
408             previousProgress = progress;
409 
410             std::bitset<3> currentAnimsRunning;
411             currentAnimsRunning[0] = anim1.GetRunning();
412             currentAnimsRunning[1] = anim2.GetRunning();
413             currentAnimsRunning[2] = anim3.GetRunning();
414 
415             size_t expectedRunning = frame > 4 ? frame > 9 ? 0 : 2 : 3;
416             ASSERT_EQ(currentAnimsRunning.count(), expectedRunning) << "Frame: " << frame << ", Loop: " << loop;
417 
418             // Check animations that are still running are proceeding
419             if (currentAnimsRunning[0]) {
420                 auto pos = GetValue(t1_->Vec3Property1());
421                 EXPECT_GT(pos, previous[0]);
422                 previous[0] = pos;
423             }
424             if (currentAnimsRunning[1]) {
425                 auto rot = GetValue(t1_->Vec3Property2());
426                 EXPECT_GT(rot, previous[1]);
427                 previous[1] = rot;
428             }
429             if (currentAnimsRunning[0]) {
430                 auto sca = GetValue(t1_->Vec3Property3());
431                 EXPECT_GT(sca, previous[2]);
432                 previous[2] = sca;
433             }
434         });
435 
436         if (loop == loopCount) {
437             // Last loop, animation should have finished
438             EXPECT_FALSE(staggered.GetRunning());
439         } else {
440             EXPECT_TRUE(staggered.GetRunning());
441             staggered.Step(GetTestClock()); // One extra step to let the animations jump back to beginning
442         }
443     }
444 
445     EXPECT_FLOAT_EQ(1.0f, staggered.GetProgress());
446 
447     EXPECT_FALSE(staggered.GetRunning());
448     EXPECT_EQ(staggered.GetProgress(), 1.f);
449     EXPECT_EQ(anim1.GetProgress(), 1.f);
450     EXPECT_EQ(anim2.GetProgress(), 1.f);
451     EXPECT_EQ(anim3.GetProgress(), 1.f);
452     EXPECT_EQ(GetValue(t1_->Vec3Property1()), to[0]);
453     EXPECT_EQ(GetValue(t1_->Vec3Property2()), to[1]);
454     EXPECT_EQ(GetValue(t1_->Vec3Property3()), to[2]);
455 }
456 
457 /**
458  * @tc.name: ParallelReverse
459  * @tc.desc: test ParallelReverse
460  * @tc.type: FUNC
461  */
462 HWTEST_F(StaggeredAnimationTest, ParallelReverse, TestSize.Level1)
463 {
464     auto staggered = META_NS::ParallelAnimation(CreateInstance(ClassId::ParallelAnimation));
465     auto anim1 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
466     auto anim2 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
467     auto anim3 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
468     auto reverse = META_NS::AnimationModifiers::Reverse(CreateInstance(ClassId::ReverseAnimationModifier));
469 
470     AttachmentContainer(staggered).Attach(reverse);
471 
472     BASE_NS::Math::Vec3 from { 0, 0, 0 };
473     BASE_NS::Math::Vec3 to[3] = { { 100, 50, 0 }, { 20, 20, 100 }, { 200, 200, 0 } };
474 
475     SetProperties(anim1, t1_->Vec3Property1(), from, to[0], TimeSpan::Milliseconds(100));
476     SetProperties(anim2, t1_->Vec3Property2(), from, to[1], TimeSpan::Milliseconds(30));
477     SetProperties(anim3, t1_->Vec3Property3(), from, to[2], TimeSpan::Milliseconds(100));
478 
479     Container c(staggered);
480     c.Add(anim1);
481     c.Add(anim2);
482     c.Add(anim3);
483     staggered.Start();
484     staggered.Step(GetTestClock());
485 
486     EXPECT_TRUE(staggered.GetRunning());
487     EXPECT_TRUE(anim1.GetRunning());
488     EXPECT_FALSE(anim2.GetRunning());
489     EXPECT_TRUE(anim3.GetRunning());
490     EXPECT_EQ(staggered.GetTotalDuration(), TimeSpan::Milliseconds(100));
491 
492     EXPECT_EQ(GetValue(t1_->Vec3Property1()), to[0]);
493     EXPECT_EQ(GetValue(t1_->Vec3Property2()), from);
494     EXPECT_EQ(GetValue(t1_->Vec3Property3()), to[2]);
495 
496     float previousProgress = -1.f;
497     auto initFrom = to[2] + BASE_NS::Math::Vec3(1, 1, 1);
498     BASE_NS::Math::Vec3 previous[3] = { initFrom, initFrom, initFrom };
499 
__anon5e1217880602(uint32_t frame) 500     StepAnimations({ staggered }, 10, 10, [&](uint32_t frame) {
501         auto progress = staggered.GetProgress();
502         // Check that progress of ParallelAnimation moves forward
503         EXPECT_GT(progress, previousProgress) << "Frame " << frame;
504         previousProgress = progress;
505 
506         std::bitset<3> currentAnimsRunning;
507         currentAnimsRunning[0] = anim1.GetRunning();
508         currentAnimsRunning[1] = anim2.GetRunning();
509         currentAnimsRunning[2] = anim3.GetRunning();
510 
511         size_t expectedRunning = frame > 6 ? frame > 9 ? 0 : 3 : 2;
512         ASSERT_EQ(currentAnimsRunning.count(), expectedRunning) << "Frame: " << frame;
513 
514         // Check animations that are still running are proceeding
515         if (currentAnimsRunning[0]) {
516             auto pos = GetValue(t1_->Vec3Property1());
517             EXPECT_LT(pos, previous[0]);
518             previous[0] = pos;
519         }
520         if (currentAnimsRunning[1]) {
521             auto rot = GetValue(t1_->Vec3Property2());
522             EXPECT_LT(rot, previous[1]);
523             previous[1] = rot;
524         }
525         if (currentAnimsRunning[0]) {
526             auto sca = GetValue(t1_->Vec3Property3());
527             EXPECT_LT(sca, previous[2]);
528             previous[2] = sca;
529         }
530     });
531 
532     EXPECT_FLOAT_EQ(1.0f, staggered.GetProgress());
533 
534     EXPECT_FALSE(staggered.GetRunning());
535     EXPECT_EQ(staggered.GetProgress(), 1.f);
536     EXPECT_EQ(anim1.GetProgress(), 0.f);
537     EXPECT_EQ(anim2.GetProgress(), 0.f);
538     EXPECT_EQ(anim3.GetProgress(), 0.f);
539     EXPECT_EQ(GetValue(t1_->Vec3Property1()), from);
540     EXPECT_EQ(GetValue(t1_->Vec3Property2()), from);
541     EXPECT_EQ(GetValue(t1_->Vec3Property3()), from);
542 }
543 
544 /**
545  * @tc.name: LoopPastEnd
546  * @tc.desc: test LoopPastEnd
547  * @tc.type: FUNC
548  */
549 HWTEST_F(StaggeredAnimationTest, LoopPastEnd, TestSize.Level1)
550 {
551     META_NS::KeyframeAnimation<float> a1(CreateInstance(ClassId::KeyframeAnimation));
552     META_NS::KeyframeAnimation<float> a2(CreateInstance(ClassId::KeyframeAnimation));
553     auto staggered = META_NS::SequentialAnimation(CreateInstance(ClassId::SequentialAnimation));
554     Container(staggered).Add(
555         a1.SetFrom(0).SetTo(10).SetProperty(t1_->FloatProperty1()).SetDuration(TimeSpan::Milliseconds(100)));
556     Container(staggered).Add(
557         a2.SetFrom(10)
558             .SetTo(0)
559             .SetProperty(t1_->FloatProperty1())
560             .SetDuration(TimeSpan::Milliseconds(100))
561             .SetCurve(interface_pointer_cast<ICurve1D>(CreateInstance(ClassId::InOutCubicEasingCurve))));
562 
563     AttachmentContainer(staggered).Attach(
564         META_NS::AnimationModifiers::Loop(CreateInstance(ClassId::LoopAnimationModifier)).LoopIndefinitely());
565 
566     staggered.Start();
567     ASSERT_TRUE(staggered.GetRunning());
568 
569     float expectedProgress = 0.f;
570     float expectedProgressStep = 20.f / 200.f; // 200ms animation with 20ms step
571 
572     // Run the animation once so that our steps hit 1.0
573     for (auto loop = 1; loop <= 3; loop++) {
574         staggered.Step(GetTestClock());
__anon5e1217880702(uint32_t frame) 575         StepAnimations({ staggered }, 10, 20, [&](uint32_t frame) {
576             auto progress = staggered.GetProgress();
577             expectedProgress += expectedProgressStep;
578             expectedProgress = expectedProgress - BASE_NS::Math::floor(expectedProgress);
579 
580             EXPECT_EQ(a1.GetRunning(), frame < 5) << "Frame: " << frame << ", loop: " << loop;
581             EXPECT_EQ(a2.GetRunning(), frame >= 5 && frame < 10) << "Frame: " << frame << ", loop: " << loop;
582         });
583     }
584 
585     staggered.Restart();
586     staggered.Step(GetTestClock());
587     expectedProgress = 0.f;
588     expectedProgressStep = 30.f / 200.f; // 200ms animation with 30ms step
589 
590     // Run again but now so that we step past 1.0
591     for (auto loop = 1; loop <= 3; loop++) {
592         auto frameCount = loop == 1 ? 6 : 7;
__anon5e1217880802(uint32_t frame) 593         StepAnimations({ staggered }, frameCount, 30, [&](uint32_t frame) {
594             auto progress = staggered.GetProgress();
595             expectedProgress += expectedProgressStep;
596             expectedProgress = expectedProgress - BASE_NS::Math::floor(expectedProgress);
597 
598             EXPECT_NEAR(progress, expectedProgress, 0.05);
599 
600             // On the seventh frame we should jump past one loop, and be at 0.05 progress or thereabouts
601             bool a1running = frame < 4;
602             bool a2running = !a1running && progress < 1.f;
603 
604             EXPECT_EQ(a1.GetRunning(), a1running) << "Frame: " << frame << ", loop: " << loop;
605             EXPECT_EQ(a2.GetRunning(), a2running) << "Frame: " << frame << ", loop: " << loop;
606         });
607     }
608 }
609 
610 /**
611  * @tc.name: Sequential
612  * @tc.desc: test Sequential
613  * @tc.type: FUNC
614  */
615 HWTEST_F(StaggeredAnimationTest, Sequential, TestSize.Level1)
616 {
617     auto staggered = META_NS::SequentialAnimation(CreateInstance(ClassId::SequentialAnimation));
618     auto anim1 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
619     auto anim2 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
620     auto anim3 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
621 
622     BASE_NS::Math::Vec3 from { 0, 0, 0 };
623     BASE_NS::Math::Vec3 to[3] = { { 100, 50, 0 }, { 20, 20, 100 }, { 200, 200, 0 } };
624 
625     // In total 150ms of animations
626     SetProperties(anim1, t1_->Vec3Property1(), from, to[0], TimeSpan::Milliseconds(50));
627     SetProperties(anim2, t1_->Vec3Property2(), from, to[1], TimeSpan::Milliseconds(100));
628     SetProperties(anim3, t1_->Vec3Property3(), from, to[2], TimeSpan::Milliseconds(50));
629 
630     Container c(staggered);
631     c.Add(anim1);
632     c.Add(anim2);
633     c.Add(anim3);
634 
635     EXPECT_EQ(staggered.GetTotalDuration(), TimeSpan::Milliseconds(200));
636 
637     staggered.Start();
638     staggered.Step(GetTestClock());
639 
640     EXPECT_TRUE(anim1.GetRunning());
641     EXPECT_TRUE(staggered.GetRunning());
642 
643     std::bitset<3> animsRun;
644     float previousProgress = 0.f;
645 
646     // 20 frames at 10ms interval should finish the animation
__anon5e1217880902(uint32_t frame) 647     RunFrames(20, [&animsRun, &anim1, &anim2, &anim3, &staggered, &previousProgress](uint32_t frame) {
648         auto progress = staggered.GetProgress();
649 
650         // Each frame should progress the animation
651         EXPECT_GT(progress, previousProgress) << "at frame " << frame;
652         previousProgress = progress;
653 
654         std::bitset<3> currentAnimsRunning;
655         currentAnimsRunning[0] = anim1.GetRunning();
656         currentAnimsRunning[1] = anim2.GetRunning();
657         currentAnimsRunning[2] = anim3.GetRunning();
658 
659         // Only one animation should be running at a time
660         EXPECT_EQ(currentAnimsRunning.count(), frame < 20 ? 1 : 0) << "at frame " << frame;
661 
662         animsRun |= currentAnimsRunning;
663 
664         // Check that total animation progress is correct for the
665         // currently running animation from the sequence
666         if (currentAnimsRunning[0]) {
667             EXPECT_GE(progress, 0.f);
668             EXPECT_LE(progress, 1.f / 4.f);
669         }
670         if (currentAnimsRunning[1]) {
671             EXPECT_GE(progress, 1.f / 4.f);
672             EXPECT_LE(progress, 3.f / 4.f);
673         }
674         if (currentAnimsRunning[2]) {
675             EXPECT_GE(progress, 3.f / 4.f);
676             EXPECT_LE(progress, 1.f);
677         }
678     });
679 
680     EXPECT_EQ(animsRun.count(), 3);
681     EXPECT_FALSE(staggered.GetRunning());
682     EXPECT_EQ(staggered.GetProgress(), 1.f);
683     EXPECT_EQ(anim1.GetProgress(), 1.f);
684     EXPECT_EQ(anim2.GetProgress(), 1.f);
685     EXPECT_EQ(anim3.GetProgress(), 1.f);
686     EXPECT_EQ(GetValue(t1_->Vec3Property1()), to[0]);
687     EXPECT_EQ(GetValue(t1_->Vec3Property2()), to[1]);
688     EXPECT_EQ(GetValue(t1_->Vec3Property3()), to[2]);
689 }
690 
691 /**
692  * @tc.name: SequentialSerialization
693  * @tc.desc: test SequentialSerialization
694  * @tc.type: FUNC
695  */
696 HWTEST_F(StaggeredAnimationTest, SequentialSerialization, TestSize.Level1)
697 {
698     TestSerialiser ser;
699     BASE_NS::Math::Vec3 from { 0, 0, 0 };
700     BASE_NS::Math::Vec3 to[3] = { { 100, 50, 0 }, { 20, 20, 100 }, { 200, 200, 0 } };
701     {
702         auto staggered = META_NS::SequentialAnimation(CreateInstance(ClassId::SequentialAnimation));
703         auto anim1 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
704         auto anim2 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
705         auto anim3 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
706 
707         // In total 150ms of animations
708         SetProperties(anim1, t1_->Vec3Property1(), from, to[0], TimeSpan::Milliseconds(50));
709         SetProperties(anim2, t1_->Vec3Property2(), from, to[1], TimeSpan::Milliseconds(100));
710         SetProperties(anim3, t1_->Vec3Property3(), from, to[2], TimeSpan::Milliseconds(50));
711 
712         Container c(staggered);
713         c.Add(anim1);
714         c.Add(anim2);
715         c.Add(anim3);
716 
717         Metadata obj(CreateInstance(ClassId::Object));
718         obj.AddProperty(t1_->Vec3Property1());
719         obj.AddProperty(t1_->Vec3Property2());
720         obj.AddProperty(t1_->Vec3Property3());
721         AttachmentContainer(obj).Attach(staggered);
722         ASSERT_TRUE(ser.Export(Object(obj)));
723         ser.Dump("app://test.json");
724     }
725 
726     auto obj = ser.Import<IMetadata>();
727     ASSERT_TRUE(obj);
728 
729     auto att = interface_cast<IAttach>(obj);
730     ASSERT_TRUE(att);
731     auto attvec = att->GetAttachments<IAnimation>();
732     ASSERT_EQ(attvec.size(), 1);
733     SequentialAnimation staggered(attvec.front());
734     ASSERT_TRUE(staggered);
735 
736     auto anims = staggered.GetAnimations();
737     ASSERT_EQ(anims.size(), 3);
738     KeyframeAnimation<BASE_NS::Math::Vec3> anim1(anims[0]);
739     ASSERT_TRUE(anim1);
740     KeyframeAnimation<BASE_NS::Math::Vec3> anim2(anims[1]);
741     ASSERT_TRUE(anim2);
742     KeyframeAnimation<BASE_NS::Math::Vec3> anim3(anims[2]);
743     ASSERT_TRUE(anim3);
744     Property<BASE_NS::Math::Vec3> prop1(anim1.GetProperty().lock());
745     ASSERT_TRUE(prop1);
746     Property<BASE_NS::Math::Vec3> prop2(anim2.GetProperty().lock());
747     ASSERT_TRUE(prop2);
748     Property<BASE_NS::Math::Vec3> prop3(anim3.GetProperty().lock());
749     ASSERT_TRUE(prop3);
750 
751     staggered.Start();
752     staggered.Step(GetTestClock());
753 
754     EXPECT_TRUE(anim1.GetRunning());
755     EXPECT_TRUE(staggered.GetRunning());
756 
757     std::bitset<3> animsRun;
758     float previousProgress = 0.f;
759 
760     // 20 frames at 10ms interval should finish the animation
__anon5e1217880a02(uint32_t frame) 761     RunFrames(20, [&animsRun, &anim1, &anim2, &anim3, &staggered, &previousProgress](uint32_t frame) {
762         auto progress = staggered.GetProgress();
763 
764         // Each frame should progress the animation
765         EXPECT_GT(progress, previousProgress) << "at frame " << frame;
766         previousProgress = progress;
767 
768         std::bitset<3> currentAnimsRunning;
769         currentAnimsRunning[0] = anim1.GetRunning();
770         currentAnimsRunning[1] = anim2.GetRunning();
771         currentAnimsRunning[2] = anim3.GetRunning();
772 
773         // Only one animation should be running at a time
774         EXPECT_EQ(currentAnimsRunning.count(), frame < 20 ? 1 : 0) << "at frame " << frame;
775 
776         animsRun |= currentAnimsRunning;
777 
778         // Check that total animation progress is correct for the
779         // currently running animation from the sequence
780         if (currentAnimsRunning[0]) {
781             EXPECT_GE(progress, 0.f);
782             EXPECT_LE(progress, 1.f / 4.f);
783         }
784         if (currentAnimsRunning[1]) {
785             EXPECT_GE(progress, 1.f / 4.f);
786             EXPECT_LE(progress, 3.f / 4.f);
787         }
788         if (currentAnimsRunning[2]) {
789             EXPECT_GE(progress, 3.f / 4.f);
790             EXPECT_LE(progress, 1.f);
791         }
792     });
793 
794     EXPECT_EQ(animsRun.count(), 3);
795     EXPECT_FALSE(staggered.GetRunning());
796     EXPECT_EQ(staggered.GetProgress(), 1.f);
797     EXPECT_EQ(anim1.GetProgress(), 1.f);
798     EXPECT_EQ(anim2.GetProgress(), 1.f);
799     EXPECT_EQ(anim3.GetProgress(), 1.f);
800     EXPECT_EQ(GetValue(prop1), to[0]);
801     EXPECT_EQ(GetValue(prop2), to[1]);
802     EXPECT_EQ(GetValue(prop3), to[2]);
803 }
804 
805 /**
806  * @tc.name: SequentialWithSameAnimation
807  * @tc.desc: test SequentialWithSameAnimation
808  * @tc.type: FUNC
809  */
810 HWTEST_F(StaggeredAnimationTest, SequentialWithSameAnimation, TestSize.Level1)
811 {
812     auto staggered = META_NS::SequentialAnimation(CreateInstance(ClassId::SequentialAnimation));
813     auto anim = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
814 
815     BASE_NS::Math::Vec3 from { 0, 0, 0 };
816     BASE_NS::Math::Vec3 to = { 100, 50, 0 };
817 
818     SetProperties(anim, t1_->Vec3Property1(), from, to, TimeSpan::Milliseconds(50));
819 
820     Container c(staggered);
821     c.Add(anim);
822     c.Add(anim);
823     c.Add(anim);
824 
825     EXPECT_EQ(staggered.GetTotalDuration(), TimeSpan::Milliseconds(150));
826 
827     staggered.Start();
828     staggered.Step(GetTestClock());
829 
830     EXPECT_TRUE(anim.GetRunning());
831     EXPECT_TRUE(staggered.GetRunning());
832 
833     float previousProgress = 0.f;
834 
835     // 20 frames + 10ms sleep at end of each frame -> Should be enough time
836     // for all animations to run
__anon5e1217880b02(uint32_t frame) 837     StepAnimations({ staggered }, 15, 10, [&](uint32_t frame) {
838         EXPECT_EQ(staggered.GetRunning(), frame < 15) << "Frame: " << frame;
839         auto progress = staggered.GetProgress();
840 
841         // Each frame should progress the animation
842         EXPECT_GT(progress, previousProgress) << "Frame: " << frame;
843         previousProgress = progress;
844     });
845 
846     EXPECT_FALSE(staggered.GetRunning());
847     EXPECT_EQ(staggered.GetProgress(), 1.f);
848     EXPECT_EQ(anim.GetProgress(), 1.f);
849 }
850 
851 /**
852  * @tc.name: SequentialModified
853  * @tc.desc: test SequentialModified
854  * @tc.type: FUNC
855  */
856 HWTEST_F(StaggeredAnimationTest, SequentialModified, TestSize.Level1)
857 {
858     auto staggered = META_NS::SequentialAnimation(CreateInstance(ClassId::SequentialAnimation));
859     auto anim1 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
860     auto anim2 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
861     auto anim3 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
862 
863     const int loopCount = 3;
864     auto loop =
865         META_NS::AnimationModifiers::Loop(CreateInstance(ClassId::LoopAnimationModifier)).SetLoopCount(loopCount);
866     AttachmentContainer(staggered).Attach(loop);
867 
868     BASE_NS::Math::Vec3 from { 0, 0, 0 };
869     BASE_NS::Math::Vec3 to[3] = { { 100, 50, 0 }, { 20, 20, 100 }, { 200, 200, 0 } };
870 
871     // In total 150ms of animations
872     SetProperties(anim1, t1_->Vec3Property1(), from, to[0], TimeSpan::Milliseconds(50));
873     SetProperties(anim2, t1_->Vec3Property2(), from, to[1], TimeSpan::Milliseconds(50));
874     SetProperties(anim3, t1_->Vec3Property3(), from, to[2], TimeSpan::Milliseconds(50));
875 
876     Container c(staggered);
877     c.Add(anim1);
878     c.Add(anim2);
879     c.Add(anim3);
880     staggered.Start();
881     staggered.Step(GetTestClock());
882 
883     EXPECT_TRUE(anim1.GetRunning());
884     EXPECT_TRUE(staggered.GetRunning());
885 
886     std::bitset<3> animsRun;
887 
888     for (int i = 0; i < loopCount; ++i) {
889         float previousProgress = -1;
890         auto loop = i + 1;
891 
__anon5e1217880c02(uint32_t frame) 892         StepAnimations({ staggered }, 15, 10, [&](uint32_t frame) {
893             auto progress = staggered.GetProgress();
894 
895             // Each frame should progress the animation
896             EXPECT_GT(progress, previousProgress) << "Frame: " << frame << ", Loop: " << loop;
897             previousProgress = progress;
898 
899             std::bitset<3> currentAnimsRunning;
900             currentAnimsRunning[0] = anim1.GetRunning();
901             currentAnimsRunning[1] = anim2.GetRunning();
902             currentAnimsRunning[2] = anim3.GetRunning();
903 
904             // Only one animation should be running at a time
905             EXPECT_EQ(currentAnimsRunning.count(), frame < 15 ? 1 : 0) << "Frame: " << frame << ", Loop: " << loop;
906 
907             animsRun |= currentAnimsRunning;
908 
909             // Check that total animation progress is correct for the
910             // currently running animation from the sequence
911             if (currentAnimsRunning[0]) {
912                 EXPECT_GE(progress, 0.f);
913                 EXPECT_LE(progress, 1.f / 3.f + std::numeric_limits<float>::epsilon());
914             }
915             if (currentAnimsRunning[1]) {
916                 EXPECT_GE(progress, 1.f / 3.f - std::numeric_limits<float>::epsilon());
917                 EXPECT_LE(progress, 2.f / 3.f + std::numeric_limits<float>::epsilon());
918             }
919             if (currentAnimsRunning[2]) {
920                 EXPECT_GE(progress, 2.f / 3.f - std::numeric_limits<float>::epsilon());
921                 EXPECT_LE(progress, 1.f);
922             }
923         });
924         if (loop == loopCount) {
925             // Last loop, animation should have finished
926             EXPECT_FALSE(staggered.GetRunning());
927         } else {
928             EXPECT_TRUE(staggered.GetRunning());
929             staggered.Step(GetTestClock()); // One extra step to let the animations jump back to beginning
930         }
931     }
932 
933     EXPECT_EQ(animsRun.count(), 3);
934     EXPECT_FALSE(staggered.GetRunning());
935     EXPECT_EQ(staggered.GetProgress(), 1.f);
936     EXPECT_EQ(anim1.GetProgress(), 1.f);
937     EXPECT_EQ(anim2.GetProgress(), 1.f);
938     EXPECT_EQ(anim3.GetProgress(), 1.f);
939     EXPECT_EQ(GetValue(t1_->Vec3Property1()), to[0]);
940     EXPECT_EQ(GetValue(t1_->Vec3Property2()), to[1]);
941     EXPECT_EQ(GetValue(t1_->Vec3Property3()), to[2]);
942 }
943 
944 /**
945  * @tc.name: DurationParallel
946  * @tc.desc: test DurationParallel
947  * @tc.type: FUNC
948  */
949 HWTEST_F(StaggeredAnimationTest, DurationParallel, TestSize.Level1)
950 {
951     auto staggered = META_NS::ParallelAnimation(CreateInstance(ClassId::ParallelAnimation));
952     auto anim1 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
953     auto anim2 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
954     auto anim3 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
955 
956     BASE_NS::Math::Vec3 from { 0, 0, 0 };
957     BASE_NS::Math::Vec3 to[3] = { { 100, 50, 0 }, { 20, 20, 100 }, { 200, 200, 0 } };
958     TimeSpan baseDuration = TimeSpan::Milliseconds(50);
959 
960     // Last animation has the longest duration
961     std::vector<TimeSpan> duration = { baseDuration, baseDuration, baseDuration * 12 };
962 
963     SetProperties(anim1, t1_->Vec3Property1(), from, to[0], duration[0]);
964     SetProperties(anim2, t1_->Vec3Property2(), from, to[1], duration[1]);
965     SetProperties(anim3, t1_->Vec3Property3(), from, to[2], duration[2]);
966 
967     Container c(staggered);
968     c.Add(anim1);
969     c.Add(anim2);
970     c.Add(anim3);
971 
972     auto staggeredDuration = *std::max_element(duration.begin(), duration.end());
973     EXPECT_EQ(staggered.GetTotalDuration(), staggeredDuration);
974 }
975 
976 /**
977  * @tc.name: ParallelWithSameAnimation
978  * @tc.desc: test ParallelWithSameAnimation
979  * @tc.type: FUNC
980  */
981 HWTEST_F(StaggeredAnimationTest, ParallelWithSameAnimation, TestSize.Level1)
982 {
983     auto staggered = META_NS::ParallelAnimation(CreateInstance(ClassId::ParallelAnimation));
984     auto anim = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
985 
986     BASE_NS::Math::Vec3 from { 0, 0, 0 };
987     BASE_NS::Math::Vec3 to = { 100, 50, 0 };
988 
989     SetProperties(anim, t1_->Vec3Property1(), from, to, TimeSpan::Milliseconds(50));
990 
991     Container c(staggered);
992     c.Add(anim);
993     c.Add(anim);
994     c.Add(anim);
995 
996     EXPECT_EQ(staggered.GetAnimations().size(), 1);
997     EXPECT_EQ(staggered.GetTotalDuration(), TimeSpan::Milliseconds(50));
998 }
999 
1000 /**
1001  * @tc.name: DurationParallelModified
1002  * @tc.desc: test DurationParallelModified
1003  * @tc.type: FUNC
1004  */
1005 HWTEST_F(StaggeredAnimationTest, DurationParallelModified, TestSize.Level1)
1006 {
1007     auto staggered = META_NS::ParallelAnimation(CreateInstance(ClassId::ParallelAnimation));
1008     auto anim1 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
1009     auto anim2 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
1010     auto anim3 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
1011 
1012     const int loopCount = 3;
1013     auto loop =
1014         META_NS::AnimationModifiers::Loop(CreateInstance(ClassId::LoopAnimationModifier)).SetLoopCount(loopCount);
1015     AttachmentContainer(staggered).Attach(loop);
1016 
1017     BASE_NS::Math::Vec3 from { 0, 0, 0 };
1018     BASE_NS::Math::Vec3 to[3] = { { 100, 50, 0 }, { 20, 20, 100 }, { 200, 200, 0 } };
1019     TimeSpan baseDuration = TimeSpan::Milliseconds(50);
1020 
1021     // Last animation has the longest duration
1022     std::vector<TimeSpan> duration = { baseDuration, baseDuration, baseDuration * 12 };
1023 
1024     SetProperties(anim1, t1_->Vec3Property1(), from, to[0], duration[0]);
1025     SetProperties(anim2, t1_->Vec3Property2(), from, to[1], duration[1]);
1026     SetProperties(anim3, t1_->Vec3Property3(), from, to[2], duration[2]);
1027 
1028     Container c(staggered);
1029     c.Add(anim1);
1030     c.Add(anim2);
1031     c.Add(anim3);
1032 
1033     auto staggeredDuration = *std::max_element(duration.begin(), duration.end());
1034     EXPECT_EQ(staggered.GetTotalDuration(), staggeredDuration * loopCount);
1035 }
1036 
1037 /**
1038  * @tc.name: DurationSequential
1039  * @tc.desc: test DurationSequential
1040  * @tc.type: FUNC
1041  */
1042 HWTEST_F(StaggeredAnimationTest, DurationSequential, TestSize.Level1)
1043 {
1044     auto staggered = META_NS::SequentialAnimation(CreateInstance(ClassId::SequentialAnimation));
1045     auto anim1 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
1046     auto anim2 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
1047     auto anim3 = META_NS::KeyframeAnimation<BASE_NS::Math::Vec3>(CreateInstance(ClassId::KeyframeAnimation));
1048 
1049     BASE_NS::Math::Vec3 from { 0, 0, 0 };
1050     BASE_NS::Math::Vec3 to[3] = { { 100, 50, 0 }, { 20, 20, 100 }, { 200, 200, 0 } };
1051     TimeSpan baseDuration = TimeSpan::Milliseconds(50);
1052 
1053     // Last animation has the longest duration
1054     std::vector<TimeSpan> duration = { baseDuration, baseDuration, baseDuration * 12 };
1055 
1056     SetProperties(anim1, t1_->Vec3Property1(), from, to[0], duration[0]);
1057     SetProperties(anim2, t1_->Vec3Property2(), from, to[1], duration[1]);
1058     SetProperties(anim3, t1_->Vec3Property3(), from, to[2], duration[2]);
1059 
1060     Container c(staggered);
1061     c.Add(anim1);
1062     c.Add(anim2);
1063     c.Add(anim3);
1064 
1065     auto staggeredDuration = std::accumulate(duration.begin(), duration.end(), TimeSpan::Zero());
1066     EXPECT_EQ(staggered.GetTotalDuration(), staggeredDuration);
1067 }
1068 
1069 /**
1070  * @tc.name: Hierarchy
1071  * @tc.desc: test Hierarchy
1072  * @tc.type: FUNC
1073  */
1074 HWTEST_F(StaggeredAnimationTest, Hierarchy, TestSize.Level1)
1075 {
1076     /*
1077     Create the following animation hierarchy:
1078     par1                    ParallelAnimation
1079       |
1080       +-- seq1              SequentialAnimation
1081       |     |
1082       |     +-- par2        ParallelAnimation
1083       |     |     |
1084       |     |     +-- a1    KeyframeAnimation
1085       |     |     +-- a2    KeyframeAnimation
1086       |     +-- a3          KeyframeAnimation
1087       +-- a4                KeyframeAnimation
1088     */
1089 
1090     auto p1 = ConstructProperty<float>("p1", 0);
1091     auto p2 = ConstructProperty<float>("p2", 0);
1092     auto p3 = ConstructProperty<float>("p3", 0);
1093     auto p4 = ConstructProperty<float>("p4", 0);
1094 
1095     auto seq1 = META_NS::SequentialAnimation(CreateInstance(ClassId::SequentialAnimation));
1096     auto par1 = META_NS::ParallelAnimation(CreateInstance(ClassId::ParallelAnimation));
1097     auto par2 = META_NS::ParallelAnimation(CreateInstance(ClassId::ParallelAnimation));
1098 
1099     auto a1 = META_NS::KeyframeAnimation<float>(CreateInstance(ClassId::KeyframeAnimation));
1100     auto a2 = META_NS::KeyframeAnimation<float>(CreateInstance(ClassId::KeyframeAnimation));
1101     auto a3 = META_NS::KeyframeAnimation<float>(CreateInstance(ClassId::KeyframeAnimation));
1102     auto a4 = META_NS::KeyframeAnimation<float>(CreateInstance(ClassId::KeyframeAnimation));
1103 
1104     float from[4] = { 0, 5, 10, 20 };
1105     float to[4] = { 10, 10, 25, 40 };
1106 
1107     SetProperties(a1, p1, from[0], to[0], TimeSpan::Milliseconds(30));
1108     SetProperties(a2, p2, from[1], to[1], TimeSpan::Milliseconds(30));
1109     SetProperties(a3, p3, from[2], to[2], TimeSpan::Milliseconds(75));
1110     SetProperties(a4, p4, from[3], to[3], TimeSpan::Milliseconds(150));
1111 
1112     par2.Add(a1).Add(a2);
1113     seq1.Add(a3);
1114     par1.Add(seq1).Add(a4);
1115     seq1.Add(par2);
1116 
1117     par1.Start();
1118     par1.Step(GetTestClock());
1119 
1120     float previousProgress = 0.f;
1121 
__anon5e1217880d02(uint32_t frame) 1122     StepAnimations({ par1 }, 15, 10, [&](uint32_t frame) {
1123         EXPECT_EQ(par1.GetRunning(), frame < 15) << "Frame " << frame;
1124 
1125         auto progress = par1.GetProgress();
1126         EXPECT_GT(progress, previousProgress) << "Frame " << frame;
1127         previousProgress = progress;
1128     });
1129 
1130     EXPECT_FALSE(par1.GetRunning());
1131 
1132     EXPECT_EQ(seq1.GetProgress(), 1.f);
1133     EXPECT_EQ(par1.GetProgress(), 1.f);
1134     EXPECT_EQ(par2.GetProgress(), 1.f);
1135     EXPECT_EQ(a1.GetProgress(), 1.f);
1136     EXPECT_EQ(a2.GetProgress(), 1.f);
1137     EXPECT_EQ(a3.GetProgress(), 1.f);
1138     EXPECT_EQ(a4.GetProgress(), 1.f);
1139     EXPECT_EQ(GetValue(p1), to[0]);
1140     EXPECT_EQ(GetValue(p2), to[1]);
1141     EXPECT_EQ(GetValue(p3), to[2]);
1142     EXPECT_EQ(GetValue(p4), to[3]);
1143 }
1144 
1145 /**
1146  * @tc.name: Reparent
1147  * @tc.desc: test Reparent
1148  * @tc.type: FUNC
1149  */
1150 HWTEST_F(StaggeredAnimationTest, Reparent, TestSize.Level1)
1151 {
1152     auto p1 = ConstructProperty<float>("p1", 0);
1153     auto p2 = ConstructProperty<float>("p2", 0);
1154     auto seq = META_NS::SequentialAnimation(CreateInstance(ClassId::SequentialAnimation));
1155     auto par = META_NS::ParallelAnimation(CreateInstance(ClassId::ParallelAnimation));
1156 
1157     auto a1 = META_NS::KeyframeAnimation<float>(CreateInstance(ClassId::KeyframeAnimation));
1158     auto a2 = META_NS::KeyframeAnimation<float>(CreateInstance(ClassId::KeyframeAnimation));
1159 
1160     auto a1cont = interface_cast<IContainable>(a1);
1161     auto a2cont = interface_cast<IContainable>(a2);
1162     ASSERT_NE(a1cont, nullptr);
1163     ASSERT_NE(a2cont, nullptr);
1164 
1165     float from[2] = { 0, 5 };
1166     float to[2] = { 10, 50 };
1167     TimeSpan duration[2] = { TimeSpan::Milliseconds(100), TimeSpan::Milliseconds(200) };
1168 
1169     SetProperties(a1, p1, from[0], to[0], duration[0]);
1170     SetProperties(a2, p2, from[1], to[1], duration[1]);
1171 
1172     seq.Add(a1).Add(a2);
1173     EXPECT_EQ(a1cont->GetParent(), seq);
1174     EXPECT_EQ(a2cont->GetParent(), seq);
1175 
1176     EXPECT_EQ(seq.GetTotalDuration(), duration[0] + duration[1]);
1177 
1178     seq.Start();
1179     seq.Step(GetTestClock());
1180 
1181     EXPECT_TRUE(seq.GetRunning());
1182     EXPECT_TRUE(a1.GetRunning());
1183 
1184     // Reparent the animation
1185     par.Add(a1);
1186     EXPECT_EQ(a1cont->GetParent(), par);
1187     EXPECT_EQ(a2cont->GetParent(), seq);
1188 
1189     EXPECT_TRUE(seq.GetRunning());
1190     EXPECT_TRUE(a1.GetRunning());
1191     seq.Stop();
1192 
1193     // Animation durations should have been updated due to hierarchy change
1194     EXPECT_EQ(seq.GetTotalDuration(), duration[1]);
1195     EXPECT_EQ(par.GetTotalDuration(), duration[0]);
1196 
1197     par.Start();
1198     EXPECT_FALSE(seq.GetRunning());
1199     EXPECT_TRUE(par.GetRunning());
1200     EXPECT_TRUE(a1.GetRunning());
1201 }
1202 
1203 /**
1204  * @tc.name: Name
1205  * @tc.desc: test Name
1206  * @tc.type: FUNC
1207  */
1208 HWTEST_F(StaggeredAnimationTest, Name, TestSize.Level1)
1209 {
1210     ParallelAnimation a1(CreateInstance(ClassId::ParallelAnimation));
1211     SequentialAnimation a2(CreateInstance(ClassId::SequentialAnimation));
1212 
1213     Named n1(a1);
1214     Named n2(a2);
1215     EXPECT_NE(n1.GetName(), "");
1216     EXPECT_NE(n2.GetName(), "");
1217 
1218     n1.SetName("Anim1");
1219     n2.SetName("Anim2");
1220 
1221     EXPECT_EQ(n1.GetName(), "Anim1");
1222     EXPECT_EQ(a1.GetPtr()->GetName(), n1.GetName());
1223     EXPECT_EQ(n2.GetName(), "Anim2");
1224     EXPECT_EQ(a2.GetPtr()->GetName(), n2.GetName());
1225 }
1226 
1227 /**
1228  * @tc.name: ParallelWithTrackAnimationSeeking
1229  * @tc.desc: test ParallelWithTrackAnimationSeeking
1230  * @tc.type: FUNC
1231  */
1232 HWTEST_F(StaggeredAnimationTest, ParallelWithTrackAnimationSeeking, TestSize.Level1)
1233 {
1234     static BASE_NS::vector<float> trackTimestamps = { 0.0f, 1.f };
1235     static BASE_NS::vector<int> trackKeyframes = { 0, 10 };
1236 
1237     auto property = ConstructProperty<int>("Prop");
1238     auto parallel = META_NS::ParallelAnimation(CreateInstance(ClassId::ParallelAnimation));
1239     auto anim = META_NS::TrackAnimation<int>(CreateInstance(ClassId::TrackAnimation));
1240     anim.SetKeyframes(trackKeyframes)
1241         .SetTimestamps(trackTimestamps)
1242         .SetProperty(property)
1243         .SetDuration(TimeSpan::Milliseconds(1000));
1244 
1245     ASSERT_TRUE(parallel);
1246     ASSERT_TRUE(anim);
1247     parallel.Add(anim);
1248     parallel.Start();
1249     parallel.Step(GetTestClock());
1250 
1251     EXPECT_TRUE(parallel.GetRunning());
1252     EXPECT_TRUE(anim.GetRunning());
1253 
1254     parallel.Pause();
1255 
1256     int count = 0;
__anon5e1217880e02null1257     property->OnChanged()->AddHandler(MakeCallback<IOnChanged>([&] {
1258         ++count;
1259         EXPECT_EQ(property->GetValue(), count);
1260     }));
1261 
1262     // should do nothing
__anon5e1217880f02(uint32_t frame) 1263     StepAnimations({ parallel }, 10, [](uint32_t frame) {});
1264 
1265     parallel.Seek(0.1f);
1266 
1267     // should do nothing
__anon5e1217881002(uint32_t frame) 1268     StepAnimations({ parallel }, 10, [](uint32_t frame) {});
1269 
1270     EXPECT_EQ(property->GetValue(), 1);
1271     EXPECT_EQ(count, 1);
1272     parallel.Seek(0.2f);
1273     EXPECT_EQ(property->GetValue(), 2);
1274     EXPECT_EQ(count, 2);
1275     parallel.Seek(0.3f);
1276     EXPECT_EQ(property->GetValue(), 3);
1277     EXPECT_EQ(count, 3);
1278 }
1279 
1280 META_END_NAMESPACE()
1281