1*af2ec015STomasz Sapeta #include "LayoutAnimationsManager.h"
2*af2ec015STomasz Sapeta #include "CollectionUtils.h"
3*af2ec015STomasz Sapeta #include "Shareables.h"
4*af2ec015STomasz Sapeta
5*af2ec015STomasz Sapeta #include <utility>
6*af2ec015STomasz Sapeta
7*af2ec015STomasz Sapeta namespace ABI49_0_0reanimated {
8*af2ec015STomasz Sapeta
configureAnimation(int tag,LayoutAnimationType type,const std::string & sharedTransitionTag,std::shared_ptr<Shareable> config)9*af2ec015STomasz Sapeta void LayoutAnimationsManager::configureAnimation(
10*af2ec015STomasz Sapeta int tag,
11*af2ec015STomasz Sapeta LayoutAnimationType type,
12*af2ec015STomasz Sapeta const std::string &sharedTransitionTag,
13*af2ec015STomasz Sapeta std::shared_ptr<Shareable> config) {
14*af2ec015STomasz Sapeta auto lock = std::unique_lock<std::mutex>(animationsMutex_);
15*af2ec015STomasz Sapeta getConfigsForType(type)[tag] = config;
16*af2ec015STomasz Sapeta if (type == SHARED_ELEMENT_TRANSITION) {
17*af2ec015STomasz Sapeta sharedTransitionGroups_[sharedTransitionTag].push_back(tag);
18*af2ec015STomasz Sapeta viewTagToSharedTag_[tag] = sharedTransitionTag;
19*af2ec015STomasz Sapeta }
20*af2ec015STomasz Sapeta }
21*af2ec015STomasz Sapeta
hasLayoutAnimation(int tag,LayoutAnimationType type)22*af2ec015STomasz Sapeta bool LayoutAnimationsManager::hasLayoutAnimation(
23*af2ec015STomasz Sapeta int tag,
24*af2ec015STomasz Sapeta LayoutAnimationType type) {
25*af2ec015STomasz Sapeta auto lock = std::unique_lock<std::mutex>(animationsMutex_);
26*af2ec015STomasz Sapeta return collection::contains(getConfigsForType(type), tag);
27*af2ec015STomasz Sapeta }
28*af2ec015STomasz Sapeta
clearLayoutAnimationConfig(int tag)29*af2ec015STomasz Sapeta void LayoutAnimationsManager::clearLayoutAnimationConfig(int tag) {
30*af2ec015STomasz Sapeta auto lock = std::unique_lock<std::mutex>(animationsMutex_);
31*af2ec015STomasz Sapeta enteringAnimations_.erase(tag);
32*af2ec015STomasz Sapeta exitingAnimations_.erase(tag);
33*af2ec015STomasz Sapeta layoutAnimations_.erase(tag);
34*af2ec015STomasz Sapeta
35*af2ec015STomasz Sapeta sharedTransitionAnimations_.erase(tag);
36*af2ec015STomasz Sapeta auto const &groupName = viewTagToSharedTag_[tag];
37*af2ec015STomasz Sapeta auto &group = sharedTransitionGroups_[groupName];
38*af2ec015STomasz Sapeta auto position = std::find(group.begin(), group.end(), tag);
39*af2ec015STomasz Sapeta if (position != group.end()) {
40*af2ec015STomasz Sapeta group.erase(position);
41*af2ec015STomasz Sapeta }
42*af2ec015STomasz Sapeta if (group.size() == 0) {
43*af2ec015STomasz Sapeta sharedTransitionGroups_.erase(groupName);
44*af2ec015STomasz Sapeta }
45*af2ec015STomasz Sapeta viewTagToSharedTag_.erase(tag);
46*af2ec015STomasz Sapeta }
47*af2ec015STomasz Sapeta
startLayoutAnimation(jsi::Runtime & rt,int tag,LayoutAnimationType type,const jsi::Object & values)48*af2ec015STomasz Sapeta void LayoutAnimationsManager::startLayoutAnimation(
49*af2ec015STomasz Sapeta jsi::Runtime &rt,
50*af2ec015STomasz Sapeta int tag,
51*af2ec015STomasz Sapeta LayoutAnimationType type,
52*af2ec015STomasz Sapeta const jsi::Object &values) {
53*af2ec015STomasz Sapeta std::shared_ptr<Shareable> config, viewShareable;
54*af2ec015STomasz Sapeta {
55*af2ec015STomasz Sapeta auto lock = std::unique_lock<std::mutex>(animationsMutex_);
56*af2ec015STomasz Sapeta config = getConfigsForType(type)[tag];
57*af2ec015STomasz Sapeta }
58*af2ec015STomasz Sapeta // TODO: cache the following!!
59*af2ec015STomasz Sapeta jsi::Value layoutAnimationRepositoryAsValue =
60*af2ec015STomasz Sapeta rt.global()
61*af2ec015STomasz Sapeta .getPropertyAsObject(rt, "global")
62*af2ec015STomasz Sapeta .getProperty(rt, "LayoutAnimationsManager");
63*af2ec015STomasz Sapeta jsi::Function startAnimationForTag =
64*af2ec015STomasz Sapeta layoutAnimationRepositoryAsValue.getObject(rt).getPropertyAsFunction(
65*af2ec015STomasz Sapeta rt, "start");
66*af2ec015STomasz Sapeta startAnimationForTag.call(
67*af2ec015STomasz Sapeta rt,
68*af2ec015STomasz Sapeta jsi::Value(tag),
69*af2ec015STomasz Sapeta jsi::Value(static_cast<int>(type)),
70*af2ec015STomasz Sapeta values,
71*af2ec015STomasz Sapeta config->getJSValue(rt));
72*af2ec015STomasz Sapeta }
73*af2ec015STomasz Sapeta
cancelLayoutAnimation(jsi::Runtime & rt,int tag,LayoutAnimationType type,bool cancelled=true,bool removeView=true)74*af2ec015STomasz Sapeta void LayoutAnimationsManager::cancelLayoutAnimation(
75*af2ec015STomasz Sapeta jsi::Runtime &rt,
76*af2ec015STomasz Sapeta int tag,
77*af2ec015STomasz Sapeta LayoutAnimationType type,
78*af2ec015STomasz Sapeta bool cancelled = true,
79*af2ec015STomasz Sapeta bool removeView = true) {
80*af2ec015STomasz Sapeta jsi::Value layoutAnimationRepositoryAsValue =
81*af2ec015STomasz Sapeta rt.global()
82*af2ec015STomasz Sapeta .getPropertyAsObject(rt, "global")
83*af2ec015STomasz Sapeta .getProperty(rt, "LayoutAnimationsManager");
84*af2ec015STomasz Sapeta jsi::Function cancelLayoutAnimation =
85*af2ec015STomasz Sapeta layoutAnimationRepositoryAsValue.getObject(rt).getPropertyAsFunction(
86*af2ec015STomasz Sapeta rt, "stop");
87*af2ec015STomasz Sapeta std::shared_ptr<Shareable> config;
88*af2ec015STomasz Sapeta {
89*af2ec015STomasz Sapeta auto lock = std::unique_lock<std::mutex>(animationsMutex_);
90*af2ec015STomasz Sapeta config = sharedTransitionAnimations_[tag];
91*af2ec015STomasz Sapeta }
92*af2ec015STomasz Sapeta if (config != nullptr) {
93*af2ec015STomasz Sapeta cancelLayoutAnimation.call(
94*af2ec015STomasz Sapeta rt, jsi::Value(tag), config->getJSValue(rt), cancelled, removeView);
95*af2ec015STomasz Sapeta }
96*af2ec015STomasz Sapeta }
97*af2ec015STomasz Sapeta
98*af2ec015STomasz Sapeta /*
99*af2ec015STomasz Sapeta The top screen on the stack triggers the animation, so we need to find
100*af2ec015STomasz Sapeta the sibling view registered in the past. This method finds view
101*af2ec015STomasz Sapeta registered in the same transition group (with the same transition tag)
102*af2ec015STomasz Sapeta which has been added to that group directly before the one that we
103*af2ec015STomasz Sapeta provide as an argument.
104*af2ec015STomasz Sapeta */
findPrecedingViewTagForTransition(int tag)105*af2ec015STomasz Sapeta int LayoutAnimationsManager::findPrecedingViewTagForTransition(int tag) {
106*af2ec015STomasz Sapeta auto const &groupName = viewTagToSharedTag_[tag];
107*af2ec015STomasz Sapeta auto const &group = sharedTransitionGroups_[groupName];
108*af2ec015STomasz Sapeta auto position = std::find(group.begin(), group.end(), tag);
109*af2ec015STomasz Sapeta if (position != group.end() && position != group.begin()) {
110*af2ec015STomasz Sapeta return *std::prev(position);
111*af2ec015STomasz Sapeta }
112*af2ec015STomasz Sapeta return -1;
113*af2ec015STomasz Sapeta }
114*af2ec015STomasz Sapeta
115*af2ec015STomasz Sapeta std::unordered_map<int, std::shared_ptr<Shareable>>
getConfigsForType(LayoutAnimationType type)116*af2ec015STomasz Sapeta &LayoutAnimationsManager::getConfigsForType(LayoutAnimationType type) {
117*af2ec015STomasz Sapeta switch (type) {
118*af2ec015STomasz Sapeta case ENTERING:
119*af2ec015STomasz Sapeta return enteringAnimations_;
120*af2ec015STomasz Sapeta case EXITING:
121*af2ec015STomasz Sapeta return exitingAnimations_;
122*af2ec015STomasz Sapeta case LAYOUT:
123*af2ec015STomasz Sapeta return layoutAnimations_;
124*af2ec015STomasz Sapeta case SHARED_ELEMENT_TRANSITION:
125*af2ec015STomasz Sapeta return sharedTransitionAnimations_;
126*af2ec015STomasz Sapeta default:
127*af2ec015STomasz Sapeta assert(false);
128*af2ec015STomasz Sapeta }
129*af2ec015STomasz Sapeta }
130*af2ec015STomasz Sapeta
131*af2ec015STomasz Sapeta } // namespace reanimated
132