/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <dali/internal/update/animation/scene-graph-constraint-base.h>
#include <dali/internal/update/common/animatable-property.h>
#include <dali/internal/update/common/property-owner-messages.h>
-#include <dali/internal/event/animation/active-constraint-base.h>
+#include <dali/internal/update/common/uniform-map.h>
#include <dali/internal/event/animation/constraint-impl.h>
#include <dali/internal/event/common/stage-impl.h>
#include <dali/internal/event/common/property-notification-impl.h>
#if defined(DEBUG_ENABLED)
Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_OBJECT" );
#endif
+
+
} // unnamed namespace
Object::Object()
-: mTypeInfo( NULL ),
+: mEventThreadServices( *Stage::GetCurrent() ),
+ mTypeInfo( NULL ),
mConstraints( NULL ),
mPropertyNotifications( NULL )
{
void Object::OnSceneObjectAdd()
{
- // Notification for this object's constraints
- if( mConstraints )
- {
- const ActiveConstraintConstIter endIter = mConstraints->end();
- for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
- {
- ActiveConstraintBase& baseConstraint = GetImplementation( *iter );
- baseConstraint.OnParentSceneObjectAdded();
- }
- }
-
// Notification for observers
for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter)
{
void Object::OnSceneObjectRemove()
{
- // Notification for this object's constraints
- if( mConstraints )
- {
- const ActiveConstraintConstIter endIter = mConstraints->end();
- for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
- {
- ActiveConstraintBase& baseConstraint = GetImplementation( *iter );
- baseConstraint.OnParentSceneObjectRemoved();
- }
- }
-
// Notification for observers
for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter )
{
int Object::GetPropertyComponentIndex( Property::Index index ) const
{
- return Property::INVALID_COMPONENT_INDEX;
+ int componentIndex = Property::INVALID_COMPONENT_INDEX;
+
+ const TypeInfo* typeInfo( GetTypeInfo() );
+ if ( typeInfo )
+ {
+ componentIndex = typeInfo->GetComponentIndex(index);
+ }
+
+ // For animatable property, check whether it is registered already and register it if not yet.
+ if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) && ( NULL == RegisterAnimatableProperty(index) ) )
+ {
+ componentIndex = Property::INVALID_COMPONENT_INDEX;
+ }
+
+ return componentIndex;
}
bool Object::Supports( Capability capability ) const
return GetDefaultPropertyName( index );
}
- if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
+ if ( ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
+ || ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) ) )
{
const TypeInfo* typeInfo( GetTypeInfo() );
if ( typeInfo )
}
}
- CustomProperty* custom = FindCustomProperty( index );
+ CustomPropertyMetadata* custom = FindCustomProperty( index );
if( custom )
{
return custom->name;
{
Property::Index index = GetDefaultPropertyIndex( name );
- if ( index == Property::INVALID_INDEX )
+ if(index == Property::INVALID_INDEX)
{
const TypeInfo* typeInfo( GetTypeInfo() );
if ( typeInfo )
{
index = typeInfo->GetPropertyIndex( name );
+ if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
+ {
+ // check whether the animatable property is registered already, if not then register one.
+ if ( NULL == RegisterAnimatableProperty(index) )
+ {
+ index = Property::INVALID_INDEX;
+ }
+ }
}
}
- if( ( index == Property::INVALID_INDEX )&&( mCustomProperties.Count() > 0 ) )
+ if( (index == Property::INVALID_INDEX)&&( mCustomProperties.Count() > 0 ) )
{
Property::Index count = PROPERTY_CUSTOM_START_INDEX;
- const CustomPropertyLookup::ConstIterator end = mCustomProperties.End();
- for( CustomPropertyLookup::ConstIterator iter = mCustomProperties.Begin(); iter != end; ++iter, ++count )
+ const PropertyMetadataLookup::ConstIterator end = mCustomProperties.End();
+ for( PropertyMetadataLookup::ConstIterator iter = mCustomProperties.Begin(); iter != end; ++iter, ++count )
{
- CustomProperty* custom = *iter;
+ CustomPropertyMetadata* custom = static_cast<CustomPropertyMetadata*>(*iter);
if ( custom->name == name )
{
index = count;
{
DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
+ bool writable = false;
+
if ( index < DEFAULT_PROPERTY_MAX_COUNT )
{
- return IsDefaultPropertyWritable( index );
+ writable = IsDefaultPropertyWritable( index );
}
-
- if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
+ else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
{
const TypeInfo* typeInfo( GetTypeInfo() );
if ( typeInfo )
{
- return typeInfo->IsPropertyWritable( index );
+ writable = typeInfo->IsPropertyWritable( index );
}
else
{
DALI_ASSERT_ALWAYS( ! "Invalid property index" );
}
}
-
- CustomProperty* custom = FindCustomProperty( index );
- if( custom )
+ else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
+ {
+ // Type Registry scene-graph properties are writable.
+ writable = true;
+ }
+ else
{
- return custom->IsWritable();
+ CustomPropertyMetadata* custom = FindCustomProperty( index );
+ if( custom )
+ {
+ writable = custom->IsWritable();
+ }
}
- return false;
+
+ return writable;
}
bool Object::IsPropertyAnimatable( Property::Index index ) const
{
DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
+ bool animatable = false;
+
if ( index < DEFAULT_PROPERTY_MAX_COUNT )
{
- return IsDefaultPropertyAnimatable( index );
+ animatable = IsDefaultPropertyAnimatable( index );
}
-
- if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
+ else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
{
// Type Registry event-thread only properties are not animatable.
- return false;
+ animatable = false;
}
-
- CustomProperty* custom = FindCustomProperty( index );
- if( custom )
+ else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
+ {
+ // Type Registry scene-graph properties are animatable.
+ animatable = true;
+ }
+ else
{
- return custom->IsAnimatable();
+ CustomPropertyMetadata* custom = FindCustomProperty( index );
+ if( custom )
+ {
+ animatable = custom->IsAnimatable();
+ }
}
- return false;
+
+ return animatable;
}
bool Object::IsPropertyAConstraintInput( Property::Index index ) const
{
DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
+ bool isConstraintInput = false;
+
if ( index < DEFAULT_PROPERTY_MAX_COUNT )
{
- return IsDefaultPropertyAConstraintInput( index );
+ isConstraintInput = IsDefaultPropertyAConstraintInput( index );
}
-
- if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
+ else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
{
// Type Registry event-thread only properties cannot be used as an input to a constraint.
- return false;
+ isConstraintInput = false;
}
-
- CustomProperty* custom = FindCustomProperty( index );
- if( custom )
+ else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
{
- // ... custom properties can be used as input to a constraint.
- return true;
+ // scene graph properties can be used as input to a constraint.
+ isConstraintInput = true;
}
- return false;
+ else
+ {
+ CustomPropertyMetadata* custom = FindCustomProperty( index );
+ if( custom )
+ {
+ // ... custom properties can be used as input to a constraint.
+ isConstraintInput = true;
+ }
+ }
+
+ return isConstraintInput;
}
Property::Type Object::GetPropertyType( Property::Index index ) const
return GetDefaultPropertyType( index );
}
- if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
+ if ( ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
+ || ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) ) )
{
const TypeInfo* typeInfo( GetTypeInfo() );
if ( typeInfo )
}
}
- CustomProperty* custom = FindCustomProperty( index );
+ CustomPropertyMetadata* custom = FindCustomProperty( index );
if( custom )
{
- return custom->type;
+ return custom->GetType();
}
return Property::NONE;
}
{
DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds" );
+ bool propertySet( true );
+
if ( index < DEFAULT_PROPERTY_MAX_COUNT )
{
SetDefaultProperty( index, propertyValue );
}
else
{
- DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
+ DALI_LOG_ERROR("Cannot find property index\n");
+ propertySet = false;
}
}
- else
+ else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
{
- CustomProperty* custom = FindCustomProperty( index );
- DALI_ASSERT_ALWAYS( custom && "Invalid property index" );
- if( custom->IsAnimatable() )
+ // check whether the animatable property is registered already, if not then register one.
+ AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty( index );
+ if(!animatableProperty)
+ {
+ DALI_LOG_ERROR("Cannot find property index\n");
+ propertySet = false;
+ }
+ else
{
// set the scene graph property value
- SetSceneGraphProperty( index, *custom, propertyValue );
+ SetSceneGraphProperty( index, *animatableProperty, propertyValue );
}
- else if( custom->IsWritable() )
+ }
+ else
+ {
+ CustomPropertyMetadata* custom = FindCustomProperty( index );
+ if( custom )
{
- custom->value = propertyValue;
- OnPropertySet(index, propertyValue);
+ if( custom->IsAnimatable() )
+ {
+ // set the scene graph property value
+ SetSceneGraphProperty( index, *custom, propertyValue );
+ }
+ else if( custom->IsWritable() )
+ {
+ custom->value = propertyValue;
+ }
+ else
+ {
+ // trying to set value on read only property is no-op
+ propertySet = false;
+ }
+ }
+ else
+ {
+ DALI_LOG_ERROR("Invalid property index\n");
+ propertySet = false;
}
- // trying to set value on read only property is no-op
+ }
+
+ // Let derived classes know that a property has been set
+ // TODO: We should not call this for read-only properties, SetDefaultProperty() && TypeInfo::SetProperty() should return a bool, which would be true if the property is set
+ if ( propertySet )
+ {
+ OnPropertySet(index, propertyValue);
}
}
}
else
{
- DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
+ DALI_LOG_ERROR("Cannot find property index\n");
}
}
- else if( mCustomProperties.Count() > 0 )
+ else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
{
- CustomProperty* custom = FindCustomProperty( index );
- DALI_ASSERT_ALWAYS( custom && "Invalid property index" );
-
- if( !custom->IsAnimatable() )
+ // check whether the animatable property is registered already, if not then register one.
+ AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty( index );
+ if(!animatableProperty)
{
- value = custom->value;
+ DALI_LOG_ERROR("Cannot find property index\n");
}
else
{
- BufferIndex bufferIndex( Stage::GetCurrent()->GetEventBufferIndex() );
-
- switch ( custom->type )
- {
- case Property::BOOLEAN:
- {
- const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( custom->GetSceneGraphProperty() );
- DALI_ASSERT_DEBUG( NULL != property );
-
- value = (*property)[ bufferIndex ];
- break;
- }
-
- case Property::FLOAT:
- {
- const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( custom->GetSceneGraphProperty() );
- DALI_ASSERT_DEBUG( NULL != property );
-
- value = (*property)[ bufferIndex ];
- break;
- }
-
- case Property::INTEGER:
- {
- const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( custom->GetSceneGraphProperty() );
- DALI_ASSERT_DEBUG( NULL != property );
-
- value = (*property)[ bufferIndex ];
- break;
- }
-
- case Property::VECTOR2:
- {
- const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( custom->GetSceneGraphProperty() );
- DALI_ASSERT_DEBUG( NULL != property );
-
- value = (*property)[ bufferIndex ];
- break;
- }
-
- case Property::VECTOR3:
- {
- const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( custom->GetSceneGraphProperty() );
- DALI_ASSERT_DEBUG( NULL != property );
-
- value = (*property)[ bufferIndex ];
- break;
- }
-
- case Property::VECTOR4:
- {
- const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( custom->GetSceneGraphProperty() );
- DALI_ASSERT_DEBUG( NULL != property );
-
- value = (*property)[ bufferIndex ];
- break;
- }
-
- case Property::MATRIX:
- {
- const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( custom->GetSceneGraphProperty() );
- DALI_ASSERT_DEBUG( NULL != property );
-
- value = (*property)[ bufferIndex ];
- break;
- }
-
- case Property::MATRIX3:
- {
- const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( custom->GetSceneGraphProperty() );
- DALI_ASSERT_DEBUG( NULL != property );
-
- value = (*property)[ bufferIndex ];
- break;
- }
-
- case Property::ROTATION:
- {
- const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( custom->GetSceneGraphProperty() );
- DALI_ASSERT_DEBUG( NULL != property );
-
- value = (*property)[ bufferIndex ];
- break;
- }
-
- default:
- {
- DALI_ASSERT_ALWAYS( false && "PropertyType enumeration is out of bounds" );
- break;
- }
- } // switch(type)
- } // if animatable
-
+ // get the animatable property value
+ value = GetPropertyValue( animatableProperty );
+ }
+ }
+ else if(mCustomProperties.Count() > 0)
+ {
+ CustomPropertyMetadata* custom = FindCustomProperty( index );
+ if(custom)
+ {
+ // get the custom property value
+ value = GetPropertyValue( custom );
+ }
+ else
+ {
+ DALI_LOG_ERROR("Invalid property index\n");
+ }
} // if custom
return value;
void Object::GetPropertyIndices( Property::IndexContainer& indices ) const
{
- indices.clear();
+ indices.Clear();
// Default Properties
GetDefaultPropertyIndices( indices );
// Custom Properties
if ( mCustomProperties.Count() > 0 )
{
- indices.reserve( indices.size() + mCustomProperties.Count() );
+ indices.Reserve( indices.Size() + mCustomProperties.Count() );
- CustomPropertyLookup::ConstIterator iter = mCustomProperties.Begin();
- const CustomPropertyLookup::ConstIterator endIter = mCustomProperties.End();
+ PropertyMetadataLookup::ConstIterator iter = mCustomProperties.Begin();
+ const PropertyMetadataLookup::ConstIterator endIter = mCustomProperties.End();
int i=0;
for ( ; iter != endIter; ++iter, ++i )
{
- indices.push_back( PROPERTY_CUSTOM_START_INDEX + i );
+ indices.PushBack( PROPERTY_CUSTOM_START_INDEX + i );
}
}
}
-Property::Index Object::RegisterProperty( const std::string& name, const Property::Value& propertyValue)
+Property::Index Object::RegisterSceneGraphProperty(const std::string& name, Property::Index index, const Property::Value& propertyValue) const
{
// Create a new property
Dali::Internal::OwnerPointer<PropertyBase> newProperty;
break;
}
- case Property::FLOAT:
+ case Property::INTEGER:
{
- newProperty = new AnimatableProperty<float>( propertyValue.Get<float>() );
+ newProperty = new AnimatableProperty<int>( propertyValue.Get<int>() );
break;
}
- case Property::INTEGER:
+ case Property::FLOAT:
{
- newProperty = new AnimatableProperty<int>( propertyValue.Get<int>() );
+ newProperty = new AnimatableProperty<float>( propertyValue.Get<float>() );
break;
}
break;
}
- case Property::UNSIGNED_INTEGER:
case Property::RECTANGLE:
case Property::STRING:
case Property::ARRAY:
case Property::MAP:
+ case Property::NONE:
{
- DALI_LOG_WARNING( "Property Type %d\n", propertyValue.GetType() );
DALI_ASSERT_ALWAYS( !"PropertyType is not animatable" );
break;
}
-
- default:
- {
- DALI_LOG_WARNING( "Property Type %d\n", propertyValue.GetType() );
- DALI_ASSERT_ALWAYS( !"PropertyType enumeration is out of bounds" );
- break;
- }
}
// get the scene property owner from derived class
const SceneGraph::PropertyOwner* scenePropertyOwner = GetPropertyOwner();
- Property::Index index = PROPERTY_CUSTOM_START_INDEX + mCustomProperties.Count();
// we can only pass properties to scene graph side if there is a scene object
if( scenePropertyOwner )
{
// keep a local pointer to the property as the OwnerPointer will pass its copy to the message
const PropertyBase* property = newProperty.Get();
- mCustomProperties.PushBack( new CustomProperty( name, propertyValue.GetType(), property ) );
+ if(index >= PROPERTY_CUSTOM_START_INDEX)
+ {
+ mCustomProperties.PushBack( new CustomPropertyMetadata( name, propertyValue.GetType(), property ) );
+ }
+ else
+ {
+ mAnimatableProperties.PushBack( new AnimatablePropertyMetadata( index, Property::INVALID_COMPONENT_INDEX, propertyValue.GetType(), property ) ); // base property
+ }
// queue a message to add the property
- InstallCustomPropertyMessage( Stage::GetCurrent()->GetUpdateInterface(), *scenePropertyOwner, newProperty.Release() ); // Message takes ownership
+ InstallCustomPropertyMessage( const_cast<EventThreadServices&>(GetEventThreadServices()), *scenePropertyOwner, newProperty.Release() ); // Message takes ownership
// notify the derived class (optional) method in case it needs to do some more work on the new property
// note! have to use the local pointer as OwnerPointer now points to NULL as it handed over its ownership
NotifyScenePropertyInstalled( *property, name, index );
+
+ return index;
}
else
{
// property was orphaned and killed so return invalid index
- index = Property::INVALID_INDEX;
+ return Property::INVALID_INDEX;
}
+}
+
+Property::Index Object::RegisterProperty( const std::string& name, const Property::Value& propertyValue)
+{
+ Property::Index index = RegisterSceneGraphProperty(name, PROPERTY_CUSTOM_START_INDEX + mCustomProperties.Count(), propertyValue);
+
+ /// @todo: don't keep a table of mappings per handle.
+ AddUniformMapping(index, name);
return index;
}
Property::Index Object::RegisterProperty( const std::string& name, const Property::Value& propertyValue, Property::AccessMode accessMode)
{
- Property::Index index = Property::INVALID_INDEX;
+ Property::Index index; // No need to initialise as it's overridden anyway
if(Property::ANIMATABLE == accessMode)
{
{
// Add entry to the property lookup
index = PROPERTY_CUSTOM_START_INDEX + mCustomProperties.Count();
- mCustomProperties.PushBack( new CustomProperty( name, propertyValue, accessMode ) );
+ mCustomProperties.PushBack( new CustomPropertyMetadata( name, propertyValue, accessMode ) );
}
return index;
{
DALI_ASSERT_ALWAYS( false && "Property notification added to event side only property." );
}
+ else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
+ {
+ // check whether the animatable property is registered already, if not then register one.
+ AnimatablePropertyMetadata* animatable = RegisterAnimatableProperty( index );
+ DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
+ }
else if ( mCustomProperties.Count() > 0 )
{
- CustomProperty* custom = FindCustomProperty( index );
+ CustomPropertyMetadata* custom = FindCustomProperty( index );
DALI_ASSERT_ALWAYS( custom && "Invalid property index" );
DALI_ASSERT_ALWAYS( custom->IsAnimatable() && "Property notification added to event side only property." );
}
}
}
-Dali::ActiveConstraint Object::ApplyConstraint( Constraint& constraint )
+void Object::AddUniformMapping( Property::Index propertyIndex, const std::string& uniformName )
{
- return Dali::ActiveConstraint( DoApplyConstraint( constraint, Dali::Handle() ) );
-}
+ // Get the address of the property if it's a scene property
+ const PropertyInputImpl* propertyPtr = GetSceneObjectInputProperty( propertyIndex );
-Dali::ActiveConstraint Object::ApplyConstraint( Constraint& constraint, Dali::Handle weightObject )
-{
- return Dali::ActiveConstraint( DoApplyConstraint( constraint, weightObject ) );
-}
+ // Check instead for newly registered properties
+ if( propertyPtr == NULL )
+ {
+ PropertyMetadata* animatable = FindAnimatableProperty( propertyIndex );
+ if( animatable != NULL )
+ {
+ propertyPtr = animatable->GetSceneGraphProperty();
+ }
+ }
-ActiveConstraintBase* Object::DoApplyConstraint( Constraint& constraint, Dali::Handle weightObject )
-{
- ActiveConstraintBase* activeConstraintImpl = constraint.CreateActiveConstraint();
- DALI_ASSERT_DEBUG( NULL != activeConstraintImpl );
+ if( propertyPtr == NULL )
+ {
+ PropertyMetadata* custom = FindCustomProperty( propertyIndex );
+ if( custom != NULL )
+ {
+ propertyPtr = custom->GetSceneGraphProperty();
+ }
+ }
- Dali::ActiveConstraint activeConstraint( activeConstraintImpl );
+ // @todo MESH_REWORK Store mappings for unstaged objects?
- if( weightObject )
+ if( propertyPtr != NULL )
{
- Object& weightObjectImpl = GetImplementation( weightObject );
- Property::Index weightIndex = weightObjectImpl.GetPropertyIndex( "weight" );
+ const SceneGraph::PropertyOwner* sceneObject = GetPropertyOwner();
- if( Property::INVALID_INDEX != weightIndex )
+ if( sceneObject != NULL )
+ {
+ SceneGraph::UniformPropertyMapping* map = new SceneGraph::UniformPropertyMapping( uniformName, propertyPtr );
+ // Message takes ownership of Uniform map (and will delete it after copy)
+ AddUniformMapMessage( GetEventThreadServices(), *sceneObject, map);
+ }
+ else
{
- activeConstraintImpl->SetCustomWeightObject( weightObjectImpl, weightIndex );
+ // @todo MESH_REWORK FIXME Need to store something that can be sent to the scene
+ // object when staged.
+ DALI_ASSERT_ALWAYS(0 && "MESH_REWORK - Need to store property whilst off-stage" );
}
}
+}
- if( !mConstraints )
+void Object::RemoveUniformMapping( const std::string& uniformName )
+{
+ const SceneGraph::PropertyOwner* sceneObject = GetSceneObject();
+ RemoveUniformMapMessage( GetEventThreadServices(), *sceneObject, uniformName);
+}
+
+Property::Value Object::GetPropertyValue( const PropertyMetadata* entry ) const
+{
+ Property::Value value;
+
+ DALI_ASSERT_ALWAYS( entry && "Invalid property metadata" );
+
+ if( !entry->IsAnimatable() )
{
- mConstraints = new ActiveConstraintContainer;
+ value = entry->value;
}
- mConstraints->push_back( activeConstraint );
+ else
+ {
+ BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
+
+ switch ( entry->GetType() )
+ {
+ case Property::BOOLEAN:
+ {
+ const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( entry->GetSceneGraphProperty() );
+ DALI_ASSERT_DEBUG( NULL != property );
+
+ value = (*property)[ bufferIndex ];
+ break;
+ }
+
+ case Property::INTEGER:
+ {
+ const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( entry->GetSceneGraphProperty() );
+ DALI_ASSERT_DEBUG( NULL != property );
+
+ value = (*property)[ bufferIndex ];
+ break;
+ }
+
+ case Property::FLOAT:
+ {
+ const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( entry->GetSceneGraphProperty() );
+ DALI_ASSERT_DEBUG( NULL != property );
+
+ value = (*property)[ bufferIndex ];
+ break;
+ }
+
+ case Property::VECTOR2:
+ {
+ const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( entry->GetSceneGraphProperty() );
+ DALI_ASSERT_DEBUG( NULL != property );
- activeConstraintImpl->FirstApply( *this, constraint.GetApplyTime() );
+ if(entry->componentIndex == 0)
+ {
+ value = (*property)[ bufferIndex ].x;
+ }
+ else if(entry->componentIndex == 1)
+ {
+ value = (*property)[ bufferIndex ].y;
+ }
+ else
+ {
+ value = (*property)[ bufferIndex ];
+ }
+ break;
+ }
+
+ case Property::VECTOR3:
+ {
+ const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( entry->GetSceneGraphProperty() );
+ DALI_ASSERT_DEBUG( NULL != property );
+
+ if(entry->componentIndex == 0)
+ {
+ value = (*property)[ bufferIndex ].x;
+ }
+ else if(entry->componentIndex == 1)
+ {
+ value = (*property)[ bufferIndex ].y;
+ }
+ else if(entry->componentIndex == 2)
+ {
+ value = (*property)[ bufferIndex ].z;
+ }
+ else
+ {
+ value = (*property)[ bufferIndex ];
+ }
+ break;
+ }
- return activeConstraintImpl;
+ case Property::VECTOR4:
+ {
+ const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( entry->GetSceneGraphProperty() );
+ DALI_ASSERT_DEBUG( NULL != property );
+
+ if(entry->componentIndex == 0)
+ {
+ value = (*property)[ bufferIndex ].x;
+ }
+ else if(entry->componentIndex == 1)
+ {
+ value = (*property)[ bufferIndex ].y;
+ }
+ else if(entry->componentIndex == 2)
+ {
+ value = (*property)[ bufferIndex ].z;
+ }
+ else if(entry->componentIndex == 3)
+ {
+ value = (*property)[ bufferIndex ].w;
+ }
+ else
+ {
+ value = (*property)[ bufferIndex ];
+ }
+ break;
+ }
+
+ case Property::MATRIX:
+ {
+ const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( entry->GetSceneGraphProperty() );
+ DALI_ASSERT_DEBUG( NULL != property );
+
+ value = (*property)[ bufferIndex ];
+ break;
+ }
+
+ case Property::MATRIX3:
+ {
+ const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( entry->GetSceneGraphProperty() );
+ DALI_ASSERT_DEBUG( NULL != property );
+
+ value = (*property)[ bufferIndex ];
+ break;
+ }
+
+ case Property::ROTATION:
+ {
+ const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( entry->GetSceneGraphProperty() );
+ DALI_ASSERT_DEBUG( NULL != property );
+
+ value = (*property)[ bufferIndex ];
+ break;
+ }
+
+ default:
+ {
+ DALI_ASSERT_ALWAYS( false && "PropertyType enumeration is out of bounds" );
+ break;
+ }
+ } // switch(type)
+ } // if animatable
+
+ return value;
}
-void Object::SetSceneGraphProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
+void Object::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
{
- switch ( entry.type )
+ switch ( entry.GetType() )
{
case Property::BOOLEAN:
{
DALI_ASSERT_DEBUG( NULL != property );
// property is being used in a separate thread; queue a message to set the property
- BakeMessage<bool>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<bool>() );
+ BakeMessage<bool>( GetEventThreadServices(), *property, value.Get<bool>() );
break;
}
- case Property::FLOAT:
+ case Property::INTEGER:
{
- const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
+ const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
DALI_ASSERT_DEBUG( NULL != property );
// property is being used in a separate thread; queue a message to set the property
- BakeMessage<float>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<float>() );
+ BakeMessage<int>( GetEventThreadServices(), *property, value.Get<int>() );
break;
}
- case Property::INTEGER:
+ case Property::FLOAT:
{
- const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
+ const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
DALI_ASSERT_DEBUG( NULL != property );
// property is being used in a separate thread; queue a message to set the property
- BakeMessage<int>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<int>() );
+ BakeMessage<float>( GetEventThreadServices(), *property, value.Get<float>() );
break;
}
DALI_ASSERT_DEBUG( NULL != property );
// property is being used in a separate thread; queue a message to set the property
- BakeMessage<Vector2>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Vector2>() );
+ if(entry.componentIndex == 0)
+ {
+ SetXComponentMessage<Vector2>( GetEventThreadServices(), *property, value.Get<float>() );
+ }
+ else if(entry.componentIndex == 1)
+ {
+ SetYComponentMessage<Vector2>( GetEventThreadServices(), *property, value.Get<float>() );
+ }
+ else
+ {
+ BakeMessage<Vector2>( GetEventThreadServices(), *property, value.Get<Vector2>() );
+ }
break;
}
DALI_ASSERT_DEBUG( NULL != property );
// property is being used in a separate thread; queue a message to set the property
- BakeMessage<Vector3>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Vector3>() );
+ if(entry.componentIndex == 0)
+ {
+ SetXComponentMessage<Vector3>( GetEventThreadServices(), *property, value.Get<float>() );
+ }
+ else if(entry.componentIndex == 1)
+ {
+ SetYComponentMessage<Vector3>( GetEventThreadServices(), *property, value.Get<float>() );
+ }
+ else if(entry.componentIndex == 2)
+ {
+ SetZComponentMessage<Vector3>( GetEventThreadServices(), *property, value.Get<float>() );
+ }
+ else
+ {
+ BakeMessage<Vector3>( GetEventThreadServices(), *property, value.Get<Vector3>() );
+ }
+
break;
}
DALI_ASSERT_DEBUG( NULL != property );
// property is being used in a separate thread; queue a message to set the property
- BakeMessage<Vector4>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Vector4>() );
+ if(entry.componentIndex == 0)
+ {
+ SetXComponentMessage<Vector4>( GetEventThreadServices(), *property, value.Get<float>() );
+ }
+ else if(entry.componentIndex == 1)
+ {
+ SetYComponentMessage<Vector4>( GetEventThreadServices(), *property, value.Get<float>() );
+ }
+ else if(entry.componentIndex == 2)
+ {
+ SetZComponentMessage<Vector4>( GetEventThreadServices(), *property, value.Get<float>() );
+ }
+ else if(entry.componentIndex == 3)
+ {
+ SetWComponentMessage<Vector4>( GetEventThreadServices(), *property, value.Get<float>() );
+ }
+ else
+ {
+ BakeMessage<Vector4>( GetEventThreadServices(), *property, value.Get<Vector4>() );
+ }
break;
}
DALI_ASSERT_DEBUG( NULL != property );
// property is being used in a separate thread; queue a message to set the property
- BakeMessage<Quaternion>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Quaternion>() );
+ BakeMessage<Quaternion>( GetEventThreadServices(), *property, value.Get<Quaternion>() );
break;
}
DALI_ASSERT_DEBUG( NULL != property );
// property is being used in a separate thread; queue a message to set the property
- BakeMessage<Matrix>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Matrix>() );
+ BakeMessage<Matrix>( GetEventThreadServices(), *property, value.Get<Matrix>() );
break;
}
DALI_ASSERT_DEBUG( NULL != property );
// property is being used in a separate thread; queue a message to set the property
- BakeMessage<Matrix3>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Matrix3>() );
+ BakeMessage<Matrix3>( GetEventThreadServices(), *property, value.Get<Matrix3>() );
break;
}
return mTypeInfo;
}
-void Object::RemoveConstraint( ActiveConstraint& constraint, bool isInScenegraph )
+void Object::ApplyConstraint( ConstraintBase& constraint )
{
- // guard against constraint sending messages during core destruction
- if ( Stage::IsInstalled() )
+ if( !mConstraints )
+ {
+ mConstraints = new ConstraintContainer;
+ }
+ mConstraints->push_back( Dali::Constraint( &constraint ) );
+}
+
+void Object::RemoveConstraint( ConstraintBase& constraint )
+{
+ // NULL if the Constraint sources are destroyed before Constraint::Apply()
+ if( mConstraints )
{
- if( isInScenegraph )
+ ConstraintIter it( std::find( mConstraints->begin(), mConstraints->end(), Dali::Constraint( &constraint ) ) );
+ if( it != mConstraints->end() )
{
- ActiveConstraintBase& baseConstraint = GetImplementation( constraint );
- baseConstraint.BeginRemove();
+ mConstraints->erase( it );
}
}
}
-void Object::RemoveConstraint( Dali::ActiveConstraint activeConstraint )
+void Object::RemoveConstraints()
{
// guard against constraint sending messages during core destruction
if( mConstraints && Stage::IsInstalled() )
{
- bool isInSceneGraph( NULL != GetSceneObject() );
-
- ActiveConstraintIter it( std::find( mConstraints->begin(), mConstraints->end(), activeConstraint ) );
- if( it != mConstraints->end() )
+ // If we have nothing in the scene-graph, just clear constraint containers
+ const SceneGraph::PropertyOwner* propertyOwner = GetSceneObject();
+ if ( NULL != propertyOwner )
{
- RemoveConstraint( *it, isInSceneGraph );
- mConstraints->erase( it );
+ const ConstraintConstIter endIter = mConstraints->end();
+ for ( ConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
+ {
+ GetImplementation( *iter ).RemoveInternal();
+ }
}
+
+ delete mConstraints;
+ mConstraints = NULL;
}
}
// guard against constraint sending messages during core destruction
if( mConstraints && Stage::IsInstalled() )
{
- bool isInSceneGraph( NULL != GetSceneObject() );
-
- ActiveConstraintIter iter( mConstraints->begin() );
+ ConstraintIter iter( mConstraints->begin() );
while(iter != mConstraints->end() )
{
- ActiveConstraintBase& constraint = GetImplementation( *iter );
+ ConstraintBase& constraint = GetImplementation( *iter );
if( constraint.GetTag() == tag )
{
- RemoveConstraint( *iter, isInSceneGraph );
+ GetImplementation( *iter ).RemoveInternal();
iter = mConstraints->erase( iter );
}
else
++iter;
}
}
- }
-}
-void Object::RemoveConstraints()
-{
- // guard against constraint sending messages during core destruction
- if( mConstraints && Stage::IsInstalled() )
- {
- // If we have nothing in the scene-graph, just clear constraint containers
- const SceneGraph::PropertyOwner* propertyOwner = GetSceneObject();
- if ( NULL != propertyOwner )
+ if ( mConstraints->empty() )
{
- const ActiveConstraintConstIter endIter = mConstraints->end();
- for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
- {
- RemoveConstraint( *iter, true );
- }
+ delete mConstraints;
+ mConstraints = NULL;
}
-
- delete mConstraints;
- mConstraints = NULL;
}
}
Object::~Object()
{
- // Notification for this object's constraints
- // (note that the ActiveConstraint handles may outlive the Object)
- if( mConstraints )
- {
- const ActiveConstraintConstIter endIter = mConstraints->end();
- for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
- {
- ActiveConstraintBase& baseConstraint = GetImplementation( *iter );
- baseConstraint.OnParentDestroyed();
- }
- }
-
// Notification for observers
for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter)
{
delete mPropertyNotifications;
}
-CustomProperty* Object::FindCustomProperty( Property::Index index ) const
+CustomPropertyMetadata* Object::FindCustomProperty( Property::Index index ) const
{
- CustomProperty* property( NULL );
+ CustomPropertyMetadata* property( NULL );
int arrayIndex = index - PROPERTY_CUSTOM_START_INDEX;
if( arrayIndex >= 0 )
{
if( arrayIndex < (int)mCustomProperties.Count() ) // we can only access the first 2 billion custom properties
{
- property = mCustomProperties[ arrayIndex ];
+ property = static_cast<CustomPropertyMetadata*>(mCustomProperties[ arrayIndex ]);
}
}
return property;
}
+AnimatablePropertyMetadata* Object::FindAnimatableProperty( Property::Index index ) const
+{
+ for ( int arrayIndex = 0; arrayIndex < (int)mAnimatableProperties.Count(); arrayIndex++ )
+ {
+ AnimatablePropertyMetadata* property = static_cast<AnimatablePropertyMetadata*>( mAnimatableProperties[ arrayIndex ] );
+ if( property->index == index )
+ {
+ return property;
+ }
+ }
+ return NULL;
+}
+
+AnimatablePropertyMetadata* Object::RegisterAnimatableProperty(Property::Index index) const
+{
+ DALI_ASSERT_ALWAYS( (( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ))
+ && "Property index is out of bounds" );
+
+ // check whether the animatable property is registered already, if not then register one.
+ AnimatablePropertyMetadata* animatableProperty = FindAnimatableProperty( index );
+ if(!animatableProperty)
+ {
+ const TypeInfo* typeInfo( GetTypeInfo() );
+ if (typeInfo)
+ {
+ Property::Index basePropertyIndex = typeInfo->GetBasePropertyIndex(index);
+ if(basePropertyIndex == Property::INVALID_INDEX)
+ {
+ // If the property is not a component of a base property, register the whole property itself.
+ RegisterSceneGraphProperty(typeInfo->GetPropertyName(index), index, Property::Value(typeInfo->GetPropertyType(index)));
+ }
+ else
+ {
+ // Since the property is a component of a base property, check whether the base property is regsitered.
+ animatableProperty = FindAnimatableProperty( basePropertyIndex );
+ if(!animatableProperty)
+ {
+ // If the base property is not registered yet, register the base property first.
+ if(Property::INVALID_INDEX != RegisterSceneGraphProperty(typeInfo->GetPropertyName(basePropertyIndex), basePropertyIndex, Property::Value(typeInfo->GetPropertyType(basePropertyIndex))))
+ {
+ animatableProperty = static_cast<AnimatablePropertyMetadata*>(mAnimatableProperties[mAnimatableProperties.Size()-1]);
+ }
+ }
+
+ if(animatableProperty)
+ {
+ // Create the metadata for the property component.
+ mAnimatableProperties.PushBack( new AnimatablePropertyMetadata( index, typeInfo->GetComponentIndex(index), animatableProperty->GetType(), animatableProperty->GetSceneGraphProperty() ) );
+ }
+ }
+
+ // The metadata has just been added and therefore should be in the end of the vector.
+ animatableProperty = static_cast<AnimatablePropertyMetadata*>(mAnimatableProperties[mAnimatableProperties.Size()-1]);
+ }
+ }
+
+ return animatableProperty;
+}
+
} // namespace Internal
} // namespace Dali