2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/event/common/type-info-impl.h>
22 #include <algorithm> // std::find_if
26 #include <dali/integration-api/debug.h>
27 #include <dali/internal/event/common/type-registry-impl.h>
28 #include <dali/internal/event/common/object-impl.h>
36 * Functor to find by given type for vector of pairs
38 template <typename S, typename T>
41 PairFinder(const S& find)
46 bool operator()(const T& p) const
48 return p.first == mFind;
57 * Functor to find a matching property name
60 struct PropertyNameFinder
62 PropertyNameFinder( const std::string& find )
67 bool operator()(const T &p) const
69 return p.second.name == mFind;
74 const std::string& mFind;
78 * Functor to find a matching property component index
81 struct PropertyComponentFinder
83 PropertyComponentFinder( Dali::Property::Index basePropertyIndex, const int find )
84 : mBasePropertyIndex( basePropertyIndex ),
89 bool operator()(const T &p) const
91 return ( p.second.basePropertyIndex == mBasePropertyIndex && p.second.componentIndex == mFind );
96 Dali::Property::Index mBasePropertyIndex;
108 TypeInfo::TypeInfo(const std::string &name, const std::string &baseTypeName, Dali::TypeInfo::CreateFunction creator)
109 : mTypeName(name), mBaseTypeName(baseTypeName), mCreate(creator)
111 DALI_ASSERT_ALWAYS(!name.empty() && "Type info construction must have a name");
112 DALI_ASSERT_ALWAYS(!baseTypeName.empty() && "Type info construction must have a base type name");
115 TypeInfo::~TypeInfo()
119 BaseHandle TypeInfo::CreateInstance() const
129 BaseObject& handle = ret.GetBaseObject();
130 Object *object = dynamic_cast<Internal::Object*>(&handle);
134 object->SetTypeInfo( this );
141 bool TypeInfo::DoActionTo(BaseObject *object, const std::string &actionName, const Property::Map &properties)
145 ActionContainer::iterator iter = find_if(mActions.begin(), mActions.end(), PairFinder<std::string, ActionPair>(actionName));
147 if( iter != mActions.end() )
149 done = (iter->second)(object, actionName, properties);
153 DALI_LOG_WARNING("Type '%s' cannot do action '%s'\n", mTypeName.c_str(), actionName.c_str());
158 Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
161 done = GetImplementation(base).DoActionTo(object, actionName, properties);
166 base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
173 bool TypeInfo::ConnectSignal( BaseObject* object, ConnectionTrackerInterface* connectionTracker, const std::string& signalName, FunctorDelegate* functor )
175 bool connected( false );
177 ConnectorContainer::iterator iter = find_if( mSignalConnectors.begin(), mSignalConnectors.end(),
178 PairFinder<std::string, ConnectionPair>(signalName) );
180 if( iter != mSignalConnectors.end() )
182 connected = (iter->second)( object, connectionTracker, signalName, functor );
188 const std::string& TypeInfo::GetName() const
193 const std::string& TypeInfo::GetBaseName() const
195 return mBaseTypeName;
198 Dali::TypeInfo::CreateFunction TypeInfo::GetCreator() const
203 size_t TypeInfo::GetActionCount() const
205 size_t count = mActions.size();
207 Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
210 count += GetImplementation(base).mActions.size();
211 base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
217 std::string TypeInfo::GetActionName(size_t index) const
221 if( index < mActions.size() )
223 name = mActions[index].first;
227 size_t count = mActions.size();
229 Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
232 size_t baseCount = GetImplementation(base).mActions.size();
234 if( index < count + baseCount )
236 name = GetImplementation(base).mActions[ index - count ].first;
242 base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
249 size_t TypeInfo::GetSignalCount() const
251 size_t count = mSignalConnectors.size();
253 Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
256 count += GetImplementation(base).mSignalConnectors.size();
257 base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
263 std::string TypeInfo::GetSignalName(size_t index) const
267 if( index < mSignalConnectors.size() )
269 name = mSignalConnectors[index].first;
273 size_t count = mSignalConnectors.size();
275 Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
278 size_t baseCount = GetImplementation(base).mSignalConnectors.size();
280 if( index < count + baseCount )
282 name = GetImplementation(base).mSignalConnectors[ index - count ].first;
288 base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
295 void TypeInfo::GetPropertyIndices( Property::IndexContainer& indices ) const
297 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
300 const TypeInfo& baseImpl( GetImplementation( base ) );
301 baseImpl.GetPropertyIndices( indices );
304 if ( ! mRegisteredProperties.empty() )
306 indices.Reserve( indices.Size() + mRegisteredProperties.size() );
308 const RegisteredPropertyContainer::const_iterator endIter = mRegisteredProperties.end();
309 for ( RegisteredPropertyContainer::const_iterator iter = mRegisteredProperties.begin(); iter != endIter; ++iter )
311 indices.PushBack( iter->first );
316 const std::string& TypeInfo::GetPropertyName( Property::Index index ) const
318 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
319 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
321 if ( iter != mRegisteredProperties.end() )
323 return iter->second.name;
326 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
329 return GetImplementation(base).GetPropertyName( index );
332 DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
335 void TypeInfo::AddActionFunction( const std::string &actionName, Dali::TypeInfo::ActionFunction function )
337 if( NULL == function)
339 DALI_LOG_WARNING("Action function is empty\n");
343 ActionContainer::iterator iter = std::find_if(mActions.begin(), mActions.end(),
344 PairFinder<std::string, ActionPair>(actionName));
346 if( iter == mActions.end() )
348 mActions.push_back( ActionPair( actionName, function ) );
352 DALI_LOG_WARNING("Action already exists in TypeRegistry Type", actionName.c_str());
357 void TypeInfo::AddConnectorFunction( const std::string& signalName, Dali::TypeInfo::SignalConnectorFunction function )
359 if( NULL == function)
361 DALI_LOG_WARNING("Connector function is empty\n");
365 ConnectorContainer::iterator iter = find_if( mSignalConnectors.begin(), mSignalConnectors.end(),
366 PairFinder<std::string, ConnectionPair>(signalName) );
368 if( iter == mSignalConnectors.end() )
370 mSignalConnectors.push_back( ConnectionPair( signalName, function ) );
374 DALI_LOG_WARNING("Signal name already exists in TypeRegistry Type for signal connector function", signalName.c_str());
379 void TypeInfo::AddProperty( const std::string& name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc )
381 // The setter can be empty as a property can be read-only.
383 if ( NULL == getFunc )
385 DALI_ASSERT_ALWAYS( ! "GetProperty Function is empty" );
389 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
390 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
392 if ( iter == mRegisteredProperties.end() )
394 mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, setFunc, getFunc, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
398 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
403 void TypeInfo::AddAnimatableProperty( const std::string& name, Property::Index index, Property::Type type )
405 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
406 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
408 if ( iter == mRegisteredProperties.end() )
410 mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, NULL, NULL, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
414 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
418 void TypeInfo::AddAnimatablePropertyComponent( const std::string& name, Property::Index index, Property::Index baseIndex, unsigned int componentIndex )
420 Property::Type type = GetPropertyType( baseIndex );
421 DALI_ASSERT_ALWAYS( ( type == Property::VECTOR2 || type == Property::VECTOR3 || type == Property::VECTOR4 ) && "Base property does not support component" );
423 bool success = false;
425 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
426 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
428 if ( iter == mRegisteredProperties.end() )
430 iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
431 PropertyComponentFinder< RegisteredPropertyPair >( baseIndex, componentIndex ) );
433 if ( iter == mRegisteredProperties.end() )
435 mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, NULL, NULL, name, baseIndex, componentIndex ) ) );
440 DALI_ASSERT_ALWAYS( success && "Property component already registered" );
443 size_t TypeInfo::GetPropertyCount() const
445 size_t count( mRegisteredProperties.size() );
447 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
450 const TypeInfo& baseImpl( GetImplementation(base) );
451 count += baseImpl.mRegisteredProperties.size();
452 base = TypeRegistry::Get()->GetTypeInfo( baseImpl.mBaseTypeName );
458 Property::Index TypeInfo::GetPropertyIndex( const std::string& name ) const
460 Property::Index index = Property::INVALID_INDEX;
462 // Slow but should not be done that often
463 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
464 PropertyNameFinder< RegisteredPropertyPair >( name ) );
466 if ( iter != mRegisteredProperties.end() )
472 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
475 index = GetImplementation(base).GetPropertyIndex( name );
482 Property::Index TypeInfo::GetBasePropertyIndex( Property::Index index ) const
484 Property::Index basePropertyIndex = Property::INVALID_INDEX;
486 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
487 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
489 if ( iter != mRegisteredProperties.end() )
491 basePropertyIndex = iter->second.basePropertyIndex;
495 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
498 basePropertyIndex = GetImplementation(base).GetBasePropertyIndex( index );
502 return basePropertyIndex;
505 int TypeInfo::GetComponentIndex( Property::Index index ) const
507 int componentIndex = Property::INVALID_COMPONENT_INDEX;
509 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
510 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
512 if ( iter != mRegisteredProperties.end() )
514 componentIndex = iter->second.componentIndex;
518 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
521 componentIndex = GetImplementation(base).GetComponentIndex( index );
525 return componentIndex;
528 bool TypeInfo::IsPropertyWritable( Property::Index index ) const
530 bool writable( false );
532 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
533 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
535 if ( iter != mRegisteredProperties.end() )
537 if( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
539 writable = true; // animatable property is writable
543 writable = iter->second.setFunc ? true : false;
548 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
551 writable = GetImplementation(base).IsPropertyWritable( index );
555 DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
562 Property::Type TypeInfo::GetPropertyType( Property::Index index ) const
564 Property::Type type( Property::NONE );
566 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
567 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
569 if ( iter != mRegisteredProperties.end() )
571 type = iter->second.type;
575 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
578 type = GetImplementation(base).GetPropertyType( index );
582 DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
589 void TypeInfo::SetProperty( BaseObject *object, Property::Index index, const Property::Value& value ) const
591 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
592 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
593 if ( iter != mRegisteredProperties.end() )
595 if( iter->second.setFunc )
597 iter->second.setFunc( object, index, value );
602 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
605 GetImplementation(base).SetProperty( object, index, value );
609 DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
614 void TypeInfo::SetProperty( BaseObject *object, const std::string& name, const Property::Value& value ) const
616 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
617 PropertyNameFinder< RegisteredPropertyPair >( name ) );
618 if ( iter != mRegisteredProperties.end() )
620 DALI_ASSERT_ALWAYS( iter->second.setFunc && "Trying to write to a read-only property" );
621 iter->second.setFunc( object, iter->first, value );
625 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
628 GetImplementation(base).SetProperty( object, name, value );
632 DALI_ASSERT_ALWAYS( ! "Cannot find property name" );
637 Property::Value TypeInfo::GetProperty( const BaseObject *object, Property::Index index ) const
639 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
640 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
641 if( iter != mRegisteredProperties.end() )
643 // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object
644 return iter->second.getFunc( const_cast< BaseObject* >( object ), index );
647 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
650 return GetImplementation( base ).GetProperty( object, index );
653 DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
656 Property::Value TypeInfo::GetProperty( const BaseObject *object, const std::string& name ) const
658 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
659 PropertyNameFinder< RegisteredPropertyPair >( name ) );
660 if( iter != mRegisteredProperties.end() )
662 // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object
663 return iter->second.getFunc( const_cast< BaseObject* >( object ), iter->first );
666 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
669 return GetImplementation( base ).GetProperty( object, name );
672 DALI_ASSERT_ALWAYS( ! "Cannot find property name" );
675 } // namespace Internal