GObject in GC implementation Plan

Derek Atkins warlord at MIT.EDU
Thu Apr 5 07:16:36 EDT 2007


Quoting Daniel Espinosa <esodan at gmail.com>:

>> >> I would think that we could just change g_free() to g_object_unref()
>> >> and let the qof_instance_release() code get executed from within the
>> >> unref calls.  Is this NOT the case?  Why wouldn't that work?
>>
>> Daniel, could you please answer this question.  I do want to make
>> sure that I'm not missing something.
>>
>
> You can't if becouse if you want to leave much of the code with out
> modification you need to call qof_instance_release() as is. if you
> don't do so you must move the code or register a function that made
> the work.

I think we have a major communication issue here...   qof_instance_release()
really doesn't do all that much interesting, and I don't understand
why that work can't be done in the QofInstance dispose() and finalize()
class functions.

> More clear: a GObject must register a function for init, class_init
> and finalize, then when you call g_object_ref and g_object_unref this
> functions will be called; but for the actual code you don't want that
> I have done in the gobjec-engine-dev, you want to keep the actual
> construction/destruction method, then keep qof_instance_release and at
> the end of this function call g_object_unref.

Yes, we want to keep the various xaccMallocFoo() and xaccFreeFoo()
function APIs.  That's the current GnuCash Engine API and callers
shouldn't care that they get a GObject..  But I think you're mistaken
about "g_object_ref" above, maybe you meant "g_object_new()"?

But I still don't see why I need to keep qof_instance_release() as an
actual API instead of doing what I did in my branch and moving that
to the dispose()/finalize() functions.   Yes, that means changing the
QOF API slightly, but that's okay -- it's a minor change.

I also kept the qof_instance_init(), but I changed the name to
qof_instance_init_data() because the GObject code wants qof_instance_init()
for itself.

> If you want a GObject to be g_object_new and g_object_unref
> compatible, you must register this functions and "move" the code you
> have now to this functions; but again you don't want to move much code
> and change the things I've done.

Sure...  BUT...   Because we're keeping the xaccMallocFoo() APIs,
and intend to keep those functions indefinitely, we can decide to
move the real init code LATER.    See, this is what I mean by "small
steps".    After six hours of real work I have a working system that
uses g_object_new() and g_object_unref() internally, and now I can
go object by object and move the init/dispose/finalize code into the
Gobject hooks...   But see how I didn't HAVE to do that in one step
to keep the system working?

> I have seen your code in the branch and I found that you aren't
> following the code conventions to create a GObject, and let me say if
> you don't follow it will be dificult to understand your work for
> others that knows some thing about GObject.

What "code conventions"?  Each new object has a {qof,gnc}_foo_{init,
class_init,finalize,dispose} API, which gets called properly.  It's
just that right now those aren't used, because they weren't NECESSARY
to get the code working.

Let me try this again en Espanol:

Estas funciones no son necesarias para un gnucash operacional!  Estas 
funciones
son bonitas, son agradables, pero no son necesarias.  Pues, para conseguir el
GnuCash que trabaja rapidamente nos posemos emigrar ese codigo un objecto
a la vez MAS ADALENTE.   Comprende?

Keep in mind, THIS IS STEP ONE!   NUMERO UNO!  The first of many.
There are MANY steps ahead but you seem to keep forgetting this,
or ignoring it, or you just really don't understand.   The primary
goal is to keep the WHOLE system working.   You need to make small
course corrections.

Here's an example:  Have you ever driven a motorboat?  Let's say you're
driving the motorboat at around 20kts (that would be 23mph or 36km/h).
Now let's say that you need to turn around.  If you jerk the controls
all the way to one side to turn the boat, most likely the force of the
curve will tip you over, or at best throw you overboard!   You need to
make the turn shallow, a small course correction.   Yes, it takes longer,
but you wont spill your precious cargo.   ( Feel free to apply this to
any moving vehicle.   If you don't believe me, go drive your car down the
highway at 60mph (96km/h) and then pull the wheel hard to one side and
see what happens.  Make sure you've paid up on your life insurance before
you do this.  Kids:  don't try this at home. )

Moving GnuCash is just like this.  We need to make small course corrections.
We need to make tiny changes that get us moving in the right direction
but don't cause us to capsize.   So the primary goal MUST be to keep
the system working.   Does your branch even COMPILE, let alone pass
all it's make check tests?   I dont think so.  And why not?  Because
you're doing too much at once.

> You can find an squeleton to create a GObject (taken from the one in
> Anjuta) in gobject-engine-dev, each objects define the functions to a
> correct construction/destruction, but you don't want to move the code
> jet.

"yet" being the operative phrase.  Now that we've got the code working
we could theoretically merge this part into trunk and then start working
on migrating the initialization and finalization routines on an object
by object.

> Then you must, in order to change a just little code:
>
> Initialization Process:
> * Change g_new with g_object_new, and keep the init process for the
> object you are working on (i.e. Account)
> * Keep qof_instance_init, and call it

I did this..

> Keep in mind that the QofInstance init must be called inmediatly after
> called g_object_new in order to keep the same process as if the object
> calls the registered function.

Yep.  I did this (although I think there may be some missing calls to
qof_instance_init_data() in some of the Clone() calls in the code).

> Destroying Process:
>
> * Remove g_free
> * Keep qof_instance_release and make shure you destroy the QofInstance
> in this call and at the end call g_object_unref

I still don't see why we need to keep qof_instance_release().  What is
it doing that I can't do from the QofInstance dispose() or finalize()
functions?

> Keep in mind that you must destroy the derived class before call
> qof_instance_release() and destroy the QofInstance member before call
> g_object_unref.

Of course.

> you can the the gobject-engine-dev for examples.

Actually, I did look in your branch for guidance, but I wanted to show
you exactly what I mean by "small steps" because clearly you didn't
understand.  Well, you didn't understand in the first branch, and you
haven't really dont much in the second branch.  I saw this project stalling
and figured a real example would show you exactly what all the rest of
us mean when we say "small steps".

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