016aa122abb6e5643c7a6b116b4475eecaef2d46
[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( unsigned 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     //@todo MESH_REWORK - Are we assuming that the index into the array is the
103     // same as the enumerated property? if enumIndex in the table was no longer
104     // debug only, wouldn't need to make this assumption.
105
106     // Look for name in default properties
107     for( unsigned int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
108     {
109       const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
110       if( 0 == strcmp( name.c_str(), property->name ) ) // dont want to convert rhs to string
111       {
112         index = i;
113         break;
114       }
115     }
116
117     return index;
118   }
119
120   bool IsDefaultPropertyWritable( Property::Index index ) const
121   {
122     bool isWritable = false;
123
124     if( index >= DEFAULT_OBJECT_PROPERTY_START_INDEX && index < DEFAULT_PROPERTY_COUNT )
125     {
126       isWritable = DEFAULT_PROPERTY_DETAILS[index].writable;
127     }
128
129     return isWritable;
130   }
131
132   bool IsDefaultPropertyAnimatable( Property::Index index ) const
133   {
134     bool isAnimatable = false;
135
136     if( index >= DEFAULT_OBJECT_PROPERTY_START_INDEX && index < DEFAULT_PROPERTY_COUNT )
137     {
138       isAnimatable =  DEFAULT_PROPERTY_DETAILS[index].animatable;
139     }
140
141     return isAnimatable;
142   }
143
144   bool IsDefaultPropertyAConstraintInput( Property::Index index ) const
145   {
146     bool isConstraintInput = false;
147
148     if( index >= DEFAULT_OBJECT_PROPERTY_START_INDEX && index < DEFAULT_PROPERTY_COUNT )
149     {
150       isConstraintInput = DEFAULT_PROPERTY_DETAILS[index].constraintInput;
151     }
152
153     return isConstraintInput;
154   }
155
156   Property::Type GetDefaultPropertyType( Property::Index index ) const
157   {
158     Property::Type type = Property::NONE;
159
160     if( index >= DEFAULT_OBJECT_PROPERTY_START_INDEX && index < DEFAULT_PROPERTY_COUNT )
161     {
162       type =  DEFAULT_PROPERTY_DETAILS[index].type;
163     }
164
165     return type;
166   }
167
168   // Get the (animatable) scene graph property. (All registered scene graph properties are animatable)
169   const SceneGraph::PropertyBase* GetRegisteredSceneGraphProperty(
170     const Object* object,
171     FindAnimatablePropertyMethod findAnimatablePropertyMethod,
172     FindCustomPropertyMethod findCustomPropertyMethod,
173     Property::Index index ) const
174   {
175     const SceneGraph::PropertyBase* property = NULL;
176     if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
177     {
178       AnimatablePropertyMetadata* animatable = (object->*findAnimatablePropertyMethod)( index );
179       DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
180       property = animatable->GetSceneGraphProperty();
181     }
182     else if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
183     {
184       CustomPropertyMetadata* custom = (object->*findCustomPropertyMethod)( index );
185       DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
186       property = custom->GetSceneGraphProperty();
187     }
188     return property;
189   }
190
191   void SetSceneGraphProperty( EventThreadServices& eventThreadServices,
192                               const Object* object,
193                               Property::Index index,
194                               const PropertyMetadata& entry,
195                               const Property::Value& value ) const
196   {
197     const SceneGraph::PropertyOwner* sceneObject = object->GetSceneObject();
198
199     switch ( entry.GetType() )
200     {
201       case Property::BOOLEAN:
202       {
203         const SceneGraph::AnimatableProperty<bool>* property = dynamic_cast< const SceneGraph::AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
204         DALI_ASSERT_DEBUG( NULL != property );
205
206         // property is being used in a separate thread; queue a message to set the property
207         SceneGraph::AnimatablePropertyMessage<bool>::Send( eventThreadServices, sceneObject, property, &SceneGraph::AnimatableProperty<bool>::Bake, value.Get<bool>() );
208
209         break;
210       }
211
212       case Property::FLOAT:
213       {
214         const SceneGraph::AnimatableProperty<float>* property = dynamic_cast< const SceneGraph::AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
215         DALI_ASSERT_DEBUG( NULL != property );
216
217         // property is being used in a separate thread; queue a message to set the property
218         SceneGraph::AnimatablePropertyMessage<float>::Send( eventThreadServices, sceneObject, property, &SceneGraph::AnimatableProperty<float>::Bake, value.Get<float>() );
219
220         break;
221       }
222
223       case Property::INTEGER:
224       {
225         const SceneGraph::AnimatableProperty<int>* property = dynamic_cast< const SceneGraph::AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
226         DALI_ASSERT_DEBUG( NULL != property );
227
228         // property is being used in a separate thread; queue a message to set the property
229         SceneGraph::AnimatablePropertyMessage<int>::Send( eventThreadServices, sceneObject, property, &SceneGraph::AnimatableProperty<int>::Bake, value.Get<int>() );
230
231         break;
232       }
233
234       case Property::VECTOR2:
235       {
236         const SceneGraph::AnimatableProperty<Vector2>* property = dynamic_cast< const SceneGraph::AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
237         DALI_ASSERT_DEBUG( NULL != property );
238
239         // property is being used in a separate thread; queue a message to set the property
240         SceneGraph::AnimatablePropertyMessage<Vector2>::Send( eventThreadServices, sceneObject, property, &SceneGraph::AnimatableProperty<Vector2>::Bake, value.Get<Vector2>() );
241
242         break;
243       }
244
245       case Property::VECTOR3:
246       {
247         const SceneGraph::AnimatableProperty<Vector3>* property = dynamic_cast< const SceneGraph::AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
248         DALI_ASSERT_DEBUG( NULL != property );
249
250         // property is being used in a separate thread; queue a message to set the property
251         SceneGraph::AnimatablePropertyMessage<Vector3>::Send( eventThreadServices, sceneObject, property, &SceneGraph::AnimatableProperty<Vector3>::Bake, value.Get<Vector3>() );
252
253         break;
254       }
255
256       case Property::VECTOR4:
257       {
258         const SceneGraph::AnimatableProperty<Vector4>* property = dynamic_cast< const SceneGraph::AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
259         DALI_ASSERT_DEBUG( NULL != property );
260
261         // property is being used in a separate thread; queue a message to set the property
262         SceneGraph::AnimatablePropertyMessage<Vector4>::Send( eventThreadServices, sceneObject, property, &SceneGraph::AnimatableProperty<Vector4>::Bake, value.Get<Vector4>() );
263
264         break;
265       }
266
267       case Property::ROTATION:
268       {
269         const SceneGraph::AnimatableProperty<Quaternion>* property = dynamic_cast< const SceneGraph::AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
270         DALI_ASSERT_DEBUG( NULL != property );
271
272         // property is being used in a separate thread; queue a message to set the property
273         SceneGraph::AnimatablePropertyMessage<Quaternion>::Send( eventThreadServices, sceneObject, property,&SceneGraph::AnimatableProperty<Quaternion>::Bake,  value.Get<Quaternion>() );
274
275         break;
276       }
277
278       case Property::MATRIX:
279       {
280         const SceneGraph::AnimatableProperty<Matrix>* property = dynamic_cast< const SceneGraph::AnimatableProperty<Matrix>* >( entry.GetSceneGraphProperty() );
281         DALI_ASSERT_DEBUG( NULL != property );
282
283         // property is being used in a separate thread; queue a message to set the property
284         SceneGraph::AnimatablePropertyMessage<Matrix>::Send( eventThreadServices, sceneObject, property,&SceneGraph::AnimatableProperty<Matrix>::Bake,  value.Get<Matrix>() );
285
286         break;
287       }
288
289       case Property::MATRIX3:
290       {
291         const SceneGraph::AnimatableProperty<Matrix3>* property = dynamic_cast< const SceneGraph::AnimatableProperty<Matrix3>* >( entry.GetSceneGraphProperty() );
292         DALI_ASSERT_DEBUG( NULL != property );
293
294         // property is being used in a separate thread; queue a message to set the property
295         SceneGraph::AnimatablePropertyMessage<Matrix3>::Send( eventThreadServices, sceneObject, property, &SceneGraph::AnimatableProperty<Matrix3>::Bake,  value.Get<Matrix3>() );
296
297         break;
298       }
299
300       default:
301       {
302         DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
303         break;
304       }
305     }
306   }
307
308   int GetPropertyComponentIndex( Property::Index index ) const
309   {
310     // TODO: MESH_REWORK
311     DALI_ASSERT_ALWAYS( false && "TODO: MESH_REWORK" );
312     return 0;
313   }
314 };
315
316
317
318 } // namespace Internal
319
320 } // namespace Dali
321
322 #endif // DALI_INTERNAL_OBJECT_IMPL_HELPER_H