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