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