6bd8a9b6ad559c74c97a2233eedcb0272a42f39a
[platform/core/uifw/dali-toolkit.git] / docs / content / programming-guide / handle-body-idiom.h
1 /*! \page handle-body-idiom Handle – body
2 <h2 class="pg">What is the Handle/Body (Pimpl) pattern?</h2>
3 It is a technique for hiding implementation details in the header file.
4 DALi achieves it by using "handles" in the public API. These handles internally contain a reference counted pointer to the concrete implementation.
5
6 <h2 class="pg">Why does Dali::Object use the Handle/Body (Pimpl) pattern?</h2>
7 It provides:
8 - Better encapsulation
9 - Easier memory management
10
11 \par Better encapsulation
12 Implementation details are hidden, only the required API is visible for the application developer.
13 This way the danger of API/ABI breaks is also reduced since the implementation of a class can change without modifying the public API.
14
15 \par Easier memory management
16 DALi objects have implicit smart-pointer semantics.
17 Each Dali::Object contains a single reference counted object which can be intitialized with the static "New" methods in the DALi API.
18 This means that C++ new/delete operators do not have to be used (or paired) in the user code (RAII idiom).
19 Of course there's no way of stopping users from allocating heap memory, but calls to the new operator can be minimised.
20
21 <h2 class="pg">What does 'implicit smart-pointer semantics' mean in the case of Dali?</h2>
22
23 Since DALi objects are just handles, they can be copied by value. When a DALi object is copied, both the copy and original will point to the same DALi resource.
24 The internal DALi resources are reference counted; copying a DALi object will increase the reference count. A resource will not be deleted until all its Dali::Object handles are destroyed, or reset.
25
26 \code
27 class AnimationTest
28 {
29 ...
30 private:
31   Animation mAnimation; // animation handle
32 }
33
34 void AnimationTest::Initialize ()
35 {
36     mAnimation = Animation::New(10.0f); // ref.count will be 1, animation object stays alive when method returns
37     ...
38 }
39
40 void AnimationTest::SetAnimation (Animation anim)
41 {
42     mAnimation = anim; // ref.count of original animation decreased, 'anim' is referenced instead
43                        // if nobody else had a reference on the initial animation, the object is destroyed
44 }
45 \endcode
46
47 In some cases an internal resource may be referenced by other internal objects.
48 A common example is when an actor is added to a container with Dali::Actor::Add() i.e. the container will reference its child.
49
50 \code
51 // At this point we own a Dali::Actor named "container"
52 // Enter a code block
53 {
54   // Create an image actor
55   Image img = Image::New(SomeImageFile);
56   Actor actor = ImageActor::New(img);
57
58   // Add the image actor to a container
59   container.Add(actor);
60 }
61 // Exit the code block
62 // At this stage the image actor is still alive
63 // We don't keep a Dali::Object handle to the image actor, but it can be retrieved from the container
64 \endcode
65
66 Objects can be implicitly converted to pointer-to-member type for validity checks.
67 \code
68 // Enter a code block
69 {
70   // Create a NULL object
71   Object object;
72   // At this stage we cannot call any of the objects methods
73
74   if (!object) // This test is will pass, since the object is NULL
75   {
76     object = SomeClass::New();
77     ...
78   }
79   ...
80 }
81 \endcode
82
83 Objects can be compared, this actually checks if the handles point to the same resource or not.
84 \code
85 void AnimationTest::SetAnimation (Animation anim)
86 {
87   if (anim != mAnimation)
88   {
89     mAnimation = anim;  // ref.count of original animation decremented (if valid), anim's reference count is increased
90     ...
91   }
92 }
93 \endcode
94
95 To sum up implicit pointer semantics, Objects can be:
96 - compared
97 - passed by value; this increases the reference count
98 - tested as a boolean value
99 - used directly as member data
100 - returned from functions
101
102 */
103