Re: Best practise inheritance

2017-03-22 Thread Emmanuele Bassi
Now that I'm not on my phone, I can probably do a better job at
replying to this email.

On 21 March 2017 at 23:21, Emmanuele Bassi  wrote:
>
> On Tue, 21 Mar 2017 at 21:23, S. Jacobi  wrote:
>>
>> On Tue, 21 Mar 2017 20:53:04 +
>> Emmanuele Bassi  wrote:
>>
>> >
>> > Also, do not store a private pointer in your instance structure, and
>> > use the get_private_instance() function that the G_DEFINE_TYPE macro
>> > creates for you.
>> >
>> So you say whenever I need access to the objects private data I should
>> call G_TYPE_INSTANCE_GET_PRIVATE, despite the mentioned overhead?
>
>
> Nope. I said to use the get_instance_private() function generated for your
> type by the G_DEFINE_TYPE macro, which uses pointer arithmetic and an offset
> computed when the class is instantiated and it's constant for all instances.

Before GObject 2.38, the private data was allocated interleaved with
each instance data in the memory block; this meant that each GType has
to compute the offset for each ancestor type in the hierarchy. After
2.38, the private instance data is allocated as a single block, and
the offset for each ancestor class is constant and known once the type
is created (assuming you're using the G_DEFINE_TYPE macros and you're
not calling g_type_class_add_private() in an ancestor of your type;
for that case we still know the offset at class init time, which means
we always know the offset before you can instantiate a type). The
known offset allows us to retrieve a pointer to the private instance
data with simple, and fast, pointer arithmetic.

The G_DEFINE_TYPE_EXTENDED macro will create a
_get_instance_private() static inline function that returns
a pointer to the private instance data. If you use
G_DEFINE_TYPE_WITH_PRIVATE, or G_DEFINE_TYPE_WITH_CODE (...
G_ADD_PRIVATE), GObject will do all the heavy lifting behind the
scenes for you — and it will ensure that any changes we make to
GObject will end up in your code with a simple rebuild.

Since getting the private instance data was "expensive" in the
beginning, the best practice was to use a private pointer inside the
instance data structure, at the cost of a slightly larger instance
structure size and at the cost of having a real instance structure
instead of just renaming `struct _GObject` to your type; now that
retrieving that data is fast, having that pointer is not necessary any
more (doing a pointer offset is actually faster than a pointer
redirection, on any modern architecture).

tl;dr: Always use G_DEFINE_TYPE and G_DECLARE_* macros to
automatically use best practices, and to avoid having to deal with the
innards of GType.

>> > The GObject tutorial has a good introduction on how to define types
>> > and how to use them.
>> >
>> Indeed. It took me a while to walk through it. However, the example
>> given in [3] has the comment /* Other members, including private data.
>> */, which would contradict your opinion, or is at least a bit unclear,
>> because final and derivable types are handled a bit differently.

>> [3] https://developer.gnome.org/gobject/stable/howto-gobject-code.html

The example you're referring to is describing the "final type" case,
where the instance structure is already *private* to the source file.
This means you don't need a Private data structure at all — i.e. all
the instance data is private.

You should use private instance data structures if you're using
G_DECLARE_DERIVABLE_TYPE and you make your instance structure public,
in order to let other people subclass your type.

Ciao,
 Emmanuele.

-- 
https://www.bassi.io
[@] ebassi [@gmail.com]
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Re: Best practise inheritance

2017-03-21 Thread Emmanuele Bassi
On Tue, 21 Mar 2017 at 21:23, S. Jacobi  wrote:

> On Tue, 21 Mar 2017 20:53:04 +
> Emmanuele Bassi  wrote:
>
> >
> > Also, do not store a private pointer in your instance structure, and
> > use the get_private_instance() function that the G_DEFINE_TYPE macro
> > creates for you.
> >
> So you say whenever I need access to the objects private data I should
> call G_TYPE_INSTANCE_GET_PRIVATE, despite the mentioned overhead?
>

Nope. I said to use the get_instance_private() function generated for your
type by the G_DEFINE_TYPE macro, which uses pointer arithmetic and an
offset computed when the class is instantiated and it's constant for all
instances.

The GET_PRIVATE macro has to compute the offset on every invocation,
instead.

