Dali 3D User Interface Engine
property-buffer-impl.cpp
Go to the documentation of this file.
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/devel-api/object/property-buffer.h> // Dali::Internal::PropertyBuffer
28 
29 namespace Dali
30 {
31 namespace Internal
32 {
33 
34 namespace
35 {
36 
44 template<Property::Type type>
46 {
47  // Create a structure that forces alignment of the data type
49  {
50  char oneChar;
52  };
53  enum { VALUE = offsetof( TestStructure, data ) };
54 };
55 
57 {
58  unsigned int alignment = 0u;
59 
60  switch( propertyType )
61  {
62  case Property::NONE:
63  case Property::STRING:
64  case Property::ARRAY:
65  case Property::MAP:
66  {
67  DALI_ASSERT_ALWAYS( false && "No size for properties with no type, or dynamic sizes" );
68  break;
69  }
70  case Property::BOOLEAN:
71  {
73  break;
74  }
75  case Property::INTEGER:
76  {
78  break;
79  }
80  case Property::FLOAT:
81  {
83  break;
84  }
85  case Property::VECTOR2:
86  {
88  break;
89  }
90  case Property::VECTOR3:
91  {
93  break;
94  }
95  case Property::VECTOR4:
96  {
98  break;
99  }
100  case Property::MATRIX3:
101  {
103  break;
104  }
105  case Property::MATRIX:
106  {
108  break;
109  }
110  case Property::RECTANGLE:
111  {
113  break;
114  }
115  case Property::ROTATION:
116  {
118  break;
119  }
120  }
121 
122  return alignment;
123 }
124 
125 } // unnamed namespace
126 
128 {
129  PropertyBufferPtr propertyBuffer( new PropertyBuffer() );
130  propertyBuffer->Initialize();
131 
132  return propertyBuffer;
133 }
134 
135 void PropertyBuffer::SetSize( std::size_t size )
136 {
137  mSize = size;
138 
139  SizeChanged();
140 
142 }
143 
144 std::size_t PropertyBuffer::GetSize() const
145 {
146  return mSize;
147 }
148 
149 void PropertyBuffer::SetData( const void* data )
150 {
151  DALI_ASSERT_DEBUG( mFormat.Count() && "Format must be set before setting the data." );
152 
153  DALI_ASSERT_ALWAYS( mSize && "Size of the buffer must be set before setting the data." );
154 
155  const char* source = static_cast<const char*>( data );
156  std::copy( source, source + mBuffer.Size(), &mBuffer[0] );
157 
159 }
160 
162 {
163  DALI_ASSERT_ALWAYS( format.Count() && "Format cannot be empty." );
164 
165  DALI_ASSERT_DEBUG( 0 == mFormat.Count() && "Format of property buffer can only be set once." );
166 
167  mFormat = format;
168 
169  FormatChanged();
170 }
171 
173 {
174  return mRenderObject;
175 }
176 
178 {
180  {
182  }
183 }
184 
186 :mEventThreadServices( *Stage::GetCurrent() )
187 ,mRenderObject(NULL)
188 ,mBufferFormat( NULL )
189 ,mSize( 0 )
190 {
191 }
192 
194 {
197 }
198 
200 {
201  size_t numComponents = mFormat.Count();
202 
203  // Create the format
204  DALI_ASSERT_DEBUG( mBufferFormat == NULL && "PropertyFormat should not be set yet" );
206  format->components.resize( numComponents );
207 
208  unsigned int currentAlignment = 0u;
209  unsigned int maxAlignmentRequired = 0u;
210 
211  for( size_t i = 0u; i < numComponents; ++i )
212  {
213  StringValuePair component = mFormat.GetPair( i );
214 
215  // Get the name
216  format->components[i].name = component.first;
217 
218  // enums are stored in the map as int
219  Property::Type type = Property::Type( component.second.Get<int>() );
220 
221  // Get the size and alignment
222  unsigned int elementSize = GetPropertyImplementationSize( type );
223  unsigned int elementAlignment = GetPropertyImplementationAlignment( type );
224 
225  // check if current alignment is compatible with new member
226  if( unsigned int offset = currentAlignment % elementAlignment )
227  {
228  // Not compatible, realign
229  currentAlignment = currentAlignment + elementSize - offset;
230  }
231 
232  // write to the format
233  format->components[i].size = elementSize;
234  format->components[i].offset = currentAlignment;
235  format->components[i].type = type;
236 
237  // update offset
238  currentAlignment += elementSize;
239 
240  // update max alignment requirement
241  if( elementAlignment > maxAlignmentRequired )
242  {
243  maxAlignmentRequired = elementAlignment;
244  }
245 
246  }
247 
248  // Check the alignment for the maxAlignment required to calculate the size of the format
249  if( maxAlignmentRequired != 0 )
250  {
251  if( unsigned int offset = currentAlignment % maxAlignmentRequired )
252  {
253  // Not compatible, realign
254  currentAlignment = currentAlignment + maxAlignmentRequired - offset;
255  }
256  }
257 
258  // Set the format size
259  format->size = currentAlignment;
260 
261  mBufferFormat = format;
262 
264  if( mSize )
265  {
266  SizeChanged();
267  }
268 }
269 
271 {
272  // Check if format and size have been set yet
273  if( mBufferFormat != NULL )
274  {
275  unsigned int bufferSize = mBufferFormat->size * mSize;
276  mBuffer.Resize( bufferSize );
277  }
278 }
279 
280 unsigned int GetPropertyImplementationSize( Property::Type& propertyType )
281 {
282  unsigned int size = 0u;
283 
284  switch( propertyType )
285  {
286  case Property::NONE:
287  case Property::STRING:
288  case Property::ARRAY:
289  case Property::MAP:
290  {
291  DALI_ASSERT_ALWAYS( "No size for properties with no type, or dynamic sizes" );
292  break;
293  }
294  case Property::BOOLEAN:
295  {
297  break;
298  }
299  case Property::INTEGER:
300  {
302  break;
303  }
304  case Property::FLOAT:
305  {
307  break;
308  }
309  case Property::VECTOR2:
310  {
312  break;
313  }
314  case Property::VECTOR3:
315  {
317  break;
318  }
319  case Property::VECTOR4:
320  {
322  break;
323  }
324  case Property::MATRIX3:
325  {
327  break;
328  }
329  case Property::MATRIX:
330  {
332  break;
333  }
334  case Property::RECTANGLE:
335  {
337  break;
338  }
339  case Property::ROTATION:
340  {
342  break;
343  }
344  }
345 
346  return size;
347 }
348 
349 
350 } // namespace Internal
351 } // namespace Dali
Dali Docs Home
Read more about Dali