doc: refactored to be more mainstream
[adg.git] / docs / adg / HACKING.xml
blobed91437b9f5e8a082bb7e8904f43ef2fb6a144f5
1 <?xml version="1.0"?>
2 <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
3                          "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
5 <chapter id="HACKING">
6 <title>Code contributions</title>
7 <subtitle>Conventions used by the ADG canvas project</subtitle>
9 <para>This is a high-level guide to how the ADG project is organized and
10 how to get started hacking on it. The following statements should be
11 considered recommendations, not rules.</para>
14 <simplesect id="HACKING.patches">
15 <title>Hints on how to submit patches</title>
17 <para>Any patch worth the inclusion in the mainstream could be submitted to the
18 <ulink url="http://dev.entidi.com/p/adg/issues/">bug tracker</ulink> or by using the
19 <ulink url="http://lists.sourceforge.net/lists/listinfo/adg-devel">mailing list</ulink>.
20 The former is preferred when the patch addresses some specific issue while
21 the latter is a better choice for generic patches and proofs of concept.</para>
23 <para>The project uses <ulink url="http://git-scm.com/">git</ulink> as version control system
24 and the repositories could be found at different places. The following are
25 all kept up to date:</para>
27 <orderedlist>
28    <listitem><ulink url="http://repo.or.cz/w/adg.git">repo.cz</ulink></listitem>
29    <listitem><ulink url="http://p.sf.net/adg/git">SourceForge</ulink></listitem>
30    <listitem><ulink url="http://gitorious.org/adg">Gitorious</ulink></listitem>
31 </orderedlist>
33 <para>The preferred way to create a patch is by using <command>git format-patch</command> to
34 generate the file. A typical usage involves the following steps:</para>
36 <informalexample><programlisting language="shell">git clone git://repo.or.cz/adg.git
37 cd adg
38 # Modify and test...
39 git commit -a
40 # Write the commit message
41 git format-patch HEAD^
42 # You have just created a proper patch file: send it</programlisting></informalexample>
43 </simplesect>
45 <simplesect id="HACKING.style">
46 <title>Coding style</title>
48 <para>The easiest way to hack the core of the ADG project (plain C language)
49 is by following the code close to the place you are hacking, but if you
50 want a written down set of rules, the coding style is loosely based on
51 the <ulink url="http://www.netbsd.org/docs/kernel/programming.html">kernel normal form</ulink>
52 style using a 4 space indentation. The tabs should be expanded to spaces
53 and there must not be any trailing spaces at the end of line or empty
54 lines at the end of a file (they are a PITA in version control). A
55 common way to deal with the latter problem is to enable the
56 <ulink url="http://dev.entidi.com/p/adg/source/tree/master/nodist/pre-commit">pre-commit</ulink>
57 hook in your own repository:</para>
59 <informalexample><programlisting language="shell">cd adg
60 cp nodist/pre-commit .git/hooks
61 chmod 0755 .git/hooks/pre-commit</programlisting></informalexample>
62 </simplesect>
64 <simplesect id="HACKING.API">
65 <title>API conventions</title>
67 <para>The rules used by the API are more rigid and they are strictly tied to the
68 <ulink url="http://library.gnome.org/devel/gobject/stable/gtype-conventions.html">GObject</ulink>
69 API conventions. The prefixes must be <code>ADG</code>, <code>Adg</code> and <code>adg</code> for the ADG canvas
70 and <code>CPML</code>, <code>Cpml</code> and <code>cpml</code> for the cairo path manipulation library. In
71 addition, the following suggestions/rules also apply:</para>
73 <informalexample><programlisting language="c">/* Method emitting "signal-name" */
74 void            adg_object_signal_name          (AdgObject      *object,
75                                                  /* Other parameters */);
77 /* Generic setter method */
78 void            adg_object_set_value            (AdgObject      *object,
79                                                  const AdgValue *value);
80 /* Setter method for boolean values */
81 void            adg_object_switch_boolean_value (AdgObject      *object,
82                                                  gboolean       *new_state);
84 /* Generic getter method */
85 const AdgValue *adg_object_get_value            (AdgObject      *object);
87 /* Getter method for boolean values */
88 gboolean        adg_object_has_boolean_value    (AdgObject      *object);
90 /* Getter method for reference counted values: an object could be
91  * referenced and unreferenced also if read-only, so no const needed */
92 AdgObject *     adg_object_get_object           (AdgObject      *object);
94 /* Getter method returning scalar values must not be const:
95  * they are passed by value */
96 ScalarType      adg_object_get_scalar_value     (AdgObject      *object);
98 /* Alternative getter method to use when the generic syntax is
99  * not allowed, such as when the value is dynamically generated */
100 void            adg_object_put_value            (AdgObject      *object,
101                                                  AdgValue       *value);
103 /* Different version of the same setter method for pair values */
104 void            adg_object_set_value            (AdgObject      *object,
105                                                  const AdgPair  *value);
106 void            adg_object_set_value_explicit   (AdgObject      *object,
107                                                  gdouble         value_x,
108                                                  gdouble         value_y);
109 void            adg_object_set_value_from_model (AdgADim        *adim,
110                                                  AdgModel       *model,
111                                                  const gchar    *named_pair);
112 </programlisting></informalexample>
114 <para>The method should be grouped by argument, that is methods working on the
115 same subject should be adjacents. The constructors must be the first ones
116 while the helper methods for signal emission should be the last ones.
117 It is preferable to keep the setter before the getter in the list.</para>
119 <para>For any other non-C contribution (makefiles, translations, bindings,
120 documentation, whatever) just follow the surronding text using a bit of
121 common sense. When no surrounding text exists, use your preferred style
122 and use it consistently.</para>
124 </simplesect>
126 <simplesect id="HACKING.Use">
127 <title>How the API should be used</title>
129 <para>The getter methods must be considered read-only. Although in some
130 circumstances some of them do not return a <emphasis>const</emphasis> value,
131 this is done just to allow referencing and unreferencing an object,
132 but still that object should be considered read-only. This means to
133 change a property you should write something along these lines:</para>
134 <informalexample><programlisting language="c">CpmlExtents extents;
136 cpml_extents_copy(&amp;extents, adg_entity_get_extents(entity));
137 /* Modify extents... */
138 adg_entity_set_extents(entity, &amp;extents);
139 </programlisting></informalexample>
141 <para>The <emphasis>put</emphasis> version of a getter usually does not have the setter
142 counterpart (because the returned value is typically computed) so the
143 above will be reduced to:</para>
144 <informalexample><programlisting language="c">CpmlExtents extents;
146 cpml_segment_put_extents(segment, &amp;extents);
147 /* Use extents... */
148 </programlisting></informalexample>
149 </simplesect>
150 </chapter>