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.
6 <h2 class="pg">Why does Dali::Object use the Handle/Body (Pimpl) pattern?</h2>
9 - Easier memory management
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.
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.
21 <h2 class="pg">What does 'implicit smart-pointer semantics' mean in the case of Dali?</h2>
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.
31 Animation mAnimation; // animation handle
34 void AnimationTest::Initialize ()
36 mAnimation = Animation::New(10.0f); // ref.count will be 1, animation object stays alive when method returns
40 void AnimationTest::SetAnimation (Animation anim)
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
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.
51 // At this point we own a Dali::Actor named "container"
54 // Create an image actor
55 Image img = Image::New(SomeImageFile);
56 Actor actor = ImageActor::New(img);
58 // Add the image actor to a container
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
66 Objects can be implicitly converted to pointer-to-member type for validity checks.
70 // Create a NULL object
72 // At this stage we cannot call any of the objects methods
74 if (!object) // This test is will pass, since the object is NULL
76 object = SomeClass::New();
83 Objects can be compared, this actually checks if the handles point to the same resource or not.
85 void AnimationTest::SetAnimation (Animation anim)
87 if (anim != mAnimation)
89 mAnimation = anim; // ref.count of original animation decremented (if valid), anim's reference count is increased
95 To sum up implicit pointer semantics, Objects can be:
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