Added missing newline chars to logging commands
[platform/core/uifw/dali-core.git] / dali / internal / event / common / type-info-impl.cpp
index d10e9cb..479f2e8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
@@ -25,7 +25,7 @@
 // INTERNAL INCLUDES
 #include <dali/integration-api/debug.h>
 #include <dali/internal/event/common/type-registry-impl.h>
-#include <dali/internal/event/common/proxy-object.h>
+#include <dali/internal/event/common/object-impl.h>
 
 using std::find_if;
 
@@ -74,6 +74,29 @@ private:
   const std::string& mFind;
 };
 
+/**
+ * Functor to find a matching property component index
+ */
+template <typename T>
+struct PropertyComponentFinder
+{
+  PropertyComponentFinder( Dali::Property::Index basePropertyIndex, const int find )
+  : mBasePropertyIndex( basePropertyIndex ),
+    mFind( find )
+  {
+  }
+
+  bool operator()(const T &p) const
+  {
+    return ( p.second.basePropertyIndex == mBasePropertyIndex && p.second.componentIndex == mFind );
+  }
+
+private:
+
+  Dali::Property::Index mBasePropertyIndex;
+  const int mFind;
+};
+
 } // namespace anon
 
 namespace Dali
@@ -104,18 +127,18 @@ BaseHandle TypeInfo::CreateInstance() const
     if ( ret )
     {
       BaseObject& handle = ret.GetBaseObject();
-      ProxyObject *proxyObject = dynamic_cast<Internal::ProxyObject*>(&handle);
+      Object *object = dynamic_cast<Internal::Object*>(&handle);
 
-      if ( proxyObject )
+      if ( object )
       {
-        proxyObject->SetTypeInfo( this );
+        object->SetTypeInfo( this );
       }
     }
   }
   return ret;
 }
 
