[Gnome-bindings] Iterator and access functions



I am not sure if other binders have had this problem, however,
as it has happened to us at many points I thought I should bring it up.
 
1) One problem which gtk-- has has quite frequently is is iterator
and access functions.  That is that many of the gtk+ functions take
integer offset into lists.   This means even though we may have a cache
to the data items address we can not use it. 

For example GtkCList...

  We have a pointer to the List, Row, Cell structures all available,
however, if we were to go through the gtk+ functions we would have to
something like this just to get the old contents of a cell and change
one field...

   find the row number...  g_list_nth(rowlist, row)
   call the gtk+ function to get the item   
   call the gtk+ function to set the item

Each of these operations is order N.  Thus even with the
pointers to the structures we have to cross the list 3 times.

This could be eliminated simply by providing an iterator interface
or by splitting the functionality between functional and convenience.

Ie.

void
gtk_clist_set_pixtext (GtkCList    *clist,
                       gint         row,
                       gint         column,
                       const gchar *text,
                       guint8       spacing,
                       GdkPixmap   *pixmap,
                       GdkBitmap   *mask)
{
  GtkCListRow *clist_row;

  g_return_if_fail (clist != NULL);
  g_return_if_fail (GTK_IS_CLIST (clist));

  if (row < 0 || row >= clist->rows)
    return;
  if (column < 0 || column >= clist->columns)
    return;

  clist_row = ROW_ELEMENT (clist, row)->data;

  /* do actual work */
}

To 

void
gtk_clist_set_pixtext (GtkCList    *clist,
                       gint         row,
                       gint         column,
                       const gchar *text,
                       guint8       spacing,
                       GdkPixmap   *pixmap,
                       GdkBitmap   *mask)
{
  GtkCListRow *clist_row;

  g_return_if_fail (clist != NULL);
  g_return_if_fail (GTK_IS_CLIST (clist));

  if (row < 0 || row >= clist->rows)
    return;


  clist_row = ROW_ELEMENT (clist, row)->data;

  gtk_clist_set_pixtext_d(clist, clist_row, columns, text, spacing, 
                          pixmap, mask);
}

void
gtk_clist_set_pixtext_d (GtkCList    *clist,
                       GtkCListRow   *row,
                       gint         column,
                       const gchar *text,
                       guint8       spacing,
                       GdkPixmap   *pixmap,
                       GdkBitmap   *mask)
{
  /* do actual work */
}


Although after seeing Havoc's GtkTextBuffer iterator interface,
I think that just having gtk+ design inline iterators is probably
better.  It would allow fast access and make for more opaque structures. 


2) Another common problem is that occasionally gtk+ returns a
pointer to a structure which we of course must copy if we want to
keep.   (I think in general it is best if gtk+ always return a pointer 
to info which must be copied rather than having the user take ownership.)
However, in some places you also must copy it just to pass it back to the 
same widget.

Example:
  gchar * text;
  guint8 spacing;
  GtkPixmap pixmap;
  GtkBitmap mask;
  gtk_clist_get_pixtext(clist, 0,0, &text, &spacing, &pixmap, &mask);
  gtk_clist_set_pixtext(clist, 0,0, text, spacing, pixmap2, mask2);

In this case, we are changing some field of a cell.  However, the
result will not be as expected.  Gtk+ frees before checking to see
if the text field is the same as the one which is passed in!
Thus this results in a seg fault.

I think for consistency and ease of binding that all gtk+ functions
should check fields against currently held values.  This would allow
substitution of fields without intermediate copies.


I am not sure if others have encountered these problems.
Hope this was appropriate for the list.

--Karl






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