Re: [Vala] reference problem



2008/8/5 picca <picca synchrotron-soleil fr>:
Hello

Here the vala code then I will explain my problem

public class Holder {
       weak List<Axis> axes;

       Holder(ref List<Axis> axes) {
               this.axes = axes
       }

       ...other method modifing the this.axes...
}

public class Geometry { // the real owner of the list
       List<Axis> axes;
       List<Holder> holders;
       public add_holder() {
               this.holders.append(new Holder(ref this.axes));
       }
}

So I create a geometry with one holder then I use the holder method to
modify the axes list owned by the geometry.

but the C code show that in the holder class

struct _Holder {
       Glist *axes;
};

holder_new(Holder *self, GList **axes)
{
               (*self).axes = (*axes);
}

So instead of modifying the Geometry list it use a new one created in
the holder.

The right C code would have been

struct _Holder {
       GList **axes;
};

holder_new(Holder *self, GList **axes)
{
       (*self).axes = axes;
}


So is it a bug ?

A complication here is that GLists do not work like most objects, in
that modifying them will potentially change their address (if the
first element changes.)  Vala isn't really set up to handle that
situation, as it doesn't allow representing a pointer to a pointer as
a field.

What Vala is producing is right to its specification.  When you pass
the axes argument with the "ref" direction, the compiler will allow
assignments to the parameter to be visible back to the caller, but
will otherwise treat the parameter as normal, which means
dereferencing when assigning it to something else.  Indeed, that is
required as the field type is just an ordinary weak reference.

In this case, everything will work fine unless the Holder makes a
change to the list which affects which axis is first, as that will
change the location of the list as a whole, which the Geometry will
not be informed about.  If something other than GList was being used,
Geometry and Holder would be properly pointing to the same object, and
would see all of each other's changes.

I would suggest the best thing to do would be to use an easier to
handler list.  Either use something like one of the lists from libgee,
or write a wrapper for GList.

-- 
Phil Housley



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