use modern construct 'nullptr' instead of 'NULL' or '0'
[platform/core/uifw/dali-core.git] / dali / devel-api / scripting / scripting.h
1 #ifndef DALI_SCRIPTING_H
2 #define DALI_SCRIPTING_H
3
4 /*
5  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/actors/actor-enumerations.h>
23 #include <dali/public-api/actors/draw-mode.h>
24 #include <dali/devel-api/animation/animation-data.h>
25 #include <dali/public-api/object/property-array.h>
26 #include <dali/public-api/object/property-map.h>
27 #include <dali/public-api/object/property-value.h>
28
29 namespace Dali
30 {
31
32 class Actor;
33
34 /**
35  * @brief Utilities for scripting support.
36  */
37 namespace Scripting
38 {
39
40 /**
41  * @brief Structure which stores an enumeration and its string equivalent.
42  */
43 struct StringEnum
44 {
45   const char* string;  ///< The string representation
46   const int32_t value; ///< The enumeration value wrapped in int
47 };
48
49 /**
50  * @brief Find the given enum index from the table
51  *
52  * @param[in]  value       The string equivalent (case-insensitive).
53  * @param[in]  table       A pointer to an array with the enumeration to string equivalents.
54  * @param[in]  tableCount  Number of items in the array.
55  * @return     The index of the enumeration. If enumeration is not found, logs an error and returns tableCount.
56  */
57 DALI_CORE_API uint32_t FindEnumIndex( const char* value, const StringEnum* table, uint32_t tableCount );
58
59 /**
60  * @brief Find the enum as an integer from the table
61  *
62  * @SINCE_1_1.12
63  *
64  * @param[in]  value       The string equivalent (case-insensitive, comma separate to OR values).
65  * @param[in]  table       A pointer to an array with the enumeration to string equivalents.
66  * @param[in]  tableCount  Number of items in the array.
67  * @param[out] integerEnum The value of the enum.
68  * @return     true if one or more enums in value.
69  */
70 DALI_CORE_API bool EnumStringToInteger( const char* const value, const StringEnum* const table, uint32_t tableCount, int& integerEnum );
71
72 /**
73  * @brief Chooses the appropriate enumeration for the provided string from the given table.
74  *
75  * @param[in]  value       The string equivalent (case-insensitive, comma separate to OR values).
76  * @param[in]  table       A pointer to an array with the enumeration to string equivalents.
77  * @param[in]  tableCount  Number of items in the array.
78  * @param[out] result      The enum value
79  *
80  * @return     True if the value was found from the table
81  */
82 template< typename T >
83 bool GetEnumeration( const char* value, const StringEnum* table, uint32_t tableCount, T& result )
84 {
85   bool retVal( false );
86   if( table )
87   {
88     int integerEnum = 0;
89     // check to avoid crash, not asserting on purpose, error is logged instead
90     if( EnumStringToInteger( value, table, tableCount, integerEnum ) )
91     {
92       result = static_cast<T>( integerEnum );
93       retVal = true;
94     }
95   }
96   return retVal;
97 }
98
99 /**
100  * @brief Gets the enumeration value from an enumeration property.
101  * An enumeration property is a property that can be set with either an INTEGER or STRING.
102  *
103  * @param[in]  propertyValue The property containing the int or string value.
104  * @param[in]  table       A pointer to an array with the enumeration to string equivalents.
105  * @param[in]  tableCount  Number of items in the array.
106  * @param[out] result      The enum value. This is not modified if the enumeration could not be converted.
107  * @return     True if the value was found successfully AND the value has changed. This is to allow the caller to do nothing if there is no change.
108  */
109 template< typename T >
110 bool GetEnumerationProperty( const Property::Value& propertyValue, const StringEnum* table, uint32_t tableCount, T& result )
111 {
112   int newValue;
113   bool set = false;
114   Property::Type type = propertyValue.GetType();
115
116   if( type == Property::INTEGER )
117   {
118     // Attempt to fetch the property as an INTEGER type.
119     if( propertyValue.Get( newValue ) )
120     {
121       // Success.
122       set = true;
123     }
124   }
125   else if( type == Property::STRING )
126   {
127     // Attempt to fetch the property as an STRING type, and convert it from string to enumeration value.
128     std::string propertyString;
129     if( table && propertyValue.Get( propertyString ) && EnumStringToInteger( propertyString.c_str(), table, tableCount, newValue ) )
130     {
131       // Success.
132       set = true;
133     }
134   }
135
136   // If the property was converted OK, AND the value has changed, update the result and return true.
137   if( set && ( result != static_cast<T>( newValue ) ) )
138   {
139     result = static_cast<T>( newValue );
140     return true;
141   }
142
143   // No change.
144   return false;
145 }
146
147 /**
148  * @brief Gets the enumeration value from a bitmask enumeration property.
149  * An enumeration property is a property that can be set with either an INTEGER, STRING or an ARRAY of STRING.
150  *
151  * @param[in]  propertyValue The property containing the int, string or and array of string values.
152  * @param[in]  table       A pointer to an array with the enumeration to string equivalents.
153  * @param[in]  tableCount  Number of items in the array.
154  * @param[out] result      The enum value. This is not modified if the enumeration could not be converted.
155  * @return     True if the value was found successfully AND the value has changed. This is to allow the caller to do nothing if there is no change.
156  */
157 template< typename T >
158 bool GetBitmaskEnumerationProperty( const Property::Value& propertyValue, const Scripting::StringEnum* table, uint32_t tableCount, T& result )
159 {
160   bool returnValue = true;
161
162   // Evaluate as a single INTEGER or STRING first.
163   if( !GetEnumerationProperty( propertyValue, table, tableCount, result ) )
164   {
165     // If not, then check if it's an ARRAY
166     if ( propertyValue.GetType() == Property::ARRAY )
167     {
168       int newValue = 0;
169       Property::Array array;
170       propertyValue.Get( array );
171       for( Property::Array::SizeType i = 0; i < array.Count(); ++i )
172       {
173         Property::Value currentValue = array[ i ];
174         // Use an initial value of -1 so any successful property conversion
175         // causes a change (and true to be returned).
176         T current = static_cast< T >( -1 );
177         if( GetEnumerationProperty( currentValue, table, tableCount, current ) )
178         {
179           newValue |= current;
180         }
181         else
182         {
183           // We hit an invalid type.
184           returnValue = false;
185           break;
186         }
187       }
188
189       // If we didn't hit an invalid type and the value has changed, update the result.
190       if( returnValue && ( result != static_cast<T>( newValue ) ) )
191       {
192         result = static_cast<T>( newValue );
193       }
194     }
195     else
196     {
197       // Property type was not ARRAY, and the single property evaluation also failed.
198       returnValue = false;
199     }
200   }
201
202   return returnValue;
203 }
204
205 /**
206  * @brief Chooses the appropriate string for the provided enumeration from the given table.
207  *
208  * @param[in]  value       The enumeration.
209  * @param[in]  table       A pointer to an array with the enumeration to string equivalents.
210  * @param[in]  tableCount  Number of items in the array.
211  *
212  * @return     The equivalent enumeration for the given string. Will return NULL if the value does not exist
213  *
214  * @note The caller is NOT responsible for cleaning up the returned pointer as it is statically allocated.
215  */
216 template< typename T >
217 const char* GetEnumerationName( T value, const StringEnum* table, uint32_t tableCount )
218 {
219   if( table )
220   {
221     for ( uint32_t i = 0; i < tableCount; ++i )
222     {
223       if ( value == T(table[ i ].value) )
224       {
225         return table[ i ].string;
226       }
227     }
228   }
229   return nullptr;
230 }
231
232 /**
233  * @brief Chooses the appropriate string for the provided enumeration from the given table.
234  * This is an optimised version that handles enumerations that start at 0 and are linear only.
235  *
236  * @param[in]  value       The enumeration.
237  * @param[in]  table       A pointer to an array with the enumeration to string equivalents.
238  * @param[in]  tableCount  Number of items in the array.
239  *
240  * @return     The equivalent enumeration for the given string. Will return NULL if the value does not exist
241  *
242  * @note The caller is NOT responsible for cleaning up the returned pointer as it is statically allocated.
243  */
244 template< typename T >
245 const char * GetLinearEnumerationName( T value, const StringEnum* table, uint32_t tableCount )
246 {
247   if ( table && ( value > 0 || value <= static_cast<int>( tableCount ) ) )
248   {
249     return table[value].string;
250   }
251   return nullptr;
252 }
253
254 /**
255  * @brief Creates an actor with the date from the property value map.
256  *
257  * @param[in] map The property value map with the properties (and hierarchy) of the actor required
258  *                 For example:
259  * @code
260  * {
261  *   "type": "Actor",
262  *   "position": [ 100, 100, 0 ],
263  *   "actors":
264  *   [
265  *     {
266  *       "type":"Actor",
267  *       "position":[0,0,0]
268  *     }
269  *   ]
270  * }
271  * @endcode
272  *
273  * @return A handle to the newly created actor.
274  */
275 DALI_CORE_API Actor NewActor( const Property::Map& map );
276
277 /**
278  * @brief Creates a Property::Map from the actor provided.
279  *
280  * @param[in]  actor The base-actor from which a Property::Map should be created
281  * @param[out] map This map is cleared and a property map of actor and its children is filled in
282  */
283 DALI_CORE_API void CreatePropertyMap( Actor actor, Property::Map& map );
284
285 /**
286  * @brief Creates description data required to create an Animation object from a property map.
287  *
288  * @param[in]  map The property value map containing the animation description
289  * @param[out] outputAnimationData Resultant data retrieved from the property map is written here
290  */
291 DALI_CORE_API void NewAnimation( const Property::Map& map, Dali::AnimationData& outputAnimationData );
292
293 } // namespace Scripting
294
295 } // namespace Dali
296
297 #endif // DALI_SCRIPTING_H