Re: [gtkmm] Wrapping by direct inheritance



On Fri, 13 Aug 1999, Karl Nelson wrote:

> In message <199908130424.GAA17961%timj@gtk.org>Tim Janik writes
> >On Sat, 7 Aug 1999, Karl Nelson wrote:
> >
> >> I have evaluated the types that we can do this with.  There
> >> is one type that is going to be a sticking point.  Gtk_Style
> >> is one that will need its own data to be usable.  This means
> >> that gtk+ will either need to make Gtk_Style an Object
> >> or make it have a data storage.  It currently has a class
> >> pointer and a reference count.  If they add a data pointer,
> >> the only difference between it and Object will be a flags 
> >> member.  Rambokid told me to just go and ask for a 
> >> data member, but I still wouldn't mind if types like that
> >> become derived from Gtk_Object.
> >
> >i doubt that we will ever derive GtkStyle from GtkObject, it is
> >in principle an auxillary structure. derivation from GtkObject
> >doesn't make much sense since a style has no reason to actually
> >emit a signal, and it would also mean that all GtkStyleClasses
> >would have to be imlpemented in terms of the type system.
> >for your purpose the simply addition of a GData* pointer should
> >be sufficient, since that way you can store your wrapper structure
> >pointer and get destroy notification.
> 
> The chief advantage to having such structures derive from GtkObject
> is so that if one is given to us without proper info we can cast
> it to a GtkObject and then use the type utils to figure out its
> type.  (We had serveral interfaces that did exactly that until
> we had it segfault on some structures.)
> 
> The additional advantage that it also gives that the ablity to
> reference the object with set of handles.  (Ie always call
> gtk_object_ref() on the object.  
> 
> It is a bit of a pain having to write a seperate handler function
> for each object type and have to call it (gdk is very bad
> about this as gdk types don't have a common object for all 
> referencable types).  Having a virtual interface that calls
> the same for a large set of object types is a big advantage 
> to a wrapper (treat them all tha same and they are happy.)
> 
> Those are my reasons (perhaps somewhat selfish) for wanting
> as many fragments as possible come from GtkObject.  They
> can have virtual ref/unref, they can have a destroy function
> and they can go through the type system.  (A simple 
> data pointer will do, but means writing a lot of specializations
> to merge the variations in gtk+ interface to be orthogonal to
> our users.)

GtkObject is not a particularly lightweight structure, it always comes
with the signal handling abilities and also the classed type system
overhead, thus it is often undesired to derive auxillary structures
from it.
i do understand your desire to not wrap every structure and its
ref/unref functions though. i'm not sure how to handle that issue
more effectively, maybe we could create a new AuxBase structure
that we derive *small* structures from and that language wrappers
can wrap consistently:


typedef struct _GAuxBase   GAuxBase;
typedef struct _GAuxVTable GAuxVTable;
typedef GAuxBase* (*GAuxRefFunc)   (GAuxBase *aux);
typedef void      (*GAuxUnRefFunc) (GAuxBase *aux);

struct _GAuxBase
{
  GAuxVTable *vtable;
  GData *data;
};
struct _GAuxVTable
{
  GAuxRefFunc ref;
  GAuxUnRefFunc unref;
};

so we'd for instance have (pseudo code, just to show idea):

struct _GdkWindow
{
  GAuxBase aux_base; /* formerly gpointer user_data; */
};

GdkWindow*
gdk_window_new (...)
{
  static const GAuxVTable window_vtable = {
    _gdk_window_ref,
    _gdk_window_unref,
  };
  GdkWindow *window = g_new (GdkWindow, 1);
  
  window->aux_base.vtable = window_vtable;
  g_datalist_init (&window->aux_base.data);
  
  [...]
}
GdkWindow*
gdk_window_ref (GdkWindow *window)
{
  return window->aux_base.vtable->ref (window);
}
void
gdk_window_unref (GdkWindow     *window);
{
  window->aux_base.vtable->ref (window);
}
void
gdk_window_set_user_data (GdkWindow *window,
                          gpointer   user_data)
{
  g_datalist_set_data (&window->aux_base.data, "user_data", user_data);
}
void
gdk_window_destroy (GdkWindow *window)
{
  [...]
  g_datalist_clear (&window->aux_base.data);
  g_free (window);
}

struct _GtkStyle
{
  GAuxBase aux_base; /* formerly GtkStyleClass *klass; */
  
  [...]
};
struct _GtkStyleClass
{
  GAuxVTable aux_vtable;
  
  [...]
};
struct _GtkAccelGroup
{
  GAuxBase aux_base;
  [...]
};
etc...

language wrappers like gtkmm can then deal with these structures
consistenly to a limited extend, that is, they always know how to
ref and unref them, and have an ability to store wrapper data
pointers and always get destroy notification. btw, GtkObject could
*not* be implemented in terms of GAuxBase.

though this may be suitable to help you to a certain extend, i'm not
sure whether an approach like this is at all feasibly or would just
add bloat without real benefit.
there'd also be a certain transition time involved (such
a change could of course only be done in 1.3) and i'm sure there
are a bunch of people that will dislike the added overhead (thus
the excessive quoting and Cc:-ing gtk-devel-list).

karl, i'm not sure we need the VTables with ref/unref at all,
please comment on that.
you certainly won't get a type id within all the auxillary
structures, but a GData* pointer could be provided for most cases,
would that be sufficient?

> 
> --Karl
> 

---
ciaoTJ



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]