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