#include <algorithm> // std::sort
// INTERNAL INCLUDES
-#include <dali/public-api/object/property-buffer.h> // Dali::Internal::PropertyBuffer
+#include <dali/public-api/object/type-registry.h>
+#include <dali/devel-api/object/property-buffer.h> // Dali::Internal::PropertyBuffer
+
#include <dali/internal/event/common/object-impl-helper.h> // Dali::Internal::ObjectHelper
#include <dali/internal/event/common/property-helper.h> // DALI_PROPERTY_TABLE_BEGIN, DALI_PROPERTY, DALI_PROPERTY_TABLE_END
#include <dali/internal/update/common/scene-graph-property-buffer.h>
* |name |type |writable|animatable|constraint-input|enum for index-checking|
*/
DALI_PROPERTY_TABLE_BEGIN
-DALI_PROPERTY( "size", UNSIGNED_INTEGER, true, false, true, Dali::PropertyBuffer::Property::SIZE )
-DALI_PROPERTY( "buffer-format", MAP, false, false, false, Dali::PropertyBuffer::Property::BUFFER_FORMAT )
+DALI_PROPERTY( "size", INTEGER, true, false, true, Dali::PropertyBuffer::Property::SIZE )
+DALI_PROPERTY( "buffer-format", MAP, false, false, false, Dali::PropertyBuffer::Property::BUFFER_FORMAT )
DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
const ObjectImplHelper<DEFAULT_PROPERTY_COUNT> PROPERTY_BUFFER_IMPL = { DEFAULT_PROPERTY_DETAILS };
+BaseHandle Create()
+{
+ return Dali::BaseHandle();
+}
+
+TypeRegistration mType( typeid( Dali::PropertyBuffer ), typeid( Dali::Handle ), Create );
+
+/**
+ * Calculate the alignment requirements of a type
+ *
+ * This is used to calculate the memory alignment requirements of a type
+ * It creates a structure with a dummy char and a member of the type we want to check
+ * this will cause the second member to be aligned by it's alignment requirement.
+ */
+template<Property::Type type>
+struct PropertyImplementationTypeAlignment
+{
+ // Create a structure that forces alignment of the data type
+ struct TestStructure
+ {
+ char oneChar; ///< Member with sizeof() == 1
+ typename PropertyImplementationType<type>::Type data;
+ };
+ enum { VALUE = offsetof( TestStructure, data ) };
+};
+
+unsigned int GetPropertyImplementationAlignment( Property::Type& propertyType )
+{
+ unsigned int alignment = 0u;
+
+ switch( propertyType )
+ {
+ case Property::NONE:
+ case Property::STRING:
+ case Property::ARRAY:
+ case Property::MAP:
+ {
+ DALI_ASSERT_ALWAYS( "No size for properties with no type, or dynamic sizes" );
+ break;
+ }
+ case Property::BOOLEAN:
+ {
+ alignment = PropertyImplementationTypeAlignment< Property::BOOLEAN >::VALUE;
+ break;
+ }
+ case Property::INTEGER:
+ {
+ alignment = PropertyImplementationTypeAlignment< Property::INTEGER >::VALUE;
+ break;
+ }
+ case Property::FLOAT:
+ {
+ alignment = PropertyImplementationTypeAlignment< Property::FLOAT >::VALUE;
+ break;
+ }
+ case Property::VECTOR2:
+ {
+ alignment = PropertyImplementationTypeAlignment< Property::VECTOR2 >::VALUE;
+ break;
+ }
+ case Property::VECTOR3:
+ {
+ alignment = PropertyImplementationTypeAlignment< Property::VECTOR3 >::VALUE;
+ break;
+ }
+ case Property::VECTOR4:
+ {
+ alignment = PropertyImplementationTypeAlignment< Property::VECTOR4 >::VALUE;
+ break;
+ }
+ case Property::MATRIX3:
+ {
+ alignment = PropertyImplementationTypeAlignment< Property::MATRIX3 >::VALUE;
+ break;
+ }
+ case Property::MATRIX:
+ {
+ alignment = PropertyImplementationTypeAlignment< Property::MATRIX >::VALUE;
+ break;
+ }
+ case Property::RECTANGLE:
+ {
+ alignment = PropertyImplementationTypeAlignment< Property::RECTANGLE >::VALUE;
+ break;
+ }
+ case Property::ROTATION:
+ {
+ alignment = PropertyImplementationTypeAlignment< Property::ROTATION >::VALUE;
+ break;
+ }
+ }
+
+ return alignment;
+}
+
} // unnamed namespace
PropertyBufferPtr PropertyBuffer::New()
new SceneGraph::PropertyBuffer::BufferType( mBuffer ) );
}
-Dali::Property::Index PropertyBuffer::GetPropertyIndex( const std::string name, std::size_t index )
-{
- //TODO: MESH_REWORK
- DALI_ASSERT_ALWAYS( false && "MESH_REWORK" );
- return 0;
-}
-
const SceneGraph::PropertyBuffer* PropertyBuffer::GetPropertyBufferSceneObject() const
{
return mSceneObject;
}
-void PropertyBuffer::SetType( Dali::PropertyBuffer::Type type )
-{
- DALI_ASSERT_DEBUG( !mTypeSet && "Type of property buffer can only be set once." );
-
- switch(type)
- {
- case Dali::PropertyBuffer::STATIC:
- {
- mIsAnimatable = false;
- break;
- }
- case Dali::PropertyBuffer::ANIMATABLE:
- {
- mIsAnimatable = true;
- break;
- }
- }
-
-#ifdef DEBUG_ENABLED
- mTypeSet = true;
-#endif // DEBUG_ENABLED
-}
-
void PropertyBuffer::SetFormat( Dali::Property::Map& format )
{
DALI_ASSERT_ALWAYS( format.Count() && "Format cannot be empty." );
{
case Dali::PropertyBuffer::Property::SIZE:
{
- value = static_cast<int>( GetSize() ); // @todo MESH_REWORK Add a size_t type to PropertyValue
+ value = static_cast<int>( GetSize() );
break;
}
case Dali::PropertyBuffer::Property::BUFFER_FORMAT:
int PropertyBuffer::GetPropertyComponentIndex( Property::Index index ) const
{
- return PROPERTY_BUFFER_IMPL.GetPropertyComponentIndex( index );
+ return Property::INVALID_COMPONENT_INDEX;
}
bool PropertyBuffer::OnStage() const
PropertyBuffer::~PropertyBuffer()
{
+ if( EventThreadServices::IsCoreRunning() )
+ {
+ EventThreadServices& eventThreadServices = GetEventThreadServices();
+ SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
+ RemoveMessage( updateManager, updateManager.GetPropertyBufferOwner(), *mSceneObject );
+
+ eventThreadServices.UnregisterObject( this );
+ }
}
PropertyBuffer::PropertyBuffer()
: mSceneObject( NULL ),
mBufferFormat( NULL ),
mSize( 0 ),
- mIsAnimatable( false ),
mOnStage( false )
-#ifdef DEBUG_ENABLED
- , mTypeSet( false )
-#endif
{
}
EventThreadServices& eventThreadServices = GetEventThreadServices();
SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
- DALI_ASSERT_ALWAYS( EventThreadServices::IsCoreRunning() && "Core is not running" );
-
mSceneObject = new SceneGraph::PropertyBuffer();
AddMessage( updateManager, updateManager.GetPropertyBufferOwner(), *mSceneObject );
+
+ eventThreadServices.RegisterObject( this );
}
void PropertyBuffer::FormatChanged()
Format* bufferFormat = new Format();
bufferFormat->components.resize( numComponents );
- unsigned int elementSize = 0;
+ unsigned int currentAlignment = 0u;
+ unsigned int maxAlignmentRequired = 0u;
+
for( size_t i = 0u; i < numComponents; ++i )
{
StringValuePair component = mFormat.GetPair( i );
// Get the name
bufferFormat->components[i].name = component.first;
- // Get the size
+ // enums are stored in the map as int
Property::Type type = Property::Type( component.second.Get<int>() );
- elementSize += GetPropertyImplementationSize( type );
- // write the accumulatedSize
- bufferFormat->components[i].accumulatedSize = elementSize;
+ // Get the size and alignment
+ unsigned int elementSize = GetPropertyImplementationSize( type );
+ unsigned int elementAlignment = GetPropertyImplementationAlignment( type );
+
+ // check if current alignment is compatible with new member
+ if( unsigned int offset = currentAlignment % elementAlignment )
+ {
+ // Not compatible, realign
+ currentAlignment = currentAlignment + elementSize - offset;
+ }
+
+ // write to the format
+ bufferFormat->components[i].size = elementSize;
+ bufferFormat->components[i].offset = currentAlignment;
+ bufferFormat->components[i].type = type;
+
+ // update offset
+ currentAlignment += elementSize;
+
+ // update max alignment requirement
+ if( elementAlignment > maxAlignmentRequired )
+ {
+ maxAlignmentRequired = elementAlignment;
+ }
+
+ }
+
+ // Check the alignment for the maxAlignment required to calculate the size of the format
+ if( unsigned int offset = currentAlignment % maxAlignmentRequired )
+ {
+ // Not compatible, realign
+ currentAlignment = currentAlignment + maxAlignmentRequired - offset;
}
+ // Set the format size
+ bufferFormat->size = currentAlignment;
+
mBufferFormat = bufferFormat;
SceneGraph::SetFormatMessage( GetEventThreadServices(),
// Check if format and size have been set yet
if( mBufferFormat != NULL )
{
- unsigned int bufferSize = mBufferFormat->GetElementSize() * mSize;
+ unsigned int bufferSize = mBufferFormat->size * mSize;
mBuffer.Resize( bufferSize );
}
}
switch( propertyType )
{
case Property::NONE:
- case Property::TYPE_COUNT:
case Property::STRING:
case Property::ARRAY:
case Property::MAP:
size = sizeof( PropertyImplementationType< Property::BOOLEAN >::Type );
break;
}
- case Property::FLOAT:
- {
- size = sizeof( PropertyImplementationType< Property::FLOAT >::Type );
- break;
- }
case Property::INTEGER:
{
size = sizeof( PropertyImplementationType< Property::INTEGER >::Type );
break;
}
- case Property::UNSIGNED_INTEGER:
+ case Property::FLOAT:
{
- size = sizeof( PropertyImplementationType< Property::UNSIGNED_INTEGER >::Type );
+ size = sizeof( PropertyImplementationType< Property::FLOAT >::Type );
break;
}
case Property::VECTOR2:
return size;
}
+
} // namespace Internal
} // namespace Dali