1 #ifndef DALI_INTERNAL_SCENEGRAPH_PROPERTY_RESETTER_H
2 #define DALI_INTERNAL_SCENEGRAPH_PROPERTY_RESETTER_H
5 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <cstdint> // int8_t
23 #include <dali/internal/update/animation/property-accessor.h>
24 #include <dali/internal/update/animation/property-component-accessor.h>
25 #include <dali/internal/update/animation/scene-graph-animator.h>
26 #include <dali/internal/update/animation/scene-graph-constraint-base.h>
27 #include <dali/internal/update/common/property-owner.h>
36 * Class to reset the watched property to it's base value. Used by UpdateManager to
37 * reset animating and constrained properties. The derived classes AnimatorResetter and
38 * ConstraintResetter are designed to match the lifecycle of the SceneGraph::Animator
39 * and SceneGraph::Constraint respectively.
41 class PropertyResetterBase : public PropertyOwner::Observer
47 ~PropertyResetterBase() override
49 if(mPropertyOwner != nullptr)
51 mPropertyOwner->RemoveObserver(*this);
58 * Watches the property owner to track if it's disconnected or not.
62 mPropertyOwner->AddObserver(*this);
63 mPropertyOwner->SetUpdated(true);
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
70 virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
72 if(mPropertyOwner != nullptr && mActive)
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.
82 mBaseProperty->ResetToBaseValue(updateBufferIndex);
87 * Called when mPropertyOwner is connected to the scene graph.
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
92 * @param[in] owner The property owner
94 void PropertyOwnerConnected(PropertyOwner& owner) override
96 mDisconnected = false;
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
105 void PropertyOwnerDisconnected(BufferIndex bufferIndex, PropertyOwner& owner) override
107 mDisconnected = true;
111 * Called shortly before the propertyOwner is destroyed
112 * @param[in] owner The property owner
114 void PropertyOwnerDestroyed(PropertyOwner& owner) override
116 mDisconnected = true;
117 mPropertyOwner = nullptr;
119 // Don't need to wait another frame as the property is being destroyed
125 * Determine if the resetter has finished.
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.
131 * @return true if the resetter has finished.
133 virtual bool IsFinished()
135 return mRunning <= STOPPED;
149 * @param[in] propertyOwner The property owner storing the base property
150 * @param[in] baseProperty The base property
152 PropertyResetterBase(PropertyOwner* propertyOwner,
153 PropertyBase* baseProperty)
154 : mPropertyOwner(propertyOwner),
155 mBaseProperty(baseProperty),
162 PropertyOwner* mPropertyOwner; ///< The property owner
163 PropertyBase* mBaseProperty; ///< The base property being animated or constrained
164 int8_t mRunning; ///< Used to determine if we should finish or not, 2 if running, 1 if aging, 0 if stopped
165 int8_t mActive; ///< 2 if active, 1 if aging, 0 if stopped
166 bool mDisconnected; ///< True if the property owner has been disconnected
169 class BakerResetter : public PropertyResetterBase
180 * @param[in] propertyOwner The owner of the property
181 * @param[in] baseProperty The property being animated
182 * @param[in] lifetime How long this resetter stays alive (1 or 2 frames)
183 * @return the new property resetter
185 static PropertyResetterBase* New(const PropertyOwner& propertyOwner,
186 const PropertyBase& baseProperty,
189 return new BakerResetter(const_cast<PropertyOwner*>(&propertyOwner),
190 const_cast<PropertyBase*>(&baseProperty),
196 * @param[in] propertyOwner The owner of the property
197 * @param[in] baseProperty The property being animated
198 * @param[in] lifetime How many frames this stays alive for
200 BakerResetter(PropertyOwner* propertyOwner,
201 PropertyBase* baseProperty,
203 : PropertyResetterBase(propertyOwner, baseProperty)
205 mRunning = lifetime == Lifetime::BAKE ? AGING : ACTIVE;
209 * Virtual destructor.
211 ~BakerResetter() override = default;
214 * @param updateBufferIndex
216 void ResetToBaseValue(BufferIndex updateBufferIndex) override
218 if(mPropertyOwner && mRunning > 0)
221 mBaseProperty->ResetToBaseValue(updateBufferIndex);
225 mPropertyOwner->SetUpdated(true);
232 * Specialization of Resetter based on templated modifier type (either Constraint or Animator)
234 template<typename ModifierType>
235 class Resetter : public PropertyResetterBase, public ModifierType::LifecycleObserver
240 * @param[in] propertyOwner The owner of the property
241 * @param[in] baseProperty The property being animated
242 * @param[in] modifier The scene-graph animator/constraint of the property
243 * @return the new property resetter
245 static PropertyResetterBase* New(const PropertyOwner& propertyOwner,
246 const PropertyBase& baseProperty,
247 const ModifierType& modifier)
249 return new Resetter<ModifierType>(const_cast<PropertyOwner*>(&propertyOwner),
250 const_cast<PropertyBase*>(&baseProperty),
251 const_cast<ModifierType*>(&modifier));
255 * Virtual destructor.
259 // Disconnect from modifier object. Although this resetter should match the lifecycle of the modifier object,
260 // there are situations where it is deleted first (e.g. if the property owner is destroyed)
263 mModifier->RemoveLifecycleObserver(*this);
270 * @param[in] propertyOwner The owner of the property
271 * @param[in] baseProperty The property being animated
272 * @param[in] modifier The scene-graph animator/constraint of the property
274 Resetter(PropertyOwner* propertyOwner,
275 PropertyBase* baseProperty,
276 ModifierType* modifier)
277 : PropertyResetterBase(propertyOwner, baseProperty),
280 // Track the lifecycle of the modifying object
281 mModifier->AddLifecycleObserver(*this);
285 * The Animator or Constraint is destroyed
287 void ObjectDestroyed() override
289 // When the modifier is destroyed, reduce the running value to ensure we stay alive for
290 // another frame to reset the other buffer.
295 ModifierType* mModifier;
298 using AnimatorResetter = Resetter<SceneGraph::AnimatorBase>;
299 using ConstraintResetter = Resetter<SceneGraph::ConstraintBase>;
301 } // namespace SceneGraph
303 } // namespace Internal
307 #endif //DALI_INTERNAL_SCENEGRAPH_PROPERTY_RESETTER_H