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