(Observers)Fix memory issues during observer iteration
[platform/core/uifw/dali-core.git] / dali / internal / event / events / gesture-processor.h
1 #ifndef __DALI_INTERNAL_GESTURE_PROCESSOR_H__
2 #define __DALI_INTERNAL_GESTURE_PROCESSOR_H__
3
4 //
5 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
6 //
7 // Licensed under the Flora License, Version 1.0 (the License);
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //     http://floralicense.org/license/
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an AS IS BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19
20 // INTERNAL INCLUDES
21 #include <dali/internal/event/events/gesture-detector-impl.h>
22 #include <dali/internal/event/events/hit-test-algorithm-impl.h>
23 #include <dali/internal/event/common/proxy-object.h>
24
25 namespace Dali
26 {
27
28 class Actor;
29
30 namespace Internal
31 {
32
33 /**
34  * Base class for the different Gesture Processors.
35  */
36 class GestureProcessor : public ProxyObject::Observer
37 {
38 protected: // Construction & Destruction
39
40   /**
41    * Protected constructor.  Cannot create an instance of GestureProcessor
42    */
43   GestureProcessor();
44
45   /**
46    * Virtual protected destructor.
47    */
48   virtual ~GestureProcessor();
49
50   // Templates and types for deriving classes
51
52   /**
53    * Given a container of derived pointer types, this populates an equivalent container of base pointer types.
54    * @param[in]   derivedContainer  A const reference to the container with pointers to the derived class.
55    * @param[out]  baseContainer     A reference to the container to populate with equivalent pointers to the base class.
56    * @pre Ensure the baseContainer is empty.
57    */
58   template< typename Detector >
59   static void UpCastContainer( const typename DerivedGestureDetectorContainer<Detector>::type& derivedContainer, GestureDetectorContainer& baseContainer )
60   {
61     baseContainer.assign( derivedContainer.begin(), derivedContainer.end() );
62   }
63
64   /**
65    * Given a container of base pointer types, this populates an equivalent container of derived pointer types.
66    * @param[in]   baseContainer     A const reference to the container with pointers to the base class.
67    * @param[out]  derivedContainer  A reference to the container to populate with equivalent pointers to the derived class.
68    * @pre Ensure the derivedContainer is empty.
69    */
70   template< typename Detector >
71   static void DownCastContainer( const GestureDetectorContainer& baseContainer, typename DerivedGestureDetectorContainer<Detector>::type& derivedContainer )
72   {
73     for ( GestureDetectorContainer::const_iterator iter = baseContainer.begin(), endIter = baseContainer.end(); iter != endIter; ++iter )
74     {
75       derivedContainer.push_back( static_cast< Detector* >( *iter ) );
76     }
77   }
78
79   /**
80    * Functor to use in GetGesturedActor() and ProcessAndEmit() methods.
81    */
82   struct Functor
83   {
84     /**
85      * This operator should be overridden to check if the gesture detector meets the parameters of the current gesture.
86      * @param[in]  detector  The gesture detector to check.
87      * @param[in]  actor     The actor that has been gestured.
88      * @return true, if it meets the parameters, false otherwise.
89      */
90     virtual bool operator() ( GestureDetector* detector, Actor* actor ) = 0;
91
92     /**
93      * This operator should be overridden to emit the gesture signal on the provided container of gesture detectors along with the actor
94      * the gesture has occurred on.
95      * @param[in]  actor             The actor which has been gestured.
96      * @param[in]  gestureDetectors  The detectors that should emit the signal.
97      * @param[in]  actorCoordinates  The local actor coordinates where the gesture took place.
98      */
99     virtual void operator() ( Dali::Actor actor, const GestureDetectorContainer& gestureDetectors, Vector2 actorCoordinates ) = 0;
100   };
101
102   // Methods for deriving classes
103
104   /**
105    * Given the hit actor and attached detectors, this walks up the actor tree to determine the actor that is connected to one (or several) gesture
106    * detectors. The functor is used to check whether the gesture falls within the gesture detector's parameters.
107    * Derived classes need to provide this functor.
108    *
109    * @param[in,out]  actor               The hit actor. When this function returns, this is the actor that has been hit by the gesture.
110    * @param[in]      connectedDetectors  Reference to the detectors connected to the derived processor
111    * @param[out]     gestureDetectors    A container containing all the gesture detectors that have the hit actor attached and satisfy the functor parameters.
112    * @param[in]      functor             A reference to Functor.  The operator() (GestureDetector*) should be used to check if the connected gesture detector
113    *                                     meets the current gesture's parameters.
114    */
115   void GetGesturedActor( Dali::Actor& actor, const GestureDetectorContainer& connectedDetectors, GestureDetectorContainer& gestureDetectors, Functor& functor );
116
117   /**
118    * This does what GetGesturedActor() does but also starts emission of the gesture (using the functor).
119    *
120    * @param[in]  hitTestResults      The Hit Test Results.
121    * @param[in]  connectedDetectors  The detectors attached to the gesture processor.
122    * @param[in]  functor             A reference to the functor which should provide an operator() to check if detector satisfies current gesture and another
123    *                                 operator() which will be called when all conditions are met and the gesture should be emitted for the actor and detectors.
124    *
125    * @pre Hit Testing should already be done.
126    */
127   void ProcessAndEmit( const HitTestAlgorithm::Results& hitTestResults, const GestureDetectorContainer& connectedDetectors, Functor& functor );
128
129   /**
130    * Hit test the screen coordinates, and place the results in hitTestResults.
131    * @param[in] stage Stage.
132    * @param[in] screenCoordinates The screen coordinates to test.
133    * @param[out] hitTestResults Structure to write results into.
134    * @return false if the system overlay was hit or no actor was hit.
135    */
136   virtual bool HitTest(Stage& stage, Vector2 screenCoordinates, HitTestAlgorithm::Results& hitTestResults);
137
138   /**
139    * Sets the mCurrentGesturedActor and connects to the required signals.
140    * @actor  actor  The actor so set.
141    */
142   void SetActor( Dali::Actor actor );
143
144   /**
145    * Resets the set actor and disconnects any connected signals.
146    */
147   void ResetActor();
148
149   /**
150    * Returns the current gestured actor if it is on stage
151    *
152    * @return The current gestured actor
153    */
154   Actor* GetCurrentGesturedActor();
155
156   // For derived classes to override
157
158   /**
159    * Called when the gestured actor is removed from the stage.
160    */
161   virtual void OnGesturedActorStageDisconnection() = 0;
162
163 private:
164
165   // Undefined
166   GestureProcessor( const GestureProcessor& );
167   GestureProcessor& operator=( const GestureProcessor& );
168
169 private:
170
171   /**
172    * This will never get called as we do not observe objects that have not been added to the scene.
173    * @param[in] proxy The proxy object.
174    * @see ProxyObject::Observer::SceneObjectAdded()
175    */
176   virtual void SceneObjectAdded(ProxyObject& proxy) { }
177
178   /**
179    * This will be called when the actor is removed from the stage, we should clear and stop
180    * observing it.
181    * @param[in] proxy The proxy object.
182    * @see ProxyObject::Observer::SceneObjectRemoved()
183    */
184   virtual void SceneObjectRemoved(ProxyObject& proxy);
185
186   /**
187    * This will be called when the actor is destroyed. We should clear the actor.
188    * No need to stop observing as the object is being destroyed anyway.
189    * @see ProxyObject::Observer::ProxyDestroyed()
190    */
191   virtual void ProxyDestroyed(ProxyObject& proxy);
192
193   // Signal Handlers
194
195   /**
196    * Signal handler called when the actor is removed from the stage.
197    * @param[in]  actor  The actor removed from the stage.
198    */
199   void OnStageDisconnection( Dali::Actor actor );
200
201 private: // Data
202
203   Actor* mCurrentGesturedActor;       ///< The current actor that has been gestured.
204   bool   mGesturedActorDisconnected;  ///< Indicates whether the gestured actor has been disconnected from the scene
205 };
206
207 } // namespace Internal
208
209 } // namespace Dali
210
211 #endif // __DALI_INTERNAL_GESTURE_PROCESSOR_H__