Update rive-cpp to 2.0 version
[platform/core/uifw/rive-tizen.git] / submodule / rive-cpp / test / state_machine_test.cpp
1 #include <rive/file.hpp>
2 #include <rive/animation/state_machine_bool.hpp>
3 #include <rive/animation/state_machine_layer.hpp>
4 #include <rive/animation/animation_state.hpp>
5 #include <rive/animation/entry_state.hpp>
6 #include <rive/animation/state_transition.hpp>
7 #include <rive/animation/state_machine_instance.hpp>
8 #include <rive/animation/state_machine_input_instance.hpp>
9 #include <rive/animation/blend_state_1d.hpp>
10 #include <rive/animation/blend_animation_1d.hpp>
11 #include <rive/animation/blend_state_direct.hpp>
12 #include <rive/animation/blend_state_transition.hpp>
13 #include "catch.hpp"
14 #include "rive_file_reader.hpp"
15 #include <cstdio>
16
17 TEST_CASE("file with state machine be read", "[file]") {
18     auto file = ReadRiveFile("../../test/assets/rocket.riv");
19
20     auto artboard = file->artboard();
21     REQUIRE(artboard != nullptr);
22     REQUIRE(artboard->animationCount() == 3);
23     REQUIRE(artboard->stateMachineCount() == 1);
24
25     auto stateMachine = artboard->stateMachine("Button");
26     REQUIRE(stateMachine != nullptr);
27
28     REQUIRE(stateMachine->layerCount() == 1);
29     REQUIRE(stateMachine->inputCount() == 2);
30
31     auto hover = stateMachine->input("Hover");
32     REQUIRE(hover != nullptr);
33     REQUIRE(hover->is<rive::StateMachineBool>());
34
35     auto press = stateMachine->input("Press");
36     REQUIRE(press != nullptr);
37     REQUIRE(press->is<rive::StateMachineBool>());
38
39     auto layer = stateMachine->layer(0);
40     REQUIRE(layer->stateCount() == 6);
41
42     REQUIRE(layer->anyState() != nullptr);
43     REQUIRE(layer->entryState() != nullptr);
44     REQUIRE(layer->exitState() != nullptr);
45
46     int foundAnimationStates = 0;
47     for (int i = 0; i < layer->stateCount(); i++) {
48         auto state = layer->state(i);
49         if (state->is<rive::AnimationState>()) {
50             foundAnimationStates++;
51             REQUIRE(state->as<rive::AnimationState>()->animation() != nullptr);
52         }
53     }
54
55     REQUIRE(foundAnimationStates == 3);
56
57     REQUIRE(layer->entryState()->transitionCount() == 1);
58     auto stateTo = layer->entryState()->transition(0)->stateTo();
59     REQUIRE(stateTo != nullptr);
60     REQUIRE(stateTo->is<rive::AnimationState>());
61     REQUIRE(stateTo->as<rive::AnimationState>()->animation() != nullptr);
62     REQUIRE(stateTo->as<rive::AnimationState>()->animation()->name() == "idle");
63
64     auto idleState = stateTo->as<rive::AnimationState>();
65     REQUIRE(idleState->transitionCount() == 2);
66     for (int i = 0; i < idleState->transitionCount(); i++) {
67         auto transition = idleState->transition(i);
68         if (transition->stateTo()->as<rive::AnimationState>()->animation()->name() == "Roll_over") {
69             // Check the condition
70             REQUIRE(transition->conditionCount() == 1);
71         }
72     }
73
74     auto abi = artboard->instance();
75     rive::StateMachineInstance smi(artboard->stateMachine("Button"), abi.get());
76
77     REQUIRE(smi.getBool("Hover")->name() == "Hover");
78     REQUIRE(smi.getBool("Press")->name() == "Press");
79     REQUIRE(smi.getBool("Hover") != nullptr);
80     REQUIRE(smi.getBool("Press") != nullptr);
81     REQUIRE(smi.stateChangedCount() == 0);
82     REQUIRE(smi.currentAnimationCount() == 0);
83 }
84
85 TEST_CASE("file with blend states loads correctly", "[file]") {
86     auto file = ReadRiveFile("../../test/assets/blend_test.riv");
87
88     auto artboard = file->artboard();
89     REQUIRE(artboard != nullptr);
90     REQUIRE(artboard->animationCount() == 4);
91     REQUIRE(artboard->stateMachineCount() == 2);
92
93     auto stateMachine = artboard->stateMachine("blend");
94     REQUIRE(stateMachine != nullptr);
95
96     REQUIRE(stateMachine->layerCount() == 1);
97     auto layer = stateMachine->layer(0);
98     REQUIRE(layer->stateCount() == 5);
99
100     REQUIRE(layer->anyState() != nullptr);
101     REQUIRE(layer->entryState() != nullptr);
102     REQUIRE(layer->exitState() != nullptr);
103
104     REQUIRE(layer->state(1)->is<rive::BlendState1D>());
105     REQUIRE(layer->state(2)->is<rive::BlendState1D>());
106
107     auto blendStateA = layer->state(1)->as<rive::BlendState1D>();
108     auto blendStateB = layer->state(2)->as<rive::BlendState1D>();
109
110     REQUIRE(blendStateA->animationCount() == 3);
111     REQUIRE(blendStateB->animationCount() == 3);
112
113     auto animation = blendStateA->animation(0);
114     REQUIRE(animation->is<rive::BlendAnimation1D>());
115     auto animation1D = animation->as<rive::BlendAnimation1D>();
116     REQUIRE(animation1D->animation() != nullptr);
117     REQUIRE(animation1D->animation()->name() == "horizontal");
118     REQUIRE(animation1D->value() == 0.0f);
119
120     animation = blendStateA->animation(1);
121     REQUIRE(animation->is<rive::BlendAnimation1D>());
122     animation1D = animation->as<rive::BlendAnimation1D>();
123     REQUIRE(animation1D->animation() != nullptr);
124     REQUIRE(animation1D->animation()->name() == "vertical");
125     REQUIRE(animation1D->value() == 100.0f);
126
127     animation = blendStateA->animation(2);
128     REQUIRE(animation->is<rive::BlendAnimation1D>());
129     animation1D = animation->as<rive::BlendAnimation1D>();
130     REQUIRE(animation1D->animation() != nullptr);
131     REQUIRE(animation1D->animation()->name() == "rotate");
132     REQUIRE(animation1D->value() == 0.0f);
133
134     REQUIRE(blendStateA->transitionCount() == 1);
135     REQUIRE(blendStateA->transition(0)->is<rive::BlendStateTransition>());
136     REQUIRE(blendStateA->transition(0)->as<rive::BlendStateTransition>()->exitBlendAnimation() !=
137             nullptr);
138 }
139
140 TEST_CASE("animation state with no animation doesn't crash", "[file]") {
141     auto file = ReadRiveFile("../../test/assets/multiple_state_machines.riv");
142
143     auto artboard = file->artboard();
144     REQUIRE(artboard != nullptr);
145     REQUIRE(artboard->animationCount() == 1);
146     REQUIRE(artboard->stateMachineCount() == 4);
147
148     auto stateMachine = artboard->stateMachine("two");
149     REQUIRE(stateMachine != nullptr);
150
151     REQUIRE(stateMachine->layerCount() == 1);
152     auto layer = stateMachine->layer(0);
153     REQUIRE(layer->stateCount() == 4);
154
155     REQUIRE(layer->anyState() != nullptr);
156     REQUIRE(layer->entryState() != nullptr);
157     REQUIRE(layer->exitState() != nullptr);
158
159     REQUIRE(layer->state(3)->is<rive::AnimationState>());
160
161     auto animationState = layer->state(3)->as<rive::AnimationState>();
162     REQUIRE(animationState->animation() == nullptr);
163
164     auto abi = artboard->instance();
165     rive::StateMachineInstance(stateMachine, abi.get()).advance(0.0f);
166 }