Added double buffered properties that can be aged
[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 // INTERNAL INCLUDES
22 #include <dali/public-api/object/property.h> // Dali::Property
23 #include <dali/public-api/object/property-index-ranges.h> // DEFAULT_DERIVED_HANDLE_PROPERTY_START_INDEX
24 #include <dali/internal/event/common/property-helper.h> // Dali::Internal::PropertyDetails
25 #include <dali/internal/event/common/stage-impl.h>
26 #include <dali/internal/update/common/animatable-property.h>
27 #include <dali/internal/update/common/property-owner-messages.h>
28 #include <dali/internal/update/manager/update-manager.h>
29
30 namespace Dali
31 {
32 namespace Internal
33 {
34 class PropertyMetadata;
35 class AnimatablePropertyMetadata;
36 class CustomPropertyMetadata;
37 class PropertyInputImpl;
38
39 namespace SceneGraph
40 {
41
42 class PropertyBase;
43 class PropertyOwner;
44
45
46 } // namespace SceneGraph
47
48 // Typedefs to allow object methods to be passed via parameter
49 typedef AnimatablePropertyMetadata* (Object::*FindAnimatablePropertyMethod)( Property::Index index ) const;
50 typedef CustomPropertyMetadata* (Object::*FindCustomPropertyMethod)( Property::Index index ) const;
51
52
53 /**
54  * Helper template class to be used by class that implement Object
55  *
56  * Example:
57  *<pre>
58  * typename ObjectImplHelper<DEFAULT_PROPERTY_COUNT, DEFAULT_PROPERTY_DETAILS> MyObjectImpl;
59  *
60  * MyObjectImpl::GetDefaultPropertyCount();
61  * </pre>
62  */
63 template<int DEFAULT_PROPERTY_COUNT>
64 struct ObjectImplHelper
65 {
66   const PropertyDetails* DEFAULT_PROPERTY_DETAILS;
67
68   unsigned int GetDefaultPropertyCount() const
69   {
70     return DEFAULT_PROPERTY_COUNT;
71   }
72
73   void GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
74   {
75     indices.reserve( DEFAULT_PROPERTY_COUNT );
76
77     for( unsigned int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
78     {
79       indices.push_back( DEFAULT_OBJECT_PROPERTY_START_INDEX + i );
80     }
81   }
82
83   const char* GetDefaultPropertyName( Property::Index index ) const
84   {
85     const char* name = NULL;
86
87     if( index >= DEFAULT_OBJECT_PROPERTY_START_INDEX && index < DEFAULT_PROPERTY_COUNT )
88     {
89       name = DEFAULT_PROPERTY_DETAILS[index].name;
90     }
91
92     return name;
93   }
94
95   Property::Index GetDefaultPropertyIndex( const std::string& name ) const
96   {
97     Property::Index index = Property::INVALID_INDEX;
98
99     //@todo MESH_REWORK - Are we assuming that the index into the array is the
100     // same as the enumerated property? if enumIndex in the table was no longer
101     // debug only, wouldn't need to make this assumption.
102
103     // Look for name in default properties
104     for( unsigned int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
105     {
106       const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
107       if( 0 == strcmp( name.c_str(), property->name ) ) // dont want to convert rhs to string
108       {
109         index = i;
110         break;
111       }
112     }
113
114     return index;
115   }
116
117   bool IsDefaultPropertyWritable( Property::Index index ) const
118   {
119     bool isWritable = false;
120
121     if( index >= DEFAULT_OBJECT_PROPERTY_START_INDEX && index < DEFAULT_PROPERTY_COUNT )
122     {
123       isWritable = DEFAULT_PROPERTY_DETAILS[index].writable;
124     }
125
126     return isWritable;
127   }
128
129   bool IsDefaultPropertyAnimatable( Property::Index index ) const
130   {
131     bool isAnimatable = false;
132
133     if( index >= DEFAULT_OBJECT_PROPERTY_START_INDEX && index < DEFAULT_PROPERTY_COUNT )
134     {
135       isAnimatable =  DEFAULT_PROPERTY_DETAILS[index].animatable;
136     }
137
138     return isAnimatable;
139   }
140
141   bool IsDefaultPropertyAConstraintInput( Property::Index index ) const
142   {
143     bool isConstraintInput = false;
144
145     if( index >= DEFAULT_OBJECT_PROPERTY_START_INDEX && index < DEFAULT_PROPERTY_COUNT )
146     {
147       isConstraintInput = DEFAULT_PROPERTY_DETAILS[index].constraintInput;
148     }
149
150     return isConstraintInput;
151   }
152
153   Property::Type GetDefaultPropertyType( Property::Index index ) const
154   {
155     Property::Type type = Property::NONE;
156
157     if( index >= DEFAULT_OBJECT_PROPERTY_START_INDEX && index < DEFAULT_PROPERTY_COUNT )
158     {
159       type =  DEFAULT_PROPERTY_DETAILS[index].type;
160     }
161
162     return type;
163   }
164
165   // Get the (animatable) scene graph property. (All registered scene graph properties are animatable)
166   const SceneGraph::PropertyBase* GetRegisteredSceneGraphProperty(
167     const Object* object,
168     FindAnimatablePropertyMethod findAnimatablePropertyMethod,
169     FindCustomPropertyMethod findCustomPropertyMethod,
170     Property::Index index ) const
171   {
172     const SceneGraph::PropertyBase* property = NULL;
173     if ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX && index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )
174     {
175       AnimatablePropertyMetadata* animatable = (object->*findAnimatablePropertyMethod)( index );
176       DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
177       property = animatable->GetSceneGraphProperty();
178     }
179     else if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
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.type )
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         DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should not come here
300         break;
301       }
302     }
303   }
304
305   int GetPropertyComponentIndex( Property::Index index ) const
306   {
307     // TODO: MESH_REWORK
308     DALI_ASSERT_ALWAYS( false && "TODO: MESH_REWORK" );
309     return 0;
310   }
311 };
312
313
314
315 } // namespace Internal
316
317 } // namespace Dali
318
319 #endif // DALI_INTERNAL_OBJECT_IMPL_HELPER_H