PropertyBuffers implementation.
[platform/core/uifw/dali-core.git] / dali / internal / event / common / property-buffer-impl.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/event/common/property-buffer-impl.h>  // Dali::Internal::PropertyBuffer
20
21 // EXTERNAL INCLUDE
22 #include <algorithm> // std::sort
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/object/property-buffer.h> // Dali::Internal::PropertyBuffer
26 #include <dali/internal/event/common/object-impl-helper.h> // Dali::Internal::ObjectHelper
27 #include <dali/internal/event/common/property-helper.h> // DALI_PROPERTY_TABLE_BEGIN, DALI_PROPERTY, DALI_PROPERTY_TABLE_END
28 #include <dali/internal/update/common/scene-graph-property-buffer.h>
29 #include <dali/internal/update/manager/update-manager.h>
30
31 namespace Dali
32 {
33 namespace Internal
34 {
35
36 using SceneGraph::PropertyBufferMetadata::Format;
37 using SceneGraph::PropertyBufferMetadata::Component;
38
39 namespace
40 {
41
42 /**
43  *            |name    |type             |writable|animatable|constraint-input|enum for index-checking|
44  */
45 DALI_PROPERTY_TABLE_BEGIN
46 DALI_PROPERTY( "size",          UNSIGNED_INTEGER, true, false,  true,   Dali::PropertyBuffer::Property::SIZE )
47 DALI_PROPERTY( "buffer-format", MAP,              false, false, false,  Dali::PropertyBuffer::Property::BUFFER_FORMAT )
48 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
49
50 const ObjectImplHelper<DEFAULT_PROPERTY_COUNT> PROPERTY_BUFFER_IMPL = { DEFAULT_PROPERTY_DETAILS };
51
52 } // unnamed namespace
53
54 PropertyBufferPtr PropertyBuffer::New()
55 {
56   PropertyBufferPtr propertyBuffer( new PropertyBuffer() );
57   propertyBuffer->Initialize();
58
59   return propertyBuffer;
60 }
61
62 void PropertyBuffer::SetSize( std::size_t size )
63 {
64   mSize = size;
65
66   SizeChanged();
67
68   SceneGraph::SetSizeMessage( GetEventThreadServices(),
69                               *mSceneObject,
70                               mSize );
71 }
72
73 std::size_t PropertyBuffer::GetSize() const
74 {
75   return mSize;
76 }
77
78 void PropertyBuffer::SetData( const void* data )
79 {
80   DALI_ASSERT_DEBUG( mFormat.Count() && "Format must be set before setting the data." );
81
82   DALI_ASSERT_ALWAYS( mSize && "Size of the buffer must be set before setting the data." );
83
84   const char* source = static_cast<const char*>( data );
85   std::copy( source, source + mBuffer.Size(), &mBuffer[0] );
86
87   SceneGraph::SetDataMessage( GetEventThreadServices(),
88                               *mSceneObject,
89                               new SceneGraph::PropertyBuffer::BufferType( mBuffer ) );
90 }
91
92 Dali::Property::Index PropertyBuffer::GetPropertyIndex( const std::string name, std::size_t index )
93 {
94   //TODO: MESH_REWORK
95   DALI_ASSERT_ALWAYS( false && "MESH_REWORK" );
96   return 0;
97 }
98
99 const SceneGraph::PropertyBuffer* PropertyBuffer::GetPropertyBufferSceneObject() const
100 {
101   return mSceneObject;
102 }
103
104 void PropertyBuffer::SetType( Dali::PropertyBuffer::Type type )
105 {
106   DALI_ASSERT_DEBUG( !mTypeSet && "Type of property buffer can only be set once." );
107
108   switch(type)
109   {
110     case  Dali::PropertyBuffer::STATIC:
111     {
112       mIsAnimatable = false;
113       break;
114     }
115     case  Dali::PropertyBuffer::ANIMATABLE:
116     {
117       mIsAnimatable = true;
118       break;
119     }
120   }
121
122 #ifdef DEBUG_ENABLED
123   mTypeSet = true;
124 #endif // DEBUG_ENABLED
125 }
126
127 void PropertyBuffer::SetFormat( Dali::Property::Map& format )
128 {
129   DALI_ASSERT_ALWAYS( format.Count() && "Format cannot be empty." );
130
131   DALI_ASSERT_DEBUG( 0 == mFormat.Count() && "Format of property buffer can only be set once." );
132
133   mFormat = format;
134
135   FormatChanged();
136 }
137
138 unsigned int PropertyBuffer::GetDefaultPropertyCount() const
139 {
140   return PROPERTY_BUFFER_IMPL.GetDefaultPropertyCount();
141 }
142
143 void PropertyBuffer::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
144 {
145   PROPERTY_BUFFER_IMPL.GetDefaultPropertyIndices( indices );
146 }
147
148 const char* PropertyBuffer::GetDefaultPropertyName(Property::Index index) const
149 {
150   return PROPERTY_BUFFER_IMPL.GetDefaultPropertyName( index );
151 }
152
153 Property::Index PropertyBuffer::GetDefaultPropertyIndex( const std::string& name ) const
154 {
155   return PROPERTY_BUFFER_IMPL.GetDefaultPropertyIndex( name );
156 }
157
158 bool PropertyBuffer::IsDefaultPropertyWritable( Property::Index index ) const
159 {
160   return PROPERTY_BUFFER_IMPL.IsDefaultPropertyWritable( index );
161 }
162
163 bool PropertyBuffer::IsDefaultPropertyAnimatable( Property::Index index ) const
164 {
165   return PROPERTY_BUFFER_IMPL.IsDefaultPropertyAnimatable( index );
166 }
167
168 bool PropertyBuffer::IsDefaultPropertyAConstraintInput( Property::Index index ) const
169 {
170   return PROPERTY_BUFFER_IMPL.IsDefaultPropertyAConstraintInput( index );
171 }
172
173 Property::Type PropertyBuffer::GetDefaultPropertyType( Property::Index index ) const
174 {
175   return PROPERTY_BUFFER_IMPL.GetDefaultPropertyType( index );
176 }
177
178 void PropertyBuffer::SetDefaultProperty( Property::Index index,
179                                          const Property::Value& propertyValue )
180 {
181   switch( index )
182   {
183     case Dali::PropertyBuffer::Property::SIZE:
184     {
185       SetSize( propertyValue.Get<int>() );
186       break;
187     }
188     case Dali::PropertyBuffer::Property::BUFFER_FORMAT:
189     {
190       DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
191       break;
192     }
193   }
194 }
195
196 void PropertyBuffer::SetSceneGraphProperty( Property::Index index,
197                                             const PropertyMetadata& entry,
198                                             const Property::Value& value )
199 {
200   PROPERTY_BUFFER_IMPL.SetSceneGraphProperty( GetEventThreadServices(), this, index, entry, value );
201 }
202
203 Property::Value PropertyBuffer::GetDefaultProperty( Property::Index index ) const
204 {
205   Property::Value value;
206
207   switch( index )
208   {
209     case Dali::PropertyBuffer::Property::SIZE:
210     {
211       value = static_cast<int>( GetSize() ); // @todo MESH_REWORK Add a size_t type to PropertyValue
212       break;
213     }
214     case Dali::PropertyBuffer::Property::BUFFER_FORMAT:
215     {
216       DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
217       break;
218     }
219   }
220   return value;
221 }
222
223 const SceneGraph::PropertyOwner* PropertyBuffer::GetPropertyOwner() const
224 {
225   return mSceneObject;
226 }
227
228 const SceneGraph::PropertyOwner* PropertyBuffer::GetSceneObject() const
229 {
230   return mSceneObject;
231 }
232
233 const SceneGraph::PropertyBase* PropertyBuffer::GetSceneObjectAnimatableProperty( Property::Index index ) const
234 {
235   DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
236   const SceneGraph::PropertyBase* property = NULL;
237
238   if( OnStage() )
239   {
240     property = PROPERTY_BUFFER_IMPL.GetRegisteredSceneGraphProperty(
241       this,
242       &PropertyBuffer::FindAnimatableProperty,
243       &PropertyBuffer::FindCustomProperty,
244       index );
245
246     if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
247     {
248       DALI_ASSERT_ALWAYS( 0 && "Property is not animatable" );
249     }
250   }
251
252   return property;
253 }
254
255 const PropertyInputImpl* PropertyBuffer::GetSceneObjectInputProperty( Property::Index index ) const
256 {
257   const PropertyInputImpl* property = NULL;
258
259   if( OnStage() )
260   {
261     const SceneGraph::PropertyBase* baseProperty =
262       PROPERTY_BUFFER_IMPL.GetRegisteredSceneGraphProperty( this,
263                                                             &PropertyBuffer::FindAnimatableProperty,
264                                                             &PropertyBuffer::FindCustomProperty,
265                                                             index );
266     property = static_cast<const PropertyInputImpl*>( baseProperty );
267
268     if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
269     {
270       if( index == Dali::PropertyBuffer::Property::SIZE )
271       {
272         // @todo MESH_REWORK
273         DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
274       }
275     }
276   }
277
278   return property;
279 }
280
281 int PropertyBuffer::GetPropertyComponentIndex( Property::Index index ) const
282 {
283   return PROPERTY_BUFFER_IMPL.GetPropertyComponentIndex( index );
284 }
285
286 bool PropertyBuffer::OnStage() const
287 {
288   return mOnStage;
289 }
290
291 void PropertyBuffer::Connect()
292 {
293   mOnStage = true;
294 }
295
296 void PropertyBuffer::Disconnect()
297 {
298   mOnStage = false;
299 }
300
301 PropertyBuffer::~PropertyBuffer()
302 {
303 }
304
305 PropertyBuffer::PropertyBuffer()
306 : mSceneObject( NULL ),
307   mBufferFormat( NULL ),
308   mSize( 0 ),
309   mIsAnimatable( false ),
310   mOnStage( false )
311 #ifdef DEBUG_ENABLED
312   , mTypeSet( false )
313 #endif
314 {
315 }
316
317 void PropertyBuffer::Initialize()
318 {
319   EventThreadServices& eventThreadServices = GetEventThreadServices();
320   SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
321
322   DALI_ASSERT_ALWAYS( EventThreadServices::IsCoreRunning() && "Core is not running" );
323
324   mSceneObject = new SceneGraph::PropertyBuffer();
325   AddMessage( updateManager, updateManager.GetPropertyBufferOwner(), *mSceneObject );
326 }
327
328 void PropertyBuffer::FormatChanged()
329 {
330   size_t numComponents = mFormat.Count();
331
332   // Create the format
333   DALI_ASSERT_DEBUG( mBufferFormat == NULL && "PropertyFormat should not be set yet" );
334   Format* bufferFormat = new Format();
335   bufferFormat->components.resize( numComponents );
336
337   unsigned int elementSize = 0;
338   for( size_t i = 0u; i < numComponents; ++i )
339   {
340     StringValuePair component = mFormat.GetPair( i );
341
342     // Get the name
343     bufferFormat->components[i].name = component.first;
344
345     // Get the size
346     Property::Type type = Property::Type( component.second.Get<int>() );
347     elementSize += GetPropertyImplementationSize( type );
348
349     // write the accumulatedSize
350     bufferFormat->components[i].accumulatedSize = elementSize;
351   }
352
353   mBufferFormat = bufferFormat;
354
355   SceneGraph::SetFormatMessage( GetEventThreadServices(),
356                                 *mSceneObject,
357                                 bufferFormat );
358
359   if( mSize )
360   {
361     SizeChanged();
362   }
363 }
364
365 void PropertyBuffer::SizeChanged()
366 {
367   // Check if format and size have been set yet
368   if( mBufferFormat != NULL )
369   {
370     unsigned int bufferSize = mBufferFormat->GetElementSize() * mSize;
371     mBuffer.Resize( bufferSize );
372   }
373 }
374
375 unsigned int GetPropertyImplementationSize( Property::Type& propertyType )
376 {
377   unsigned int size = 0u;
378
379   switch( propertyType )
380   {
381     case Property::NONE:
382     case Property::TYPE_COUNT:
383     case Property::STRING:
384     case Property::ARRAY:
385     case Property::MAP:
386     {
387       DALI_ASSERT_ALWAYS( "No size for properties with no type, or dynamic sizes" );
388       break;
389     }
390     case Property::BOOLEAN:
391     {
392       size = sizeof( PropertyImplementationType< Property::BOOLEAN >::Type );
393       break;
394     }
395     case Property::FLOAT:
396     {
397       size = sizeof( PropertyImplementationType< Property::FLOAT >::Type );
398       break;
399     }
400     case Property::INTEGER:
401     {
402       size = sizeof( PropertyImplementationType< Property::INTEGER >::Type );
403       break;
404     }
405     case Property::UNSIGNED_INTEGER:
406     {
407       size = sizeof( PropertyImplementationType< Property::UNSIGNED_INTEGER >::Type );
408       break;
409     }
410     case Property::VECTOR2:
411     {
412       size = sizeof( PropertyImplementationType< Property::VECTOR2 >::Type );
413       break;
414     }
415     case Property::VECTOR3:
416     {
417       size = sizeof( PropertyImplementationType< Property::VECTOR3 >::Type );
418       break;
419     }
420     case Property::VECTOR4:
421     {
422       size = sizeof( PropertyImplementationType< Property::VECTOR4 >::Type );
423       break;
424     }
425     case Property::MATRIX3:
426     {
427       size = sizeof( PropertyImplementationType< Property::MATRIX3 >::Type );
428       break;
429     }
430     case Property::MATRIX:
431     {
432       size = sizeof( PropertyImplementationType< Property::MATRIX >::Type );
433       break;
434     }
435     case Property::RECTANGLE:
436     {
437       size = sizeof( PropertyImplementationType< Property::RECTANGLE >::Type );
438       break;
439     }
440     case Property::ROTATION:
441     {
442       size = sizeof( PropertyImplementationType< Property::ROTATION >::Type );
443       break;
444     }
445   }
446
447   return size;
448 }
449
450 } // namespace Internal
451 } // namespace Dali