Revert "[Tizen] Not execute the remove callback"
[platform/core/uifw/dali-core.git] / dali / internal / event / events / gesture-detector-impl.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/event/events/gesture-detector-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <algorithm>
23
24 // INTERNAL INCLUDES
25 #include <dali/integration-api/debug.h>
26 #include <dali/internal/event/common/stage-impl.h>
27 #include <dali/internal/event/common/thread-local-storage.h>
28 #include <dali/internal/event/events/actor-gesture-data.h>
29 #include <dali/internal/event/events/gesture-event-processor.h>
30
31 namespace Dali
32 {
33 namespace Internal
34 {
35 GestureDetector::GestureDetector(GestureType::Value type, const SceneGraph::PropertyOwner* sceneObject)
36 : Object(sceneObject),
37   mType(type),
38   mGestureEventProcessor(ThreadLocalStorage::Get().GetGestureEventProcessor())
39 {
40 }
41
42 GestureDetector::~GestureDetector()
43 {
44   if(!mPendingAttachActors.empty())
45   {
46     for(GestureDetectorActorContainer::iterator iter = mPendingAttachActors.begin(), endIter = mPendingAttachActors.end(); iter != endIter; ++iter)
47     {
48       Actor* actor(*iter);
49       actor->RemoveObserver(*this);
50       actor->GetGestureData().RemoveGestureDetector(*this);
51     }
52
53     mPendingAttachActors.clear();
54   }
55
56   if(!mAttachedActors.empty())
57   {
58     for(GestureDetectorActorContainer::iterator iter = mAttachedActors.begin(), endIter = mAttachedActors.end(); iter != endIter; ++iter)
59     {
60       Actor* actor(*iter);
61       actor->RemoveObserver(*this);
62       actor->GetGestureData().RemoveGestureDetector(*this);
63     }
64
65     mAttachedActors.clear();
66
67     // Guard to allow handle destruction after Core has been destroyed
68     if(Stage::IsInstalled())
69     {
70       mGestureEventProcessor.RemoveGestureDetector(this);
71     }
72   }
73 }
74
75 void GestureDetector::Attach(Actor& actor)
76 {
77   if(!IsAttached(actor))
78   {
79     if(actor.OnScene())
80     {
81       // Register with EventProcessor if first actor being added
82       if(mAttachedActors.empty())
83       {
84         mGestureEventProcessor.AddGestureDetector(this, actor.GetScene());
85       }
86       mAttachedActors.push_back(&actor);
87       // We need to observe the actor's destruction
88       actor.AddObserver(*this);
89       // Add the detector to the actor (so the actor knows it requires this gesture when going through hit-test algorithm)
90       actor.GetGestureData().AddGestureDetector(*this);
91       // Notification for derived classes
92       OnActorAttach(actor);
93     }
94     else
95     {
96       actor.AddObserver(*this);
97       // Add the detector to the actor (so the actor knows it requires this gesture when going through hit-test algorithm)
98       actor.GetGestureData().AddGestureDetector(*this);
99
100       mPendingAttachActors.push_back(&actor);
101     }
102   }
103 }
104
105 void GestureDetector::SceneObjectAdded(Object& object)
106 {
107   Actor& actor = dynamic_cast<Actor&>(object);
108
109   // Make sure the actor has not already been attached. Can't use IsAttached() as that checks the pending list as well
110   if(find(mAttachedActors.begin(), mAttachedActors.end(), &actor) == mAttachedActors.end())
111   {
112     GestureDetectorActorContainer::iterator match = find(mPendingAttachActors.begin(), mPendingAttachActors.end(), &actor);
113
114     if(match != mPendingAttachActors.end())
115     {
116       mPendingAttachActors.erase(match);
117
118       // Register with EventProcessor if first actor being added
119       if(mAttachedActors.empty())
120       {
121         mGestureEventProcessor.AddGestureDetector(this, actor.GetScene());
122       }
123       mAttachedActors.push_back(&actor);
124
125       // Notification for derived classes
126       OnActorAttach(actor);
127     }
128     else
129     {
130       // Actor was not in the pending list
131       DALI_ASSERT_DEBUG(false);
132     }
133   }
134   else
135   {
136     // Check if actor has been attached and is still in the pending list - this would not be correct
137     DALI_ASSERT_DEBUG(find(mPendingAttachActors.begin(), mPendingAttachActors.end(), &actor) == mPendingAttachActors.end());
138   }
139 }
140
141 void GestureDetector::Detach(Actor& actor)
142 {
143   if(!mPendingAttachActors.empty())
144   {
145     GestureDetectorActorContainer::iterator match = find(mPendingAttachActors.begin(), mPendingAttachActors.end(), &actor);
146
147     if(match != mPendingAttachActors.end())
148     {
149       // We no longer need to observe the actor's destruction
150       actor.RemoveObserver(*this);
151
152       // Remove detector from actor-gesture-data
153       actor.GetGestureData().RemoveGestureDetector(*this);
154
155       mPendingAttachActors.erase(match);
156     }
157   }
158
159   if(!mAttachedActors.empty())
160   {
161     GestureDetectorActorContainer::iterator match = find(mAttachedActors.begin(), mAttachedActors.end(), &actor);
162
163     if(match != mAttachedActors.end())
164     {
165       // We no longer need to observe the actor's destruction
166       actor.RemoveObserver(*this);
167
168       // Remove detector from actor-gesture-data
169       actor.GetGestureData().RemoveGestureDetector(*this);
170
171       mAttachedActors.erase(match);
172
173       // Notification for derived classes
174       OnActorDetach(actor);
175
176       // Unregister from gesture event processor if we do not have any actors
177       if(mAttachedActors.empty())
178       {
179         // Guard to allow handle destruction after Core has been destroyed
180         if(Stage::IsInstalled())
181         {
182           mGestureEventProcessor.RemoveGestureDetector(this);
183         }
184       }
185     }
186   }
187 }
188
189 void GestureDetector::DetachAll()
190 {
191   if(!mPendingAttachActors.empty())
192   {
193     GestureDetectorActorContainer pendingActors(mPendingAttachActors);
194
195     mPendingAttachActors.clear();
196
197     for(GestureDetectorActorContainer::iterator iter = pendingActors.begin(), endIter = pendingActors.end(); iter != endIter; ++iter)
198     {
199       Actor* actor(*iter);
200
201       // We no longer need to observe the actor's destruction
202       actor->RemoveObserver(*this);
203
204       // Remove detector from actor-gesture-data
205       actor->GetGestureData().RemoveGestureDetector(*this);
206     }
207   }
208
209   if(!mAttachedActors.empty())
210   {
211     GestureDetectorActorContainer attachedActors(mAttachedActors);
212
213     // Clear mAttachedActors before we call OnActorDetach in case derived classes call a method which manipulates mAttachedActors.
214     mAttachedActors.clear();
215
216     for(GestureDetectorActorContainer::iterator iter = attachedActors.begin(), endIter = attachedActors.end(); iter != endIter; ++iter)
217     {
218       Actor* actor(*iter);
219
220       // We no longer need to observe the actor's destruction
221       actor->RemoveObserver(*this);
222
223       // Remove detector from actor-gesture-data
224       actor->GetGestureData().RemoveGestureDetector(*this);
225
226       // Notification for derived classes
227       OnActorDetach(*actor);
228     }
229
230     // Guard to allow handle destruction after Core has been destroyed
231     if(Stage::IsInstalled())
232     {
233       // Unregister from gesture event processor
234       mGestureEventProcessor.RemoveGestureDetector(this);
235     }
236   }
237 }
238
239 size_t GestureDetector::GetAttachedActorCount() const
240 {
241   return mPendingAttachActors.size() + mAttachedActors.size();
242 }
243
244 Dali::Actor GestureDetector::GetAttachedActor(size_t index) const
245 {
246   Dali::Actor actor;
247
248   if(index < mPendingAttachActors.size())
249   {
250     actor = Dali::Actor(mPendingAttachActors[index]);
251   }
252   else if(index < mPendingAttachActors.size() + mAttachedActors.size())
253   {
254     actor = Dali::Actor(mAttachedActors[index - mPendingAttachActors.size()]);
255   }
256
257   return actor;
258 }
259
260 bool GestureDetector::IsAttached(Actor& actor) const
261 {
262   return (find(mPendingAttachActors.begin(), mPendingAttachActors.end(), &actor) != mPendingAttachActors.end()) ||
263          (find(mAttachedActors.begin(), mAttachedActors.end(), &actor) != mAttachedActors.end());
264 }
265
266 void GestureDetector::ObjectDestroyed(Object& object)
267 {
268   if(!mPendingAttachActors.empty())
269   {
270     GestureDetectorActorContainer::iterator match = find(mPendingAttachActors.begin(), mPendingAttachActors.end(), &object);
271
272     if(match != mPendingAttachActors.end())
273     {
274       mPendingAttachActors.erase(match);
275     }
276   }
277
278   if(!mAttachedActors.empty())
279   {
280     GestureDetectorActorContainer::iterator match = find(mAttachedActors.begin(), mAttachedActors.end(), &object);
281
282     if(match != mAttachedActors.end())
283     {
284       mAttachedActors.erase(match);
285
286       // Notification for derived classes
287       OnActorDestroyed(object);
288
289       // Unregister from gesture event processor if we do not have any actors
290       if(mAttachedActors.empty())
291       {
292         // Guard to allow handle destruction after Core has been destroyed
293         if(Stage::IsInstalled())
294         {
295           mGestureEventProcessor.RemoveGestureDetector(this);
296         }
297       }
298     }
299   }
300 }
301
302 } // namespace Internal
303
304 } // namespace Dali