GObject in GC implementation Plan
Derek Atkins
warlord at MIT.EDU
Fri Mar 30 05:52:35 EDT 2007
Hi,
Sorry for not responding to this sooner.. Apparently it fell into
my Spam folder and I didn't notice it until today. Mea Culpa.
More inline...
"Daniel Espinosa" <esodan at gmail.com> writes:
> GOBJECT IN GC IMPLEMENTATION PLAN:
>
> OBJECTIVE
>
> Get GObject as the base of GC's objects. With the following advantages:
> - Get ref counting
> - Get signals events
I would say that these are three objectives, not one, and that these
three objectives do not have to happen at once. In other words I think
we can have a multi-step process:
1) Get GObject as the base of GC's objects. Get this to work by
itself using the existing (non-refcounted) methods. Obviously
this is going to require changing EVERY object in the tree at
once, so it's a major bit of work, but let's make this as SMALL
as possible. ONLY use GObjects for create/destroy. Don't do
refcounting. Don't do signals. Don't change the QOF String
types to GTypes in the APIs. Keep all that, just change the
objects to use GObject. Once we get that working then we can
merge into trunk!
2) Implement GObject refcounting. I think this might be able to go
on an object by object basis, but I don't know for sure. But as
we get working state, perhaps merge into trunk.
3) Use gobject signaling. Again, I think these can be done object by
object.
But the point here is that these are SEPARATE tasks and should be done
in separate steps.
> STATE OF THE ART
>
[snip]
>
> STEPS TO GET GOBJECT
>
> In order to get GObject as the base class for the GC's objects and get
> its functionalities, we can go though the following options:
>
>
>
>
> ******OPTION 1: PORT QofEntity TO USE GObject AS BASE CLASS
>
> Step 1:
> Setup QofEntity, QofInstance and ALL GC's objects to be GObjects in
> order to have a correct construction/destruction process, this will
> ensure a correct refcounting.
>
> **ADVANTAGES
> Make all in one step and get GObject from the base QOF system.
>
> **DISADVANTAGES
> Too many changes to be mergable in Trunk.
I'm not sure I agree, but let's just say that I agree for now..
> *******OPTION 2: PORT QofInstance TO USE GObject AS BASE CLASS
>
> Step 1:
> Merge QofInstance and QofEntity. This allow to get a single class used
> as the base for the GC's objects.
>
> Step 2:
> Setup QofInstance and ALL GC's objects to be GObjects and be sure to
> have a correct construction/destruction process, this will ensure a
> correct refcounting.
>
> **ADVANTAGES
> Make all in few steps and get GObject from the base QOF system.
> Simplify the object class hierarchy.
>
> **DISADVANTAGES
> Too many changes to be mergable in Trunk.
I'm not sure I agree here. I think that if you break it down
into truly the smallest pieces then it WOULD be mergible. See
what I wrote above.
For example, to GObjectize the GnuCash Account object in this way
would require only minor changes xaccInitAccount(),
xaccMallocAccount(), and xaccFreeAccount(). In particular:
xaccInitAccount():
Remove qof_instance_init() because it's no longer needed.
xaccMallocAccount():
change g_new0() to g_object_new() to create the "GncAccount" object
xaccFreeAccount():
remove qof_instance_release() because it's no longer needed
change g_free() to g_object_destroy() to destroy the gobject.
That's it (well, except for the GncAccount GType hooks). I think this
is fairly straightforward and could be done with minimal impact. I
don't even think you need to change anything in the Account headers or
account structure. Once you change QofInstance to be based on GObject
everything else is just inherited so only these minimal changes are
required to "get it working".
Now, you might argue that this really isn't using GObject properly,
and I'd agree. See above about doing it in multiple steps. Doing it
THIS way we get a working system sooner, and then we can migrate to
each gobject feature over time, one feature at a time. It means we
have a small set of changes that we COULD merge into trunk and would
reduce the risk of failure.
> *******OPTION 3: PORT GC's OBJECT TO USE GObject AS BASE CLASS
>
> Step 1: (this step can be done Object by Object, don't need to work in
> all objects at the same time)
> Make the QofInstance member as a Pointer, and allow to create a
> pointer to a QofInstance when the object is created using
> g_object_new. This means:
>
> - Add a new function in QofInstance to allow create an instance,
> setup it and return a pointer to a QofInstance
> - No modification in the current QofInstance implementation
> - Will need to change all references (JUST in the currently changing
> object) from 'object->inst.[someQofInstanceMember]' to
> 'object->inst->[someQofInstanceMember]'
> - Needs to change the definition of QOF_INSTANCE macro to call a
> functions witch returns the QofInstance pointer member of the GC's
> object
I suppose we could do this, but we'd need a forward pointer from
the QofInstance back to the main object, so you can convert from a
QofInstance TO an e.g. Account* or Transaction* or Split*. We need
to be able to convert back and forth... And there are probably LOTS
of places where we get a QofIstance and ASSUME that we can C-Cast it
back to our primary type. E.g., I'm sure there's lots of code that
says:
gint foo(QofInstance* inst)
{
...
Account* acc = (Account*) inst;
...
}
ALL of this code would be broken by this approach.
> Step 2:
> Setup the currently working object to be a GObject. This means:
> - The base class will be GObject not QofInstance
> - Other objects, not currently changing, will use the same
> QofInstance base class and its current construction/destruction
> process
>
> Step 3:
> Merge QofInstance and QofEntity. This allow to get a single base class.
>
> Step 4:
> Setup QofInstance to be a GObject and be sure to have a correct
> construction/destruction process, this will ensure a correct
> refcounting.
>
> Step 5:
> Now we can change the base class from GObject to QofInstance in all
> GC's objects.
>
> **ADVANTAGES
> Get GObject features directly in GC's objects quickly.
> Allows to delay the required modifications in QOF to later steps.
> Allows to modify QOF WITH OUT modify the GC's objects; even is
> possible to work on QOF with out modify the GC's objects, but this
> delay to get GObject in GC
> Once the process in QOF to GObject is finished we can change the base
> class in GC's objects again to QofInstance
> Simplify the object class hierarchy.
>
> **DISADVANTAGES
> Require to change the base class of the GC's objects from QofInstance
> to GObject.
> Needs to change the code from direct access to the members in
> QofInstance from '.' to '->'.
I think these are some major disadvantanges. I still like options
#1 or #2 (tending towards #2) with the caveats that we make minimal
changes like I point out above. Enough to get it to work even
though we don't use the full extent of gobject functionality right
from the beginning.
Thanks,
-derek
--
Derek Atkins, SB '93 MIT EE, SM '95 MIT Media Laboratory
Member, MIT Student Information Processing Board (SIPB)
URL: http://web.mit.edu/warlord/ PP-ASEL-IA N1NWH
warlord at MIT.EDU PGP key available
More information about the gnucash-devel
mailing list