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