Re: [anjuta-devel] Scons Support in Anjuta



Hi Sébastien,
Thanks for your thorough explanation, I think I understand (and like)
the idea. I still have some concerns with the implementation (see
below).

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

Le 25/08/2010 11:45, Abderrahim Kitouni a écrit :
1) Some things seem redundant and there are surely some differences I
don't understand e.g. new_root_node vs. get_root,
add_{group,target,source} vs. new_node vs. add_{file,name}_node

Yes, things are redundant because I have changed the interface several 
times keeping the old functions in order to make a smoother transition 
for me.

I have planned to keep only the following functions:
[...]
Although I don't like the free_node function, I'm fine with this
interface (now that I know it's only 6 methods :-)). It's the
AnjutaProject* structs.


I have decided to remove this function from the backend because I think 
it can be useful to create the node and add it at a later time. 
So this means that e.g. to add a source file to a target, new_node is
called to create the source file node, then it's added to the target
node using AnjutaProjectNode API and then save_node is called. Right?

* set_boolean_property/set_string_property/set_list_property. This is 
replaced by set_property. Each property has a type, so it is not a 
problem to set a boolean property with a string. We can consider that 
the string "0" is for false and "1" for true. For list property, the 
set_property function doesn't replace the current value so it is rather 
an insertion.

* remove_property. This is done in free_node function.
[...]
* configure replaced by set_property on the root_node.
I'm not sure I understand the whole property stuff, could you elaborate
a bit? IIUC, it's for information that's not sources but is attached to
targets like CFLAGS and such?

* get_root. I think it's not needed. You create yourself the root node 
with new_node to load it. So you just need to keep it.
Who is "yourself"? You're talking from the project manager point of
view?


2) there are only functions to set the properties, and not to get them.
Are these are just workarounds because a node cannot notify the project?
I'd rather have both get and set on the project backend.

The AnjutaProjectNode and AnjutaProjectProperty are not GObject but 
Why not? ;-) I think a GObject is more bindings friendly (and by
bindings, I mean GObject-introspection) and I beleive the implementation
could be cleaner. new_node would still be needed (or alternatively a
function that would return a GType for a given node type, whichever
feels cleaner).

opaque C structure like GHashTable or GRegex. They don't have virtual 
functions, they have normal methods those cannot be overriden by example 
anjuta_project_node_get_name, anjuta_project_node_parent...

So, in order to get a property you use the function 
anjuta_project_node_first_property and then anjuta_project_property_next.

It means that the project backend has to create a C structure 
representing the project using AnjutaProjectNode.
That's the problem I'm facing right now (or rather, I was facing when I
last touched this). You have no way to create an AnjutaProjectNode, it
doesn't have a _new function.


I need interface functions only for loading and saving this C structure.

Then, I let some liberty to the project backend to allocate the memory 
as it wants. By example in C, you can allocate more memory than the 
minimum needed for a GNode to have to space for your own specific data. 
So, I have new_node and free_node for creating and deleting node and 
set_property for creating property. Properties are then deleted when the 
node is deleted. In addition, these functions allow the backend to check 
that the node or the property is valid, the new_node function know the 
parent where it will be added.
The problem is that you cannot really allocate "more than the minimum
needed" when using e.g. Python (and even in Vala it does require some
"clever hacks") [1]. I thought about working around this by keeping a
hashtable in the plugin for extra data, but there is the problem of not
being able to create an AnjutaProjectNode.


3) Could you please explain the big picture of how everything is
supposed to work. I'll try to adapt it as a doc comment.

The minimal backend plugin has to implement the load_node function. This 
function will get as argument an AnjutaProjectNode object of type 
ANJUTA_PROJECT_ROOT which contains a GFile corresponding to the 
directory of your project. It has to load the project files and create 
new AnjutaProjectNode children to represent the project data. Currently, 
I have defined the following type of node.
   ANJUTA_PROJECT_GROUP
   ANJUTA_PROJECT_TARGET
   ANJUTA_PROJECT_SOURCE
   ANJUTA_PROJECT_MODULE
   ANJUTA_PROJECT_PACKAGE

Each type of node is represented differently by the generic project 
manager. By example a group is represented with a directory icon but it 
is not mandatory to correspond to a directory in your backend. Each type 
of node is described with AnjutaProjectTargetInformation structure 
defining its name.

The backend will create all nodes of the project and each node include a 
field AnjutaProjectNodeState defining what is possible to do with this 
node. So the backend can decide that only sources can be added to a target.
This one seems nice, removing all assumptions about the underlying
system. The backend can decide for example that packages are added
directly to sources rather than to a module.


The backend needs to implement get_node_info too which defined which 
types of node are available.

The free_node and new_node function are needed at least for creating the 
root node.

Then, if you modify the project, you need to implement set_property 
which is like new_node and the save_node function which is really 
difficult to do.
Why would it be difficult? (Unless you mean writing to a hand-editable
file, which is a problem of its own).


I think I have a quite clear idea on how it should work, but there are 
quite a lots of work remaining and the interface could change if you 
have better ideas.

To try to summarize all this. I have written a C structure 
AnjutaProjectNode representing a project. The project manager use this 
structure to do all its operation. The backend has to implement one 
function load_node function to create this structure from the project files.

I don't think it's a problem for bindings. You need bindings for the 
whole AnjutaProjectNode structure, but it is an opaque C structure like 
GMarkupParseContext so I think this can be done without too much 
trouble. Then, it's just one function.
I don't think GMarkupParseContext has binding everywhere (almost every
language has its own "xml subset" parser) and is introspection-friendly
(the fact that it needs a struct full of callbacks isn't really nice),
but being in GLib, it cannot depend on GObject.

I think a simple solution to this is to make AnjutaProjectNode *really*
opaque (rather than a typedef of GNode), add new and free functions, and
register it as a boxed. I don't know if this will affect the existing C
backends, but if they really need the "allocate more than the minimum
memory" trick, then it would be best to just use a GObject (or maybe an
extra user_data field will do).

I hope, this mail is not too long. Tell me, if you think that some parts 
are not needed or if you want more details. I haven't explained everything.
Thanks for the explanations. The only thing I don't understand right now
is the properties. (and I hope they won't have a problem).

Seems we're getting really close to something useable :-)

Regards,
Abderrahim

[1] I'm mentioning Python and Vala because that's what I'm trying to
use. But even other high-level languages may have problems.




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