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