GObject
-------

Every GObject is attached a C++ class instance that provides the C++ bindings
for this object. This is done using the system described below.

Every C++ binding class has a "constructor" method which is autogenerated by codegen
and it simply creates an instance of this class. This method is not a member of the
class, but it is a friend of the class, so that it can call the private constructor.
The constructor and the friend declaration are both declared inside the Q*_WRAPPER
macro at the top of the class definition. A pointer to this constructor method is then
saved inside the quark data of the GType that this class provides bindings for. The
code that does this is also generated by codegen and it is called from the global init()
function of the relevant namespace (QGlib::init() and QGst::init()).

When the C object is first wrapped using RefPointer::wrap(), the wrap method
checks the GType of this C object and constructs a C++ class instance that best
matches the GType of the object. That means that if the given GType has a pointer to
a constructor method saved in its qdata, then it is used, otherwise, it tries the
GType of the parent and this goes on recursively. In the worst case, a QGlib::Object
instance will be created, which is the wrapper for GObject, the parent of all object
types.

After the C++ class instance has been created, a pointer to it is saved inside the
GObject instance qdata. This allows it to be reused; if for some reason all the references
to this instance are dropped from the C++ side and then later RefPointer::wrap() is
called again on the same C instance, it reuses the same C++ instance that was created
earlier. The C++ instance is finally deleted when the C instance is also deleted. A
GObject weak reference is used internally to get a notification when the C instance has
been deleted.


GObject Interfaces
------------------

Interfaces are handled in a similar way, but not exactly the same.

Interfaces are generally implemented by GObject subclasses in a way that resembles
multiple inheritance. In C++ we use multiple inheritance to simulate this. So for
example, because GstBin implements the GstChildProxy interface and inherits GstElement,
in C++ the class is:

  class Bin : public Element, public ChildProxy

Now in this case, if we have a QGst::Element pointer that is actually a QGst::Bin instance,
the simplest way to cast to the ChildProxy interface is to use C++'s dynamic_cast().

However, it is not always possible to have a class that inherits from all the supported
interfaces, since in many cases those interfaces are either dynamic or implemented in
unknown subclasses. This is the case for example with the various GStreamer elements which
are implemented inside plugins and as a result, their class definition is not known before
runtime.

So, for all those GStreamer elements, the C++ class that is generally created is
QGst::Element - which does not inherit from any interface - and the interfaces are added
dynamically when needed, in the following way: First, a GType check is performed to see if
the element really implements the requested interface. If it does, a constructor method for
the C++ class that wraps the interface is requested from the interface's GType qdata
and this method is used to construct the interface's C++ instance, as it is done with GObject.
This interface C++ instance is then also saved inside the GObject instance qdata, but using
a different quark as a key for every interface, so that multiple interface C++ instances can
be saved.

This functionality is all hidden inside RefPointer::dynamicCast(), which hides the complexity
from the user and offers it as if it was part of the programming language.


GstMiniObject
-------------

GstMiniObject is a special case, since it does not inherit from GObject, but is a boxed type
instead. In general, the same technique as in GObject is used, with the most notable difference
being that GstMiniObject has no qdata on its instance and no weak references, so the C++ class
instance cannot be saved on the C instance and cannot be deleted when the C instance is deleted.
To work this around, an external reference count is added on the C++ class instance, which is
incremented and deincremented from RefPointer. Unfortunately this whole technique does not allow
reuse of the C++ instance; the C++ instance is deleted as soon as all the RefPointers that point
to it are destroyed, just like it would happen with QSharedPointer.