>
> > The GObject tutorial has a good introduction on how to define types
> > and how to use them.
> >
> Indeed. It took me a while to walk through it. However, the example
> given in [3] has the comment /* Other members, including private data.
> */, which would contradict your opinion, or is at least a bit unclear,
> because final and derivable types are handled a bit differently.


Please, file a bug against the documentation component of the GLib product
in Bugzilla, so we can fix this and make it clearer.

Ciao,
 Emmanuele.

>
> [3] https://developer.gnome.org/gobject/stable/howto-gobject-code.html
>
> > Ciao,
> >  Emmanuele.
> > On Tue, 21 Mar 2017 at 19:57, Nicola Fontana  wrote:
> >
> > >
> > > the lookup indeed is quite expensive, and looking at the
> > > implementation [1] it is not that straightforward.
> > >
> > > The very same example provided by the official documentation [2]
> > > caches that pointer into the instance struct.
> > >
> > > [1] https://git.gnome.org/browse/glib/tree/gobject/gtype.c#n4709
> > > [2]
> > >
> https://developer.gnome.org/gobject/stable/gobject-Type-Information.html#g-type-class-add-private
> > >
> ___
> gtk-app-devel-list mailing list
> gtk-app-devel-list@gnome.org
> https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
>
-- 
https://www.bassi.io
[@] ebassi [@gmail.com]
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: Best practise inheritance

2017-03-21 Thread S. Jacobi
On Tue, 21 Mar 2017 20:53:04 +
Emmanuele Bassi  wrote:

> 
> Also, do not store a private pointer in your instance structure, and
> use the get_private_instance() function that the G_DEFINE_TYPE macro
> creates for you.
> 
So you say whenever I need access to the objects private data I should
call G_TYPE_INSTANCE_GET_PRIVATE, despite the mentioned overhead?

> The GObject tutorial has a good introduction on how to define types
> and how to use them.
> 
Indeed. It took me a while to walk through it. However, the example
given in [3] has the comment /* Other members, including private data.
*/, which would contradict your opinion, or is at least a bit unclear,
because final and derivable types are handled a bit differently.

[3] https://developer.gnome.org/gobject/stable/howto-gobject-code.html

> Ciao,
>  Emmanuele.
> On Tue, 21 Mar 2017 at 19:57, Nicola Fontana  wrote:
> 
> >
> > the lookup indeed is quite expensive, and looking at the
> > implementation [1] it is not that straightforward.
> >
> > The very same example provided by the official documentation [2]
> > caches that pointer into the instance struct.
> >
> > [1] https://git.gnome.org/browse/glib/tree/gobject/gtype.c#n4709
> > [2]
> > https://developer.gnome.org/gobject/stable/gobject-Type-Information.html#g-type-class-add-private
> >
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: Best practise inheritance

2017-03-21 Thread Emmanuele Bassi
Don't use g_type_class_add_privat(). Either use the define type with
private macro, or the define type with code macro with G_ADD_PRIVATE.

Also, do not store a private pointer in your instance structure, and use
the get_private_instance() function that the G_DEFINE_TYPE macro creates
for you.

The GObject tutorial has a good introduction on how to define types and how
to use them.

Ciao,
 Emmanuele.
On Tue, 21 Mar 2017 at 19:57, Nicola Fontana  wrote:

> Il Tue, 21 Mar 2017 17:55:31 + Tristan Van Berkom <
> tristan.vanber...@codethink.co.uk> scrisse:
>
> > ...
> >   o I believe the lookups with G_TYPE_INSTANCE_GET_PRIVATE() are just
> > as cheap as the pointer dereference (as it will be implemented
> > using simple pointer arithmetic).
>
> Hi Tristan,
>
> the lookup indeed is quite expensive, and looking at the
> implementation [1] it is not that straightforward.
>
> The very same example provided by the official documentation [2]
> caches that pointer into the instance struct.
>
> [1] https://git.gnome.org/browse/glib/tree/gobject/gtype.c#n4709
> [2]
> https://developer.gnome.org/gobject/stable/gobject-Type-Information.html#g-type-class-add-private
>
> Ciao.
> --
> Nicola
> ___
> gtk-app-devel-list mailing list
> gtk-app-devel-list@gnome.org
> https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

