Re: [anjuta-devel] Scons Support in Anjuta



Hi,
              في ث، 31-08-2010 عند 22:25 +0200 ، كتب Sébastien Granjoux:
Hi,

Le 31/08/2010 13:12, Abderrahim Kitouni a écrit :
Freeing things isn't something you want to do in a high level language
(and that' why I suggested a GObject, you can just unref it and be done
with it).

Ok, I see. But I don't think it's a problem here because you cannot copy 
a AnjutaProjectNode. Each AnjutaProjectNode is owned by its parent which 
has a pointer on it.
But since it's not created with something like
anjuta_project_node_create_child, the one context creating it needs to
own it for a while.
 If you copy it the new node hasn't a parent so it's 
a different node. I think reference counting such object is not useful 
because the reference count is always 1 (new object) or 0 (the object is 
free).
Which brings us to another question: how to "copy" a ProjectNode?
Actually copying is incorrect for the reasons you describe. But how
about reference-counting? and what about the proxy nodes? can they be
used as "copies"? (not that anyone is going to copy a node, but just to
be sure things won't break if someone does.)


That's right (although I don't agree with the numbers you give), and
that's why I proposed using a boxed type instead.

I haven't checked the numbers, they could be wrong. But I think a boxed 
type will not fit because as I have explained above an AnjutaProjectNode 
is really a node. Its address is stored in the parent node and its 
sibling, so it you move it to another address it's not the same node 
anymore. I don't see any need to copy a AnjutaProjectNode so I don't see 
the user of such boxed.
The problem is not that it's going to be copied, but that it needs to be
freed.

I have seen a GLib.GPointer object but I haven't understand its use.
Not much, just so you can say: "this structure is of that type, and if
don't know that type treat it as a void*". IOW, it's useless from
bindings POV.


That's totally wrong. A binding that doesn't allow subclassing GObject
isn't a GObject binding. (even when using libpeas, the only known
limitations in bindings right now is vfuncs).

Yes, it's wrong. After writing this mail, I have done some search and I 
have seen that python bindings at least allow to subclass GObject. It 
think it's the minimum to bind GObject.

But then, I don't understand why libpeas hide the GObject plugin object 
but it's another discussion.
Because Javascript bindings (both gjs and seed) don't support overriding
virtual methods. (and both allow to subclass GObject, and register
properties and signals)


1. We write a anjuta_project_node_new that is creating a GNode having an
AnjutaProjectNodeData as parameters.
Sounds ok. Can be better, but this is already enough. And make sure you
hide the fact that it's a GNode (for Vala) and register it as a boxed
(for scripting languages).

I'm agree that I should hide the fact that it is a GNode, it doesn't 
matter for backend in other languages. But, I don't understand why it 
should be register as a boxed type. For me it should be just a number.
Replacing:
typedef GNode AnjutaProjectNode;
with:
typedef struct _GNode AnjutaProjectNode;
is enough to make GI think it's unrelated to GNode, and won't affect C
backends. So I think we should go with this.

Making it a number doesn't make sense if the backend is supposed to
allocate it.


2. Better, the anjuta_project_node_new has an additional gpointer as
argument and create a AnjutaGenericProjectNodeData which is an
AnjutaProjectNodeData and a gpointer.
This can be a solution, but how memory management is done? (keeping
everything passed to this in a list and removing it on free_node doesn't
sound like a good idea). We won't need both this and the above one, one
can just pass null if they dont need extra data.

Yes, need 1 or 2 not both. The advantage of this solution is that it 
should be easier to get the specific data from the node number, you 
don't need to look in a hashtable.
I'm also leaning to this solution, 

3. Another possibility is add a sizeof argument to the generic
anjuta_project_node_new and allocate additional memory (more than just
the size of a gpointer) and put all your specific data here.
I think we would be reinventing some wheel here,
g_type_class_add_private does the same thing more or less.

Yes, g_type_class_add_private data does the same thing for a GObject, 
but AnjutaProjectNode is not a GObject so I cannot use 
g_type_class_add_private on it.
What I meant is that it's better to switch to GObject rather than
reinventing the same mechanism. But I think I'll go for 1. or 2. above.


Yes, that's the point: most structs in GLib aren't used in bindings
because they provide basic functionality available in most languages.

Yes, I have looked in python bindings and I have not seen any bindings 
for most GLib objects. But I don't understand what's happen when you 
define a function that is using one of the GLib structure. By example 
how do you implement a function in python which has to return a GRegex 
object ?
I think you can just create a GRegex, get a big scary warning, and
return it taking the risk of causing a memory leak. And then, if it gets
really annoying, you file a bug, hoping it'll be fixed. But since
virtually nobody has such api, it won't be a problem for most people. 

Or does it means that all arguments and return values should be limited 
to gint, gchar, gchar *, gfloat ?
You forgot the most important : GObject subclasses and boxed types ;-)

(and just to see how scary are warnings I was talking about, and can
even get to the state where there are actually bugs).

In [1]: from gi.repository import GLib

In [2]: n = GLib.Node.new(230)

** (process:16623): WARNING **: Transfer mode should be set to None for
struct types as there is no way to free them safely.  Ignoring transfer
mode to prevent a potential invalid free. This may cause a leak in your
application.

In [3]: n2 = n.prepend(GLib.Node.new(450))

** (process:16623): WARNING **: Transfer mode should be set to None for
struct types as there is no way to free them safely.  Ignoring transfer
mode to prevent a potential invalid free. This may cause a leak in your
application.

** (process:16623): WARNING **: Transfer mode should be set to None for
struct types as there is no way to free them safely.  Ignoring transfer
mode to prevent a potential invalid free. This may cause a leak in your
application.

** (process:16623): WARNING **:
(pygi-argument.c:1656):_pygi_argument_release: runtime check failed: (!
g_type_info_is_pointer (type_info) || transfer == GI_TRANSFER_NOTHING)

In [4]: n2.data
Out[4]: 319


But the backend needs to know how to free this structure (witch is going
to be opaque, right?).

Not really. I think the type of an AnjutaProjectNode should be seen by 
the backend as a number like a gpointer.
A gpointer isn't seen as a number, and that wouldn't help since it needs
to be freed. (but see my proposal below).

The implementation of the ianjuta_project_node_free in the backend is:
- Find the data corresponding to the number of the node and free them.
- call the C function anjuta_project_node_free on this number
Calling a free method really isn't pretty, especially since it will
generate a big warning saying that you may have caused a memory leak
(even though you know what you're doing).



So here is my proposal (I'm trying to implement it right now):

* use the struct _GNode trick so that only C backends are aware that its
actually a GNode.
* add _new and _free functions: 
AnjutaProjectNode *anjuta_project_node_new (AnjutaProjectNodeType type,
                                            AnjutaProjectProperty *properties,
                                            GFile *file,
                                            gchar *name,
                                            AnjutaProjectNodeState state);
(I'm thinking of adding a gpointer user_data at the end).

* Register it as a boxed (maybe using anjuta_project_proxy_new instead
of a real copy and making _free aware of this).

This should bring it to a state where it's useable, and the next step
would be AnjutaProjectProperty.

Regards,
Abderrahim




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