GObject in GC implementation Plan

Josh Sled jsled at asynchronous.org
Wed Mar 21 18:35:39 EDT 2007


On Wed, 2007-03-21 at 00:42 -0600, Daniel Espinosa wrote: 
> Get GObject as the base of GC's objects. With the following advantages:
> 	- Get ref counting
> 	- Get signals events

Using GObject is a prerequisite of either of the separate "ref counting"
and "signals" projects, but aren't advantages that directly follow from
using GObject.


> ******OPTION 1: PORT QofEntity TO USE GObject AS BASE CLASS
> *******OPTION 2: PORT QofInstance TO USE GObject AS BASE CLASS
> *******OPTION 3: PORT GC's OBJECT TO USE GObject AS BASE CLASS

I read Option1-Step1 and Option2-Step2 as basically the same thing:
"everything will just happen".  They're not really "steps"; I don't take
away from them a clear plan of action.

Option 3 is broken out better, but it doesn't seem as suitable as Option
2.  In particular, I don't see why one would change the type hierarchy
twice (in Steps 2 and 5).  As well, it seems pretty agreeable all around
to merge QofInstance and QofEntity from the start.  At least for the
purposes of discussion, let's call this merged type "GncObject".

I'd agree with Chris; Option 2 is probably the better path.  Or maybe a
modified version of Option 3, where:

- QofInstance and QofEntity are combined

- The GnuCash types then subclass GncObject.

  - QofInstance fields are just inherited (not included by pointer)

- Minimal changes to use G[nc]Object.  I'm thinking, here, for example:

    // ..._get_type() { ...g_type_static_register()... }
    // ...

    Account*
    xaccAccountMalloc()
    {
        Account *a = g_object_new(GNC_ACCOUNT_TYPE, NULL);
        // ...existing Account setup...
        return a;
    }

  ...and, well, that's about all.  No signal or property registration,
  in particular.


[from Option 3...] 
> Step 4:
> Setup QofInstance to be a GObject and be sure to have a correct
> construction/destruction process, this will ensure a correct
> refcounting.

I'd suggest — in any plan — deferring handling "correct"
construction/destruction and ref counting to a later phase of work.


In particular, here's what I see happening.  Once you start to modify
(say) xaccFreeTransaction() to be "correct", it will want to look like:

    xaccFreeTransaction(Transaction *t)
    {
        g_object_unref(t);
    }

...then it only makes sense for its dispose handler to look like...

    {
        GList *splits = ...;
        g_list_foreach(splits, g_object_unref, ...);
    }

...which means you have to have "correct" both ref and unref behavior
for the Splits, which means, they need a "correct" dispose handler
like...

    {
        g_object_unref(split->account);
    }

...which means ... for it to be "correct", everything needs to happen
all at once.  It quickly gets to a point where a bunch of changes need
to be made to every file at the same time, increasing the chance that
the whole set isn't clear or clearly acceptable.

I don't think that that necessarily needs to be the case. Better
construction/destruction and ref-counting can be phased in.  In
particular, I think there are related groups of objects (Maybe {Account,
Split, Transaction}.  {GncCommodity, GncPrice, GncNumeric} ... &c.) that
could ref-count with each other, probably while intentionally ignoring
other groups of objects.  Along the way it wouldn't be fully "correct"
nor complete, but it'd be much more tractable.

Maybe you mean something else by "correct", though.

-- 
...jsled
http://asynchronous.org/ - a=jsled;b=asynchronous.org; echo ${a}@${b}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
Url : http://lists.gnucash.org/pipermail/gnucash-devel/attachments/20070321/79a42373/attachment.bin 


More information about the gnucash-devel mailing list