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);
66 * Reset the property to it's base value if the property owner is still alive and on stage
67 * @param[in] updateBufferIndex the current buffer index
69 virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
71 if(mPropertyOwner != nullptr && mActive)
73 // If property-owner has disconnected, start aging.
74 // We need to reset the property for two frames after disconnection to ensure both
75 // property values are set appropriately.
81 mBaseProperty->ResetToBaseValue(updateBufferIndex);
86 * Called when mPropertyOwner is connected to the scene graph.
88 * Note, this resetter object may be created after the property owner has been connected
89 * to the stage, so we track disconnection and re-connection instead of connection
91 * @param[in] owner The property owner
93 void PropertyOwnerConnected(PropertyOwner& owner) override
95 mDisconnected = false;
100 * Called when mPropertyOwner is disconnected from the scene graph.
101 * @param[in] bufferIndex the current buffer index
102 * @param[in] owner The property owner
104 void PropertyOwnerDisconnected(BufferIndex bufferIndex, PropertyOwner& owner) override
106 mDisconnected = true;
110 * Called shortly before the propertyOwner is destroyed
111 * @param[in] owner The property owner
113 void PropertyOwnerDestroyed(PropertyOwner& owner) override
115 mDisconnected = true;
116 mPropertyOwner = nullptr;
118 // Don't need to wait another frame as the property is being destroyed
124 * Determine if the resetter has finished.
126 * If an animation or constraint stops, then we need to reset the
127 * property in the next frame as well to ensure both property values
128 * are set appropriately.
130 * @return true if the resetter has finished.
132 virtual bool IsFinished()
134 return mRunning <= STOPPED;
148 * @param[in] propertyOwner The property owner storing the base property
149 * @param[in] baseProperty The base property
151 PropertyResetterBase(PropertyOwner* propertyOwner,
152 PropertyBase* baseProperty)
153 : mPropertyOwner(propertyOwner),
154 mBaseProperty(baseProperty),
161 PropertyOwner* mPropertyOwner; ///< The property owner
162 PropertyBase* mBaseProperty; ///< The base property being animated or constrained
163 int8_t mRunning; ///< Used to determine if we should finish or not, 2 if running, 1 if aging, 0 if stopped
164 int8_t mActive; ///< 2 if active, 1 if aging, 0 if stopped
165 bool mDisconnected; ///< True if the property owner has been disconnected
168 class BakerResetter : public PropertyResetterBase
179 * @param[in] propertyOwner The owner of the property
180 * @param[in] baseProperty The property being animated
181 * @param[in] lifetime How long this resetter stays alive (1 or 2 frames)
182 * @return the new property resetter
184 static PropertyResetterBase* New(const PropertyOwner& propertyOwner,
185 const PropertyBase& baseProperty,
188 return new BakerResetter(const_cast<PropertyOwner*>(&propertyOwner),
189 const_cast<PropertyBase*>(&baseProperty),
195 * @param[in] propertyOwner The owner of the property
196 * @param[in] baseProperty The property being animated
197 * @param[in] lifetime How many frames this stays alive for
199 BakerResetter(PropertyOwner* propertyOwner,
200 PropertyBase* baseProperty,
202 : PropertyResetterBase(propertyOwner, baseProperty)
204 mRunning = lifetime == Lifetime::BAKE ? ACTIVE : AGING;
208 * Virtual destructor.
210 ~BakerResetter() override = default;
213 * @param updateBufferIndex
215 void ResetToBaseValue(BufferIndex updateBufferIndex) override
217 if(mPropertyOwner && mRunning > 0)
220 mBaseProperty->ResetToBaseValue(updateBufferIndex);
222 // @todo Consider adding mPropertyOwner->SetUpdated(true) here.
228 * Specialization of Resetter based on templated modifier type (either Constraint or Animator)
230 template<typename ModifierType>
231 class Resetter : public PropertyResetterBase, public ModifierType::LifecycleObserver
236 * @param[in] propertyOwner The owner of the property
237 * @param[in] baseProperty The property being animated
238 * @param[in] modifier The scene-graph animator/constraint of the property
239 * @return the new property resetter
241 static PropertyResetterBase* New(const PropertyOwner& propertyOwner,
242 const PropertyBase& baseProperty,
243 const ModifierType& modifier)
245 return new Resetter<ModifierType>(const_cast<PropertyOwner*>(&propertyOwner),
246 const_cast<PropertyBase*>(&baseProperty),
247 const_cast<ModifierType*>(&modifier));
251 * Virtual destructor.
255 // Disconnect from modifier object. Although this resetter should match the lifecycle of the modifier object,
256 // there are situations where it is deleted first (e.g. if the property owner is destroyed)
259 mModifier->RemoveLifecycleObserver(*this);
266 * @param[in] propertyOwner The owner of the property
267 * @param[in] baseProperty The property being animated
268 * @param[in] modifier The scene-graph animator/constraint of the property
270 Resetter(PropertyOwner* propertyOwner,
271 PropertyBase* baseProperty,
272 ModifierType* modifier)
273 : PropertyResetterBase(propertyOwner, baseProperty),
276 // Track the lifecycle of the modifying object
277 mModifier->AddLifecycleObserver(*this);
281 * The Animator or Constraint is destroyed
283 void ObjectDestroyed() override
285 // When the modifier is destroyed, reduce the running value to ensure we stay alive for
286 // another frame to reset the other buffer.
291 ModifierType* mModifier;
294 using AnimatorResetter = Resetter<SceneGraph::AnimatorBase>;
295 using ConstraintResetter = Resetter<SceneGraph::ConstraintBase>;
297 } // namespace SceneGraph
299 } // namespace Internal
303 #endif //DALI_INTERNAL_SCENEGRAPH_PROPERTY_RESETTER_H