use modern construct 'override' in the derive class.
[platform/core/uifw/dali-core.git] / dali / internal / update / animation / scene-graph-constraint-base.h
1 #ifndef DALI_INTERNAL_SCENE_GRAPH_CONSTRAINT_BASE_H
2 #define DALI_INTERNAL_SCENE_GRAPH_CONSTRAINT_BASE_H
3
4 /*
5  * Copyright (c) 2019 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0
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
21 // INTERNAL INCLUDES
22 #include <dali/public-api/animation/constraint.h>
23 #include <dali/public-api/common/dali-common.h>
24 #include <dali/internal/common/message.h>
25 #include <dali/internal/event/common/event-thread-services.h>
26 #include <dali/internal/update/common/animatable-property.h>
27 #include <dali/internal/update/common/property-owner.h>
28 #include <dali/internal/update/common/scene-graph-buffers.h>
29 #include <dali/internal/update/animation/scene-graph-constraint-declarations.h>
30
31 namespace Dali
32 {
33
34 namespace Internal
35 {
36
37 // value types used by messages
38 template <> struct ParameterType< Dali::Constraint::RemoveAction >
39 : public BasicType< Dali::Constraint::RemoveAction > {};
40
41 namespace SceneGraph
42 {
43 using PropertyOwnerContainer = Dali::Vector<PropertyOwner*>;
44 using PropertyOwnerIter      = PropertyOwnerContainer::Iterator;
45
46 /**
47  * An abstract base class for Constraints.
48  * This can be used to constrain a property of a scene-object, after animations have been applied.
49  */
50 class ConstraintBase : public PropertyOwner::Observer
51 {
52 public:
53   /**
54    * Observer to determine when the constraint is no longer present
55    */
56   class LifecycleObserver
57   {
58   public:
59     /**
60      * Called shortly before the constraint is destroyed.
61      */
62     virtual void ObjectDestroyed() = 0;
63
64   protected:
65     /**
66      * Virtual destructor, no deletion through this interface
67      */
68     virtual ~LifecycleObserver() = default;
69   };
70
71 public:
72   using RemoveAction = Dali::Constraint::RemoveAction;
73
74   /**
75    * Constructor
76    * @param ownerContainer the properties to constraint
77    * @oparam removeAction perform when removed
78    */
79   ConstraintBase( PropertyOwnerContainer& ownerContainer, RemoveAction removeAction );
80
81   /**
82    * Virtual destructor.
83    */
84   ~ConstraintBase() override;
85
86   /**
87    * Property resetter observes the lifecycle of this object
88    */
89   void AddLifecycleObserver( LifecycleObserver& observer )
90   {
91     mLifecycleObserver = &observer;
92   }
93
94   /**
95    * Property resetter observers the lifecycle of this object
96    */
97   void RemoveLifecycleObserver( LifecycleObserver& observer )
98   {
99     mLifecycleObserver = nullptr;
100   }
101
102   /**
103    * Initialize the constraint.
104    * This should by called by a scene-object, when the constraint is connected.
105    */
106   void OnConnect()
107   {
108     StartObservation();
109
110     mDisconnected = false;
111   }
112
113   /**
114    * @copydoc Dali::Constraint::SetRemoveAction()
115    */
116   void SetRemoveAction( RemoveAction action )
117   {
118     mRemoveAction = action;
119   }
120
121   /**
122    * @copydoc Dali::Constraint::GetRemoveAction()
123    */
124   RemoveAction GetRemoveAction() const
125   {
126     return mRemoveAction;
127   }
128
129   /**
130    * Constrain the associated scene object.
131    * @param[in] updateBufferIndex The current update buffer index.
132    */
133   virtual void Apply( BufferIndex updateBufferIndex ) = 0;
134
135   /**
136    * Helper for internal test cases; only available for debug builds.
137    * @return The current number of Constraint instances in existence.
138    */
139   static uint32_t GetCurrentInstanceCount();
140
141   /**
142    * Helper for internal test cases; only available for debug builds.
143    * @return The total number of Constraint instances created during the Dali core lifetime.
144    */
145   static uint32_t GetTotalInstanceCount();
146
147 private:
148
149   /**
150    * Helper to start observing property owners
151    */
152   void StartObservation()
153   {
154     const PropertyOwnerIter end =  mObservedOwners.End();
155     for( PropertyOwnerIter iter = mObservedOwners.Begin(); end != iter; ++iter )
156     {
157       (*iter)->AddObserver( *this );
158     }
159   }
160
161   /**
162    * Helper to stop observing property owners
163    */
164   void StopObservation()
165   {
166     const PropertyOwnerIter end =  mObservedOwners.End();
167     for( PropertyOwnerIter iter = mObservedOwners.Begin(); end != iter; ++iter )
168     {
169       (*iter)->RemoveObserver( *this );
170     }
171
172     mObservedOwners.Clear();
173   }
174
175   /**
176    * @copydoc PropertyOwner::Observer::PropertyOwnerConnected()
177    */
178   void PropertyOwnerConnected( PropertyOwner& owner ) override
179   {
180   }
181
182   /**
183    * @copydoc PropertyOwner::Observer::PropertyOwnerDisconnected()
184    */
185   void PropertyOwnerDisconnected( BufferIndex bufferIndex, PropertyOwner& owner ) override
186   {
187     if ( !mDisconnected )
188     {
189       // Stop observing property owners
190       StopObservation();
191
192       // Notification for derived class
193       OnDisconnect();
194
195       mDisconnected = true;
196     }
197   }
198
199   /**
200    * @copydoc PropertyOwner::Observer::PropertyOwnerDestroyed()
201    */
202   void PropertyOwnerDestroyed( PropertyOwner& owner ) override
203   {
204     if ( !mDisconnected )
205     {
206       // Discard pointer to destroyed property owner. Otherwise StopObservation() would crash when trying to remove
207       //the constraint from the destroyed PropertyOwner's observers list
208       PropertyOwnerIter iter = std::find( mObservedOwners.Begin(), mObservedOwners.End(), &owner );
209       if( mObservedOwners.End() != iter )
210       {
211         mObservedOwners.Erase( iter );
212       }
213
214       // Stop observing the rest of property owners
215       StopObservation();
216
217       // Notification for derived class
218       OnDisconnect();
219
220       mDisconnected = true;
221
222     }
223   }
224
225   /**
226    * Notify the derived class to disconnect from property owners
227    */
228   virtual void OnDisconnect() = 0;
229
230 protected:
231
232   RemoveAction mRemoveAction;
233
234   bool mFirstApply   : 1;
235   bool mDisconnected : 1;
236
237 private:
238
239   PropertyOwnerContainer mObservedOwners; ///< A set of pointers to each observed object. Not owned.
240   LifecycleObserver* mLifecycleObserver; ///< Resetter observers this object
241
242 #ifdef DEBUG_ENABLED
243   static uint32_t mCurrentInstanceCount;  ///< The current number of Constraint instances in existence.
244   static uint32_t mTotalInstanceCount;    ///< The total number of Constraint instances created during the Dali core lifetime.
245 #endif
246 };
247
248 // Messages for ConstraintBase
249
250 inline void  SetRemoveActionMessage( EventThreadServices& eventThreadServices, const ConstraintBase& constraint, Dali::Constraint::RemoveAction removeAction )
251 {
252   using LocalType = MessageValue1<ConstraintBase, Dali::Constraint::RemoveAction>;
253
254   // Reserve some memory inside the message queue
255   uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
256
257   // Construct message in the message queue memory; note that delete should not be called on the return value
258   new (slot) LocalType( &constraint, &ConstraintBase::SetRemoveAction, removeAction );
259 }
260
261 } // namespace SceneGraph
262
263 } // namespace Internal
264
265 } // namespace Dali
266
267 #endif // DALI_INTERNAL_SCENE_GRAPH_CONSTRAINT_BASE_H