-- 
https://www.bassi.io
[@] ebassi [@gmail.com]
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: Best practise inheritance

2017-03-21 Thread Nicola Fontana
Il Tue, 21 Mar 2017 17:55:31 + Tristan Van Berkom 
 scrisse:

> ...
>   o I believe the lookups with G_TYPE_INSTANCE_GET_PRIVATE() are just
>     as cheap as the pointer dereference (as it will be implemented
>     using simple pointer arithmetic).

Hi Tristan,

the lookup indeed is quite expensive, and looking at the
implementation [1] it is not that straightforward.

The very same example provided by the official documentation [2]
caches that pointer into the instance struct.

[1] https://git.gnome.org/browse/glib/tree/gobject/gtype.c#n4709
[2] 
https://developer.gnome.org/gobject/stable/gobject-Type-Information.html#g-type-class-add-private

Ciao.
-- 
Nicola
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Re: Best practise inheritance

2017-03-21 Thread Tristan Van Berkom
On Tue, 2017-03-21 at 18:27 +0100, S. Jacobi wrote:
> On Mon, 20 Mar 2017 16:01:39 +
> Tristan Van Berkom  wrote:
> 
> > 
> > 
> > Use instance private data, this will not need any priv pointer and
> > can be done with th G_DEFINE_TYPE_WITH_PRIVATE() macro, and another
> > to lookup your private data inside your C file (under the hood,
> > this
> > uses negative instance offsets with power nter arithmatic, so
> > public
> > and private data are on the same allocated memory slice)
> > 
> 
> This is still a bit unclear to me, because I found no good reference
> what instance private data really is, apart from a patch on the
> mailing
> list. So is it just GObject "magic" that puts private fields into
> special memory locations and can therefore retain ABI compatibility?
> Because from what I read, I define my structs the same way.
> 
> struct _MyType
> {
>   GtkWidget   parent;
>   MyTypePriv *priv;
> }
> G_DEFINE_TYPE (MyType, my_type, GTK_TYPE_WIDGET)
> 
> and
> 
> struct _MyType
> {
>   GtkWidget   parent;
>   MyTypePriv *priv;
> }
> G_DEFINE_TYPE_WITH_PRIVATE (MyType, my_type, GTK_TYPE_WIDGET)
> 
> would be first a struct with "normal" private data and second a
> struct
> with instance private data. Or am I completely on the wrong track
> here?

This describes a bit of what you're after:

   https://developer.gnome.org/gobject/stable/howto-gobject-code.html

The key points here are that:

  o MyType structure does not need any 'priv' pointer, as it can be
    looked up at any time.
  o G_DEFINE_TYPE_WITH_PRIVATE() expects that a MyTypePrivate structure
    is defined above
  o G_TYPE_INSTANCE_GET_PRIVATE() can be called in your C file to
    access the allocated MyTypePrivate structure for a given instance.

    See: https://developer.gnome.org/gobject/stable/gobject-Type-Inform
ation.html#G-TYPE-INSTANCE-GET-PRIVATE:CAPS

At the end of the day, the main memory slice for an object instance
will be created with space for your MyTypePrivate structure, but the
sizeof() that structure will be computed at runtime so it does not
effect ABI.

This means:
  o No need for allocating an extra pointer to point to private data
  o Less overall memory fragmentation, because private data is
    allocated on the object instance itself.
  o I believe the lookups with G_TYPE_INSTANCE_GET_PRIVATE() are just
    as cheap as the pointer dereference (as it will be implemented
    using simple pointer arithmetic).

Cheers,
    -Tristan

___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Re: Best practise inheritance

2017-03-21 Thread S. Jacobi
On Mon, 20 Mar 2017 16:01:39 +
Tristan Van Berkom  wrote:

> 
> Use instance private data, this will not need any priv pointer and
> can be done with th G_DEFINE_TYPE_WITH_PRIVATE() macro, and another
> to lookup your private data inside your C file (under the hood, this
> uses negative instance offsets with power nter arithmatic, so public
> and private data are on the same allocated memory slice)
> 

This is still a bit unclear to me, because I found no good reference
what instance private data really is, apart from a patch on the mailing
list. So is it just GObject "magic" that puts private fields into
special memory locations and can therefore retain ABI compatibility?
Because from what I read, I define my structs the same way.

