From 339c654ebfb6edb654d47a837f51056bc4fcf671 Mon Sep 17 00:00:00 2001 From: Paul Wisbey Date: Fri, 7 Mar 2014 17:24:08 +0000 Subject: [PATCH] Custom property owning objects [Issue#] n/a [Problem] There is no way of using custom properties without an actor. [Cause] Can't instantiate a Constrainable object. [Solution] Add method to create Constrainable objects. Signed-off-by: Paul Wisbey Change-Id: I0233ec5621ffdbe032d2e6e6bec8ec12d2a5463f --- automated-tests/dali-test-suite/actors/.gitignore | 1 + automated-tests/dali-test-suite/actors/file.list | 1 + automated-tests/dali-test-suite/actors/tslist | 1 + .../actors/utc-Dali-Constrainable.cpp | 114 +++++++++++++++ capi/dali/public-api/object/constrainable.h | 14 +- dali/internal/event/common/proxy-object.cpp | 94 ++++++++++++- dali/internal/event/common/proxy-object.h | 2 +- dali/internal/event/effects/shader-effect-impl.cpp | 94 ------------- dali/internal/event/effects/shader-effect-impl.h | 5 - .../event/object/custom-object-internal.cpp | 156 +++++++++++++++++++++ .../internal/event/object/custom-object-internal.h | 141 +++++++++++++++++++ dali/internal/file.list | 1 + dali/internal/update/common/property-owner.cpp | 5 + dali/internal/update/common/property-owner.h | 10 +- dali/internal/update/manager/update-manager.cpp | 46 ++++++ dali/internal/update/manager/update-manager.h | 35 +++++ dali/public-api/object/constrainable.cpp | 11 ++ 17 files changed, 627 insertions(+), 104 deletions(-) create mode 100644 automated-tests/dali-test-suite/actors/utc-Dali-Constrainable.cpp create mode 100644 dali/internal/event/object/custom-object-internal.cpp create mode 100644 dali/internal/event/object/custom-object-internal.h diff --git a/automated-tests/dali-test-suite/actors/.gitignore b/automated-tests/dali-test-suite/actors/.gitignore index fed2e60..2002e7a 100644 --- a/automated-tests/dali-test-suite/actors/.gitignore +++ b/automated-tests/dali-test-suite/actors/.gitignore @@ -13,6 +13,7 @@ utc-Dali-LightActor utc-Dali-Layer utc-Dali-Stage utc-Dali-CustomActor +utc-Dali-Constrainable utc-Dali-RenderableActor utc-Dali-BaseHandle utc-Dali-Handle diff --git a/automated-tests/dali-test-suite/actors/file.list b/automated-tests/dali-test-suite/actors/file.list index b1a5432..e4c750c 100644 --- a/automated-tests/dali-test-suite/actors/file.list +++ b/automated-tests/dali-test-suite/actors/file.list @@ -10,5 +10,6 @@ TARGETS += \ utc-Dali-Stage \ utc-Dali-TextActor \ utc-Dali-CustomActor \ + utc-Dali-Constrainable \ utc-Dali-BaseHandle \ utc-Dali-Handle \ diff --git a/automated-tests/dali-test-suite/actors/tslist b/automated-tests/dali-test-suite/actors/tslist index bd8e428..12b42e9 100644 --- a/automated-tests/dali-test-suite/actors/tslist +++ b/automated-tests/dali-test-suite/actors/tslist @@ -8,6 +8,7 @@ /dali-test-suite/actors/utc-Dali-Stage /dali-test-suite/actors/utc-Dali-TextActor /dali-test-suite/actors/utc-Dali-CustomActor +/dali-test-suite/actors/utc-Dali-Constrainable /dali-test-suite/actors/utc-Dali-RenderableActor /dali-test-suite/actors/utc-Dali-BaseHandle /dali-test-suite/actors/utc-Dali-Handle diff --git a/automated-tests/dali-test-suite/actors/utc-Dali-Constrainable.cpp b/automated-tests/dali-test-suite/actors/utc-Dali-Constrainable.cpp new file mode 100644 index 0000000..48bd659 --- /dev/null +++ b/automated-tests/dali-test-suite/actors/utc-Dali-Constrainable.cpp @@ -0,0 +1,114 @@ +// +// Copyright (c) 2014 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include + +#include +#include + +#include + +#include + +using namespace Dali; + +static void Startup(); +static void Cleanup(); + +extern "C" +{ + void (*tet_startup)() = Startup; + void (*tet_cleanup)() = Cleanup; +} + +enum +{ + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, +}; + +#define MAX_NUMBER_OF_TESTS 10000 +extern "C" { + struct tet_testlist tet_testlist[MAX_NUMBER_OF_TESTS]; +} + +// Add test functionality for all APIs in the class (Positive and Negative) +TEST_FUNCTION( UtcDaliConstrainableDownCast, POSITIVE_TC_IDX ); +TEST_FUNCTION( UtcDaliConstrainableDownCastNegative, NEGATIVE_TC_IDX ); +TEST_FUNCTION( UtcDaliConstrainableCustomProperty, POSITIVE_TC_IDX ); + + +// Called only once before first test is run. +static void Startup() +{ +} + +// Called only once after last test is run +static void Cleanup() +{ +} + +static void UtcDaliConstrainableDownCast() +{ + TestApplication application; + + Handle handle = Constrainable::New(); + + Constrainable customHandle1 = Constrainable::DownCast( handle ); + DALI_TEST_CHECK( customHandle1 ); + + Constrainable customHandle2 = DownCast< Constrainable >( handle ); + DALI_TEST_CHECK( customHandle2 ); +} + +static void UtcDaliConstrainableDownCastNegative() +{ + TestApplication application; + + Image image = Image::New( "temp" ); + Constrainable customHandle1 = Constrainable::DownCast( image ); + DALI_TEST_CHECK( ! customHandle1 ); + + Constrainable empty; + Constrainable customHandle2 = Constrainable::DownCast( empty ); + DALI_TEST_CHECK( ! customHandle2 ); +} + +static void UtcDaliConstrainableCustomProperty() +{ + TestApplication application; + + Constrainable handle = Constrainable::New(); + + float startValue(1.0f); + Property::Index index = handle.RegisterProperty( "test-property", startValue ); + DALI_TEST_CHECK( handle.GetProperty(index) == startValue ); + + application.SendNotification(); + application.Render(0); + DALI_TEST_CHECK( handle.GetProperty(index) == startValue ); + application.Render(0); + DALI_TEST_CHECK( handle.GetProperty(index) == startValue ); + + handle.SetProperty( index, 5.0f ); + + application.SendNotification(); + application.Render(0); + DALI_TEST_CHECK( handle.GetProperty(index) == 5.0f ); + application.Render(0); + DALI_TEST_CHECK( handle.GetProperty(index) == 5.0f ); +} + diff --git a/capi/dali/public-api/object/constrainable.h b/capi/dali/public-api/object/constrainable.h index 86eab80..4fbdd7e 100644 --- a/capi/dali/public-api/object/constrainable.h +++ b/capi/dali/public-api/object/constrainable.h @@ -46,6 +46,12 @@ class Constrainable : public Handle public: /** + * Create a constrainable object. + * @return A handle to a newly allocated object. + */ + static Constrainable New(); + + /** * This constructor provides an uninitialized Dali::Constrainable. * This should be initialized with a Dali New() method before use. * Methods called on an uninitialized Dali::Constrainable will assert. @@ -60,6 +66,13 @@ public: Constrainable(); /** + * Downcast a handle to a custom object. + * @param[in] handle The handle to cast. + * @return A handle to a custom object or an empty handle. + */ + static Constrainable DownCast( BaseHandle handle ); + + /** * Dali::Handle is intended as a base class */ virtual ~Constrainable(); @@ -106,7 +119,6 @@ public: public: - /** * This constructor is used by Dali New() methods. * @param [in] handle A pointer to a newly allocated Dali resource diff --git a/dali/internal/event/common/proxy-object.cpp b/dali/internal/event/common/proxy-object.cpp index 801a055..6d8603e 100644 --- a/dali/internal/event/common/proxy-object.cpp +++ b/dali/internal/event/common/proxy-object.cpp @@ -750,7 +750,99 @@ void ProxyObject::DeleteRemovedConstraints() ++iter; } } - } +} + +void ProxyObject::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value ) +{ + switch ( entry.type ) + { + case Property::BOOLEAN: + { + AnimatableProperty* property = dynamic_cast< AnimatableProperty* >( entry.GetSceneGraphProperty() ); + DALI_ASSERT_DEBUG( NULL != property ); + + // property is being used in a separate thread; queue a message to set the property + BakeMessage( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get() ); + break; + } + + case Property::FLOAT: + { + AnimatableProperty* property = dynamic_cast< AnimatableProperty* >( entry.GetSceneGraphProperty() ); + DALI_ASSERT_DEBUG( NULL != property ); + + // property is being used in a separate thread; queue a message to set the property + BakeMessage( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get() ); + break; + } + + case Property::VECTOR2: + { + AnimatableProperty* property = dynamic_cast< AnimatableProperty* >( entry.GetSceneGraphProperty() ); + DALI_ASSERT_DEBUG( NULL != property ); + + // property is being used in a separate thread; queue a message to set the property + BakeMessage( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get() ); + break; + } + + case Property::VECTOR3: + { + AnimatableProperty* property = dynamic_cast< AnimatableProperty* >( entry.GetSceneGraphProperty() ); + DALI_ASSERT_DEBUG( NULL != property ); + + // property is being used in a separate thread; queue a message to set the property + BakeMessage( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get() ); + break; + } + + case Property::VECTOR4: + { + AnimatableProperty* property = dynamic_cast< AnimatableProperty* >( entry.GetSceneGraphProperty() ); + DALI_ASSERT_DEBUG( NULL != property ); + + // property is being used in a separate thread; queue a message to set the property + BakeMessage( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get() ); + break; + } + + case Property::ROTATION: + { + AnimatableProperty* property = dynamic_cast< AnimatableProperty* >( entry.GetSceneGraphProperty() ); + DALI_ASSERT_DEBUG( NULL != property ); + + // property is being used in a separate thread; queue a message to set the property + BakeMessage( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get() ); + break; + } + + case Property::MATRIX: + { + AnimatableProperty* property = dynamic_cast< AnimatableProperty* >( entry.GetSceneGraphProperty() ); + DALI_ASSERT_DEBUG( NULL != property ); + + // property is being used in a separate thread; queue a message to set the property + BakeMessage( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get() ); + break; + } + + case Property::MATRIX3: + { + AnimatableProperty* property = dynamic_cast< AnimatableProperty* >( entry.GetSceneGraphProperty() ); + DALI_ASSERT_DEBUG( NULL != property ); + + // property is being used in a separate thread; queue a message to set the property + BakeMessage( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get() ); + break; + } + + default: + { + DALI_ASSERT_ALWAYS(false && "Property type enumeration out of bounds"); // should not come here + break; + } + } +} CustomPropertyLookup& ProxyObject::GetCustomPropertyLookup() const { diff --git a/dali/internal/event/common/proxy-object.h b/dali/internal/event/common/proxy-object.h index 95f37a1..5b985c0 100644 --- a/dali/internal/event/common/proxy-object.h +++ b/dali/internal/event/common/proxy-object.h @@ -378,7 +378,7 @@ private: // Default property extensions for derived classes * @param [in] entry An entry from the CustomPropertyLookup. * @param [in] value The new value of the property. */ - virtual void SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value ) = 0; + virtual void SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value ); /** * Retrieve a default property value. diff --git a/dali/internal/event/effects/shader-effect-impl.cpp b/dali/internal/event/effects/shader-effect-impl.cpp index b25cf01..df53643 100644 --- a/dali/internal/event/effects/shader-effect-impl.cpp +++ b/dali/internal/event/effects/shader-effect-impl.cpp @@ -698,100 +698,6 @@ void ShaderEffect::SetDefaultProperty( Property::Index index, const Property::Va } } -void ShaderEffect::SetCustomProperty( Property::Index /* index */, const CustomProperty& entry, const Property::Value& value ) -{ - DALI_ASSERT_ALWAYS(entry.IsAnimatable() && "shader effect has only animatable properties"); - - switch ( entry.type ) - { - case Property::BOOLEAN: - { - AnimatableProperty* property = dynamic_cast< AnimatableProperty* >( entry.GetSceneGraphProperty() ); - DALI_ASSERT_DEBUG( NULL != property ); - - // property is being used in a separate thread; queue a message to set the property - BakeMessage( mUpdateManager.GetEventToUpdate(), *property, value.Get() ); - break; - } - - case Property::FLOAT: - { - AnimatableProperty* property = dynamic_cast< AnimatableProperty* >( entry.GetSceneGraphProperty() ); - DALI_ASSERT_DEBUG( NULL != property ); - - // property is being used in a separate thread; queue a message to set the property - BakeMessage( mUpdateManager.GetEventToUpdate(), *property, value.Get() ); - break; - } - - case Property::VECTOR2: - { - AnimatableProperty* property = dynamic_cast< AnimatableProperty* >( entry.GetSceneGraphProperty() ); - DALI_ASSERT_DEBUG( NULL != property ); - - // property is being used in a separate thread; queue a message to set the property - BakeMessage( mUpdateManager.GetEventToUpdate(), *property, value.Get() ); - break; - } - - case Property::VECTOR3: - { - AnimatableProperty* property = dynamic_cast< AnimatableProperty* >( entry.GetSceneGraphProperty() ); - DALI_ASSERT_DEBUG( NULL != property ); - - // property is being used in a separate thread; queue a message to set the property - BakeMessage( mUpdateManager.GetEventToUpdate(), *property, value.Get() ); - break; - } - - case Property::VECTOR4: - { - AnimatableProperty* property = dynamic_cast< AnimatableProperty* >( entry.GetSceneGraphProperty() ); - DALI_ASSERT_DEBUG( NULL != property ); - - // property is being used in a separate thread; queue a message to set the property - BakeMessage( mUpdateManager.GetEventToUpdate(), *property, value.Get() ); - break; - } - - case Property::ROTATION: - { - AnimatableProperty* property = dynamic_cast< AnimatableProperty* >( entry.GetSceneGraphProperty() ); - DALI_ASSERT_DEBUG( NULL != property ); - - // property is being used in a separate thread; queue a message to set the property - BakeMessage( mUpdateManager.GetEventToUpdate(), *property, value.Get() ); - break; - } - - case Property::MATRIX: - { - AnimatableProperty* property = dynamic_cast< AnimatableProperty* >( entry.GetSceneGraphProperty() ); - DALI_ASSERT_DEBUG( NULL != property ); - - // property is being used in a separate thread; queue a message to set the property - BakeMessage( mUpdateManager.GetEventToUpdate(), *property, value.Get() ); - break; - } - - case Property::MATRIX3: - { - AnimatableProperty* property = dynamic_cast< AnimatableProperty* >( entry.GetSceneGraphProperty() ); - DALI_ASSERT_DEBUG( NULL != property ); - - // property is being used in a separate thread; queue a message to set the property - BakeMessage( mUpdateManager.GetEventToUpdate(), *property, value.Get() ); - break; - } - - default: - { - DALI_ASSERT_ALWAYS(false && "Property type enumeration out of bounds"); // should not come here - break; - } - } -} - Property::Value ShaderEffect::GetDefaultProperty(Property::Index /*index*/) const { // none of our properties are readable so return empty diff --git a/dali/internal/event/effects/shader-effect-impl.h b/dali/internal/event/effects/shader-effect-impl.h index e0c2773..a40238b 100644 --- a/dali/internal/event/effects/shader-effect-impl.h +++ b/dali/internal/event/effects/shader-effect-impl.h @@ -228,11 +228,6 @@ public: // Default property extensions from ProxyObject virtual void SetDefaultProperty( Property::Index index, const Property::Value& propertyValue ); /** - * @copydoc Dali::Internal::ProxyObject::SetCustomProperty() - */ - virtual void SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value ); - - /** * @copydoc Dali::Internal::ProxyObject::GetDefaultProperty() */ virtual Property::Value GetDefaultProperty( Property::Index index ) const; diff --git a/dali/internal/event/object/custom-object-internal.cpp b/dali/internal/event/object/custom-object-internal.cpp new file mode 100644 index 0000000..7607f80 --- /dev/null +++ b/dali/internal/event/object/custom-object-internal.cpp @@ -0,0 +1,156 @@ +// +// Copyright (c) 2014 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// CLASS HEADER +#include + +// INTERNAL INCLUDES +#include +#include +#include +#include +#include +#include + +using Dali::Internal::SceneGraph::PropertyOwner; +using Dali::Internal::SceneGraph::PropertyBase; +using Dali::Internal::SceneGraph::UpdateManager; +using Dali::Internal::SceneGraph::AnimatableProperty; + +namespace +{ +const std::string INVALID_PROPERTY_NAME; +} + +namespace Dali +{ + +namespace Internal +{ + +CustomObject* CustomObject::New() +{ + return new CustomObject(); +} + +bool CustomObject::IsSceneObjectRemovable() const +{ + return false; +} + +const SceneGraph::PropertyOwner* CustomObject::GetSceneObject() const +{ + return mUpdateObject; +} + +const PropertyBase* CustomObject::GetSceneObjectAnimatableProperty( Property::Index index ) const +{ + const PropertyBase* property( NULL ); + + CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index ); + + DALI_ASSERT_ALWAYS( GetCustomPropertyLookup().end() != entry && "index is invalid" ); + + property = dynamic_cast( entry->second.GetSceneGraphProperty() ); + + return property; +} + +const PropertyInputImpl* CustomObject::GetSceneObjectInputProperty( Property::Index index ) const +{ + return GetSceneObjectAnimatableProperty( index ); +} + +unsigned int CustomObject::GetDefaultPropertyCount() const +{ + return 0u; +} + +void CustomObject::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const +{ +} + +const std::string& CustomObject::GetDefaultPropertyName( Property::Index index ) const +{ + return INVALID_PROPERTY_NAME; +} + +Property::Index CustomObject::GetDefaultPropertyIndex(const std::string& name) const +{ + return Property::INVALID_INDEX; +} + +bool CustomObject::IsDefaultPropertyWritable(Property::Index index) const +{ + return false; +} + +bool CustomObject::IsDefaultPropertyAnimatable(Property::Index index) const +{ + return false; +} + +Property::Type CustomObject::GetDefaultPropertyType(Property::Index index) const +{ + return Property::NONE; +} + +void CustomObject::SetDefaultProperty( Property::Index index, const Property::Value& property ) +{ + // do nothing +} + +Property::Value CustomObject::GetDefaultProperty(Property::Index index) const +{ + return Property::Value(); +} + +void CustomObject::InstallSceneObjectProperty( PropertyBase& newProperty, const std::string& name, unsigned int index ) +{ + if( NULL != mUpdateObject ) + { + // mUpdateObject is being used in a separate thread; queue a message to add the property + InstallCustomPropertyMessage( Stage::GetCurrent()->GetUpdateInterface(), *mUpdateObject, newProperty ); // Message takes ownership + } +} + +CustomObject::~CustomObject() +{ + // Guard to allow handle destruction after Core has been destroyed + if( Stage::IsInstalled() ) + { + if( NULL != mUpdateObject ) + { + RemoveObjectMessage( Stage::GetCurrent()->GetUpdateManager(), mUpdateObject ); + mUpdateObject = NULL; // object is about to be destroyed + } + } +} + +CustomObject::CustomObject() +{ + PropertyOwner* updateObject = PropertyOwner::New(); + + // Pass ownership to the update-thread + AddObjectMessage( Stage::GetCurrent()->GetUpdateManager(), updateObject ); + + // Keep as const since this should only be modified from update-thread + mUpdateObject = updateObject; +} + +} // namespace Internal + +} // namespace Dali diff --git a/dali/internal/event/object/custom-object-internal.h b/dali/internal/event/object/custom-object-internal.h new file mode 100644 index 0000000..c5a9c07 --- /dev/null +++ b/dali/internal/event/object/custom-object-internal.h @@ -0,0 +1,141 @@ +#ifndef __DALI_INTERNAL_CUSTOM_OBJECT_H__ +#define __DALI_INTERNAL_CUSTOM_OBJECT_H__ + +// +// Copyright (c) 2014 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an AS IS BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// INTERNAL INCLUDES +#include + +namespace Dali +{ + +namespace Internal +{ + +namespace SceneGraph +{ +class PropertyOwner; +} + +class CustomObject : public ProxyObject +{ +public: + + /** + * Create a new custom object. + * @return A pointer to the newly allocated object. + */ + static CustomObject* New(); + + /** + * @copydoc Dali::Internal::ProxyObject::IsSceneObjectRemovable() + */ + virtual bool IsSceneObjectRemovable() const; + + /** + * @copydoc Dali::Internal::ProxyObject::GetSceneObject() + */ + virtual const SceneGraph::PropertyOwner* GetSceneObject() const; + + /** + * @copydoc Dali::Internal::ProxyObject::GetSceneObjectAnimatableProperty() + */ + virtual const SceneGraph::PropertyBase* GetSceneObjectAnimatableProperty( Property::Index index ) const; + + /** + * @copydoc Dali::Internal::ProxyObject::GetSceneObjectInputProperty() + */ + virtual const PropertyInputImpl* GetSceneObjectInputProperty( Property::Index index ) const; + + /** + * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyCount() + */ + virtual unsigned int GetDefaultPropertyCount() const; + + /** + * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyIndices() + */ + virtual void GetDefaultPropertyIndices( Property::IndexContainer& indices ) const; + + /** + * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyName() + */ + virtual const std::string& GetDefaultPropertyName(Property::Index index) const; + + /** + * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyIndex() + */ + virtual Property::Index GetDefaultPropertyIndex(const std::string& name) const; + + /** + * @copydoc Dali::Internal::ProxyObject::IsDefaultPropertyWritable() + */ + virtual bool IsDefaultPropertyWritable(Property::Index index) const; + + /** + * @copydoc Dali::Internal::ProxyObject::IsDefaultPropertyAnimatable() + */ + virtual bool IsDefaultPropertyAnimatable(Property::Index index) const; + + /** + * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyType() + */ + virtual Property::Type GetDefaultPropertyType(Property::Index index) const; + + /** + * @copydoc Dali::Internal::ProxyObject::SetDefaultProperty() + */ + virtual void SetDefaultProperty(Property::Index index, const Property::Value& propertyValue); + + /** + * @copydoc Dali::Internal::ProxyObject::GetDefaultProperty() + */ + virtual Property::Value GetDefaultProperty( Property::Index index ) const; + + /** + * @copydoc Dali::Internal::ProxyObject::InstallSceneObjectProperty() + */ + virtual void InstallSceneObjectProperty( SceneGraph::PropertyBase& newProperty, const std::string& name, unsigned int index ); + +protected: + + /** + * A reference counted object may only be deleted by calling Unreference() + */ + virtual ~CustomObject(); + + /** + * Private constructor; see also CustomObject::New() + */ + CustomObject(); + + // Undefined + CustomObject(const CustomObject&); + + // Undefined + CustomObject& operator=(const CustomObject& rhs); + +protected: + + SceneGraph::PropertyOwner* mUpdateObject; +}; + +} // namespace Internal + +} // namespace Dali + +#endif // __DALI_INTERNAL_CUSTOM_OBJECT_H__ diff --git a/dali/internal/file.list b/dali/internal/file.list index a7748a8..10a2129 100644 --- a/dali/internal/file.list +++ b/dali/internal/file.list @@ -96,6 +96,7 @@ internal_src_files = \ $(internal_src_dir)/event/modeling/model-factory.cpp \ $(internal_src_dir)/event/modeling/model-impl.cpp \ $(internal_src_dir)/event/modeling/model-logger.cpp \ + $(internal_src_dir)/event/object/custom-object-internal.cpp \ $(internal_src_dir)/event/render-tasks/render-task-impl.cpp \ $(internal_src_dir)/event/render-tasks/render-task-list-impl.cpp \ $(internal_src_dir)/event/resources/archive.cpp \ diff --git a/dali/internal/update/common/property-owner.cpp b/dali/internal/update/common/property-owner.cpp index a67e390..d2283e0 100644 --- a/dali/internal/update/common/property-owner.cpp +++ b/dali/internal/update/common/property-owner.cpp @@ -33,6 +33,11 @@ namespace Internal namespace SceneGraph { +PropertyOwner* PropertyOwner::New() +{ + return new PropertyOwner(); +} + PropertyOwner::~PropertyOwner() { DisconnectFromSceneGraph(); diff --git a/dali/internal/update/common/property-owner.h b/dali/internal/update/common/property-owner.h index 9e68bd2..b3dfa12 100644 --- a/dali/internal/update/common/property-owner.h +++ b/dali/internal/update/common/property-owner.h @@ -46,7 +46,7 @@ typedef OwnerContainer< PropertyBase* > OwnedPropertyContainer; typedef OwnedPropertyContainer::Iterator OwnedPropertyIter; /** - * Base for scene-graph objects which own properties. + * An update-thread object which own properties. * This allows observers to track the lifetime of the object & its properties. */ class PropertyOwner @@ -64,6 +64,12 @@ public: }; /** + * Create a property owner. + * @return A newly allocated object. + */ + static PropertyOwner* New(); + + /** * Virtual destructor; this is intended as a base class. */ virtual ~PropertyOwner(); @@ -166,7 +172,7 @@ private: * Called after ResetToBaseValues; derived classes should reset any default properties. * @param[in] currentBufferIndex The buffer to reset. */ - virtual void ResetDefaultProperties( BufferIndex updateBufferIndex ) = 0; + virtual void ResetDefaultProperties( BufferIndex updateBufferIndex ) {} protected: diff --git a/dali/internal/update/manager/update-manager.cpp b/dali/internal/update/manager/update-manager.cpp index 4e8aebc..921030b 100644 --- a/dali/internal/update/manager/update-manager.cpp +++ b/dali/internal/update/manager/update-manager.cpp @@ -265,6 +265,8 @@ struct UpdateManager::Impl SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers + OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties) + AnimationContainer animations; ///< A container of owned animations PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications. @@ -436,6 +438,34 @@ void UpdateManager::AttachToNode( Node* node, NodeAttachment* attachment ) attachment->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() ); } +void UpdateManager::AddObject( PropertyOwner* object ) +{ + DALI_ASSERT_DEBUG( NULL != object ); + + mImpl->customObjects.PushBack( object ); +} + +void UpdateManager::RemoveObject( PropertyOwner* object ) +{ + DALI_ASSERT_DEBUG( NULL != object ); + + OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects; + + // Find the object and destroy it + for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter ) + { + PropertyOwner* current = *iter; + if ( current == object ) + { + customObjects.Erase( iter ); + return; + } + } + + // Should not reach here + DALI_ASSERT_DEBUG(false); +} + void UpdateManager::AddAnimation( Animation* animation ) { mImpl->animations.PushBack( animation ); @@ -743,6 +773,12 @@ void UpdateManager::ResetProperties() (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() ); } + // Reset custom object properties to base values + for (OwnerContainer::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter) + { + (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() ); + } + // Reset animatable shader properties to base values for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter) { @@ -809,6 +845,16 @@ void UpdateManager::ApplyConstraints() mImpl->activeConstraints = 0; + // constrain custom objects... (in construction order) + OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects; + + const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End(); + for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter ) + { + PropertyOwner& object = **iter; + mImpl->activeConstraints += ConstrainPropertyOwner( object, mSceneGraphBuffers.GetUpdateBufferIndex() ); + } + // constrain nodes... (in Depth First traversal order) if ( mImpl->root ) { diff --git a/dali/internal/update/manager/update-manager.h b/dali/internal/update/manager/update-manager.h index c22317a..c8cbaf2 100644 --- a/dali/internal/update/manager/update-manager.h +++ b/dali/internal/update/manager/update-manager.h @@ -211,6 +211,19 @@ public: */ void AttachToNode( Node* node, NodeAttachment* attachment ); + /** + * Add a newly created object. + * @param[in] object The object to add. + * @post The object is owned by UpdateManager. + */ + void AddObject( PropertyOwner* object ); + + /** + * Remove an object. + * @param[in] object The object to remove. + */ + void RemoveObject( PropertyOwner* object ); + // Animations /** @@ -554,6 +567,28 @@ inline void AttachToNodeMessage( UpdateManager& manager, const Node& constParent new (slot) LocalType( &manager, &UpdateManager::AttachToNode, &parent, attachment ); } +inline void AddObjectMessage( UpdateManager& manager, PropertyOwner* object ) +{ + typedef MessageValue1< UpdateManager, OwnerPointer > LocalType; + + // Reserve some memory inside the message queue + unsigned int* slot = manager.GetEventToUpdate().ReserveMessageSlot( sizeof( LocalType ) ); + + // Construct message in the message queue memory; note that delete should not be called on the return value + new (slot) LocalType( &manager, &UpdateManager::AddObject, object ); +} + +inline void RemoveObjectMessage( UpdateManager& manager, PropertyOwner* object ) +{ + typedef MessageValue1< UpdateManager, PropertyOwner* > LocalType; + + // Reserve some memory inside the message queue + unsigned int* slot = manager.GetEventToUpdate().ReserveMessageSlot( sizeof( LocalType ) ); + + // Construct message in the message queue memory; note that delete should not be called on the return value + new (slot) LocalType( &manager, &UpdateManager::RemoveObject, object ); +} + inline void AddAnimationMessage( UpdateManager& manager, Animation* animation ) { typedef MessageValue1< UpdateManager, Animation* > LocalType; diff --git a/dali/public-api/object/constrainable.cpp b/dali/public-api/object/constrainable.cpp index dfd8d11..67f78d2 100644 --- a/dali/public-api/object/constrainable.cpp +++ b/dali/public-api/object/constrainable.cpp @@ -19,10 +19,16 @@ #include #include #include +#include namespace Dali { +Constrainable Constrainable::New() +{ + return Constrainable( Internal::CustomObject::New() ); +} + Constrainable::Constrainable(Dali::Internal::Object* handle) : Handle(handle) { @@ -32,6 +38,11 @@ Constrainable::Constrainable() { } +Constrainable Constrainable::DownCast( BaseHandle handle ) +{ + return Constrainable( dynamic_cast(handle.GetObjectPtr()) ); +} + Constrainable::~Constrainable() { } -- 2.7.4