f80df08fe0379b109eb1a838e3380671df499d98
[platform/core/uifw/dali-core.git] / capi / dali / public-api / object / base-handle.h
1 #ifndef __DALI_BASE_HANDLE_H__
2 #define __DALI_BASE_HANDLE_H__
3
4 /*
5  * Copyright (c) 2014 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 /**
22  * @addtogroup CAPI_DALI_OBJECT_MODULE
23  * @{
24  */
25
26 // EXTERNAL INCLUDES
27 #include <string>
28
29 // INTERNAL INCLUDES
30 #include <dali/public-api/common/dali-common.h>
31 #include <dali/public-api/object/property-types.h>
32 #include <dali/public-api/object/property-value.h>
33 #include <dali/public-api/object/ref-object.h>
34 #include <dali/public-api/signals/functor-delegate.h>
35
36 namespace Dali DALI_IMPORT_API
37 {
38
39 class BaseObject;
40 class ConnectionTrackerInterface;
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  */
58 class BaseHandle
59 {
60 public:
61
62   /**
63    * @brief Used for null pointer assignment below
64    */
65   class NullType
66   {
67     NullType() { }
68   };
69
70   /**
71    * @brief This constructor is used by Dali New() methods.
72    *
73    * @param [in] handle A pointer to a newly allocated Dali resource
74    */
75   BaseHandle(Dali::BaseObject* handle);
76
77   /**
78    * @brief This constructor provides an uninitialized Dali::BaseHandle.
79    *
80    * This should be initialized with a Dali New() method before use.
81    * Methods called on an uninitialized Dali::BaseHandle will assert.
82    * @code
83    * BaseHandle handle; // uninitialized
84    * handle.SomeMethod(); // unsafe! This will assert
85    *
86    * handle = SomeClass::New(); // now initialized
87    * handle.SomeMethod(); // safe
88    * @endcode
89    */
90   BaseHandle();
91
92   /**
93    * @brief Dali::BaseHandle is intended as a base class.
94    */
95   virtual ~BaseHandle();
96
97   /**
98    * @brief This copy constructor is required for (smart) pointer semantics.
99    *
100    * @param [in] handle A reference to the copied handle
101    */
102   BaseHandle(const BaseHandle& handle);
103
104   /**
105    * @brief This assignment operator is required for (smart) pointer semantics.
106    *
107    * It makes this handle use the same BaseObject as the copied handle
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 This method is defined to allow assignment of the NULL value,
115    * and will throw an exception if passed any other value.
116    *
117    * Assigning to NULL is an alias for Reset().
118    * @param [in] rhs  A NULL pointer
119    * @return A reference to this handle
120    */
121   BaseHandle& operator=(NullType* rhs);
122
123   /**
124    * @brief Connects a void() functor to a specified signal.
125    *
126    * @pre The signal must be available in this object.
127    * @param [in] connectionTracker A connection tracker which can be used to disconnect.
128    * @param [in] signalName Name of the signal to connect to.
129    * @param [in] functor The functor to copy.
130    * @return True if the signal was available.
131    */
132   template <class T>
133   bool ConnectSignal( ConnectionTrackerInterface* connectionTracker, const std::string& signalName, const T& functor )
134   {
135     return DoConnectSignal( connectionTracker, signalName, FunctorDelegate::New( functor ) );
136   }
137
138   /**
139    * @brief Perform action on this object with the given action name and attributes.
140    *
141    * @param [in] actionName The command for the action.
142    * @param [in] attributes The list of attributes for the action.
143    * @return The action is performed by the object or not.
144    */
145   bool DoAction(const std::string& actionName, const std::vector<Property::Value>& attributes);
146
147   /**
148    * @brief Returns the type name for the Handle.
149    *
150    * Will return an empty string if the typename does not exist. This will happen for types that
151    * have not registered with type-registry.
152    *
153    * @return The type name. Empty string if the typename does not exist.
154    */
155   const std::string& GetTypeName() const;
156
157 public:
158
159   // BaseHandle accessors
160
161   /**
162    * @brief Retrieve the internal Dali resource.
163    *
164    * This is useful for checking the reference count of the internal resource.
165    * This method will assert, if the Dali::BaseHandle has not been initialized.
166    * @return The BaseObject which is referenced by the BaseHandle.
167    */
168   BaseObject& GetBaseObject();
169
170   /**
171    * @brief Retrieve the internal Dali resource.
172    *
173    * This is useful for checking the reference count of the internal resource.
174    * This method will assert, if the Dali::BaseHandle has not been initialized.
175    * @return The BaseObject which is referenced by the BaseHandle.
176    */
177   const BaseObject& GetBaseObject() const;
178
179   /**
180    * @brief Resets the handle.
181    *
182    * If no other handle copies exist, the internal Dali resouce will be deleted.
183    * Calling this is not required i.e. it will happen automatically when a Dali::BaseHandle is destroyed.
184    */
185   void Reset();
186
187   // BaseHandle comparisons - This is a variation of the safe bool idiom
188
189   /**
190    * @brief Pointer-to-member type.
191    * Objects can be implicitly converted to this for validity checks.
192    */
193   typedef void (BaseHandle::*BooleanType)() const;
194
195   /**
196    * @brief Converts an handle to a BooleanType.
197    *
198    * This is useful for checking whether the handle is empty.
199    */
200   operator BooleanType() const;
201
202   /**
203    * @brief Equality operator overload.
204    *
205    * @param [in] rhs A reference to the compared handle.
206    * @return true if the handle handles point to the same Dali resource, or if both are NULL.
207    */
208   bool operator==(const BaseHandle& rhs) const;
209
210   /**
211    * @brief Inequality operator overload.
212    *
213    * @param [in] rhs A reference to the compared handle.
214    * @return true if the handle handles point to the different Dali resources.
215    */
216   bool operator!=(const BaseHandle& rhs) const;
217
218   /**
219    * @brief Get the reference counted object pointer.
220    *
221    * @return A pointer to the reference counted object.
222    */
223   Dali::RefObject* GetObjectPtr() const;
224
225 private:
226
227   /**
228    * @brief Not intended for application developers.
229    *
230    * @param [in] connectionTracker A connection tracker which can be used to disconnect.
231    * @param [in] signalName Name of the signal to connect to.
232    * @param [in] functorDelegate A newly allocatated functor delegate (takes ownership).
233    * @return True if the signal was available.
234    */
235   bool DoConnectSignal( ConnectionTrackerInterface* connectionTracker, const std::string& signalName, FunctorDelegate* functorDelegate );
236
237   /**
238    * @brief Used by the safe bool idiom.
239    *
240    */
241   void ThisIsSaferThanReturningVoidStar() const {}
242
243 private:
244
245   IntrusivePtr<Dali::RefObject> mObjectHandle; ///< Object this handle points at.
246 };
247
248 /**
249  * @brief Template wrapper to downcast an base object handle to derived class handle.
250  *
251  * @pre The BaseHandle has been initialized.
252  * @param handle to a base object
253  * @return handle pointer to either a valid deriving handle or an uninitialized handle
254  */
255 template< class T >
256 T DownCast( BaseHandle handle )
257 {
258   return T::DownCast( handle );
259 }
260
261 // See also BaseHandle::BooleanType() conversion
262
263 /**
264  * @brief Equality operator
265  */
266 template <typename T>
267 bool operator==(const BaseHandle& lhs, const T& rhs)
268 {
269   // We depart from the safe bool idiom to allow Dali::BaseHandle derived classes to be compared
270   return lhs == static_cast<const BaseHandle&>(rhs);
271 }
272
273 /**
274  * @brief Equality operator
275  */
276 template <typename T>
277 bool operator!=(const BaseHandle& lhs, const T& rhs)
278 {
279   // We depart from the safe bool idiom to allow Dali::BaseHandle derived classes to be compared
280   return lhs != static_cast<const BaseHandle&>(rhs);
281 }
282
283 // More Operators
284
285 /**
286  * @brief Less than operator
287  */
288 bool operator<(const BaseHandle& lhs, const BaseHandle& rhs);
289
290 } // namespace Dali
291
292 /**
293  * @}
294  */
295 #endif // __DALI_BASE_HANDLE_H__