struct _MyType
{
  GtkWidget   parent;
  MyTypePriv *priv;
}
G_DEFINE_TYPE (MyType, my_type, GTK_TYPE_WIDGET)

and

struct _MyType
{
  GtkWidget   parent;
  MyTypePriv *priv;
}
G_DEFINE_TYPE_WITH_PRIVATE (MyType, my_type, GTK_TYPE_WIDGET)

would be first a struct with "normal" private data and second a struct
with instance private data. Or am I completely on the wrong track here?
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: Best practise inheritance

2017-03-20 Thread Joël Krähemann
Hello Mr. Jacobi

What I personally like to see is doing events. It makes your OOP extensible.
And is the usual way how things are done in GUI programming.

But it is not limited to GUI. For instance this event is handled by a
GUI callback
to toggle a button.

http://git.savannah.nongnu.org/cgit/gsequencer.git/tree/ags/audio/ags_audio.c#n781

Bests,
Joël



On Mon, Mar 20, 2017 at 6:37 PM, Joël Krähemann  wrote:
> Hi
>
> You don't have to use myWidget->parent since you dereference the pointer.
> A pointer to a struct always points to the first field of the topmost
> nesting level.
>
> so it would be:
>
> gtk_widget_set_name(myWidget);
>
>
> Bests,
> Joël
>
>
>
> On Mon, Mar 20, 2017 at 6:29 PM, S. Jacobi  wrote:
>> On Mon, 20 Mar 2017 18:10:16 +0100
>> Joël Krähemann  wrote:
>>
>>> Hi
>>>
>>> As Tristan told you. The struct contains the other struct as not using
>>> a pointer.
>>>
>>> struct MyCompositeWidget
>>> {
>>>   GtkAlignment alignment;
>>>
>>>   GtkBox *box;
>>> };
>>>
>> The parent-is-a-pointer mistake was just me not thinking when I wrote
>> the mail. If have seen it being done correctly everywhere. This makes
>> gtk_widget_set_name (myWidget->parent, "myWidget"); syntactically wrong
>> however.
>> ___
>> gtk-app-devel-list mailing list
>> gtk-app-devel-list@gnome.org
>> https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Re: Best practise inheritance

2017-03-20 Thread Joël Krähemann
Hi

You don't have to use myWidget->parent since you dereference the pointer.
A pointer to a struct always points to the first field of the topmost
nesting level.

so it would be:

gtk_widget_set_name(myWidget);


Bests,
Joël



On Mon, Mar 20, 2017 at 6:29 PM, S. Jacobi  wrote:
> On Mon, 20 Mar 2017 18:10:16 +0100
> Joël Krähemann  wrote:
>
>> Hi
>>
>> As Tristan told you. The struct contains the other struct as not using
>> a pointer.
>>
>> struct MyCompositeWidget
>> {
>>   GtkAlignment alignment;
>>
>>   GtkBox *box;
>> };
>>
> The parent-is-a-pointer mistake was just me not thinking when I wrote
> the mail. If have seen it being done correctly everywhere. This makes
> gtk_widget_set_name (myWidget->parent, "myWidget"); syntactically wrong
> however.
> ___
> gtk-app-devel-list mailing list
> gtk-app-devel-list@gnome.org
> https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Re: Best practise inheritance

2017-03-20 Thread S. Jacobi
On Mon, 20 Mar 2017 18:10:16 +0100
Joël Krähemann  wrote:

> Hi
> 
> As Tristan told you. The struct contains the other struct as not using
> a pointer.
> 
> struct MyCompositeWidget
> {
>   GtkAlignment alignment;
> 
>   GtkBox *box;
> };
> 
The parent-is-a-pointer mistake was just me not thinking when I wrote
the mail. If have seen it being done correctly everywhere. This makes
gtk_widget_set_name (myWidget->parent, "myWidget"); syntactically wrong
however.
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Re: Best practise inheritance

2017-03-20 Thread S. Jacobi
On Mon, 20 Mar 2017 16:01:39 +
Tristan Van Berkom  wrote:

