[dali_2.3.31] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / internal / event / animation / animator-connector-base.h
1 #ifndef DALI_INTERNAL_ANIMATOR_CONNECTOR_BASE_H
2 #define DALI_INTERNAL_ANIMATOR_CONNECTOR_BASE_H
3
4 /*
5  * Copyright (c) 2021 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/internal/event/common/object-impl.h>
23 #include <dali/internal/update/common/property-resetter.h>
24 #include <dali/internal/update/manager/update-manager.h>
25 #include <dali/public-api/animation/alpha-function.h>
26 #include <dali/public-api/animation/time-period.h>
27 #include <dali/public-api/common/dali-common.h>
28
29 namespace Dali
30 {
31 namespace Internal
32 {
33 class Animation;
34
35 /**
36  * An abstract base class to create animator connectors and property re-setters for them when needed.
37  *
38  * The scene-graph objects are created by a Object e.g. Actor is a proxy for SceneGraph::Node.
39  * AnimatorConnectorBase observes the proxy object, in order to detect when a scene-graph object is created
40  * to avoid having unnecessary animations on the scene-graph and allow apps to create animations in initialisation
41  */
42 class AnimatorConnectorBase : public Object::Observer
43 {
44 public:
45   /**
46    * Constructor.
47    */
48   AnimatorConnectorBase(Object&           object,
49                         Property::Index   propertyIndex,
50                         int32_t           componentIndex,
51                         AlphaFunction     alpha,
52                         const TimePeriod& period)
53   : mObject(&object),
54     mAlphaFunction(alpha),
55     mTimePeriod(period),
56     mPropertyIndex(propertyIndex),
57     mComponentIndex(componentIndex)
58   {
59     object.AddObserver(*this);
60   }
61
62   /**
63    * Virtual destructor.
64    */
65   ~AnimatorConnectorBase() override
66   {
67     if(mObject)
68     {
69       mObject->RemoveObserver(*this);
70     }
71   }
72
73   /**
74    * Helper function to create a Scenegraph::Animator and PropertyResetter and add it to its correspondent
75    * SceneGraph::Animation.
76    *
77    * @note This function will only be called the first time the object is added to the scene or at creation time if
78    * the object was already in the scene
79    */
80   void CreateAnimator()
81   {
82     DALI_ASSERT_DEBUG(mAnimator == nullptr);
83     DALI_ASSERT_DEBUG(mParent != nullptr);
84
85     //Get the PropertyOwner the animator is going to animate
86     const SceneGraph::PropertyOwner& propertyOwner = mObject->GetSceneObject();
87
88     // Get SceneGraph::BaseProperty
89     const SceneGraph::PropertyBase* baseProperty = mObject->GetSceneObjectAnimatableProperty(mPropertyIndex);
90     DALI_ASSERT_ALWAYS(baseProperty && "Property is not animatable");
91
92     // Check if property is a component of another property
93     const int32_t componentIndex = mObject->GetPropertyComponentIndex(mPropertyIndex);
94     if(componentIndex != Property::INVALID_COMPONENT_INDEX)
95     {
96       mComponentIndex = componentIndex;
97     }
98
99     // call the type specific method to create the concrete animator
100     bool resetterRequired = DoCreateAnimator(propertyOwner, *baseProperty);
101
102     DALI_ASSERT_DEBUG(mAnimator != nullptr);
103
104     // Add the new SceneGraph::Animator to its correspondent SceneGraph::Animation via message
105     const SceneGraph::Animation* animation = mParent->GetSceneObject();
106     DALI_ASSERT_DEBUG(nullptr != animation);
107     AddAnimatorMessage(mParent->GetEventThreadServices(), *animation, *mAnimator);
108
109     // Add the new SceneGraph::PropertyResetter to the update manager via message
110     if(resetterRequired)
111     {
112       OwnerPointer<SceneGraph::PropertyResetterBase> resetter = SceneGraph::AnimatorResetter::New(propertyOwner, *baseProperty, *mAnimator);
113       AddResetterMessage(mParent->GetEventThreadServices().GetUpdateManager(), resetter);
114     }
115   }
116
117   /**
118    * Type specific extension of animator creation
119    */
120   virtual bool DoCreateAnimator(const SceneGraph::PropertyOwner& propertyOwner, const SceneGraph::PropertyBase& baseProperty) = 0;
121
122   /**
123    * Set the parent of the AnimatorConnector.
124    * @pre The connector does not already have a parent.
125    * @param [in] parent The parent object.
126    */
127   void SetParent(Animation& parent)
128   {
129     DALI_ASSERT_ALWAYS(mParent == nullptr && "AnimationConnector already has a parent");
130     mParent = &parent;
131
132     if(mObject)
133     {
134       CreateAnimator();
135     }
136   }
137
138   /**
139    * Retrieve the parent of the AnimatorConnector.
140    * @return The parent object, or nullptr.
141    */
142   Animation* GetParent() const
143   {
144     return mParent;
145   }
146
147   Object* GetObject() const
148   {
149     return mObject;
150   }
151
152   Property::Index GetPropertyIndex() const
153   {
154     return mPropertyIndex;
155   }
156
157   int32_t GetComponentIndex() const
158   {
159     return mComponentIndex;
160   }
161
162 private:
163   /**
164    * From Object::Observer
165    */
166   void SceneObjectAdded(Object& object) final
167   {
168     // If the animator has not been created yet, create it now.
169     if(!mAnimator && mObject)
170     {
171       CreateAnimator();
172     }
173   }
174
175   /**
176    * From Object::Observer
177    */
178   void SceneObjectRemoved(Object& object) final
179   {
180   }
181
182   /**
183    * From Object::Observer
184    */
185   void ObjectDestroyed(Object& object) override
186   {
187     mObject = nullptr;
188   }
189
190 protected:
191   Animation*                mParent{nullptr}; ///< The parent owns the connector.
192   Object*                   mObject;          ///< Not owned by the animator connector. Valid until ObjectDestroyed() is called.
193   SceneGraph::AnimatorBase* mAnimator{nullptr};
194
195   AlphaFunction mAlphaFunction;
196   TimePeriod    mTimePeriod;
197
198   Property::Index mPropertyIndex;
199   int32_t         mComponentIndex;
200 };
201
202 } // namespace Internal
203
204 } // namespace Dali
205
206 #endif // DALI_INTERNAL_ANIMATOR_CONNECTOR_BASE_H