2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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.
18 #include <dali/internal/event/common/type-info-impl.h>
21 #include <algorithm> // std::find_if
25 #include <dali/integration-api/debug.h>
26 #include <dali/internal/event/common/type-registry-impl.h>
34 * Functor to find by given type for vector of pairs
36 template <typename S, typename T>
39 PairFinder(const S& find)
44 bool operator()(const T& p) const
46 return p.first == mFind;
55 * Functor to find a matching property name
58 struct PropertyNameFinder
60 PropertyNameFinder( const std::string& find )
65 bool operator()(const T &p) const
67 return p.second.name == mFind;
72 const std::string& mFind;
83 TypeInfo::TypeInfo(const std::string &name, const std::string &baseTypeName, Dali::TypeInfo::CreateFunction creator)
84 : mTypeName(name), mBaseTypeName(baseTypeName), mCreate(creator)
86 DALI_ASSERT_ALWAYS(!name.empty() && "Type info construction must have a name");
87 DALI_ASSERT_ALWAYS(!baseTypeName.empty() && "Type info construction must have a base type name");
94 BaseHandle TypeInfo::CreateInstance()
105 bool TypeInfo::DoActionTo(BaseObject *object, const std::string &actionName, const std::vector<Property::Value> &properties)
109 ActionContainer::iterator iter = find_if(mActions.begin(), mActions.end(), PairFinder<std::string, ActionPair>(actionName));
111 if( iter != mActions.end() )
113 done = (iter->second)(object, actionName, properties);
117 DALI_LOG_WARNING("Type '%s' cannot do action '%s'\n", mTypeName.c_str(), actionName.c_str());
122 Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
125 done = GetImplementation(base).DoActionTo(object, actionName, properties);
130 base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
137 bool TypeInfo::ConnectSignal( BaseObject* object, ConnectionTrackerInterface* connectionTracker, const std::string& signalName, FunctorDelegate* functor )
139 bool connected( false );
141 ConnectorContainerV2::iterator iter = find_if( mSignalConnectors.begin(), mSignalConnectors.end(),
142 PairFinder<std::string, ConnectionPairV2>(signalName) );
144 if( iter != mSignalConnectors.end() )
146 connected = (iter->second)( object, connectionTracker, signalName, functor );
152 const std::string& TypeInfo::GetName()
157 const std::string& TypeInfo::GetBaseName()
159 return mBaseTypeName;
162 Dali::TypeInfo::CreateFunction TypeInfo::GetCreator()
167 Dali::TypeInfo::NameContainer TypeInfo::GetActions()
169 Dali::TypeInfo::NameContainer ret;
171 for(ActionContainer::iterator iter = mActions.begin(); iter != mActions.end(); ++iter)
173 ret.push_back(iter->first);
176 Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
179 for(ActionContainer::iterator iter = GetImplementation(base).mActions.begin();
180 iter != GetImplementation(base).mActions.end(); ++iter)
182 ret.push_back(iter->first);
185 base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
191 Dali::TypeInfo::NameContainer TypeInfo::GetSignals()
193 Dali::TypeInfo::NameContainer ret;
195 for(ConnectorContainerV2::iterator iter = mSignalConnectors.begin(); iter != mSignalConnectors.end(); ++iter)
197 ret.push_back(iter->first);
200 Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
203 for(ConnectorContainerV2::iterator iter = GetImplementation(base).mSignalConnectors.begin();
204 iter != GetImplementation(base).mSignalConnectors.end(); ++iter)
206 ret.push_back(iter->first);
209 base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
215 void TypeInfo::GetPropertyIndices( Property::IndexContainer& indices ) const
217 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
220 const TypeInfo& baseImpl( GetImplementation( base ) );
221 baseImpl.GetPropertyIndices( indices );
224 if ( ! mRegisteredProperties.empty() )
226 indices.reserve( indices.size() + mRegisteredProperties.size() );
228 const RegisteredPropertyContainer::const_iterator endIter = mRegisteredProperties.end();
229 for ( RegisteredPropertyContainer::const_iterator iter = mRegisteredProperties.begin(); iter != endIter; ++iter )
231 indices.push_back( iter->first );
236 const std::string& TypeInfo::GetPropertyName( Property::Index index ) const
238 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
239 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
241 if ( iter != mRegisteredProperties.end() )
243 return iter->second.name;
246 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
249 return GetImplementation(base).GetPropertyName( index );
252 DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as ProxyObject
254 // Property not found, return reference to invalid property string.
255 static const std::string EMPTY_PROPERTY_NAME;
256 return EMPTY_PROPERTY_NAME;
259 void TypeInfo::AddActionFunction( const std::string &actionName, Dali::TypeInfo::ActionFunction function )
261 if( NULL == function)
263 DALI_LOG_WARNING("Action function is empty\n");
267 ActionContainer::iterator iter = std::find_if(mActions.begin(), mActions.end(),
268 PairFinder<std::string, ActionPair>(actionName));
270 if( iter == mActions.end() )
272 mActions.push_back( ActionPair( actionName, function ) );
276 DALI_LOG_WARNING("Action already exists in TypeRegistry Type", actionName.c_str());
281 void TypeInfo::AddConnectorFunction( const std::string& signalName, Dali::TypeInfo::SignalConnectorFunctionV2 function )
283 if( NULL == function)
285 DALI_LOG_WARNING("Connector function is empty\n");
289 ConnectorContainerV2::iterator iter = find_if( mSignalConnectors.begin(), mSignalConnectors.end(),
290 PairFinder<std::string, ConnectionPairV2>(signalName) );
292 if( iter == mSignalConnectors.end() )
294 mSignalConnectors.push_back( ConnectionPairV2( signalName, function ) );
298 DALI_LOG_WARNING("Signal name already exists in TypeRegistry Type for signal connector function", signalName.c_str());
303 void TypeInfo::AddProperty( const std::string& name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc )
305 // The setter can be empty as a property can be read-only.
307 if ( NULL == getFunc )
309 DALI_ASSERT_ALWAYS( ! "GetProperty Function is empty" );
313 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
314 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
316 if ( iter == mRegisteredProperties.end() )
318 mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, setFunc, getFunc, name ) ) );
322 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
327 unsigned int TypeInfo::GetPropertyCount() const
329 unsigned int count( mRegisteredProperties.size() );
331 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
334 const TypeInfo& baseImpl( GetImplementation(base) );
335 count += baseImpl.mRegisteredProperties.size();
336 base = TypeRegistry::Get()->GetTypeInfo( baseImpl.mBaseTypeName );
342 Property::Index TypeInfo::GetPropertyIndex( const std::string& name ) const
344 Property::Index index = Property::INVALID_INDEX;
346 // Slow but should not be done that often
347 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
348 PropertyNameFinder< RegisteredPropertyPair >( name ) );
350 if ( iter != mRegisteredProperties.end() )
356 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
359 index = GetImplementation(base).GetPropertyIndex( name );
366 bool TypeInfo::IsPropertyWritable( Property::Index index ) const
368 bool writable( false );
370 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
371 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
373 if ( iter != mRegisteredProperties.end() )
375 writable = iter->second.setFunc ? true : false;
379 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
382 writable = GetImplementation(base).IsPropertyWritable( index );
386 DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as ProxyObject
393 Property::Type TypeInfo::GetPropertyType( Property::Index index ) const
395 Property::Type type( Property::NONE );
397 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
398 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
400 if ( iter != mRegisteredProperties.end() )
402 type = iter->second.type;
406 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
409 type = GetImplementation(base).GetPropertyType( index );
413 DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as ProxyObject
420 void TypeInfo::SetProperty( BaseObject *object, Property::Index index, const Property::Value& value )
422 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
423 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
424 if ( iter != mRegisteredProperties.end() )
426 DALI_ASSERT_ALWAYS( iter->second.setFunc && "Trying to write to a read-only property" );
427 iter->second.setFunc( object, index, value );
431 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
434 GetImplementation(base).SetProperty( object, index, value );
438 DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as ProxyObject
443 void TypeInfo::SetProperty( BaseObject *object, const std::string& name, const Property::Value& value )
445 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
446 PropertyNameFinder< RegisteredPropertyPair >( name ) );
447 if ( iter != mRegisteredProperties.end() )
449 DALI_ASSERT_ALWAYS( iter->second.setFunc && "Trying to write to a read-only property" );
450 iter->second.setFunc( object, iter->first, value );
454 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
457 GetImplementation(base).SetProperty( object, name, value );
461 DALI_ASSERT_ALWAYS( ! "Cannot find property name" );
466 Property::Value TypeInfo::GetProperty( const BaseObject *object, Property::Index index )
468 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
469 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
470 if( iter != mRegisteredProperties.end() )
472 // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object
473 return iter->second.getFunc( const_cast< BaseObject* >( object ), index );
476 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
479 return GetImplementation( base ).GetProperty( object, index );
482 DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as ProxyObject
484 return Property::Value();
487 Property::Value TypeInfo::GetProperty( const BaseObject *object, const std::string& name )
489 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
490 PropertyNameFinder< RegisteredPropertyPair >( name ) );
491 if( iter != mRegisteredProperties.end() )
493 // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object
494 return iter->second.getFunc( const_cast< BaseObject* >( object ), iter->first );
497 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
500 return GetImplementation( base ).GetProperty( object, name );
503 DALI_ASSERT_ALWAYS( ! "Cannot find property name" );
505 return Property::Value();
508 } // namespace Internal