> 
> Use instance private data, this will not need any priv pointer and
> can be done with th G_DEFINE_TYPE_WITH_PRIVATE() macro, and another
> to lookup your private data inside your C file (under the hood, this
> uses negative instance offsets with power nter arithmatic, so public
> and private data are on the same allocated memory slice)
> 

So how is instance private data different from the priv field in the
struct? Only because G_DEFINE_TYPE_WITH_PRIVATE was called?
This is (roughly) what I found in the developer docs describing what
the boilerplate parts should look like:
myType.h

#include 

#define MY_TYPE my_type_get_type ()
G_DECLARE_FINAL_TYPE (MyType, my_type, MY, TYPE, GtkWidget)

/* function declarations */

myType.c

#include "myType.h"

/* Private structure definition. */
typedef struct {
  guint i;
  /* stuff */
} MyTypePrivate;


struct _MyType
{
  GtkWidget parent;

  /* Other members, including private data. */
}

G_DEFINE_TYPE_WITH_PRIVATE (MyType, my_type, GTK_TYPE_WIDGET)

So do I have to add the MyTypePrivat *priv field to the struct _MyType
definition (where the comment is)? And is this (finally) the recommended
way of "inheritance"?

> 
> There is no difference for accessing these things as inherited code
> or external code: do so with API (no such thing as "protected").
>

It makes a difference to the compiler I suppose. The nicest way would
be to use
MyType *myWidget;
gtk_widget_set_name (myWidget, "myWidget");
but the pointer types don't match.
Also, gtk_widget_set_name (myWidget->parent, "myWidget"); and
gtk_widget_set_name (GTK_WIDGET (myWidget), "myWidget"); seem a bit
different to me, because the first only affects the internal parent
instance, the second affects the whole custom widget. I do not know
enough about GTK internals if those two are semantically equivalent
anyway.

___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: Best practise inheritance

2017-03-20 Thread Joël Krähemann
Hi

No, you can talk in C of direct inheritance. Or implementing an interface.

As Tristan told you. The struct contains the other struct as not using
a pointer.

struct MyCompositeWidget
{
  GtkAlignment alignment;

  GtkBox *box;
};

The properties are inherited, too. As long you use
g_type_register_static() or alike
passing the parent type. You can peek the parent class.

It might hard to understand for you what has the meaning class. A
class has always
the very same methods. Else you have to subtype and override the class.

The class methods can chained up by using the peeked class.

GTK_WIDGET_CLASS(my_composite_widget_parent_class)->show(my_instance)

Note GLib-Object interfaces are limited to one nesting level of GTypeInterface.

So there is no interface inheritance.

I think it's a good point to do object orientated programming with C
because you have to
know what's going on.

Bests,
Joël


On Mon, Mar 20, 2017 at 5:15 PM, Tristan Van Berkom
 wrote:
> On Mon, 2017-03-20 at 16:36 +0100, S. Jacobi wrote:
>> First of all, inheritance may be the wrong word here in plain c, but
>> I
>> don't know how else to name it.
>
> Sorry replied to this from my phone and missed some things...
>
>> In different projects I see different approaches how to derive custom
>> widgets from existing ones. I can roughly group them into 2 to 3.
>>
>> 1) The header only has a typedef to make the struct opaque. All
>> variables needed are put into the struct in the .c file.
>>
>> myType.h
>> typedef struct _MyTypeMyType;
>>
>> myType.c
>> struct _MyType
>> {
>>   GtkWidget   *parent;
>>   /* additions */
>>   guinti;
>>   ...
>> };
>
> Note also that this approach imposes that absolutely nothing can derive
> from MyType later, because MyType becomes anonymous.
>
>>
>> 2a) The header defines a private struct, and all variables needed are
>> put into this private struct.
>>
>> myType.h
>> typedef struct _MyTypePriv MyTypePriv;
>> typedef struct _MyType   MyType;
>>
>> myType.c
>> struct _MyTypePriv
>> {
>>   GtkWidget   *parent;
>>   /* additions */
>>   guinti;
>> };
>>
>> struct _MyType
>> {
>>   MyTypePriv  *priv;
>> };
>
> Actually this approach (2a) I've never seen before, not a good idea,
> but possibly works (except for the other detail below)...
>
>
>> 2b) Similar to 2a, but the parent is put in the "main" struct, not
>> the
>> private part.
>>
>> myType.h
>> typedef struct _MyTypePriv MyTypePriv;
>> typedef struct _MyType   MyType;
>>
>> myType.c
>> struct _MyTypePriv
>> {
>>   /* additions */
>>   guinti;
>> };
>>
>> struct _MyType
>> {
>>   GtkWidget   *parent
>>   MyTypePriv  *priv;
>> };
>
> So in all of these cases, you have missed an important detail:
>
> struct _MyType {
> GtkWidget *parent_instance;
>
> ... anything else...
> }
>
> Is wrong, as it will only reserve one pointer size for the parent
> structure, what you have been seeing is always in fact:
>
> struct _MyType {
> GtkWidget parent_instance
>
> ... anything else ...
> }
>
> The parent instance must be known and not anonymous, you need to
> include the struct itself as the first member of your derived type, not
> merely a pointer to that.
>
> Cheers,
> -Tristan
>
> ___
> gtk-app-devel-list mailing list
> gtk-app-devel-list@gnome.org
> https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Re: Best practise inheritance