-bool TypeInfo::DoActionTo(BaseObject *object, const std::string &actionName, const std::vector<Property::Value> &properties)
+  bool TypeInfo::DoActionTo(BaseObject *object, const std::string &actionName, const Property::Map &properties)
 {
   bool done = false;
 
@@ -151,8 +174,8 @@ bool TypeInfo::ConnectSignal( BaseObject* object, ConnectionTrackerInterface* co
 {
   bool connected( false );
 
-  ConnectorContainerV2::iterator iter = find_if( mSignalConnectors.begin(), mSignalConnectors.end(),
-                                                 PairFinder<std::string, ConnectionPairV2>(signalName) );
+  ConnectorContainer::iterator iter = find_if( mSignalConnectors.begin(), mSignalConnectors.end(),
+                                                 PairFinder<std::string, ConnectionPair>(signalName) );
 
   if( iter != mSignalConnectors.end() )
   {
@@ -177,67 +200,96 @@ Dali::TypeInfo::CreateFunction TypeInfo::GetCreator() const
   return mCreate;
 }
 
-void TypeInfo::GetActions( Dali::TypeInfo::NameContainer& ret ) const
+size_t TypeInfo::GetActionCount() const
 {
-  for(ActionContainer::const_iterator iter = mActions.begin(); iter != mActions.end(); ++iter)
-  {
-    ret.push_back(iter->first);
-  }
+  size_t count = mActions.size();
 
   Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
   while( base )
   {
-    for(ActionContainer::const_iterator iter = GetImplementation(base).mActions.begin();
-        iter != GetImplementation(base).mActions.end(); ++iter)
-    {
-      ret.push_back(iter->first);
-    }
-
+    count += GetImplementation(base).mActions.size();
     base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
   }
+
+  return count;
 }
 
-void TypeInfo::GetSignals(Dali::TypeInfo::NameContainer& ret) const
+std::string TypeInfo::GetActionName(size_t index) const
 {
-  for(ConnectorContainerV2::const_iterator iter = mSignalConnectors.begin(); iter != mSignalConnectors.end(); ++iter)
+  std::string name;
+
+  if( index < mActions.size() )
   {
-    ret.push_back(iter->first);
+    name = mActions[index].first;
   }
-
-  Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
-  while( base )
+  else
   {
-    for(ConnectorContainerV2::const_iterator iter = GetImplementation(base).mSignalConnectors.begin();
-        iter != GetImplementation(base).mSignalConnectors.end(); ++iter)
+    size_t count = mActions.size();
+
+    Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
+    while( base )
     {
-      ret.push_back(iter->first);
-    }
+      size_t baseCount = GetImplementation(base).mActions.size();
 
-    base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
+      if( index < count + baseCount )
+      {
+        name = GetImplementation(base).mActions[ index - count ].first;
+        break;
+      }
+
+      count += baseCount;
+
+      base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
+    }
   }
+
+  return name;
 }
 
-void TypeInfo::GetProperties( Dali::TypeInfo::NameContainer& ret ) const
+size_t TypeInfo::GetSignalCount() const
 {
-  Property::IndexContainer indices;
+  size_t count = mSignalConnectors.size();
 
-  GetPropertyIndices(indices);
+  Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
+  while( base )
+  {
+    count += GetImplementation(base).mSignalConnectors.size();
+    base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
+  }
 
-  ret.reserve(indices.size());
+  return count;
+}
+
+std::string TypeInfo::GetSignalName(size_t index) const
+{
+  std::string name;
 
-  typedef std::vector< Property::Index > IndexContainer; ///< A vector of property indices
-  for(Property::IndexContainer::iterator iter = indices.begin(); iter != indices.end(); ++iter)
+  if( index < mSignalConnectors.size() )
   {
-    const std::string& name = GetPropertyName( *iter );
-    if(name.size())
-    {
-      ret.push_back( name );
-    }
-    else
+    name = mSignalConnectors[index].first;
+  }
+  else
+  {
+    size_t count = mSignalConnectors.size();
+
+    Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
+    while( base )
     {
-      DALI_LOG_WARNING("Property had no name\n");
+      size_t baseCount = GetImplementation(base).mSignalConnectors.size();
+
+      if( index < count + baseCount )
+      {
+        name = GetImplementation(base).mSignalConnectors[ index - count ].first;
+        break;
+      }
+
+      count += baseCount;
+
+      base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
     }
   }
+
+  return name;
 }
 
 void TypeInfo::GetPropertyIndices( Property::IndexContainer& indices ) const
@@ -251,12 +303,12 @@ void TypeInfo::GetPropertyIndices( Property::IndexContainer& indices ) const
 
   if ( ! mRegisteredProperties.empty() )
   {
-    indices.reserve( indices.size() + mRegisteredProperties.size() );
+    indices.Reserve( indices.Size() + mRegisteredProperties.size() );
 
     const RegisteredPropertyContainer::const_iterator endIter = mRegisteredProperties.end();
     for ( RegisteredPropertyContainer::const_iterator iter = mRegisteredProperties.begin(); iter != endIter; ++iter )
     {
-      indices.push_back( iter->first );
+      indices.PushBack( iter->first );
     }
   }
 }
@@ -277,11 +329,7 @@ const std::string& TypeInfo::GetPropertyName( Property::Index index ) const
     return GetImplementation(base).GetPropertyName( index );
   }
 
-  DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as ProxyObject
-
-  // Property not found, return reference to invalid property string.
-  static const std::string EMPTY_PROPERTY_NAME;
-  return EMPTY_PROPERTY_NAME;
+  DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
 }
 
 void TypeInfo::AddActionFunction( const std::string &actionName, Dali::TypeInfo::ActionFunction function )
@@ -301,12 +349,12 @@ void TypeInfo::AddActionFunction( const std::string &actionName, Dali::TypeInfo:
     }
     else
     {
-      DALI_LOG_WARNING("Action already exists in TypeRegistry Type", actionName.c_str());
+      DALI_LOG_WARNING("Action already exists in TypeRegistry Type\n", actionName.c_str());
     }
   }
 }
 
-void TypeInfo::AddConnectorFunction( const std::string& signalName, Dali::TypeInfo::SignalConnectorFunctionV2 function )
+void TypeInfo::AddConnectorFunction( const std::string& signalName, Dali::TypeInfo::SignalConnectorFunction function )
 {
   if( NULL == function)
   {
@@ -314,16 +362,16 @@ void TypeInfo::AddConnectorFunction( const std::string& signalName, Dali::TypeIn
   }
   else
   {
-    ConnectorContainerV2::iterator iter = find_if( mSignalConnectors.begin(), mSignalConnectors.end(),
-                                                   PairFinder<std::string, ConnectionPairV2>(signalName) );
+    ConnectorContainer::iterator iter = find_if( mSignalConnectors.begin(), mSignalConnectors.end(),
+                                                   PairFinder<std::string, ConnectionPair>(signalName) );
 
     if( iter == mSignalConnectors.end() )
     {
-      mSignalConnectors.push_back( ConnectionPairV2( signalName, function ) );
+      mSignalConnectors.push_back( ConnectionPair( signalName, function ) );
     }
     else
     {
-      DALI_LOG_WARNING("Signal name already exists in TypeRegistry Type for signal connector function", signalName.c_str());
+      DALI_LOG_WARNING("Signal name already exists in TypeRegistry Type for signal connector function\n", signalName.c_str());
     }
   }
 }
@@ -343,7 +391,7 @@ void TypeInfo::AddProperty( const std::string& name, Property::Index index, Prop
 
     if ( iter == mRegisteredProperties.end() )
     {
-      mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, setFunc, getFunc, name ) ) );
+      mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, setFunc, getFunc, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
     }
     else
     {
@@ -352,9 +400,80 @@ void TypeInfo::AddProperty( const std::string& name, Property::Index index, Prop
   }
 }
 
