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