Interface definition prerequisites

To specify that an interface requires the presence of other interfaces when implemented, GObject introduces the concept of prerequisites: it is possible to associate a list of prerequisite types to an interface. For example, if object A wishes to implement interface I1, and if interface I1 has a prerequisite on interface I2, A has to implement both I1 and I2.

The mechanism described above is, in practice, very similar to Java's interface I1 extends interface I2. The example below shows the GObject equivalent:

1
2
/* Make the MamanIbar interface require MamanIbaz interface. */
G_DEFINE_INTERFACE (MamanIbar, maman_ibar, MAMAN_TYPE_IBAZ);

In the G_DEFINE_INTERFACE call above, the third parameter defines the prerequisite type. This is the GType of either an interface or a class. In this case the MamanIbaz interface is a prerequisite of the MamanIbar. The code below shows how an implementation can implement both interfaces and register their implementations:

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
static void
maman_ibar_do_another_action (MamanIbar *ibar)
{
  MamanBar *self = MAMAN_BAR (ibar);

  g_print ("Bar implementation of IBar interface Another Action: 0x%x.\n",
           self->instance_member);
}

static void
maman_ibar_interface_init (MamanIbarInterface *iface)
{
  iface->do_another_action = maman_ibar_do_another_action;
}

static void
maman_ibaz_do_action (MamanIbaz *ibaz)
{
  MamanBar *self = MAMAN_BAR (ibaz);

  g_print ("Bar implementation of Ibaz interface Action: 0x%x.\n",
           self->instance_member);
}

static void
maman_ibaz_do_something (MamanIbaz *ibaz)
{
  MamanBar *self = MAMAN_BAR (ibaz);

  g_print ("Bar implementation of Ibaz interface Something: 0x%x.\n",
           self->instance_member);
}

static void
maman_ibaz_interface_init (MamanIbazInterface *iface)
{
  iface->do_action = maman_ibaz_do_action;
  iface->do_something = maman_ibaz_do_something;
}

static void
maman_bar_class_init (MamanBarClass *klass)
{

}

static void
maman_bar_init (MamanBar *self)
{
  self->instance_member = 0x666;
}

G_DEFINE_TYPE_WITH_CODE (MamanBar, maman_bar, G_TYPE_OBJECT,
                         G_IMPLEMENT_INTERFACE (MAMAN_TYPE_IBAZ,
                                                maman_ibaz_interface_init)
                         G_IMPLEMENT_INTERFACE (MAMAN_TYPE_IBAR,
                                                maman_ibar_interface_init))

It is very important to notice that the order in which interface implementations are added to the main object is not random: g_type_add_interface_static, which is called by G_IMPLEMENT_INTERFACE, must be invoked first on the interfaces which have no prerequisites and then on the others.