2017-03-20 Thread Tristan Van Berkom
On Mon, 2017-03-20 at 16:36 +0100, S. Jacobi wrote:
> First of all, inheritance may be the wrong word here in plain c, but
> I
> don't know how else to name it.

Sorry replied to this from my phone and missed some things...

> In different projects I see different approaches how to derive custom
> widgets from existing ones. I can roughly group them into 2 to 3.
> 
> 1) The header only has a typedef to make the struct opaque. All
> variables needed are put into the struct in the .c file.
> 
> myType.h
> typedef struct _MyTypeMyType;
> 
> myType.c
> struct _MyType
> {
>   GtkWidget   *parent;
>   /* additions */
>   guint    i;
>   ...
> };

Note also that this approach imposes that absolutely nothing can derive
from MyType later, because MyType becomes anonymous.

> 
> 2a) The header defines a private struct, and all variables needed are
> put into this private struct.
> 
> myType.h
> typedef struct _MyTypePriv MyTypePriv;
> typedef struct _MyType   MyType;
> 
> myType.c
> struct _MyTypePriv
> {
>   GtkWidget   *parent;
>   /* additions */
>   guint    i;
> };
> 
> struct _MyType
> {
>   MyTypePriv  *priv;
> };

Actually this approach (2a) I've never seen before, not a good idea,
but possibly works (except for the other detail below)...


> 2b) Similar to 2a, but the parent is put in the "main" struct, not
> the
> private part.
> 
> myType.h
> typedef struct _MyTypePriv MyTypePriv;
> typedef struct _MyType   MyType;
> 
> myType.c
> struct _MyTypePriv
> {
>   /* additions */
>   guint    i;
> };
> 
> struct _MyType
> {
>   GtkWidget   *parent
>   MyTypePriv  *priv;
> };

So in all of these cases, you have missed an important detail:

struct _MyType {
    GtkWidget *parent_instance;

    ... anything else...
}

Is wrong, as it will only reserve one pointer size for the parent
structure, what you have been seeing is always in fact:

struct _MyType {
    GtkWidget parent_instance

    ... anything else ...
}

The parent instance must be known and not anonymous, you need to
include the struct itself as the first member of your derived type, not
merely a pointer to that.

Cheers,
    -Tristan

___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Re: Best practise inheritance

2017-03-20 Thread Tristan Van Berkom
Hi

> On Mar 20, 2017, at 3:36 PM, S. Jacobi  wrote:
> 
> First of all, inheritance may be the wrong word here in plain c, but I
> don't know how else to name it.
> 
> In different projects I see different approaches how to derive custom
> widgets from existing ones. I can roughly group them into 2 to 3.
> 
> 1) The header only has a typedef to make the struct opaque. All
> variables needed are put into the struct in the .c file.
> 
> myType.h
> typedef struct _MyTypeMyType;
> 
> myType.c
> struct _MyType
> {
>  GtkWidget*parent;
>  /* additions */
>  guint i;
>  ...
> };

This is unsafe, the size of an instance structure is part of ABI so it can 
never change without releasing a completely new library soname.

You can use this style but its then easy to forget that restriction, so just 
dont.

