Re: [anjuta-devel] New project interface and introspection



Hello,

              في ث، 05-10-2010 عند 21:46 +0200 ، كتب Sébastien Granjoux:
Le 04/10/2010 23:33, Abderrahim Kitouni a écrit :
So it needs to be renamed anjuta_project_node_get_group_from_file. I
have no problem with this.
Maybe anjuta_project_node_get_node_from_file, but you see the idea.

Ok, I have called it group/target/source because I'm not sure that 
another node with a different type cannot have the same GFile object.
Well, as I understand it, the project manager uses a GFile to identify
nodes, so I expect every file to map to exactly one node.

4. Call ianjuta_project_add_node immediately:
The fact that the project backend can be called from two different
threads is a bit scary.

Yes, I would like to avoid this too but I haven't really a better 
solution yet.

Right now, the GUI thread only calls
get_node_info which is supposed to return a constant list (and even
then, the python GIL can get in the way) but having more 'multithreaded'
calls is asking for trouble.

Not exactly, the GUI thread can use most anjuta_project_node function, 
like anjuta_project_node_get_file, anjuta_project_node_first_child...
What I meant is IAnjutaProject methods (which are implemented in the
project backend and may thus need some synchronization there).


5. Add ianjuta_project_new_node:
This can reasonably be done, making new_node another 'constant return'
method. However, the node should definitely be owned by the caller : it
makes it easier to avoid memory leaks (at the cost of one added
g_object_unref call).

That's fine for me if the node is owned by the caller. The issue is that 
I would like to have only a single owner for each node. I don't know how 
to enforce this with GObject. Most of the time a node is owned by the 
project which can change it at any time (in a thread). Creating a node 
not owned by the project will be useful in such case to be sure that the 
project will no change it.
I think there is no need to enforce it. Right now, only the project
manager and the backend have access to the project tree, it should be
easy to have some rule on when it's fine to access/modify something and
when it's not.

The closest thing possible can be to return a floating node with 
ianjuta_project_new_node and get the project get a reference on it only 
when ianjuta_project_add_node is used. It's possible in Python and quite 
simple in C. But it's still possible to add additional reference on the 
node and keep them after adding the node in the project which I would 
prefer to avoid.
I'm not sure how python handles these, but as I see it,
gobject-introspection doesn't have a way to specify that a function
returns a floating reference. Either way, floating references are only
for C convenience, and you should expect the returned reference to be
ref_sink'ed immediately.


Another issue is that ianjuta_project_new_node is node not really a 
constant return. The plugins using this function needs the GFile 
associated with the node, this GFile depends on the parent of the node. 
So ianjuta_project_new_node needs the parent and will at least read it. 
It's possible to make it works but it needs some care.
What I meant is that it can do its job without looking at the state of
the project object (and could thus be thread-safe), and just use its
parameters.


6. Make the function async, that is, pass a callback to the pm method,
and the callback will be called when the node is ready to be used. The
problem with this approach is that it can make things look like the user
command was ignored when saving/loading takes too much time.

Yes, moreover it's more difficult to use and I think callback could be 
annoying for bindings too.
Yes, it could be annoying if some plugin would like to implement the
project manager interface, but this isn't really something one wants to
do.


I could move all thread functions in the backend so
it's will not be mandatory. But I'm afraid it will make it much more
difficult to do.
Right. What would be even more difficult is changing the current
implementation.

While I'm replying to this mail, I think that probably the interface is 
not right now. It needs too much explanations. I have a new proposal.

Remove all thread stuff from the project manager and move it in the 
backend part. I suppose I can move this stuff in libanjuta and avoid 
duplicate code anyway. But, it means using thread is not mandatory and I 
don't have to split add_node and new_node function. I could keep the 
same interface than now, just that all functions, including load_node 
and save_node are called in the GUI thread.

I think this is the best option : the backend already has to take care
because it can be called from multiple threads, so having it implement
it's own threading is better (and it can even implement that using
processes, as it is recommended for python). And for simple,
machine-friendly formats, the backend may skip explicit threading
altogether, and just use e.g g_file_load_contents in order not to block
the GUI.

It must be possible to use threads to implement these functions. So 
returning from ianjuta_project_load_node doesn't mean that the node is 
loaded (and same for ianjuta_project_save_node).

Perhaps, I can rename the node_updated signal to node_loaded signal, 
emitted when the node is loaded. Note that some of its children can be 
not fully loaded.
Either way is fine for me.


Currently, the project is automatically reloaded if the project files 
change on disk and the node_loaded will be emitted when the load is 
completed. Should we have another signal like node_changed and wait for 
a ianjuta_project_load_node call to reload the project ?

Do we need a node_saved signal ?

Instead of those signal, we could use callback, for node_saved that's 
fine. For node_loaded, it's not so obvious because it's nice to have 
this signal as soon as possible, when a part of the project is loaded, 
and still be able to get for other nodes which need more time to be loaded.

What do you think ?
It's hard to argue without the big picture. I have some questions :

Will other plugins have access to the project nodes? Or are these just
for the project manager? If they aren't exposed outside the project
manager, I think we don't need to worry about ownership. We just need to
put some rules on when it is fine to modify something and when it isn't.
Exposing the project nodes will make it easier for other plugins though
(they don't need to keep asking the project manager for the children of
a given node as identified by a GFile).

Is the following description to how it should work correct?

"When opening a project, the project manager finds the correct backend
and creates an IAnjutaProject object, and calls load_node passing the
root node. The backend then goes on to start a thread for doing the
actual work and sends progress signals to the project manager.

The backend is also responsible for monitoring its files for changes
from outside Anjuta, if such a file is changed, the project (or a part
thereof) should be reloaded, and appropriate signals emitted.

When the changes are done inside Anjuta, the project manager calls
add_node_before or add_node_after and then (immediately?) calls
save_node in which the backend is responsible for writing out the
modified nodes."


It's will change the interface one more time but I have already changed 
it so many time. Anyway, I would like to progress on the autotools 
backend, so I will not change it immediately.

That's fine for me. (and if I can help in something, I'm here ;-))

In other news, I've tried to implement a sample project backend (using a
simple xml file) in Vala. And aside from a bug in valac, it seems easy
enough (although it is the kind that reorganizes your project file, not
very nice). But the current interface is definitely ok for simple
projects as well.


Regards,
Abderrahim




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