Re: [anjuta-devel] Scons Support in Anjuta



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:

        /**
        * IAnjutaProject::node_updated:
        * @obj: Self
        * @node: Updated node.
        *
        * This signal is emitted when the project is changed.
        */
        void ::node_updated (gpointer node);

        /**
         * ianjuta_project_load_node:
         * @obj: Self
         * @node: Project node to reload
         * @err: Error propagation and reporting
         *
         * Reload a project node
         *
         * Return value: The newly loaded node, NULL if error
         */
        AnjutaProjectNode *load_node (AnjutaProjectNode *node);

        /**
         * ianjuta_project_save_node:
         * @obj: Self
         * @node: Project node to save
         * @err: Error propagation and reporting
         *
         * Save a project node
         *
         * Return value: The saved node, NULL if error
         */
        AnjutaProjectNode *save_node (AnjutaProjectNode *node);

        /**
         * ianjuta_project_new_node:
         * @obj: Self
         * @parent: Parent
         * @type: Node type
         * @file: Optional file object for the node
         * @name: Optional name for the node
         * @err: Error propagation and reporting
         *
         * Create a new node
         *
         * Return value: The new node, NULL if error
         */
AnjutaProjectNode *new_node (AnjutaProjectNode *parent, AnjutaProjectNodeType type, GFile *file, const gchar *name);

        /**
         * ianjuta_project_free_node:
         * @obj: Self
         * @node: Node
         * @err: Error propagation and reporting
         *
         * Free an already existing node
         */
        void free_node (AnjutaProjectNode *node);

        /**
         * ianjuta_project_set_property:
         * @obj: Self
         * @node: Node
         * @property: Property
         * @value: Value
         * @err: Error propagation and reporting
         *
         * Change a properties on node.
         *
         * Return value: FALSE if some properties cannot be set.
         */
gboolean set_property (AnjutaProjectNode *parent, AnjutaProjectProperty* property, const gchar *value);

        /**
         * ianjuta_project_get_node_info:
         * @obj: Self
         * @err: Error propagation and reporting
         *
         * Return a list of possible node. This is static list depending
         * depending on each backend.
         *
         * Return value: TRUE if the property has been successfully removed
         * else FALSE
         */
        List<AnjutaProjectNodeInformation *> get_node_info();



Here is now some additional historical informations, if you have already understand how it's working you can skip this part:

* new_root_node has been replaced by new_node which has exactly the same function but has more argument to be more generic allowing to create new nodes for root, source, target, group, package and module.

* add_file_node/add_name_node has been replaced by new_node. This was used with the new_root_node function but there is more difference. This function was responsible for adding the node in the project tree too. A bit like the current set_property function.

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. Typically, the backend is creating the node in a worker thread. But while the backend is creating the node, the GUI thread could try to access the project tree. So the backend cannot update the project tree to add the node itself. The node is added later in the GUI thread using an event.

* remove_node replaced by free_node. Like for the previous function, I think it's better to remove the node using generic function anjuta_project_node_remove which has to be done in the GUI thread and free the node later which can be done in another thread.

* 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.

* load replaced by load_node with the root_node as argument. load_node allow me to reload only a part of the project. Some node, like module nodes, takes a very long time to load so I think it's useful to be able to load only a part of the project.

* refresh replaced by load_node.

* get_capabilities replaced by the AnjutaProjectNodeState field in an AnjutaProjectNode. This enable you to allow new source file only a part of the targets.

* get_target_types replaced by get_node_info.

* configure replaced by set_property on the root_node.

* 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.

* get_packages, it is replaced by anjuta_project_first_child, getting all child of type KANJUTA_PROJECT_PACKAGE.

* add_group/add_target/add_source replaced first by add_file_node/add_name_node which have been replaced by new_node.

* configure_node replaced by set_property.



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 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.


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.



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.


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.




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 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.


Regards,

Sébastien



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