Fixes and cleanup.
[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( mType == Dali::PropertyBuffer::TYPE_COUNT && "Type can only be set once." );
107   DALI_ASSERT_DEBUG( type != Dali::PropertyBuffer::TYPE_COUNT && "Type must be set to a valid value." );
108
109   mType = type;
110 }
111
112 void PropertyBuffer::SetFormat( Dali::Property::Map& format )
113 {
114   DALI_ASSERT_ALWAYS( format.Count() && "Format cannot be empty." );
115
116   DALI_ASSERT_DEBUG( 0 == mFormat.Count() && "Format of property buffer can only be set once." );
117
118   mFormat = format;
119
120   FormatChanged();
121 }
122
123 unsigned int PropertyBuffer::GetDefaultPropertyCount() const
124 {
125   return PROPERTY_BUFFER_IMPL.GetDefaultPropertyCount();
126 }
127
128 void PropertyBuffer::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
129 {
130   PROPERTY_BUFFER_IMPL.GetDefaultPropertyIndices( indices );
131 }
132
133 const char* PropertyBuffer::GetDefaultPropertyName(Property::Index index) const
134 {
135   return PROPERTY_BUFFER_IMPL.GetDefaultPropertyName( index );
136 }
137
138 Property::Index PropertyBuffer::GetDefaultPropertyIndex( const std::string& name ) const
139 {
140   return PROPERTY_BUFFER_IMPL.GetDefaultPropertyIndex( name );
141 }
142
143 bool PropertyBuffer::IsDefaultPropertyWritable( Property::Index index ) const
144 {
145   return PROPERTY_BUFFER_IMPL.IsDefaultPropertyWritable( index );
146 }
147
148 bool PropertyBuffer::IsDefaultPropertyAnimatable( Property::Index index ) const
149 {
150   return PROPERTY_BUFFER_IMPL.IsDefaultPropertyAnimatable( index );
151 }
152
153 bool PropertyBuffer::IsDefaultPropertyAConstraintInput( Property::Index index ) const
154 {
155   return PROPERTY_BUFFER_IMPL.IsDefaultPropertyAConstraintInput( index );
156 }
157
158 Property::Type PropertyBuffer::GetDefaultPropertyType( Property::Index index ) const
159 {
160   return PROPERTY_BUFFER_IMPL.GetDefaultPropertyType( index );
161 }
162
163 void PropertyBuffer::SetDefaultProperty( Property::Index index,
164                                          const Property::Value& propertyValue )
165 {
166   switch( index )
167   {
168     case Dali::PropertyBuffer::Property::SIZE:
169     {
170       SetSize( propertyValue.Get<int>() );
171       break;
172     }
173     case Dali::PropertyBuffer::Property::BUFFER_FORMAT:
174     {
175       DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
176       break;
177     }
178   }
179 }
180
181 void PropertyBuffer::SetSceneGraphProperty( Property::Index index,
182                                             const PropertyMetadata& entry,
183                                             const Property::Value& value )
184 {
185   PROPERTY_BUFFER_IMPL.SetSceneGraphProperty( GetEventThreadServices(), this, index, entry, value );
186 }
187
188 Property::Value PropertyBuffer::GetDefaultProperty( Property::Index index ) const
189 {
190   Property::Value value;
191
192   switch( index )
193   {
194     case Dali::PropertyBuffer::Property::SIZE:
195     {
196       value = static_cast<int>( GetSize() ); // @todo MESH_REWORK Add a size_t type to PropertyValue
197       break;
198     }
199     case Dali::PropertyBuffer::Property::BUFFER_FORMAT:
200     {
201       DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
202       break;
203     }
204   }
205   return value;
206 }
207
208 const SceneGraph::PropertyOwner* PropertyBuffer::GetPropertyOwner() const
209 {
210   return mSceneObject;
211 }
212
213 const SceneGraph::PropertyOwner* PropertyBuffer::GetSceneObject() const
214 {
215   return mSceneObject;
216 }
217
218 const SceneGraph::PropertyBase* PropertyBuffer::GetSceneObjectAnimatableProperty( Property::Index index ) const
219 {
220   DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
221   const SceneGraph::PropertyBase* property = NULL;
222
223   if( OnStage() )
224   {
225     property = PROPERTY_BUFFER_IMPL.GetRegisteredSceneGraphProperty(
226       this,
227       &PropertyBuffer::FindAnimatableProperty,
228       &PropertyBuffer::FindCustomProperty,
229       index );
230
231     if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
232     {
233       DALI_ASSERT_ALWAYS( 0 && "Property is not animatable" );
234     }
235   }
236
237   return property;
238 }
239
240 const PropertyInputImpl* PropertyBuffer::GetSceneObjectInputProperty( Property::Index index ) const
241 {
242   const PropertyInputImpl* property = NULL;
243
244   if( OnStage() )
245   {
246     const SceneGraph::PropertyBase* baseProperty =
247       PROPERTY_BUFFER_IMPL.GetRegisteredSceneGraphProperty( this,
248                                                             &PropertyBuffer::FindAnimatableProperty,
249                                                             &PropertyBuffer::FindCustomProperty,
250                                                             index );
251     property = static_cast<const PropertyInputImpl*>( baseProperty );
252
253     if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
254     {
255       if( index == Dali::PropertyBuffer::Property::SIZE )
256       {
257         // @todo MESH_REWORK
258         DALI_ASSERT_ALWAYS( 0 && "MESH_REWORK" );
259       }
260     }
261   }
262
263   return property;
264 }
265
266 int PropertyBuffer::GetPropertyComponentIndex( Property::Index index ) const
267 {
268   return PROPERTY_BUFFER_IMPL.GetPropertyComponentIndex( index );
269 }
270
271 bool PropertyBuffer::OnStage() const
272 {
273   return mOnStage;
274 }
275
276 void PropertyBuffer::Connect()
277 {
278   mOnStage = true;
279 }
280
281 void PropertyBuffer::Disconnect()
282 {
283   mOnStage = false;
284 }
285
286 PropertyBuffer::~PropertyBuffer()
287 {
288 }
289
290 PropertyBuffer::PropertyBuffer()
291 : mSceneObject( NULL ),
292   mBufferFormat( NULL ),
293   mSize( 0 ),
294   mType( Dali::PropertyBuffer::TYPE_COUNT ),
295   mOnStage( false )
296 {
297 }
298
299 void PropertyBuffer::Initialize()
300 {
301   EventThreadServices& eventThreadServices = GetEventThreadServices();
302   SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
303
304   DALI_ASSERT_ALWAYS( EventThreadServices::IsCoreRunning() && "Core is not running" );
305
306   mSceneObject = new SceneGraph::PropertyBuffer();
307   AddMessage( updateManager, updateManager.GetPropertyBufferOwner(), *mSceneObject );
308 }
309
310 void PropertyBuffer::FormatChanged()
311 {
312   size_t numComponents = mFormat.Count();
313
314   // Create the format
315   DALI_ASSERT_DEBUG( mBufferFormat == NULL && "PropertyFormat should not be set yet" );
316   Format* bufferFormat = new Format();
317   bufferFormat->components.resize( numComponents );
318
319   unsigned int elementSize = 0;
320   for( size_t i = 0u; i < numComponents; ++i )
321   {
322     StringValuePair component = mFormat.GetPair( i );
323
324     // Get the name
325     bufferFormat->components[i].name = component.first;
326
327     // Get the size ( enums are stored in the map as int )
328     Property::Type type = Property::Type( component.second.Get<int>() );
329     elementSize += GetPropertyImplementationSize( type );
330
331     // write the accumulatedSize
332     bufferFormat->components[i].accumulatedSize = elementSize;
333   }
334
335   mBufferFormat = bufferFormat;
336
337   SceneGraph::SetFormatMessage( GetEventThreadServices(),
338                                 *mSceneObject,
339                                 bufferFormat );
340
341   if( mSize )
342   {
343     SizeChanged();
344   }
345 }
346
347 void PropertyBuffer::SizeChanged()
348 {
349   // Check if format and size have been set yet
350   if( mBufferFormat != NULL )
351   {
352     unsigned int bufferSize = mBufferFormat->GetElementSize() * mSize;
353     mBuffer.Resize( bufferSize );
354   }
355 }
356
357 unsigned int GetPropertyImplementationSize( Property::Type& propertyType )
358 {
359   unsigned int size = 0u;
360
361   switch( propertyType )
362   {
363     case Property::NONE:
364     case Property::TYPE_COUNT:
365     case Property::STRING:
366     case Property::ARRAY:
367     case Property::MAP:
368     {
369       DALI_ASSERT_ALWAYS( "No size for properties with no type, or dynamic sizes" );
370       break;
371     }
372     case Property::BOOLEAN:
373     {
374       size = sizeof( PropertyImplementationType< Property::BOOLEAN >::Type );
375       break;
376     }
377     case Property::INTEGER:
378     {
379       size = sizeof( PropertyImplementationType< Property::INTEGER >::Type );
380       break;
381     }
382     case Property::UNSIGNED_INTEGER:
383     {
384       size = sizeof( PropertyImplementationType< Property::UNSIGNED_INTEGER >::Type );
385       break;
386     }
387     // TODO : MESH_REWORK : uncoment this code
388 //    case Property::UNSIGNED_SHORT:
389 //    {
390 //      size = sizeof( PropertyImplementationType< Property::UNSIGNED_SHORT >::Type );
391 //      break;
392 //    }
393     case Property::FLOAT:
394     {
395       size = sizeof( PropertyImplementationType< Property::FLOAT >::Type );
396       break;
397     }
398     case Property::VECTOR2:
399     {
400       size = sizeof( PropertyImplementationType< Property::VECTOR2 >::Type );
401       break;
402     }
403     case Property::VECTOR3:
404     {
405       size = sizeof( PropertyImplementationType< Property::VECTOR3 >::Type );
406       break;
407     }
408     case Property::VECTOR4:
409     {
410       size = sizeof( PropertyImplementationType< Property::VECTOR4 >::Type );
411       break;
412     }
413     case Property::MATRIX3:
414     {
415       size = sizeof( PropertyImplementationType< Property::MATRIX3 >::Type );
416       break;
417     }
418     case Property::MATRIX:
419     {
420       size = sizeof( PropertyImplementationType< Property::MATRIX >::Type );
421       break;
422     }
423     case Property::RECTANGLE:
424     {
425       size = sizeof( PropertyImplementationType< Property::RECTANGLE >::Type );
426       break;
427     }
428     case Property::ROTATION:
429     {
430       size = sizeof( PropertyImplementationType< Property::ROTATION >::Type );
431       break;
432     }
433   }
434
435   return size;
436 }
437
438 } // namespace Internal
439 } // namespace Dali