void DALI_TEST_EQUALS( const char* str1, const std::string &str2, const char* location);
/**
+ * Test if a property value type is equal to a trivial type.
+ */
+template<typename Type>
+inline void DALI_TEST_VALUE_EQUALS( Property::Value&& value1, Type value2, float epsilon, const char* location)
+{
+ Property::Value value2b(value2);
+ DALI_TEST_EQUALS(value1, value2b, epsilon, location);
+}
+
+
+/**
* Test whether one unsigned integer value is greater than another.
* Test succeeds if value1 > value2
* @param[in] value1 The first value
*/
#include <iostream>
-
+#include <typeinfo>
#include <stdlib.h>
#include <dali/public-api/dali-core.h>
#include <dali/devel-api/actors/actor-devel.h>
END_TEST;
}
+
int UtcDaliHandleSetPropertyNegative(void)
{
TestApplication application;
}
END_TEST;
}
+
+
+int UtcDaliHandleIndexOperatorByIndexP01(void)
+{
+ TestApplication application;
+ Actor actor = Actor::New();
+
+ actor[Actor::Property::SIZE] = Vector3( 100.0f, 200.0f, 1.0f );
+
+ DALI_TEST_EQUALS( actor.GetProperty<Vector3>(Actor::Property::SIZE), Vector3( 100.0f, 200.0f, 1.0f ), 0.001f, TEST_LOCATION );
+
+
+ actor.SetProperty( Actor::Property::POSITION, Vector3( 10.0f, 20.0f, 0.0f ) );
+
+ Vector3 position = actor[ Actor::Property::POSITION ];
+ DALI_TEST_EQUALS( position, Vector3( 10.0f, 20.0f, 0.0f ), TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliHandleIndexOperatorByIndexP02(void)
+{
+ TestApplication application;
+ Actor actor = Actor::New();
+
+ const Vector4 defaultActorColor(1.0f, 1.0f, 1.0f, 1.0f);
+ actor.SetProperty(Actor::Property::COLOR, defaultActorColor);
+ actor[Actor::Property::COLOR_RED] = 0.5f;
+
+ DALI_TEST_EQUALS( actor.GetProperty<float>(Actor::Property::COLOR_RED), 0.5f, 0.001f, TEST_LOCATION);
+ DALI_TEST_EQUALS( actor.GetProperty<Vector4>(Actor::Property::COLOR), Vector4(0.5f, 1.0f, 1.0f, 1.0f), 0.001f, TEST_LOCATION);
+
+ actor.SetProperty( Actor::Property::POSITION, Vector3( 10.0f, 20.0f, 0.0f ) );
+
+ DALI_TEST_EQUALS( (float)actor[ Actor::Property::POSITION_Z ], 0.0f, 0.001f, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliHandleIndexOperatorByIndexP03(void)
+{
+ TestApplication application;
+ Actor actor = Actor::New();
+
+ const Vector4 defaultActorColor(1.0f, 1.0f, 1.0f, 1.0f);
+ actor.SetProperty(Actor::Property::COLOR, defaultActorColor);
+
+ // Value under test is second to allow compiler to deduce type
+ DALI_TEST_VALUE_EQUALS( actor[Actor::Property::COLOR_RED], 1.0f, 0.001f, TEST_LOCATION);
+
+ actor.SetProperty( Actor::Property::POSITION, Vector3( 10.0f, 20.0f, 0.0f ) );
+
+ DALI_TEST_EQUALS( (float)actor[ Actor::Property::POSITION_Z ], 0.0f, 0.001f, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliHandleIndexOperatorByNameP01(void)
+{
+ TestApplication application;
+ Actor actor = Actor::New();
+
+ actor["size"] = Vector3( 100.0f, 200.0f, 1.0f );
+
+ DALI_TEST_VALUE_EQUALS( actor.GetProperty(Actor::Property::SIZE), Vector3( 100.0f, 200.0f, 1.0f ), 0.001f, TEST_LOCATION );
+
+ actor.SetProperty( Actor::Property::POSITION, Vector3( 10.0f, 20.0f, 0.0f ) );
+ Vector3 position = actor[ "position" ];
+
+ DALI_TEST_EQUALS( position, Vector3( 10.0f, 20.0f, 0.0f ), 0.001f, TEST_LOCATION );
+
+ END_TEST;
+}
+
+
+int UtcDaliHandleIndexOperatorByNameP02(void)
+{
+ TestApplication application;
+ Actor actor = Actor::New();
+
+ const Vector4 defaultActorColor(1.0f, 1.0f, 1.0f, 1.0f);
+ actor.SetProperty(Actor::Property::COLOR, defaultActorColor);
+ actor["colorRed"] = 0.5f;
+
+ DALI_TEST_VALUE_EQUALS( actor.GetProperty(Actor::Property::COLOR_RED), 0.5f, 0.001f, TEST_LOCATION);
+ DALI_TEST_VALUE_EQUALS( actor.GetProperty(Actor::Property::COLOR), Vector4(0.5f, 1.0f, 1.0f, 1.0f), 0.001f, TEST_LOCATION);
+
+ actor.SetProperty( Actor::Property::POSITION, Vector3( 10.0f, 20.0f, 0.0f ) );
+
+ float positionY = actor[ "positionY" ];
+ DALI_TEST_EQUALS( positionY, 20.0f, 0.001f, TEST_LOCATION );
+
+ // Should automatically promote IndirectValue to Property::Value rvalue.
+ DALI_TEST_VALUE_EQUALS( actor["positionZ"], 0.0f, 0.001f, TEST_LOCATION );
+
+ END_TEST;
+}
+
+
+int UtcDaliHandleIndexOperatorNegative02(void)
+{
+ TestApplication application;
+
+ Actor actor;
+ try
+ {
+ Vector3 position = actor[Actor::Property::POSITION];
+ if( position == position )
+ {
+ DALI_TEST_CHECK(false); // Should throw before reaching here.
+ }
+ DALI_TEST_CHECK(false); // Should throw before reaching here.
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // Assert expected
+ }
+
+ END_TEST;
+}
${public_api_src_dir}/math/vector4.cpp
${public_api_src_dir}/object/any.cpp
${public_api_src_dir}/object/base-handle.cpp
- ${public_api_src_dir}/object/handle.cpp
${public_api_src_dir}/object/base-object.cpp
+ ${public_api_src_dir}/object/handle.cpp
+ ${public_api_src_dir}/object/indirect-value.cpp
${public_api_src_dir}/object/object-registry.cpp
${public_api_src_dir}/object/property.cpp
${public_api_src_dir}/object/property-array.cpp
${public_api_src_dir}/object/base-handle.h
${public_api_src_dir}/object/base-object.h
${public_api_src_dir}/object/handle.h
+ ${public_api_src_dir}/object/indirect-value.h
${public_api_src_dir}/object/object-registry.h
${public_api_src_dir}/object/property-array.h
${public_api_src_dir}/object/property-conditions.h
GetImplementation(*this).RemoveConstraints( tag );
}
+IndirectValue Handle::operator[]( Property::Index index )
+{
+ // Will assert on access if handle is empty
+ return IndirectValue(*this, index);
+}
+
+IndirectValue Handle::operator[]( const std::string& name )
+{
+ // Will assert immediately when GetPropertyIndex is called if handle is empty
+ return IndirectValue(*this, GetPropertyIndex(name));
+}
+
namespace WeightObject
{
// INTERNAL INCLUDES
#include <dali/public-api/common/dali-common.h>
#include <dali/public-api/object/base-handle.h>
+#include <dali/public-api/object/indirect-value.h>
#include <dali/public-api/object/property-types.h>
#include <dali/public-api/object/property-value.h>
#include <dali/public-api/object/property-notification-declarations.h>
#include <dali/public-api/object/ref-object.h>
+
namespace Dali
{
/**
* @pre The Object has been initialized.
*/
void RemoveConstraints( uint32_t tag );
+
+ /**
+ * @brief Index operator, using integer lookup.
+ *
+ * Returns an object that can be assigned to or cast from, enabling
+ * the indexed property to be either read or written.
+ *
+ * @param[in] index The index of the property to access.
+ * @return indirect value. Should have shorter scope than the handle
+ */
+ IndirectValue operator[]( Property::Index index );
+
+ /**
+ * @brief Index operator, using name lookup.
+ *
+ * Returns an object that can be assigned to or cast from, enabling
+ * the named property to be either read or written.
+ *
+ * @param[in] name The name of the property to access.
+ * @return indirect value. Should have shorter scope than the handle
+ */
+ IndirectValue operator[]( const std::string& name );
};
/**
--- /dev/null
+/*
+ * Copyright (c) 2020 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 <dali/public-api/object/indirect-value.h>
+#include <dali/public-api/object/handle.h>
+#include <dali/internal/event/common/object-impl.h>
+
+namespace Dali
+{
+
+IndirectValue::IndirectValue( Handle& handle, Property::Index index )
+: mHandle(handle.GetObjectPtr()),
+ mIndex(index),
+ mExtension(nullptr)
+{
+}
+
+void IndirectValue::operator= (Property::Value value)
+{
+ Handle(static_cast<Dali::Internal::Object*>(mHandle.Get())).SetProperty(mIndex, value);
+}
+
+Property::Value IndirectValue::GetProperty()
+{
+ return Handle(static_cast<Dali::Internal::Object*>(mHandle.Get())).GetProperty(mIndex);
+}
+
+IndirectValue& IndirectValue::operator=( IndirectValue&& ) = default;
+
+IndirectValue::IndirectValue( IndirectValue&& ) = default;
+
+
+} // namespace Dali
--- /dev/null
+#ifndef DALI_INDIRECT_VALUE_H
+#define DALI_INDIRECT_VALUE_H
+
+/*
+ * Copyright (c) 2020 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/object/property.h>
+#include <dali/public-api/object/property-value.h>
+#include <dali/public-api/object/ref-object.h>
+
+namespace Dali
+{
+/**
+ * @addtogroup dali_core_object
+ * @{
+ */
+
+class Handle;
+
+
+/**
+ * @brief Dali::IndirectValue is an intermediate object that enables a simpler
+ * syntax for addressing properties.
+ *
+ * @SINCE_1_9.27
+ * object["property"] = value;
+ * float value = object["property"];
+ *
+ * It is not intended to be directly instantiated, instead, any Handle type
+ * will generate a temporary object using the above syntax.
+ */
+class DALI_CORE_API IndirectValue
+{
+public:
+ /**
+ * @brief Assignment operator
+ *
+ * @SINCE_1_9.27
+ * Enables "handle[property] = value" syntax.
+ * @param[in] value The value to assign
+ */
+ void operator=(Property::Value value);
+
+ /**
+ * @brief Explicit cast operator for property value.
+ *
+ * @SINCE_1_9.27
+ * Enables implicit promotion of this to a Property::Value type parameter
+ * @return The property value
+ */
+ operator Property::Value()
+ {
+ return GetProperty();
+ }
+
+ /**
+ * @brief Cast operator
+ *
+ * @SINCE_1_9.27
+ * Enables "value = handle[property]" syntax.
+ * @tparam Type The type of the associated property
+ * @return The associated property cast to the desired type
+ */
+ template <typename Type>
+ inline operator Type()
+ {
+ Property::Value value = GetProperty();
+ return value.Get<Type>();
+ }
+
+private:
+ /// @cond internal
+
+ /**
+ * @brief Move constructor.
+ *
+ * @SINCE_1_9.27
+ * Making this private to prevent construction of auto type or IndirectValue type.
+ * @param[in] rhs The object to move
+ */
+ DALI_INTERNAL IndirectValue( IndirectValue&& rhs );
+
+ /**
+ * @brief Move assignment operator.
+ *
+ * @SINCE_1_9.27
+ * Making this private to prevent assignment to auto type or IndirectValue type.
+ * @param[in] rhs The object to move
+ */
+ DALI_INTERNAL IndirectValue& operator=( IndirectValue&& rhs );
+
+ /**
+ * @brief Accessor for handle property.
+ *
+ * @SINCE_1_9.27
+ * @return The handle's property value
+ * @note Asserts if the handle is empty
+ */
+ Property::Value GetProperty();
+
+ friend class Handle; ///< Only Handle types can construct this object
+
+ /**
+ * @brief Private constructor
+ *
+ * @SINCE_1_9.27
+ * @param[in] handle A reference to the associated handle
+ * @param[in] index The index to the associated property
+ */
+ DALI_INTERNAL IndirectValue( Handle& handle, Property::Index index );
+private:
+ IntrusivePtr<Dali::RefObject> mHandle; ///< A handle to the property owner
+ Property::Index mIndex; ///< Index of the property in the property owner.
+
+ struct Extension; ///< Reserved for future use
+ Extension* mExtension; ///< Reserved for future use
+
+ /// @endcond
+};
+
+/**
+ * @}
+ */
+} // Namespace Dali
+
+#endif // DALI_INDIRECT_VALUE_H