595baee272cd754e32dd34a6700336df598cf9af
[platform/core/uifw/dali-core.git] / dali / internal / event / common / object-impl-helper.h
1 #ifndef DALI_INTERNAL_OBJECT_IMPL_HELPER_H
2 #define DALI_INTERNAL_OBJECT_IMPL_HELPER_H
3
4 /*
5  * Copyright (c) 2014 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 // EXTERNAL INCLUDEs
22 #include <cstring>
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/object/property.h> // Dali::Property
26 #include <dali/public-api/object/property-index-ranges.h> // DEFAULT_DERIVED_HANDLE_PROPERTY_START_INDEX
27 #include <dali/internal/event/common/property-helper.h> // Dali::Internal::PropertyDetails
28 #include <dali/internal/event/common/stage-impl.h>
29 #include <dali/internal/update/common/animatable-property.h>
30 #include <dali/internal/update/common/property-owner-messages.h>
31 #include <dali/internal/update/manager/update-manager.h>
32
33 namespace Dali
34 {
35 namespace Internal
36 {
37 class PropertyMetadata;
38 class AnimatablePropertyMetadata;
39 class CustomPropertyMetadata;
40 class PropertyInputImpl;
41
42 namespace SceneGraph
43 {
44
45 class PropertyBase;
46 class PropertyOwner;
47
48
49 } // namespace SceneGraph
50
51 // Typedefs to allow object methods to be passed via parameter
52 typedef AnimatablePropertyMetadata* (Object::*FindAnimatablePropertyMethod)( Property::Index index ) const;
53 typedef CustomPropertyMetadata* (Object::*FindCustomPropertyMethod)( Property::Index index ) const;
54
55
56 /**
57  * Helper template class to be used by class that implement Object
58  *
59  * Example:
60  *<pre>
61  * typename ObjectImplHelper<DEFAULT_PROPERTY_COUNT, DEFAULT_PROPERTY_DETAILS> MyObjectImpl;
62  *
63  * MyObjectImpl::GetDefaultPropertyCount();
64  * </pre>
65  */
66 template<int DEFAULT_PROPERTY_COUNT>
67 struct ObjectImplHelper
68 {
69   const PropertyDetails* DEFAULT_PROPERTY_DETAILS;
70
71   unsigned int GetDefaultPropertyCount() const
72   {
73     return DEFAULT_PROPERTY_COUNT;
74   }
75
76   void GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
77   {
78     indices.Reserve( DEFAULT_PROPERTY_COUNT );
79
80     for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
81     {
82       indices.PushBack( DEFAULT_OBJECT_PROPERTY_START_INDEX + i );
83     }
84   }
85
86   const char* GetDefaultPropertyName( Property::Index index ) const
87   {
88     const char* name = NULL;
89
90     if( index >= DEFAULT_OBJECT_PROPERTY_START_INDEX && index < DEFAULT_PROPERTY_COUNT )
91     {
92       name = DEFAULT_PROPERTY_DETAILS[index].name;
93     }
94
95     return name;
96   }
97
98   Property::Index GetDefaultPropertyIndex( const std::string& name ) const
99   {
100     Property::Index index = Property::INVALID_INDEX;
101
102     // Look for name in default properties
103     for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
104     {
105       const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
106       if( 0 == strcmp( name.c_str(), property->name ) ) // dont want to convert rhs to string
107       {
108         index = i;
109         break;
110       }
111     }
112
113     return index;
114   }
115
116   bool IsDefaultPropertyWritable( Property::Index index ) const
117   {
118     bool isWritable = false;
119
120     if( index >= DEFAULT_OBJECT_PROPERTY_START_INDEX && index < DEFAULT_PROPERTY_COUNT )
121     {
122       isWritable = DEFAULT_PROPERTY_DETAILS[index].writable;
123     }
124
125     return isWritable;
126   }
127
128   bool IsDefaultPropertyAnimatable( Property::Index index ) const
129   {
130     bool isAnimatable = false;
131
132     if( index >= DEFAULT_OBJECT_PROPERTY_START_INDEX && index < DEFAULT_PROPERTY_COUNT )
133     {
134       isAnimatable =  DEFAULT_PROPERTY_DETAILS[index].animatable;
135     }
136
137     return isAnimatable;
138   }
139
140   bool IsDefaultPropertyAConstraintInput( Property::Index index ) const
141   {
142     bool isConstraintInput = false;
143
144     if( index >= DEFAULT_OBJECT_PROPERTY_START_INDEX && index < DEFAULT_PROPERTY_COUNT )
145     {
146       isConstraintInput = DEFAULT_PROPERTY_DETAILS[index].constraintInput;
147     }
148
149     return isConstraintInput;
150   }
151
152   Property::Type GetDefaultPropertyType( Property::Index index ) const
153   {
154     Property::Type type = Property::NONE;
155
156     if( index >= DEFAULT_OBJECT_PROPERTY_START_INDEX && index < DEFAULT_PROPERTY_COUNT )
157     {
158       type =  DEFAULT_PROPERTY_DETAILS[index].type;
159     }
160
161     return type;
162   }
163
164   // Get the (animatable) scene graph property. (All registered scene graph properties are animatable)
165   const SceneGraph::PropertyBase* GetRegisteredSceneGraphProperty(
166     const Object* object,
167     FindAnimatablePropertyMethod findAnimatablePropertyMethod,
168     FindCustomPropertyMethod findCustomPropertyMethod,
169     Property::Index index ) const
170   {
171     const SceneGraph::PropertyBase* property = NULL;
172     if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
173     {
174       AnimatablePropertyMetadata* animatable = (object->*findAnimatablePropertyMethod)( index );
175       DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
176       property = animatable->GetSceneGraphProperty();
177     }
178     else if ( ( index > CHILD_PROPERTY_REGISTRATION_START_INDEX ) && // Child properties are also stored as custom properties
179               ( index <= PROPERTY_CUSTOM_MAX_INDEX ) )
180     {
181       CustomPropertyMetadata* custom = (object->*findCustomPropertyMethod)( index );
182       DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
183       property = custom->GetSceneGraphProperty();
184     }
185     return property;
186   }
187
188   void SetSceneGraphProperty( EventThreadServices& eventThreadServices,
189                               const Object* object,
190                               Property::Index index,
191                               const PropertyMetadata& entry,
192                               const Property::Value& value ) const
193   {
194     const SceneGraph::PropertyOwner* sceneObject = object->GetSceneObject();
195
196     switch ( entry.GetType() )
197     {
198       case Property::BOOLEAN:
199       {
200         const SceneGraph::AnimatableProperty<bool>* property = dynamic_cast< const SceneGraph::AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
201         DALI_ASSERT_DEBUG( NULL != property );
202
203         // property is being used in a separate thread; queue a message to set the property
204         SceneGraph::AnimatablePropertyMessage<bool>::Send( eventThreadServices, sceneObject, property, &SceneGraph::AnimatableProperty<bool>::Bake, value.Get<bool>() );
205
206         break;
207       }
208
209       case Property::FLOAT:
210       {
211         const SceneGraph::AnimatableProperty<float>* property = dynamic_cast< const SceneGraph::AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
212         DALI_ASSERT_DEBUG( NULL != property );
213
214         // property is being used in a separate thread; queue a message to set the property
215         SceneGraph::AnimatablePropertyMessage<float>::Send( eventThreadServices, sceneObject, property, &SceneGraph::AnimatableProperty<float>::Bake, value.Get<float>() );
216
217         break;
218       }
219
220       case Property::INTEGER:
221       {
222         const SceneGraph::AnimatableProperty<int>* property = dynamic_cast< const SceneGraph::AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
223         DALI_ASSERT_DEBUG( NULL != property );
224
225         // property is being used in a separate thread; queue a message to set the property
226         SceneGraph::AnimatablePropertyMessage<int>::Send( eventThreadServices, sceneObject, property, &SceneGraph::AnimatableProperty<int>::Bake, value.Get<int>() );
227
228         break;
229       }
230
231       case Property::VECTOR2:
232       {
233         const SceneGraph::AnimatableProperty<Vector2>* property = dynamic_cast< const SceneGraph::AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
234         DALI_ASSERT_DEBUG( NULL != property );
235
236         // property is being used in a separate thread; queue a message to set the property
237         SceneGraph::AnimatablePropertyMessage<Vector2>::Send( eventThreadServices, sceneObject, property, &SceneGraph::AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
238
239         break;
240       }
241
242       case Property::VECTOR3:
243       {
244         const SceneGraph::AnimatableProperty<Vector3>* property = dynamic_cast< const SceneGraph::AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
245         DALI_ASSERT_DEBUG( NULL != property );
246
247         // property is being used in a separate thread; queue a message to set the property
248         SceneGraph::AnimatablePropertyMessage<Vector3>::Send( eventThreadServices, sceneObject, property, &SceneGraph::AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
249
250         break;
251       }
252
253       case Property::VECTOR4:
254       {
255         const SceneGraph::AnimatableProperty<Vector4>* property = dynamic_cast< const SceneGraph::AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
256         DALI_ASSERT_DEBUG( NULL != property );
257
258         // property is being used in a separate thread; queue a message to set the property
259         SceneGraph::AnimatablePropertyMessage<Vector4>::Send( eventThreadServices, sceneObject, property, &SceneGraph::AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
260
261         break;
262       }
263
264       case Property::ROTATION:
265       {
266         const SceneGraph::AnimatableProperty<Quaternion>* property = dynamic_cast< const SceneGraph::AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
267         DALI_ASSERT_DEBUG( NULL != property );
268
269         // property is being used in a separate thread; queue a message to set the property
270         SceneGraph::AnimatablePropertyMessage<Quaternion>::Send( eventThreadServices, sceneObject, property,&SceneGraph::AnimatableProperty<Quaternion>::Bake,  value.Get<Quaternion>() );
271
272         break;
273       }
274
275       case Property::MATRIX:
276       {
277         const SceneGraph::AnimatableProperty<Matrix>* property = dynamic_cast< const SceneGraph::AnimatableProperty<Matrix>* >( entry.GetSceneGraphProperty() );
278         DALI_ASSERT_DEBUG( NULL != property );
279
280         // property is being used in a separate thread; queue a message to set the property
281         SceneGraph::AnimatablePropertyMessage<Matrix>::Send( eventThreadServices, sceneObject, property,&SceneGraph::AnimatableProperty<Matrix>::Bake,  value.Get<Matrix>() );
282
283         break;
284       }
285
286       case Property::MATRIX3:
287       {
288         const SceneGraph::AnimatableProperty<Matrix3>* property = dynamic_cast< const SceneGraph::AnimatableProperty<Matrix3>* >( entry.GetSceneGraphProperty() );
289         DALI_ASSERT_DEBUG( NULL != property );
290
291         // property is being used in a separate thread; queue a message to set the property
292         SceneGraph::AnimatablePropertyMessage<Matrix3>::Send( eventThreadServices, sceneObject, property, &SceneGraph::AnimatableProperty<Matrix3>::Bake,  value.Get<Matrix3>() );
293
294         break;
295       }
296
297       default:
298       {
299         // ignore non-scene-graph types
300       }
301     }
302   }
303 };
304
305
306
307 } // namespace Internal
308
309 } // namespace Dali
310
311 #endif // DALI_INTERNAL_OBJECT_IMPL_HELPER_H