305fb148e95f0fb6f8066a5409ca175acc837a95
[platform/core/uifw/dali-core.git] / dali / internal / update / common / property-resetter.h
1 #ifndef DALI_INTERNAL_SCENEGRAPH_PROPERTY_RESETTER_H
2 #define DALI_INTERNAL_SCENEGRAPH_PROPERTY_RESETTER_H
3
4 /*
5  * Copyright (c) 2018 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 // EXTERNAL INCLDUES
21 #include <cstdint> // int8_t
22
23 #include <dali/internal/update/animation/scene-graph-animator.h>
24 #include <dali/internal/update/animation/scene-graph-constraint-base.h>
25 #include <dali/internal/update/animation/property-accessor.h>
26 #include <dali/internal/update/animation/property-component-accessor.h>
27 #include <dali/internal/update/common/property-owner.h>
28
29 namespace Dali
30 {
31 namespace Internal
32 {
33 namespace SceneGraph
34 {
35
36 /**
37  * Class to reset the watched property to it's base value. Used by UpdateManager to
38  * reset animating and constrained properties. The derived classes AnimatorResetter and
39  * ConstraintResetter are designed to match the lifecycle of the SceneGraph::Animator
40  * and SceneGraph::Constraint respectively.
41  */
42 class PropertyResetterBase : public PropertyOwner::Observer
43 {
44 public:
45   /**
46    * Virtual Destructor
47    */
48   virtual ~PropertyResetterBase()
49   {
50     if( mPropertyOwner != nullptr )
51     {
52       mPropertyOwner->RemoveObserver(*this);
53     }
54   }
55
56   /**
57    * Initialize.
58    *
59    * Watches the property owner to track if it's disconnected or not.
60    */
61   void Initialize()
62   {
63     mPropertyOwner->AddObserver(*this);
64   }
65
66   /**
67    * Reset the property to it's base value if the property owner is still alive and on stage
68    * @param[in] updateBufferIndex the current buffer index
69    */
70   void ResetToBaseValue( BufferIndex updateBufferIndex )
71   {
72     if( mPropertyOwner != nullptr && mActive )
73     {
74       // If property-owner has disconnected, start aging.
75       // We need to reset the property for two frames after disconnection to ensure both
76       // property values are set appropriately.
77       if( mDisconnected )
78       {
79         --mActive;
80       }
81
82       mBaseProperty->ResetToBaseValue( updateBufferIndex );
83     }
84   };
85
86   /**
87    * Called when mPropertyOwner is connected to the scene graph.
88    *
89    * Note, this resetter object may be created after the property owner has been connected
90    * to the stage, so we track disconnection and re-connection instead of connection
91    *
92    * @param[in] owner The property owner
93    */
94   virtual void PropertyOwnerConnected( PropertyOwner& owner ) override
95   {
96     mDisconnected = false;
97     mActive = ACTIVE;
98   }
99
100   /**
101    * Called when mPropertyOwner is disconnected from the scene graph.
102    * @param[in] bufferIndex the current buffer index
103    * @param[in] owner The property owner
104    */
105   virtual void PropertyOwnerDisconnected( BufferIndex bufferIndex, PropertyOwner& owner ) override
106   {
107     mDisconnected = true;
108   }
109
110   /**
111    * Called shortly before the propertyOwner is destroyed
112    * @param[in] owner The property owner
113    */
114   virtual void PropertyOwnerDestroyed( PropertyOwner& owner ) override
115   {
116     mDisconnected = true;
117     mPropertyOwner = nullptr;
118
119     // Don't need to wait another frame as the property is being destroyed
120     mActive = STOPPED;
121     mRunning = STOPPED;
122   }
123
124   /**
125    * Determine if the resetter has finished.
126    *
127    * If an animation or constraint stops, then we need to reset the
128    * property in the next frame as well to ensure both property values
129    * are set appropriately.
130    *
131    * @return true if the resetter has finished.
132    */
133   virtual bool IsFinished()
134   {
135     bool finished = mRunning <= STOPPED;
136     if( mRunning == AGING )
137     {
138       mRunning = STOPPED;
139     }
140     return finished;
141   }
142
143 protected:
144
145   enum
146   {
147     STOPPED = 0,
148     AGING   = 1,
149     ACTIVE  = 2,
150   };
151
152   /**
153    * Constructor
154    *
155    * @param[in] propertyOwner The property owner storing the base property
156    * @param[in] baseProperty The base property
157    */
158   PropertyResetterBase( PropertyOwner* propertyOwner,
159                         PropertyBase* baseProperty )
160   : mPropertyOwner( propertyOwner ),
161     mBaseProperty( baseProperty ),
162     mRunning( ACTIVE ),
163     mActive( ACTIVE ),
164     mDisconnected( false )
165   {
166   }
167
168   PropertyOwner* mPropertyOwner; ///< The property owner
169   PropertyBase* mBaseProperty;   ///< The base property being animated or constrained
170   int8_t mRunning;                  ///< Used to determine if we should finish or not, 2 if running, 1 if aging, 0 if stopped
171   int8_t mActive;                   ///< 2 if active, 1 if aging, 0 if stopped
172   bool mDisconnected;            ///< True if the property owner has been disconnected
173 };
174
175
176 /**
177  * Specialization of Resetter based on templated modifier type (either Constraint or Animator)
178  */
179 template< typename ModifierType>
180 class Resetter : public PropertyResetterBase, public ModifierType::LifecycleObserver
181 {
182 public:
183
184   /**
185    * New method.
186    * @param[in] propertyOwner  The owner of the property
187    * @param[in] baseProperty   The property being animated
188    * @param[in] modifier       The scene-graph animator/constraint of the property
189    * @return the new property resetter
190    */
191   static PropertyResetterBase* New( const PropertyOwner& propertyOwner,
192                                     const PropertyBase& baseProperty,
193                                     const ModifierType& modifier )
194   {
195     return new Resetter<ModifierType>( const_cast<PropertyOwner*>( &propertyOwner ),
196                                        const_cast<PropertyBase*>( &baseProperty ),
197                                        const_cast<ModifierType*>( &modifier ) );
198   }
199
200   /**
201    * Virtual destructor.
202    */
203   virtual ~Resetter()
204   {
205     // Disconnect from modifier object. Although this resetter should match the lifecycle of the modifier object,
206     // there are situations where it is deleted first (e.g. if the property owner is destroyed)
207     if( mModifier )
208     {
209       mModifier->RemoveLifecycleObserver(*this);
210     }
211   }
212
213 private:
214   /**
215    * Constructor
216    * @param[in] propertyOwner The owner of the property
217    * @param[in] baseProperty  The property being animated
218    * @param[in] modifier      The scene-graph animator/constraint of the property
219    */
220   Resetter( PropertyOwner* propertyOwner,
221             PropertyBase* baseProperty,
222             ModifierType* modifier )
223   : PropertyResetterBase( propertyOwner, baseProperty ),
224     mModifier( modifier )
225   {
226     // Track the lifecycle of the modifying object
227     mModifier->AddLifecycleObserver(*this);
228   }
229
230   /**
231    * The Animator or Constraint is destroyed
232    */
233   virtual void ObjectDestroyed() override
234   {
235     // When the modifier is destroyed, reduce the running value to ensure we stay alive for
236     // another frame to reset the other buffer.
237     --mRunning;
238     mModifier = nullptr;
239   }
240
241   ModifierType* mModifier;
242 };
243
244
245 typedef Resetter<SceneGraph::AnimatorBase> AnimatorResetter;
246 typedef Resetter<SceneGraph::ConstraintBase> ConstraintResetter;
247
248
249
250 } // namespace SceneGraph
251
252 } // namespace Internal
253
254 } // namespace Dali
255
256 #endif //DALI_INTERNAL_SCENEGRAPH_PROPERTY_RESETTER_H