> 2a) The header defines a private struct, and all variables needed are
> put into this private struct.
> 
> myType.h
> typedef struct _MyTypePriv MyTypePriv;
> typedef struct _MyType   MyType;
> 
> myType.c
> struct _MyTypePriv
> {
>  GtkWidget*parent;
>  /* additions */
>  guint i;
> };
> 
> struct _MyType
> {
>  MyTypePriv*priv;
> };

This is safe, and was a measure to ensure private details stay private while 
retaining instance size (before better approaches were developed).

> 
> 2b) Similar to 2a, but the parent is put in the "main" struct, not the
> private part.
> 
> myType.h
> typedef struct _MyTypePriv MyTypePriv;
> typedef struct _MyType   MyType;
> 
> myType.c
> struct _MyTypePriv
> {
>  /* additions */
>  guint i;
> };
> 
> struct _MyType
> {
>  GtkWidget*parent
>  MyTypePriv*priv;
> };
> 

This is also legacy, occurrences of this in gtk+ proper will only exist to 
retain ABI compat with an older release where publicly exposed members already 
existed.

Even in the cases where the pointer is considered public, we prefer to wrap it 
in an explicit accessor (this also makes life easier for bindings using 
introspection).

> So my first question: What is the best way here? And are there
> (functional) differences between these?

Use instance private data, this will not need any priv pointer and can be done 
with th G_DEFINE_TYPE_WITH_PRIVATE() macro, and another to lookup your private 
data inside your C file (under the hood, this uses negative instance offsets 
with power nter arithmatic, so public and private data are on the same 
allocated memory slice)


> And my second question is closely related: How to access "inherited"
> properties, or call "inherited" functions? I see these variants in the
> following examples, where I have:
> MyType *myWidget;

There is no difference for accessing these things as inherited code or external 
code: do so with API (no such thing as "protected").

Alternatively, you can bend the rules by providing private accessors usually 
prefixed with _, without exporting these symbols in your shared library to 
users (gtk+ does this in many places, for strictly private object interactions).

Cheers,
-Tristan

> 1) gtk_widget_set_name (GTK_WIDGET (myWidget), "myWidget");
> 2) gtk_widget_set_name (myWidget->parent, "myWidget");
> 3) gtk_widget_set_name (myWidget->priv->parent, "myWidget");
> 
> I am looking forward to helpful replies.
> Thanks and kind regards
> ___
> gtk-app-devel-list mailing list
> gtk-app-devel-list@gnome.org
> https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
> 

___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Best practise inheritance

2017-03-20 Thread S. Jacobi
First of all, inheritance may be the wrong word here in plain c, but I
don't know how else to name it.

In different projects I see different approaches how to derive custom
widgets from existing ones. I can roughly group them into 2 to 3.

1) The header only has a typedef to make the struct opaque. All
variables needed are put into the struct in the .c file.

myType.h
typedef struct _MyType  MyType;

myType.c
struct _MyType
{
  GtkWidget *parent;
  /* additions */
  guint  i;
  ...
};

2a) The header defines a private struct, and all variables needed are
put into this private struct.

myType.h
typedef struct _MyTypePriv MyTypePriv;
typedef struct _MyType MyType;

myType.c
struct _MyTypePriv
{
  GtkWidget *parent;
  /* additions */
  guint  i;
};

struct _MyType
{
  MyTypePriv*priv;
};

2b) Similar to 2a, but the parent is put in the "main" struct, not the
private part.

myType.h
typedef struct _MyTypePriv MyTypePriv;
typedef struct _MyType MyType;

myType.c
struct _MyTypePriv
{
  /* additions */
  guint  i;
};

struct _MyType
{
  GtkWidget *parent
  MyTypePriv*priv;
};

So my first question: What is the best way here? And are there
(functional) differences between these?

And my second question is closely related: How to access "inherited"
properties, or call "inherited" functions? I see these variants in the
following examples, where I have:
MyType *myWidget;

1) gtk_widget_set_name (GTK_WIDGET (myWidget), "myWidget");
2) gtk_widget_set_name (myWidget->parent, "myWidget");
3) gtk_widget_set_name (myWidget->priv->parent, "myWidget");

I am looking forward to helpful replies.
Thanks and kind regards
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list