-unsigned int TypeInfo::GetPropertyCount() const
+void TypeInfo::AddAnimatableProperty( const std::string& name, Property::Index index, Property::Type type )
+{
+  RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
+                                                        PairFinder< Property::Index, RegisteredPropertyPair>(index) );
+
+  if ( iter == mRegisteredProperties.end() )
+  {
+    mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, NULL, NULL, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
+  }
+  else
+  {
+    DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
+  }
+}
+
+void TypeInfo::AddAnimatableProperty( const std::string& name, Property::Index index, const Property::Value& defaultValue )
+{
+  RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
+                                                        PairFinder< Property::Index, RegisteredPropertyPair>(index) );
+
+  if ( iter == mRegisteredProperties.end() )
+  {
+    mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( defaultValue.GetType(), NULL, NULL, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
+    mPropertyDefaultValues.push_back( PropertyDefaultValuePair( index, defaultValue ) );
+  }
+  else
+  {
+    DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
+  }
+}
+
+void TypeInfo::AddAnimatablePropertyComponent( const std::string& name, Property::Index index, Property::Index baseIndex, unsigned int componentIndex )
+{
+  Property::Type type = GetPropertyType( baseIndex );
+  DALI_ASSERT_ALWAYS( ( type == Property::VECTOR2 || type == Property::VECTOR3 || type == Property::VECTOR4 ) && "Base property does not support component" );
+
+  bool success = false;
+
+  RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
+                                                        PairFinder< Property::Index, RegisteredPropertyPair>(index) );
+
+  if ( iter == mRegisteredProperties.end() )
+  {
+    iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
+                    PropertyComponentFinder< RegisteredPropertyPair >( baseIndex, componentIndex ) );
+
+    if ( iter == mRegisteredProperties.end() )
+    {
+      mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, NULL, NULL, name, baseIndex, componentIndex ) ) );
+      success = true;
+    }
+  }
+
+  DALI_ASSERT_ALWAYS( success && "Property component already registered" );
+}
+
+void TypeInfo::AddChildProperty( const std::string& name, Property::Index index, Property::Type type )
 {
-  unsigned int count( mRegisteredProperties.size() );
+  RegisteredPropertyContainer::iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
+                                                        PairFinder< Property::Index, RegisteredPropertyPair>(index) );
+
+  if ( iter == mRegisteredChildProperties.end() )
+  {
+    mRegisteredChildProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, NULL, NULL, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
+  }
+  else
+  {
+    DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
+  }
+}
+
+size_t TypeInfo::GetPropertyCount() const
+{
+  size_t count( mRegisteredProperties.size() );
 
   Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
   while ( base )
@@ -391,6 +510,122 @@ Property::Index TypeInfo::GetPropertyIndex( const std::string& name ) const
   return index;
 }
 
