summaryrefslogtreecommitdiff
path: root/Source/++DFB/README
blob: b7ba5b0ba7aa385597075aaba87dd887eb63a31e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
++DFB is an advanced version of DFB++

It's an incompatible fork with fundamental changes.

Applications no longer deal with interface pointers. The classes
wrapping around interfaces are used a container for an interface
pointer, providing garbage collection the "direct" way 8-)

By overwriting certain operators, e.g. '=', the need to care
about AddRef() and Release() has been eliminated. These methods
aren't even available anymore.

All interfaces are released automatically now, either caused by
finalization of an object having interface members, or by leaving
a stack frame with an interface hold in a local variable.

This also eliminates duplication of code caused by the lack of
a C++ equivalent to Java's "finally" block.

The following code is using DFB++:

void DFBImage::Load( std::string filename )
{
	IDirectFB              *dfb      = NULL;
	IDirectFBImageProvider *provider = NULL;
	IDirectFBSurface       *surface  = NULL;

	try {
		DFBSurfaceDescription desc;

		dfb = DirectFB::Create();

		provider = dfb->CreateImageProvider( filename.data() );

		provider->GetSurfaceDescription( &desc );

		surface = dfb->CreateSurface( desc );

		provider->RenderTo( surface, NULL );
	}
	/* Work around missing "finally". */
	catch (...) {
		if (surface)
			surface->Release();

		if (provider)
			provider->Release();

		if (dfb)
			dfb->Release();

		throw;
	}

	m_surface = surface;	/* Keep pointer to interface object. */

	provider->Release();
	dfb->Release();
}

This is how it's looking using ++DFB:

void DFBImage::Load( std::string filename )
{
	IDirectFB              dfb;
	IDirectFBImageProvider provider;
	IDirectFBSurface       surface;
	DFBSurfaceDescription  desc;

	dfb = DirectFB::Create();

	provider = dfb.CreateImageProvider( filename.data() );

	provider.GetSurfaceDescription( &desc );

	surface = dfb.CreateSurface( desc );

	provider.RenderTo( surface, NULL );

	m_surface = surface;
}

The last line instructs the container object 'm_surface' (member)
to take the interface pointer from 'surface' after calling AddRef().

Leaving the stack frame due to an exception or a return causes
finalization of the local container objects 'dfb', 'provider'
and 'surface' calling Release() if they've already been assigned
an interface pointer.

The suggested way of passing interfaces via parameters
is to use C++ references as in this declaration:

	void PrepareTarget( IDirectFBSurface &target );

Explicitly releasing an interface is as simple as this:

	m_surface = NULL;