2 * Copyright (c) 2014 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/proxy-object.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;
85 TypeInfo::TypeInfo(const std::string &name, const std::string &baseTypeName, Dali::TypeInfo::CreateFunction creator)
86 : mTypeName(name), mBaseTypeName(baseTypeName), mCreate(creator)
88 DALI_ASSERT_ALWAYS(!name.empty() && "Type info construction must have a name");
89 DALI_ASSERT_ALWAYS(!baseTypeName.empty() && "Type info construction must have a base type name");
96 BaseHandle TypeInfo::CreateInstance() const
106 BaseObject& handle = ret.GetBaseObject();
107 ProxyObject *proxyObject = dynamic_cast<Internal::ProxyObject*>(&handle);
111 proxyObject->SetTypeInfo( this );
118 bool TypeInfo::DoActionTo(BaseObject *object, const std::string &actionName, const std::vector<Property::Value> &properties)
122 ActionContainer::iterator iter = find_if(mActions.begin(), mActions.end(), PairFinder<std::string, ActionPair>(actionName));
124 if( iter != mActions.end() )
126 done = (iter->second)(object, actionName, properties);
130 DALI_LOG_WARNING("Type '%s' cannot do action '%s'\n", mTypeName.c_str(), actionName.c_str());
135 Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
138 done = GetImplementation(base).DoActionTo(object, actionName, properties);
143 base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
150 bool TypeInfo::ConnectSignal( BaseObject* object, ConnectionTrackerInterface* connectionTracker, const std::string& signalName, FunctorDelegate* functor )
152 bool connected( false );
154 ConnectorContainerV2::iterator iter = find_if( mSignalConnectors.begin(), mSignalConnectors.end(),
155 PairFinder<std::string, ConnectionPairV2>(signalName) );
157 if( iter != mSignalConnectors.end() )
159 connected = (iter->second)( object, connectionTracker, signalName, functor );
165 const std::string& TypeInfo::GetName() const
170 const std::string& TypeInfo::GetBaseName() const
172 return mBaseTypeName;
175 Dali::TypeInfo::CreateFunction TypeInfo::GetCreator() const
180 void TypeInfo::GetActions( Dali::TypeInfo::NameContainer& ret ) const
182 for(ActionContainer::const_iterator iter = mActions.begin(); iter != mActions.end(); ++iter)
184 ret.push_back(iter->first);
187 Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
190 for(ActionContainer::const_iterator iter = GetImplementation(base).mActions.begin();
191 iter != GetImplementation(base).mActions.end(); ++iter)
193 ret.push_back(iter->first);
196 base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
200 void TypeInfo::GetSignals(Dali::TypeInfo::NameContainer& ret) const
202 for(ConnectorContainerV2::const_iterator iter = mSignalConnectors.begin(); iter != mSignalConnectors.end(); ++iter)
204 ret.push_back(iter->first);
207 Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
210 for(ConnectorContainerV2::const_iterator iter = GetImplementation(base).mSignalConnectors.begin();
211 iter != GetImplementation(base).mSignalConnectors.end(); ++iter)
213 ret.push_back(iter->first);
216 base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
220 void TypeInfo::GetProperties( Dali::TypeInfo::NameContainer& ret ) const
222 Property::IndexContainer indices;
224 GetPropertyIndices(indices);
226 ret.reserve(indices.size());
228 typedef std::vector< Property::Index > IndexContainer; ///< A vector of property indices
229 for(Property::IndexContainer::iterator iter = indices.begin(); iter != indices.end(); ++iter)
231 const std::string& name = GetPropertyName( *iter );
234 ret.push_back( name );
238 DALI_LOG_WARNING("Property had no name\n");
243 void TypeInfo::GetPropertyIndices( Property::IndexContainer& indices ) const
245 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
248 const TypeInfo& baseImpl( GetImplementation( base ) );
249 baseImpl.GetPropertyIndices( indices );
252 if ( ! mRegisteredProperties.empty() )
254 indices.reserve( indices.size() + mRegisteredProperties.size() );
256 const RegisteredPropertyContainer::const_iterator endIter = mRegisteredProperties.end();
257 for ( RegisteredPropertyContainer::const_iterator iter = mRegisteredProperties.begin(); iter != endIter; ++iter )
259 indices.push_back( iter->first );
264 const std::string& TypeInfo::GetPropertyName( Property::Index index ) const
266 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
267 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
269 if ( iter != mRegisteredProperties.end() )
271 return iter->second.name;
274 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
277 return GetImplementation(base).GetPropertyName( index );
280 DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as ProxyObject
282 // Property not found, return reference to invalid property string.
283 static const std::string EMPTY_PROPERTY_NAME;
284 return EMPTY_PROPERTY_NAME;
287 void TypeInfo::AddActionFunction( const std::string &actionName, Dali::TypeInfo::ActionFunction function )
289 if( NULL == function)
291 DALI_LOG_WARNING("Action function is empty\n");
295 ActionContainer::iterator iter = std::find_if(mActions.begin(), mActions.end(),
296 PairFinder<std::string, ActionPair>(actionName));
298 if( iter == mActions.end() )
300 mActions.push_back( ActionPair( actionName, function ) );
304 DALI_LOG_WARNING("Action already exists in TypeRegistry Type", actionName.c_str());
309 void TypeInfo::AddConnectorFunction( const std::string& signalName, Dali::TypeInfo::SignalConnectorFunctionV2 function )
311 if( NULL == function)
313 DALI_LOG_WARNING("Connector function is empty\n");
317 ConnectorContainerV2::iterator iter = find_if( mSignalConnectors.begin(), mSignalConnectors.end(),
318 PairFinder<std::string, ConnectionPairV2>(signalName) );
320 if( iter == mSignalConnectors.end() )
322 mSignalConnectors.push_back( ConnectionPairV2( signalName, function ) );
326 DALI_LOG_WARNING("Signal name already exists in TypeRegistry Type for signal connector function", signalName.c_str());
331 void TypeInfo::AddProperty( const std::string& name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc )
333 // The setter can be empty as a property can be read-only.
335 if ( NULL == getFunc )
337 DALI_ASSERT_ALWAYS( ! "GetProperty Function is empty" );
341 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
342 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
344 if ( iter == mRegisteredProperties.end() )
346 mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, setFunc, getFunc, name ) ) );
350 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
355 unsigned int TypeInfo::GetPropertyCount() const
357 unsigned int count( mRegisteredProperties.size() );
359 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
362 const TypeInfo& baseImpl( GetImplementation(base) );
363 count += baseImpl.mRegisteredProperties.size();
364 base = TypeRegistry::Get()->GetTypeInfo( baseImpl.mBaseTypeName );
370 Property::Index TypeInfo::GetPropertyIndex( const std::string& name ) const
372 Property::Index index = Property::INVALID_INDEX;
374 // Slow but should not be done that often
375 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
376 PropertyNameFinder< RegisteredPropertyPair >( name ) );
378 if ( iter != mRegisteredProperties.end() )
384 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
387 index = GetImplementation(base).GetPropertyIndex( name );
394 bool TypeInfo::IsPropertyWritable( Property::Index index ) const
396 bool writable( false );
398 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
399 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
401 if ( iter != mRegisteredProperties.end() )
403 writable = iter->second.setFunc ? true : false;
407 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
410 writable = GetImplementation(base).IsPropertyWritable( index );
414 DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as ProxyObject
421 Property::Type TypeInfo::GetPropertyType( Property::Index index ) const
423 Property::Type type( Property::NONE );
425 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
426 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
428 if ( iter != mRegisteredProperties.end() )
430 type = iter->second.type;
434 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
437 type = GetImplementation(base).GetPropertyType( index );
441 DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as ProxyObject
448 void TypeInfo::SetProperty( BaseObject *object, Property::Index index, const Property::Value& value ) const
450 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
451 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
452 if ( iter != mRegisteredProperties.end() )
454 DALI_ASSERT_ALWAYS( iter->second.setFunc && "Trying to write to a read-only property" );
455 iter->second.setFunc( object, index, value );
459 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
462 GetImplementation(base).SetProperty( object, index, value );
466 DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as ProxyObject
471 void TypeInfo::SetProperty( BaseObject *object, const std::string& name, const Property::Value& value ) const
473 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
474 PropertyNameFinder< RegisteredPropertyPair >( name ) );
475 if ( iter != mRegisteredProperties.end() )
477 DALI_ASSERT_ALWAYS( iter->second.setFunc && "Trying to write to a read-only property" );
478 iter->second.setFunc( object, iter->first, value );
482 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
485 GetImplementation(base).SetProperty( object, name, value );
489 DALI_ASSERT_ALWAYS( ! "Cannot find property name" );
494 Property::Value TypeInfo::GetProperty( const BaseObject *object, Property::Index index ) const
496 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
497 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
498 if( iter != mRegisteredProperties.end() )
500 // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object
501 return iter->second.getFunc( const_cast< BaseObject* >( object ), index );
504 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
507 return GetImplementation( base ).GetProperty( object, index );
510 DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as ProxyObject
512 return Property::Value();
515 Property::Value TypeInfo::GetProperty( const BaseObject *object, const std::string& name ) const
517 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
518 PropertyNameFinder< RegisteredPropertyPair >( name ) );
519 if( iter != mRegisteredProperties.end() )
521 // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object
522 return iter->second.getFunc( const_cast< BaseObject* >( object ), iter->first );
525 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
528 return GetImplementation( base ).GetProperty( object, name );
531 DALI_ASSERT_ALWAYS( ! "Cannot find property name" );
533 return Property::Value();
536 } // namespace Internal