a689502d888c47ede27c1f718e8fac99c9a1a058
[platform/core/uifw/dali-core.git] / dali / public-api / object / base-handle.h
1 #ifndef DALI_BASE_HANDLE_H
2 #define DALI_BASE_HANDLE_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 // EXTERNAL INCLUDES
22 #include <string>
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/common/dali-common.h>
26 #include <dali/public-api/object/property-types.h>
27 #include <dali/public-api/object/property-value.h>
28 #include <dali/public-api/object/ref-object.h>
29 #include <dali/public-api/signals/functor-delegate.h>
30
31 namespace Dali
32 {
33 /**
34  * @addtogroup dali_core_object
35  * @{
36  */
37
38 class BaseObject;
39 class ConnectionTrackerInterface;
40 class TypeInfo;
41
42 /**
43  * @brief Dali::BaseHandle is a handle to an internal Dali resource.
44  *
45  * Each Dali handle consists of a single private pointer, and a set of non-virtual forwarding functions.
46  * This hides the internal implementation, so it may be modified without affecting the public interface.
47  *
48  * Dali handles have implicit smart-pointer semantics.
49  * This avoids the need to match resource allocation methods like new/delete (the RAII idiom).
50  *
51  * Dali handles can be copied by value.
52  * When a Dali handle is copied, both the copy and original will point to the same Dali resource.
53  *
54  * The internal Dali resources are reference counted. copying a Dali handle will increase the reference count.
55  * A resource will not be deleted until all its Dali::BaseHandle handles are destroyed, or reset.
56  *
57  * @SINCE_1_0.0
58  */
59 class DALI_CORE_API BaseHandle
60 {
61 public:
62
63   /**
64    * @brief This constructor is used by Dali New() methods.
65    *
66    * @SINCE_1_0.0
67    * @param[in] handle A pointer to a newly allocated Dali resource
68    */
69   BaseHandle(Dali::BaseObject* handle);
70
71   /**
72    * @brief This constructor provides an uninitialized Dali::BaseHandle.
73    *
74    * This should be initialized with a Dali New() method before use.
75    * Methods called on an uninitialized Dali::BaseHandle will assert.
76    * @code
77    * BaseHandle handle; // uninitialized
78    * handle.SomeMethod(); // unsafe! This will assert
79    *
80    * handle = SomeClass::New(); // now initialized
81    * handle.SomeMethod(); // safe
82    * @endcode
83    * @SINCE_1_0.0
84    */
85   BaseHandle();
86
87   /**
88    * @brief Dali::BaseHandle is intended as a base class.
89    *
90    * This is non-virtual since derived BaseHandle types must not contain data.
91    * @SINCE_1_0.0
92    */
93   ~BaseHandle();
94
95   /**
96    * @brief This copy constructor is required for (smart) pointer semantics.
97    *
98    * @SINCE_1_0.0
99    * @param[in] handle A reference to the copied handle
100    */
101   BaseHandle(const BaseHandle& handle);
102
103   /**
104    * @brief This assignment operator is required for (smart) pointer semantics.
105    *
106    * It makes this handle use the same BaseObject as the copied handle
107    * @SINCE_1_0.0
108    * @param[in] rhs A reference to the copied handle
109    * @return A reference to this handle
110    */
111   BaseHandle& operator=(const BaseHandle& rhs);
112
113   /**
114    * @brief Move constructor.
115    *
116    * @SINCE_1_9.22
117    * @param[in] rhs A reference to the moved handle
118    */
119   BaseHandle( BaseHandle&& rhs );
120
121   /**
122    * @brief Move assignment operator.
123    *
124    * @SINCE_1_9.22
125    * @param[in] rhs A reference to the moved handle
126    * @return A reference to this handle
127    */
128   BaseHandle& operator=( BaseHandle&& rhs );
129
130   /**
131    * @brief Connects a void() functor to a specified signal.
132    *
133    * @SINCE_1_0.0
134    * @param[in] connectionTracker A connection tracker which can be used to disconnect
135    * @param[in] signalName Name of the signal to connect to
136    * @param[in] functor The functor to copy
137    * @return True if the signal was available
138    * @pre The signal must be available in this object.
139    */
140   template <class T>
141   bool ConnectSignal( ConnectionTrackerInterface* connectionTracker, const std::string& signalName, const T& functor )
142   {
143     return DoConnectSignal( connectionTracker, signalName, FunctorDelegate::New( functor ) );
144   }
145
146   /**
147    * @brief Performs an action on this object with the given action name and attributes.
148    *
149    * Usage example: -
150    * @code
151    * BaseHandle handle = SomeClass::New(); // Initialized with New() method
152    *
153    * Property::Map attributes; // Type is Property Map
154    * handle.DoAction("show", attributes);
155    * @endcode
156    * @SINCE_1_0.0
157    * @param[in] actionName The command for the action
158    * @param[in] attributes The list of attributes for the action
159    * @return The action is performed by the object or not
160    */
161   bool DoAction(const std::string& actionName, const Property::Map& attributes);
162
163   /**
164    * @brief Returns the type name for the Handle.
165    *
166    * Will return an empty string if the typename does not exist. This will happen for types that
167    * have not registered with type-registry.
168    *
169    * @SINCE_1_0.0
170    * @return The type name. Empty string if the typename does not exist
171    */
172   const std::string& GetTypeName() const;
173
174   /**
175    * @brief Returns the type info for the Handle.
176    *
177    * @SINCE_1_0.0
178    * @param[out] info The type information
179    * @return true if the type info exists
180    */
181   bool GetTypeInfo(Dali::TypeInfo& info) const;
182
183 public:
184
185   // BaseHandle accessors
186
187   /**
188    * @brief Retrieves the internal Dali resource.
189    *
190    * This is useful for checking the reference count of the internal resource.
191    * This method will not check the validity of the handle so the caller is expected to check it by using if (handle).
192    * @SINCE_1_0.0
193    * @return The BaseObject which is referenced by the BaseHandle
194    */
195   BaseObject& GetBaseObject();
196
197   /**
198    * @brief Retrieves the internal Dali resource.
199    *
200    * This is useful for checking the reference count of the internal resource.
201    * This method will not check the validity of the handle so the caller is expected to check it by using if (handle).
202    * @SINCE_1_0.0
203    * @return The BaseObject which is referenced by the BaseHandle
204    */
205   const BaseObject& GetBaseObject() const;
206
207   /**
208    * @brief Resets the handle.
209    *
210    * If no other handle copies exist, the internal Dali resource will be deleted.
211    * Calling this is not required i.e. it will happen automatically when a Dali::BaseHandle is destroyed.
212    * @SINCE_1_0.0
213    */
214   void Reset();
215
216   // BaseHandle comparisons - This is a variation of the safe bool idiom
217
218   /**
219    * @brief Pointer-to-member type.
220    * Objects can be implicitly converted to this for validity checks.
221    */
222   typedef void (BaseHandle::*BooleanType)() const;
223
224   /**
225    * @brief Converts an handle to a BooleanType.
226    *
227    * This is useful for checking whether the handle is empty.
228    * @SINCE_1_0.0
229    */
230   operator BooleanType() const;
231
232   /**
233    * @brief Equality operator overload.
234    *
235    * @SINCE_1_0.0
236    * @param[in] rhs A reference to the compared handle
237    * @return True if the handle handles point to the same Dali resource, or if both are NULL
238    */
239   bool operator==(const BaseHandle& rhs) const;
240
241   /**
242    * @brief Inequality operator overload.
243    *
244    * @SINCE_1_0.0
245    * @param[in] rhs A reference to the compared handle
246    * @return True if the handle handles point to the different Dali resources
247    */
248   bool operator!=(const BaseHandle& rhs) const;
249
250   /**
251    * @brief Gets the reference counted object pointer.
252    *
253    * @SINCE_1_0.0
254    * @return A pointer to the reference counted object
255    */
256   Dali::RefObject* GetObjectPtr() const;
257
258 private:
259
260   /**
261    * @brief Not intended for application developers.
262    *
263    * @SINCE_1_0.0
264    * @param[in] connectionTracker A connection tracker which can be used to disconnect
265    * @param[in] signalName Name of the signal to connect to
266    * @param[in] functorDelegate A newly allocated functor delegate (takes ownership)
267    * @return True if the signal was available
268    */
269   bool DoConnectSignal( ConnectionTrackerInterface* connectionTracker, const std::string& signalName, FunctorDelegate* functorDelegate );
270
271 protected:
272
273   /**
274    * @brief Used by the safe bool idiom.
275    *
276    * The safe bool idiom basically provides a Boolean test for classes. It validates objects
277    * in a boolean context without the usual harmful side effects.
278    * @SINCE_1_0.0
279    */
280   void ThisIsSaferThanReturningVoidStar() const {}
281
282 private:
283
284   IntrusivePtr<Dali::RefObject> mObjectHandle; ///< Object this handle points at.
285
286 };
287
288 /**
289  * @brief Template wrapper to downcast a base object handle to derived class handle.
290  *
291  * @SINCE_1_0.0
292  * @param[in] handle Handle to a base object
293  * @return Handle pointer to either a valid deriving handle or an uninitialized handle
294  * @pre The BaseHandle has been initialized.
295  */
296 template< class T >
297 inline T DownCast( BaseHandle handle )
298 {
299   return T::DownCast( handle );
300 }
301
302 // See also BaseHandle::BooleanType() conversion
303
304 /**
305  * @brief Equality operator.
306  * @SINCE_1_0.0
307  * @param[in] lhs A reference to compare
308  * @param[in] rhs A reference to compare to
309  * @return True if the handle handles point to the same Dali resource, or if both are NULL
310  */
311 template <typename T>
312 inline bool operator==(const BaseHandle& lhs, const T& rhs)
313 {
314   // We depart from the safe bool idiom to allow Dali::BaseHandle derived classes to be compared
315   return lhs == static_cast<const BaseHandle&>(rhs);
316 }
317
318 /**
319  * @brief Equality operator.
320  * @SINCE_1_0.0
321  * @param[in] lhs A reference to compare
322  * @param[in] rhs A reference to compare to
323  * @return True if the handle handles point to the different Dali resources
324  */
325 template <typename T>
326 inline bool operator!=(const BaseHandle& lhs, const T& rhs)
327 {
328   // We depart from the safe bool idiom to allow Dali::BaseHandle derived classes to be compared
329   return lhs != static_cast<const BaseHandle&>(rhs);
330 }
331
332 /**
333  * @brief Less than operator.
334  * @SINCE_1_0.0
335  * @param[in] lhs A reference to compare
336  * @param[in] rhs A reference to compare to
337  * @return True if lhs less than rhs
338  */
339 inline bool operator<(const BaseHandle& lhs, const BaseHandle& rhs)
340 {
341   return lhs.GetObjectPtr() < rhs.GetObjectPtr();
342 }
343
344 /**
345  * @}
346  */
347 } // namespace Dali
348
349 #endif // DALI_BASE_HANDLE_H