Merge "Remove handle::operator=(NULL) as it is duplicating handle.Reset() functionali...
[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) 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 // 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 class BaseObject;
35 class ConnectionTrackerInterface;
36 class TypeInfo;
37
38 /**
39  * @brief Dali::BaseHandle is a handle to an internal Dali resource.
40  *
41  * Each Dali handle consists of a single private pointer, and a set of non-virtual forwarding functions.
42  * This hides the internal implementation, so it may be modified without affecting the public interface.
43  *
44  * Dali handles have implicit smart-pointer semantics.
45  * This avoids the need to match resource allocation methods like new/delete (the RAII idiom).
46  *
47  * Dali handles can be copied by value.
48  * When a Dali handle is copied, both the copy and original will point to the same Dali resource.
49  *
50  * The internal Dali resources are reference counted. copying a Dali handle will increase the reference count.
51  * A resource will not be deleted until all its Dali::BaseHandle handles are destroyed, or reset.
52  *
53  */
54 class DALI_IMPORT_API BaseHandle
55 {
56 public:
57
58   /**
59    * @brief This constructor is used by Dali New() methods.
60    *
61    * @param [in] handle A pointer to a newly allocated Dali resource
62    */
63   BaseHandle(Dali::BaseObject* handle);
64
65   /**
66    * @brief This constructor provides an uninitialized Dali::BaseHandle.
67    *
68    * This should be initialized with a Dali New() method before use.
69    * Methods called on an uninitialized Dali::BaseHandle will assert.
70    * @code
71    * BaseHandle handle; // uninitialized
72    * handle.SomeMethod(); // unsafe! This will assert
73    *
74    * handle = SomeClass::New(); // now initialized
75    * handle.SomeMethod(); // safe
76    * @endcode
77    */
78   BaseHandle();
79
80   /**
81    * @brief Dali::BaseHandle is intended as a base class
82    *
83    * This is non-virtual since derived BaseHandle types must not contain data.
84    */
85   ~BaseHandle();
86
87   /**
88    * @brief This copy constructor is required for (smart) pointer semantics.
89    *
90    * @param [in] handle A reference to the copied handle
91    */
92   BaseHandle(const BaseHandle& handle);
93
94   /**
95    * @brief This assignment operator is required for (smart) pointer semantics.
96    *
97    * It makes this handle use the same BaseObject as the copied handle
98    * @param [in] rhs  A reference to the copied handle
99    * @return A reference to this handle
100    */
101   BaseHandle& operator=(const BaseHandle& rhs);
102
103   /**
104    * @brief Connects a void() functor to a specified signal.
105    *
106    * @pre The signal must be available in this object.
107    * @param [in] connectionTracker A connection tracker which can be used to disconnect.
108    * @param [in] signalName Name of the signal to connect to.
109    * @param [in] functor The functor to copy.
110    * @return True if the signal was available.
111    */
112   template <class T>
113   bool ConnectSignal( ConnectionTrackerInterface* connectionTracker, const std::string& signalName, const T& functor )
114   {
115     return DoConnectSignal( connectionTracker, signalName, FunctorDelegate::New( functor ) );
116   }
117
118   /**
119    * @brief Perform action on this object with the given action name and attributes.
120    *
121    * @param [in] actionName The command for the action.
122    * @param [in] attributes The list of attributes for the action.
123    * @return The action is performed by the object or not.
124    */
125   bool DoAction(const std::string& actionName, const std::vector<Property::Value>& attributes);
126
127   /**
128    * @brief Returns the type name for the Handle.
129    *
130    * Will return an empty string if the typename does not exist. This will happen for types that
131    * have not registered with type-registry.
132    *
133    * @return The type name. Empty string if the typename does not exist.
134    */
135   const std::string& GetTypeName() const;
136
137   /**
138    * @brief Returns the type info for the Handle.
139    *
140    * @return The type info.
141    */
142   bool GetTypeInfo(Dali::TypeInfo& info) const;
143
144 public:
145
146   // BaseHandle accessors
147
148   /**
149    * @brief Retrieve the internal Dali resource.
150    *
151    * This is useful for checking the reference count of the internal resource.
152    * This method will assert, if the Dali::BaseHandle has not been initialized.
153    * @return The BaseObject which is referenced by the BaseHandle.
154    */
155   BaseObject& GetBaseObject();
156
157   /**
158    * @brief Retrieve the internal Dali resource.
159    *
160    * This is useful for checking the reference count of the internal resource.
161    * This method will assert, if the Dali::BaseHandle has not been initialized.
162    * @return The BaseObject which is referenced by the BaseHandle.
163    */
164   const BaseObject& GetBaseObject() const;
165
166   /**
167    * @brief Resets the handle.
168    *
169    * If no other handle copies exist, the internal Dali resouce will be deleted.
170    * Calling this is not required i.e. it will happen automatically when a Dali::BaseHandle is destroyed.
171    */
172   void Reset();
173
174   // BaseHandle comparisons - This is a variation of the safe bool idiom
175
176   /**
177    * @brief Pointer-to-member type.
178    * Objects can be implicitly converted to this for validity checks.
179    */
180   typedef void (BaseHandle::*BooleanType)() const;
181
182   /**
183    * @brief Converts an handle to a BooleanType.
184    *
185    * This is useful for checking whether the handle is empty.
186    */
187   operator BooleanType() const;
188
189   /**
190    * @brief Equality operator overload.
191    *
192    * @param [in] rhs A reference to the compared handle.
193    * @return true if the handle handles point to the same Dali resource, or if both are NULL.
194    */
195   bool operator==(const BaseHandle& rhs) const;
196
197   /**
198    * @brief Inequality operator overload.
199    *
200    * @param [in] rhs A reference to the compared handle.
201    * @return true if the handle handles point to the different Dali resources.
202    */
203   bool operator!=(const BaseHandle& rhs) const;
204
205   /**
206    * @brief Get the reference counted object pointer.
207    *
208    * @return A pointer to the reference counted object.
209    */
210   Dali::RefObject* GetObjectPtr() const;
211
212 private:
213
214   /**
215    * @brief Not intended for application developers.
216    *
217    * @param [in] connectionTracker A connection tracker which can be used to disconnect.
218    * @param [in] signalName Name of the signal to connect to.
219    * @param [in] functorDelegate A newly allocatated functor delegate (takes ownership).
220    * @return True if the signal was available.
221    */
222   bool DoConnectSignal( ConnectionTrackerInterface* connectionTracker, const std::string& signalName, FunctorDelegate* functorDelegate );
223
224   /**
225    * @brief Used by the safe bool idiom.
226    *
227    */
228   void ThisIsSaferThanReturningVoidStar() const {}
229
230 private:
231
232   IntrusivePtr<Dali::RefObject> mObjectHandle; ///< Object this handle points at.
233
234 };
235
236 /**
237  * @brief Template wrapper to downcast an base object handle to derived class handle.
238  *
239  * @pre The BaseHandle has been initialized.
240  * @param handle to a base object
241  * @return handle pointer to either a valid deriving handle or an uninitialized handle
242  */
243 template< class T >
244 inline T DownCast( BaseHandle handle )
245 {
246   return T::DownCast( handle );
247 }
248
249 // See also BaseHandle::BooleanType() conversion
250
251 /**
252  * @brief Equality operator
253  */
254 template <typename T>
255 inline bool operator==(const BaseHandle& lhs, const T& rhs)
256 {
257   // We depart from the safe bool idiom to allow Dali::BaseHandle derived classes to be compared
258   return lhs == static_cast<const BaseHandle&>(rhs);
259 }
260
261 /**
262  * @brief Equality operator
263  */
264 template <typename T>
265 inline bool operator!=(const BaseHandle& lhs, const T& rhs)
266 {
267   // We depart from the safe bool idiom to allow Dali::BaseHandle derived classes to be compared
268   return lhs != static_cast<const BaseHandle&>(rhs);
269 }
270
271 /**
272  * @brief Less than operator
273  */
274 inline bool operator<(const BaseHandle& lhs, const BaseHandle& rhs)
275 {
276   return lhs.GetObjectPtr() < rhs.GetObjectPtr();
277 }
278
279 } // namespace Dali
280
281 #endif // __DALI_BASE_HANDLE_H__