+Property::Index TypeInfo::GetBasePropertyIndex( Property::Index index ) const
+{
+  Property::Index basePropertyIndex = Property::INVALID_INDEX;
+
+  RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
+                                                          PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
+
+  if ( iter != mRegisteredProperties.end() )
+  {
+    basePropertyIndex = iter->second.basePropertyIndex;
+  }
+  else
+  {
+    Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
+    if ( base )
+    {
+      basePropertyIndex = GetImplementation(base).GetBasePropertyIndex( index );
+    }
+  }
+
+  return basePropertyIndex;
+}
+
+int TypeInfo::GetComponentIndex( Property::Index index ) const
+{
+  int componentIndex = Property::INVALID_COMPONENT_INDEX;
+
+  RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
+                                                          PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
+
+  if ( iter != mRegisteredProperties.end() )
+  {
+    componentIndex = iter->second.componentIndex;
+  }
+  else
+  {
+    Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
+    if ( base )
+    {
+      componentIndex = GetImplementation(base).GetComponentIndex( index );
+    }
+  }
+
+  return componentIndex;
+}
+
+Property::Index TypeInfo::GetChildPropertyIndex( const std::string& name ) const
+{
+  Property::Index index = Property::INVALID_INDEX;
+
+  // Slow but should not be done that often
+  RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
+                                                          PropertyNameFinder< RegisteredPropertyPair >( name ) );
+
+  if ( iter != mRegisteredChildProperties.end() )
+  {
+    index = iter->first;
+  }
+  else
+  {
+    Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
+    if ( base )
+    {
+      index = GetImplementation(base).GetChildPropertyIndex( name );
+    }
+  }
+
+  return index;
+}
+
+const std::string& TypeInfo::GetChildPropertyName( Property::Index index ) const
+{
+  RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
+                                                          PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
+
+  if ( iter != mRegisteredChildProperties.end() )
+  {
+    return iter->second.name;
+  }
+
+  Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
+  if ( base )
+  {
+    return GetImplementation(base).GetChildPropertyName( index );
+  }
+
+  DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
+}
+
+Property::Type TypeInfo::GetChildPropertyType( Property::Index index ) const
+{
+  Property::Type type( Property::NONE );
+
+  RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
+                                                          PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
+
+  if ( iter != mRegisteredChildProperties.end() )
+  {
+    type = iter->second.type;
+  }
+  else
+  {
+    Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
+    if ( base )
+    {
+      type = GetImplementation(base).GetChildPropertyType( index );
+    }
+    else
+    {
+      DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
+    }
+  }
+
+  return type;
+}
+
 bool TypeInfo::IsPropertyWritable( Property::Index index ) const
 {
   bool writable( false );
@@ -400,7 +635,14 @@ bool TypeInfo::IsPropertyWritable( Property::Index index ) const
 
   if ( iter != mRegisteredProperties.end() )
   {
-    writable = iter->second.setFunc ? true : false;
+    if( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
+    {
+      writable = true; // animatable property is writable
+    }
+    else
+    {
+      writable = iter->second.setFunc ? true : false;
+    }
   }
   else
   {
@@ -411,7 +653,7 @@ bool TypeInfo::IsPropertyWritable( Property::Index index ) const
     }
     else
     {
-      DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as ProxyObject
+      DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
     }
   }
 
@@ -438,21 +680,37 @@ Property::Type TypeInfo::GetPropertyType( Property::Index index ) const
     }
     else
     {
-      DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as ProxyObject
+      DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
     }
   }
 
   return type;
 }
 
+Property::Value TypeInfo::GetPropertyDefaultValue( Property::Index index ) const
+{
+  PropertyDefaultValueContainer::const_iterator iter = find_if( mPropertyDefaultValues.begin(), mPropertyDefaultValues.end(),
+                                                    PairFinder< Property::Index, PropertyDefaultValuePair >( index ) );
+  if( iter !=  mPropertyDefaultValues.end() )
+  {
+    return iter->second;
+  }
+  else
+  {
+    return Property::Value( GetPropertyType( index ) );
+  }
+}
+
 void TypeInfo::SetProperty( BaseObject *object, Property::Index index, const Property::Value& value ) const
 {
   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
                                                               PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
   if ( iter != mRegisteredProperties.end() )
   {
-    DALI_ASSERT_ALWAYS( iter->second.setFunc && "Trying to write to a read-only property" );
-    iter->second.setFunc( object, index, value );
+    if( iter->second.setFunc )
+    {
+      iter->second.setFunc( object, index, value );
+    }
   }
   else
   {
@@ -463,7 +721,7 @@ void TypeInfo::SetProperty( BaseObject *object, Property::Index index, const Pro
     }
     else
     {
-      DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as ProxyObject
+      DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
     }
   }
 }
@@ -507,9 +765,7 @@ Property::Value TypeInfo::GetProperty( const BaseObject *object, Property::Index
     return GetImplementation( base ).GetProperty( object, index );
   }
 
-  DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as ProxyObject
-
-  return Property::Value();
+  DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
 }
 
 Property::Value TypeInfo::GetProperty( const BaseObject *object, const std::string& name ) const
@@ -529,8 +785,6 @@ Property::Value TypeInfo::GetProperty( const BaseObject *object, const std::stri
   }
 
   DALI_ASSERT_ALWAYS( ! "Cannot find property name" );
-
-  return Property::Value();
 }
 
 } // namespace Internal