[glib] docs: Remove commented out sections from GObject how-to



commit f1287a9b2f995b8c7ec228cc3b3418670ef92695
Author: Philip Withnall <philip withnall collabora co uk>
Date:   Fri Feb 20 12:54:05 2015 +0000

    docs: Remove commented out sections from GObject how-to
    
    Unused, outdated, and unsalvagable.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=744060

 docs/reference/gobject/tut_howto.xml |  402 ----------------------------------
 1 files changed, 0 insertions(+), 402 deletions(-)
---
diff --git a/docs/reference/gobject/tut_howto.xml b/docs/reference/gobject/tut_howto.xml
index 149f979..98f7875 100644
--- a/docs/reference/gobject/tut_howto.xml
+++ b/docs/reference/gobject/tut_howto.xml
@@ -1424,407 +1424,5 @@ maman_file_write (MamanFile    *self,
       parameter types.
     </para>
   </sect1>
-
-<!-- 
-  this is utterly wrong and should be completely removed - or rewritten
-  with a better example than writing a buffer using synchronous signals.
-
-  <sect1>
-    <title>How to provide more flexibility to users?</title>
-
-    <para>
-      The previous implementation does the job but the signal facility of
-      GObject can be used to provide even more flexibility to this file
-      change notification mechanism. One of the key ideas is to make the
-      process of writing data to the file part of the signal emission
-      process to allow users to be notified either before or after the
-      data is written to the file.
-    </para>
-    
-    <para>
-      To integrate the process of writing the data to the file into the
-      signal emission mechanism, we can register a default class closure
-      for this signal which will be invoked during the signal emission,
-      just like any other user-connected signal handler. 
-    </para>
-    
-    <para>
-      The first step to implement this idea is to change the signature of
-      the signal: we need to pass around the buffer to write and its size.
-      To do this, we use our own marshaller which will be generated
-      through GLib's glib-genmarshal tool. We thus create a file named <filename>marshall.list</filename> 
which contains
-      the following single line:
-<informalexample><programlisting>
-VOID:POINTER,UINT
-</programlisting></informalexample>
-      and use the Makefile provided in <filename>sample/signal/Makefile</filename> to generate the file named
-      <filename>maman-file-complex-marshall.c</filename>. This C file is finally included in 
-      <filename>maman-file-complex.c</filename>.
-    </para>
-
-    <para>
-      Once the marshaller is present, we register the signal and its marshaller in the class_init function 
-      of the object <type>MamanFileComplex</type> (full source for this object is included in 
-      <filename>sample/signal/maman-file-complex.{h|c}</filename>):
-<informalexample><programlisting>
-GClosure *default_closure;
-GType param_types[2];
-
-default_closure = g_cclosure_new (G_CALLBACK (default_write_signal_handler),
-                                  (gpointer)0xdeadbeaf /* user_data */, 
-                                  NULL /* destroy_data */);
-
-param_types[0] = G_TYPE_POINTER;
-param_types[1] = G_TYPE_UINT;
-klass->write_signal_id = 
-  g_signal_newv ("write",
-                 G_TYPE_FROM_CLASS (g_class),
-                 G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
-                 default_closure /* class closure */,
-                 NULL /* accumulator */,
-                 NULL /* accu_data */,
-                 maman_file_complex_VOID__POINTER_UINT,
-                 G_TYPE_NONE /* return_type */,
-                 2     /* n_params */,
-                 param_types /* param_types */);
-</programlisting></informalexample>
-      The code shown above first creates the closure which contains the code to complete the file write. This
-      closure is registered as the default class_closure of the newly created signal.
-    </para>
-
-    <para>
-      Of course, you need to implement completely the code for the default closure since I just provided
-      a skeleton:
-<informalexample><programlisting>
-static void
-default_write_signal_handler (GObject *obj, guint8 *buffer, guint size, gpointer user_data)
-{
-  g_assert (user_data == (gpointer)0xdeadbeaf);
-  /* Here, we trigger the real file write. */
-  g_print ("default signal handler: 0x%x %u\n", buffer, size);
-}
-</programlisting></informalexample>
-    </para>
-
-    <para>
-      Finally, the client code must invoke the <function>maman_file_complex_write</function> function which 
-      triggers the signal emission:
-<informalexample><programlisting>
-void maman_file_complex_write (MamanFileComplex *self, guint8 *buffer, guint size)
-{
-  /* trigger event */
-  g_signal_emit (self,
-                 MAMAN_FILE_COMPLEX_GET_CLASS (self)->write_signal_id,
-                 0, /* details */
-                 buffer, size);
-}
-</programlisting></informalexample>
-    </para>
-    
-    <para>
-      The client code (as shown in <filename>sample/signal/test.c</filename> and below) can now connect 
signal handlers before 
-      and after the file write is completed: since the default signal handler which does the write itself 
runs during the 
-      RUN_LAST phase of the signal emission, it will run after all handlers connected with <function><link 
linkend="g-signal-connect">g_signal_connect</link></function>
-      and before all handlers connected with <function><link 
linkend="g-signal-connect-after">g_signal_connect_after</link></function>. If you intent to write a GObject
-      which emits signals, I would thus urge you to create all your signals with the G_SIGNAL_RUN_LAST such 
that your users
-      have a maximum of flexibility as to when to get the event. Here, we combined it with 
G_SIGNAL_NO_RECURSE and 
-      G_SIGNAL_NO_HOOKS to ensure our users will not try to do really weird things with our GObject. I 
strongly advise you
-      to do the same unless you really know why (in which case you really know the inner workings of GSignal 
by heart and
-      you are not reading this).
-    </para>
-    
-    <para>
-<informalexample><programlisting>
-static void complex_write_event_before (GObject *file, guint8 *buffer, guint size, gpointer user_data)
-{
-  g_assert (user_data == NULL);
-  g_print ("Complex Write event before: 0x%x, %u\n", buffer, size);
-}
-
-static void complex_write_event_after (GObject *file, guint8 *buffer, guint size, gpointer user_data)
-{
-  g_assert (user_data == NULL);
-  g_print ("Complex Write event after: 0x%x, %u\n", buffer, size);
-}
-
-static void test_file_complex (void)
-{
-  guint8 buffer[100];
-  GObject *file;
-
-  file = g_object_new (MAMAN_FILE_COMPLEX_TYPE, NULL);
-
-  g_signal_connect (G_OBJECT (file), "write",
-                    (GCallback)complex_write_event_before,
-                    NULL);
-
-  g_signal_connect_after (G_OBJECT (file), "write",
-                          (GCallback)complex_write_event_after,
-                          NULL);
-
-  maman_file_complex_write (MAMAN_FILE_COMPLEX (file), buffer, 50);
-
-  g_object_unref (G_OBJECT (file));
-}
-</programlisting></informalexample>
-      The code above generates the following output on my machine:
-<programlisting>
-Complex Write event before: 0xbfffe280, 50
-default signal handler: 0xbfffe280 50
-Complex Write event after: 0xbfffe280, 50
-</programlisting>
-    </para>
-
--->
-
-<!--
-  this is also utterly wrong on so many levels that I don't even want
-  to enumerate them. it's also full of completely irrelevant footnotes
-  about personal preferences demonstrating a severe lack of whatsoever
-  clue. the whole idea of storing the signal ids inside the Class
-  structure is so fundamentally flawed that I'll require a frontal
-  lobotomy just to forget I've ever seen it.
-
-    <sect2>
-    <title>How most people do the same thing with less code</title>
-    
-      <para>For many historic reasons related to how the ancestor of GObject used to work in GTK+ 1.x 
versions,
-        there is a much <emphasis>simpler</emphasis> 
-        <footnote>
-          <para>I personally think that this method is horribly mind-twisting: it adds a new indirection
-          which unnecessarily complicates the overall code path. However, because this method is widely used
-          by all of GTK+ and GObject code, readers need to understand it. The reason why this is done that 
way
-          in most of GTK+ is related to the fact that the ancestor of GObject did not provide any other way 
to
-          create a signal with a default handler than this one. Some people have tried to justify that it is 
done
-          that way because it is better, faster (I am extremely doubtful about the faster bit. As a matter 
of fact,
-          the better bit also mystifies me ;-). I have the feeling no one really knows and everyone does it
-          because they copy/pasted code from code which did the same. It is probably better to leave this 
-          specific trivia to hacker legends domain...
-          </para>
-        </footnote>
-        way to create a signal with a default handler than to create 
-        a closure by hand and to use the <function><link 
linkend="g-signal-newv">g_signal_newv</link></function>.
-      </para>
-    
-      <para>For example, <function><link linkend="g-signal-new">g_signal_new</link></function> can be used 
to create a signal which uses a default 
-        handler which is stored in the class structure of the object. More specifically, the class structure 
-        contains a function pointer which is accessed during signal emission to invoke the default handler 
and
-        the user is expected to provide to <function><link 
linkend="g-signal-new">g_signal_new</link></function> the offset from the start of the
-        class structure to the function pointer.
-          <footnote>
-            <para>I would like to point out here that the reason why the default handler of a signal is 
named everywhere
-             a class_closure is probably related to the fact that it used to be really a function pointer 
stored in
-             the class structure.
-            </para>
-          </footnote>
-      </para>
-    
-      <para>The following code shows the declaration of the <type>MamanFileSimple</type> class structure 
which contains
-        the <function>write</function> function pointer.
-<informalexample><programlisting>
-struct _MamanFileSimpleClass {
-  GObjectClass parent;
-        
-  guint write_signal_id;
-
-  /* signal default handlers */
-  void (*write) (MamanFileSimple *self, guint8 *buffer, guint size);
-};
-</programlisting></informalexample>
-        The <function>write</function> function pointer is initialized in the class_init function of the 
object
-        to <function>default_write_signal_handler</function>:
-<informalexample><programlisting>
-static void
-maman_file_simple_class_init (gpointer g_class,
-                               gpointer g_class_data)
-{
-  GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
-  MamanFileSimpleClass *klass = MAMAN_FILE_SIMPLE_CLASS (g_class);
-
-  klass->write = default_write_signal_handler;
-</programlisting></informalexample>
-        Finally, the signal is created with <function><link 
linkend="g-signal-new">g_signal_new</link></function> in the same class_init function:
-<informalexample><programlisting>
-klass->write_signal_id = 
- g_signal_new ("write",
-               G_TYPE_FROM_CLASS (g_class),
-               G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
-               G_STRUCT_OFFSET (MamanFileSimpleClass, write),
-               NULL /* accumulator */,
-               NULL /* accu_data */,
-               maman_file_complex_VOID__POINTER_UINT,
-               G_TYPE_NONE /* return_type */,
-               2     /* n_params */,
-               G_TYPE_POINTER,
-               G_TYPE_UINT);
-</programlisting></informalexample>
-        Of note, here, is the 4th argument to the function: it is an integer calculated by the 
<function><link linkend="G-STRUCT-OFFSET">G_STRUCT_OFFSET</link></function>
-        macro which indicates the offset of the member <emphasis>write</emphasis> from the start of the 
-        <type>MamanFileSimpleClass</type> class structure.
-        <footnote>
-          <para>GSignal uses this offset to create a special wrapper closure 
-           which first retrieves the target function pointer before calling it.
-          </para>
-        </footnote>
-     </para>
-
-     <para>
-       While the complete code for this type of default handler looks less cluttered as shown in 
-       <filename>sample/signal/maman-file-simple.{h|c}</filename>, it contains numerous subtleties.
-       The main subtle point which everyone must be aware of is that the signature of the default 
-       handler created that way does not have a user_data argument: 
-       <function>default_write_signal_handler</function> is different in 
-       <filename>sample/signal/maman-file-complex.c</filename> and in 
-       <filename>sample/signal/maman-file-simple.c</filename>.
-     </para>
-
-     <para>If you have doubts about which method to use, I would advise you to use the second one which
-       involves <function><link linkend="g-signal-new">g_signal_new</link></function> rather than 
<function><link linkend="g-signal-newv">g_signal_newv</link></function>: 
-       it is better to write code which looks like the vast majority of other GTK+/GObject code than to
-       do it your own way. However, now, you know why.
-     </para>
-
-   </sect2>
-
-  </sect1>
--->
-
-<!--
-  yet another pointless section. if we are scared of possible abuses
-  from the users then we should not be mentioning it inside a tutorial
-  for beginners. but, obviously, there's nothing to be afraid of - it's
-  just that this section must be completely reworded.
-
-  <sect1>
-    <title>How users can abuse signals (and why some think it is good)</title>
-
-    <para>Now that you know how to create signals to which the users can connect easily and at any point in
-      the signal emission process thanks to <function><link 
linkend="g-signal-connect">g_signal_connect</link></function>, 
-      <function><link linkend="g-signal-connect-after">g_signal_connect_after</link></function> and 
G_SIGNAL_RUN_LAST, it is time to look into how your
-      users can and will screw you. This is also interesting to know how you too, can screw other people.
-      This will make you feel good and eleet.
-    </para>
-    
-    <para>
-      The users can:
-      <itemizedlist>
-         <listitem><para>stop the emission of the signal at anytime</para></listitem>
-         <listitem><para>override the default handler of the signal if it is stored as a function
-           pointer in the class structure (which is the preferred way to create a default signal handler,
-           as discussed in the previous section).</para></listitem>
-       </itemizedlist> 
-    </para>
-    
-    <para>
-      In both cases, the original programmer should be as careful as possible to write code which is
-      resistant to the fact that the default handler of the signal might not able to run. This is obviously
-      not the case in the example used in the previous sections since the write to the file depends on 
whether
-      or not the default handler runs (however, this might be your goal: to allow the user to prevent the 
file 
-      write if he wishes to).
-    </para>
-    
-    <para>
-      If all you want to do is to stop the signal emission from one of the callbacks you connected yourself,
-      you can call <function><link linkend="g-signal-stop-by-name">g_signal_stop_by_name</link></function>. 
Its use is very simple which is why I won't detail 
-      it further.
-    </para>
-    
-    <para>
-      If the signal's default handler is just a virtual function pointer, it is also possible to override 
-      it yourself from the class_init function of a type which derives from the parent. That way, when the 
signal
-      is emitted, the parent class will use the function provided by the child as a signal default handler.
-      Of course, it is also possible (and recommended) to chain up from the child to the parent's default 
signal 
-      handler to ensure the integrity of the parent object.
-    </para>
-    
-    <para>
-      Overriding a class method and chaining up was demonstrated in <xref linkend="howto-gobject-methods"/> 
-      which is why I won't bother to show exactly how to do it here again.
-    </para>
-
-  </sect1>
-
--->
-
 </chapter>
-
-<!--
-  <sect2>
-    <title>Warning on signal creation and default closure</title>
-
-    <para>
-      Most of the existing code I have seen up to now (in both GTK+, GNOME libraries and
-      many GTK+ and GNOME applications) using signals uses a small
-      variation of the default handler pattern I have shown in the previous section.
-    </para>
-
-    <para>
-      Usually, the <function><link linkend="g-signal-new">g_signal_new</link></function> function is 
preferred over
-      <function><link linkend="g-signal-newv">g_signal_newv</link></function>. When <function><link 
linkend="g-signal-new">g_signal_new</link></function>
-      is used, the default closure is exported as a virtual function. For example,
-      <filename>gobject.h</filename> contains the declaration of <link 
linkend="GObjectClass"><type>GObjectClass</type></link>
-      whose notify virtual function is the default handler for the <emphasis>notify</emphasis>
-      signal:
-<informalexample><programlisting>
-struct  _GObjectClass
-{
-  GTypeClass   g_type_class;
-
-  /* class methods and other stuff. */
-
-  /* signals */
-  void (*notify) (GObject     *object,
-                  GParamSpec  *pspec);
-};
-</programlisting></informalexample>
-     </para>
-
-     <para>
-       <filename>gobject.c</filename>'s <function><link 
linkend="g-object-do-class-init">g_object_do_class_init</link></function> function
-       registers the <emphasis>notify</emphasis> signal and initializes this virtual function
-       to NULL:
-<informalexample><programlisting>
-static void
-g_object_do_class_init (GObjectClass *class)
-{
-
-  /* Stuff */
-
-  class->notify = NULL;
-
-  gobject_signals[NOTIFY] =
-    g_signal_new ("notify",
-                  G_TYPE_FROM_CLASS (class),
-                  G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS,
-                  G_STRUCT_OFFSET (GObjectClass, notify),
-                  NULL, NULL,
-                  g_cclosure_marshal_VOID__PARAM,
-                  G_TYPE_NONE,
-                  1, G_TYPE_PARAM);
-}
-</programlisting></informalexample>
-       <function><link linkend="g-signal-new">g_signal_new</link></function> creates a <link 
linkend="GClosure"><type>GClosure</type></link> which dereferences the
-       type's class structure to access the virtual function pointer and invoke it if it not NULL. The
-       virtual function is ignored it is set to NULL.
-     </para>
-
-     <para>
-       To understand the reason for such a complex scheme to access the signal's default handler, 
-       you must remember the whole reason for the use of these signals. The goal here is to delegate
-       a part of the process to the user without requiring the user to subclass the object to override
-       one of the virtual functions. The alternative to subclassing, that is, the use of signals
-       to delegate processing to the user, is, however, a bit less optimal in terms of speed: rather
-       than just dereferencing a function pointer in a class structure, you must start the whole
-       process of signal emission which is a bit heavyweight.
-     </para>
-
-     <para>
-       This is why some people decided to use virtual functions for some signal's default handlers:
-       rather than having users connect a handler to the signal and stop the signal emission
-       from within that handler, you just need to override the default virtual function which is
-       supposedly more efficient.
-     </para>
-
-    </sect2>
--->
 </part>


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